You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.4 KiB
76 lines
2.4 KiB
import * as THREE from 'three'
|
|
import type { ITool } from './ITool.ts'
|
|
import { watch } from 'vue'
|
|
import type Viewport from '@/designer/Viewport.ts'
|
|
import { Line2 } from 'three/examples/jsm/lines/Line2.js'
|
|
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'
|
|
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'
|
|
|
|
/**
|
|
* 选择工具,用于在设计器中显示选中对象的包围盒
|
|
*/
|
|
export default class SelectInspect implements ITool {
|
|
viewport: any
|
|
material: LineMaterial
|
|
selectionBox: Line2
|
|
|
|
constructor() {
|
|
// 颜色变成黄
|
|
const color = 0xffff00 // 0xff0000
|
|
const lineWidth = 2
|
|
this.material = new LineMaterial({ color, linewidth: lineWidth })
|
|
}
|
|
|
|
init(viewport: Viewport) {
|
|
this.viewport = viewport
|
|
|
|
this.viewport.watchList.push(watch(() => this.viewport.state.selectedObject, (selectedObject) => {
|
|
if (this.selectionBox) {
|
|
viewport.scene.remove(this.selectionBox)
|
|
this.selectionBox.geometry.dispose()
|
|
this.selectionBox = null
|
|
}
|
|
|
|
const expandAmount = 0.2 // 扩展包围盒的大小
|
|
if (selectedObject !== null) {
|
|
// 避免某些蒙皮网格的帧延迟效应(e.g. Michelle.glb)
|
|
selectedObject.updateWorldMatrix(false, true)
|
|
|
|
const box = new THREE.Box3().setFromObject(selectedObject)
|
|
box.expandByScalar(expandAmount)
|
|
|
|
const size = new THREE.Vector3()
|
|
box.getSize(size)
|
|
|
|
const center = new THREE.Vector3()
|
|
box.getCenter(center)
|
|
|
|
// 创建包围盒几何体
|
|
const helperGeometry = new THREE.BoxGeometry(size.x, size.y, size.z)
|
|
const edgesGeometry = new THREE.EdgesGeometry(helperGeometry)
|
|
|
|
// 使用 LineGeometry 包装 edgesGeometry
|
|
const lineGeom = new LineGeometry()
|
|
//@ts-ignore
|
|
lineGeom.setPositions(edgesGeometry.attributes.position.array)
|
|
|
|
const selectionBox = new Line2(lineGeom, this.material)
|
|
selectionBox.computeLineDistances()
|
|
selectionBox.position.copy(center)
|
|
selectionBox.name = 'selectionBox'
|
|
this.selectionBox = selectionBox
|
|
|
|
this.viewport.scene.add(selectionBox)
|
|
}
|
|
}))
|
|
}
|
|
|
|
destory() {
|
|
// 销毁选择工具
|
|
if (this.selectionBox) {
|
|
this.viewport.scene.remove(this.selectionBox)
|
|
this.selectionBox.geometry.dispose()
|
|
this.selectionBox = null
|
|
}
|
|
}
|
|
}
|