6 changed files with 106 additions and 40 deletions
@ -0,0 +1,76 @@ |
|||
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 |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue