Browse Source

包围盒优化

master
修宁 6 months ago
parent
commit
bfce920b79
  1. 4
      src/core/Constract.ts
  2. 93
      src/core/controls/SelectInspect.ts
  3. 23
      src/editor/Model2DEditor.vue
  4. 4
      vite.config.ts

4
src/core/Constract.ts

@ -22,6 +22,10 @@ const Constract = Object.freeze({
// 选择模式 // 选择模式
CursorModeSelectByRec: 'selectByRec', CursorModeSelectByRec: 'selectByRec',
// 黄选扩展包围盒的大小
RED_EXPAND_AMOUNT: 0.02,
YELLOW_EXPAND_AMOUNT: 0.1,
HEIGHT_GSTORE: 0.03, HEIGHT_GSTORE: 0.03,
HEIGHT_MEASURE: 0.02, HEIGHT_MEASURE: 0.02,
HEIGHT_RACK: 0, HEIGHT_RACK: 0,

93
src/core/controls/SelectInspect.ts

@ -8,6 +8,7 @@ import EventBus from '@/runtime/EventBus'
import { markRaw } from 'vue' import { markRaw } from 'vue'
import { getMeta } from '@/core/manager/ModuleManager.ts' import { getMeta } from '@/core/manager/ModuleManager.ts'
import MouseMoveInspect from '@/core/controls/MouseMoveInspect.ts' import MouseMoveInspect from '@/core/controls/MouseMoveInspect.ts'
import Constract from '@/core/Constract.ts'
let pdFn, pmFn, puFn let pdFn, pmFn, puFn
@ -19,12 +20,12 @@ export default class SelectInspect implements IControls {
/** /**
* 线 * 线
*/ */
yellowMaterial: LineMaterial = new LineMaterial({ color: 0xffff00, linewidth: 2 }) yellowMaterial: LineMaterial = new LineMaterial({ color: 0xffff00, linewidth: 3 })
/** /**
* 线 * 线
*/ */
redMaterial: LineMaterial = new LineMaterial({ color: 0xff0000, linewidth: 2 }) redMaterial: LineMaterial = new LineMaterial({ color: 0xff0000, linewidth: 3 })
/** /**
* *
@ -132,36 +133,43 @@ export default class SelectInspect implements IControls {
this.viewport.scene.add(this.redSelectionGroup) this.viewport.scene.add(this.redSelectionGroup)
} }
/**
*
*/
createRedSelectionBox(object: THREE.Object3D) { createRedSelectionBox(object: THREE.Object3D) {
// 如果对象没有 entityId,则不创建包围盒线框 // 如果对象没有 entityId,则不创建包围盒线框
if (!object.userData.entityId) { if (!object.userData.entityId) {
return return
} }
// 如果选中的对象小于 0.5,要扩展包围盒
const RED_EXPAND_AMOUNT = 0.01 // 扩展包围盒的大小
// 避免某些蒙皮网格的帧延迟效应(e.g. Michelle.glb)
object.updateWorldMatrix(false, true)
const box = new THREE.Box3().setFromObject(object) const box = new THREE.Box3().setFromObject(object)
box.expandByScalar(RED_EXPAND_AMOUNT) box.expandByScalar(Constract.RED_EXPAND_AMOUNT) // 假设 Constract.RED_EXPAND_AMOUNT 已定义
const size = new THREE.Vector3() const min = box.min
box.getSize(size) const max = box.max
const center = new THREE.Vector3() const corners = [
box.getCenter(center) new THREE.Vector3(min.x - Constract.RED_EXPAND_AMOUNT, max.y + Constract.RED_EXPAND_AMOUNT, min.z - Constract.RED_EXPAND_AMOUNT),
new THREE.Vector3(max.x + Constract.RED_EXPAND_AMOUNT, max.y + Constract.RED_EXPAND_AMOUNT, min.z - Constract.RED_EXPAND_AMOUNT),
new THREE.Vector3(max.x + Constract.RED_EXPAND_AMOUNT, max.y + Constract.RED_EXPAND_AMOUNT, max.z + Constract.RED_EXPAND_AMOUNT),
new THREE.Vector3(min.x - Constract.RED_EXPAND_AMOUNT, max.y + Constract.RED_EXPAND_AMOUNT, max.z + Constract.RED_EXPAND_AMOUNT)
]
// 构建矩形边框(4 条边)
const positions = []
for (let i = 0; i < 4; i++) {
const p1 = corners[i]
const p2 = corners[(i + 1) % 4]
positions.push(p1.x, p1.y, p1.z)
positions.push(p2.x, p2.y, p2.z)
}
// 创建包围盒几何体 // 创建几何体
const helperGeometry = new THREE.BoxGeometry(size.x, size.y, size.z)
const edgesGeometry = new THREE.EdgesGeometry(helperGeometry)
const lineGeom = new LineGeometry() const lineGeom = new LineGeometry()
// @ts-ignore const vertices = new Float32Array(positions)
lineGeom.setPositions(edgesGeometry.attributes.position.array) lineGeom.setPositions(vertices)
const selectionBox = new Line2(lineGeom, this.redMaterial) const selectionBox = new Line2(lineGeom, this.redMaterial)
selectionBox.computeLineDistances() selectionBox.computeLineDistances()
selectionBox.position.copy(center)
this.redSelectionGroup.add(selectionBox) this.redSelectionGroup.add(selectionBox)
} }
@ -177,30 +185,43 @@ export default class SelectInspect implements IControls {
} }
this.selectionId = selectedObject.userData?.entityId this.selectionId = selectedObject.userData?.entityId
// 如果选中的对象小于 0.5,要扩展包围盒
const YELLOW_EXPAND_AMOUNT = 0.03 // 扩展包围盒的大小
// 避免某些蒙皮网格的帧延迟效应(e.g. Michelle.glb) // 避免某些蒙皮网格的帧延迟效应(e.g. Michelle.glb)
selectedObject.updateWorldMatrix(false, true) selectedObject.updateWorldMatrix(false, true)
const box = new THREE.Box3().setFromObject(selectedObject) const box = new THREE.Box3().setFromObject(selectedObject)
box.expandByScalar(YELLOW_EXPAND_AMOUNT)
const size = new THREE.Vector3()
box.getSize(size)
const center = new THREE.Vector3() const min = box.min
box.getCenter(center) const max = box.max
const corners = [
new THREE.Vector3(min.x - Constract.YELLOW_EXPAND_AMOUNT, max.y + Constract.YELLOW_EXPAND_AMOUNT, min.z - Constract.YELLOW_EXPAND_AMOUNT),
new THREE.Vector3(max.x + Constract.YELLOW_EXPAND_AMOUNT, max.y + Constract.YELLOW_EXPAND_AMOUNT, min.z - Constract.YELLOW_EXPAND_AMOUNT),
new THREE.Vector3(max.x + Constract.YELLOW_EXPAND_AMOUNT, max.y + Constract.YELLOW_EXPAND_AMOUNT, max.z + Constract.YELLOW_EXPAND_AMOUNT),
new THREE.Vector3(min.x - Constract.YELLOW_EXPAND_AMOUNT, max.y + Constract.YELLOW_EXPAND_AMOUNT, max.z + Constract.YELLOW_EXPAND_AMOUNT)
]
// 构建矩形边框(4 条边)
const positions = []
for (let i = 0; i < 4; i++) {
const p1 = corners[i]
const p2 = corners[(i + 1) % 4]
positions.push(p1.x, p1.y, p1.z)
positions.push(p2.x, p2.y, p2.z)
}
// 创建包围盒几何体 // 创建几何体
const helperGeometry = new THREE.BoxGeometry(size.x, size.y, size.z)
const edgesGeometry = new THREE.EdgesGeometry(helperGeometry)
const lineGeom = new LineGeometry() const lineGeom = new LineGeometry()
// @ts-ignore const vertices = new Float32Array(positions)
lineGeom.setPositions(edgesGeometry.attributes.position.array) lineGeom.setPositions(vertices)
const selectionBox = new Line2(lineGeom, this.yellowMaterial) const selectionBox = new Line2(lineGeom, this.yellowMaterial)
selectionBox.computeLineDistances() selectionBox.computeLineDistances()
selectionBox.position.copy(center)
// 获取包围盒中心并设置位置
const center = new THREE.Vector3()
box.getCenter(center)
// selectionBox.position.copy(center)
selectionBox.computeLineDistances()
this.selectionBox = selectionBox this.selectionBox = selectionBox
console.log('selectedItem', this.viewport.state.selectedItem) console.log('selectedItem', this.viewport.state.selectedItem)

23
src/editor/Model2DEditor.vue

@ -11,10 +11,12 @@
<el-button-group> <el-button-group>
<el-button :icon="renderIcon('antd CameraFilled')" link <el-button :icon="renderIcon('antd CameraFilled')" link
:type="state?.view3DMode===Constract.Mode2D?'primary':''" :type="state?.view3DMode===Constract.Mode2D?'primary':''"
@click="state.view3DMode = Constract.Mode2D">2D</el-button> @click="state.view3DMode = Constract.Mode2D">2D
</el-button>
<el-button :icon="renderIcon('fa CameraRetro')" link <el-button :icon="renderIcon('fa CameraRetro')" link
:type="state?.view3DMode===Constract.Mode3D?'primary':''" :type="state?.view3DMode===Constract.Mode3D?'primary':''"
@click="state.view3DMode = Constract.Mode3D">3D</el-button> @click="state.view3DMode = Constract.Mode3D">3D
</el-button>
</el-button-group> </el-button-group>
</div> </div>
<div class="section-content"> <div class="section-content">
@ -69,18 +71,25 @@
<component :is="renderIcon('element Search')"></component> <component :is="renderIcon('element Search')"></component>
</template> </template>
</el-input> </el-input>
<el-text type="warning">00001</el-text> <el-button title="红选目标数" link type="warning" size="small">
{{ state?.selectedEntityId }}
</el-button>
<span class="section-toolbar-line"></span> <span class="section-toolbar-line"></span>
<el-text type="danger">00011</el-text> <el-button title="红选目标数" link type="danger" size="small">
{{ state?.multiSelectedEntityIds?.length }}
</el-button>
<span class="section-toolbar-line"></span> <span class="section-toolbar-line"></span>
<div> <el-button title="摄像头" :icon="renderIcon('element Camera')" link size="small">
{{ toFixed(state?.camera.position.x) }}, {{ toFixed(state?.camera.position.x) }},
{{ toFixed(state?.camera.position.y) }}, {{ toFixed(state?.camera.position.y) }},
{{ toFixed(state?.camera.position.z) }} {{ toFixed(state?.camera.position.z) }}
</div> </el-button>
<span class="section-toolbar-line"></span> <span class="section-toolbar-line"></span>
<div> <div>
{{ toFixed(state?.mouse.x) }},{{ toFixed(state?.mouse.z) }} <el-button title="鼠标所在位置" :icon="renderIcon('element Mouse')" link size="small">
{{ toFixed(state?.mouse.x) }},{{ toFixed(state?.mouse.z) }}
</el-button>
</div> </div>
</div> </div>
</div> </div>

4
vite.config.ts

@ -3,13 +3,13 @@ import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
// import vueJsx from '@vitejs/plugin-vue-jsx' // import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools' // import vueDevTools from 'vite-plugin-vue-devtools'
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
vue(), vue(),
// vueJsx(), // vueJsx(),
vueDevTools(), // vueDevTools(),
], ],
resolve: { resolve: {
alias: { alias: {

Loading…
Cancel
Save