Browse Source

包围盒优化

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

4
src/core/Constract.ts

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

87
src/core/controls/SelectInspect.ts

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

21
src/editor/Model2DEditor.vue

@ -11,10 +11,12 @@
<el-button-group>
<el-button :icon="renderIcon('antd CameraFilled')" link
: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
: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>
</div>
<div class="section-content">
@ -69,18 +71,25 @@
<component :is="renderIcon('element Search')"></component>
</template>
</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>
<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>
<div>
<el-button title="摄像头" :icon="renderIcon('element Camera')" link size="small">
{{ toFixed(state?.camera.position.x) }},
{{ toFixed(state?.camera.position.y) }},
{{ toFixed(state?.camera.position.z) }}
</div>
</el-button>
<span class="section-toolbar-line"></span>
<div>
<el-button title="鼠标所在位置" :icon="renderIcon('element Mouse')" link size="small">
{{ toFixed(state?.mouse.x) }},{{ toFixed(state?.mouse.z) }}
</el-button>
</div>
</div>
</div>

4
vite.config.ts

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

Loading…
Cancel
Save