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

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
}
}
}