diff --git a/src/core/engine/Viewport.ts b/src/core/engine/Viewport.ts index 207ec27..bf28234 100644 --- a/src/core/engine/Viewport.ts +++ b/src/core/engine/Viewport.ts @@ -26,6 +26,7 @@ import LabelManager from '@/core/manager/LabelManager.ts' import type InstancePointManager from '@/core/manager/InstancePointManager.ts' import type LineSegmentManager from '@/core/manager/LineSegmentManager.ts' import type { Object3DLike } from '@/types/ModelTypes.ts' +import type InstanceMeshManager from '@/core/manager/InstanceMeshManager.ts' /** * 视窗对象 @@ -65,6 +66,9 @@ export default class Viewport { // 点实例管理器 moduleName -> InstancePointManager pointManagerMap: Map = new Map() + // 对象实例管理器 moduleName -> InstanceMeshManager + meshManager: Map = new Map() + // 线段实例管理器 moduleName -> InstancePointManager lineSegmentManagerMap: Map = new Map() @@ -113,6 +117,22 @@ export default class Viewport { * @param typeName 点类型名称 * @param createFn 创建点管理器的函数 */ + getOrCreateMeshManager(typeName: string, createFn: () => InstanceMeshManager): InstanceMeshManager { + let meshManager = this.meshManager.get(typeName) + if (!meshManager) { + meshManager = createFn() + if (meshManager) { + this.meshManager.set(typeName, meshManager) + } + } + return meshManager + } + + /** + * 获取或创建点管理器 + * @param typeName 点类型名称 + * @param createFn 创建点管理器的函数 + */ getOrCreatePointManager(typeName: string, createFn: () => InstancePointManager): InstancePointManager { let pointManager = this.pointManagerMap.get(typeName) if (!pointManager) { diff --git a/src/core/manager/InstanceMeshManager.ts b/src/core/manager/InstanceMeshManager.ts index 56cde0c..aaf0acf 100644 --- a/src/core/manager/InstanceMeshManager.ts +++ b/src/core/manager/InstanceMeshManager.ts @@ -18,8 +18,9 @@ export default class InstanceMeshManager { private readonly dummy: THREE.Object3D = new THREE.Object3D() - constructor(name: string, viewport: Viewport, allowSelect: boolean, allowDrag: boolean, - geometry: THREE.BufferGeometry, material: THREE.Material) { + constructor(name: string, viewport: Viewport, + geometry: THREE.BufferGeometry, material: THREE.Material, + allowSelect: boolean, allowDrag: boolean) { this.name = name this.viewport = viewport this.allowSelect = allowSelect @@ -65,7 +66,22 @@ export default class InstanceMeshManager { return new InstanceMeshWrap(entityId, this, blockIndex, meshIndex) } - delete(wrap: InstanceMeshWrap) { + delete(wrapOrId: InstanceMeshWrap | string) { + let wrap: InstanceMeshWrap + if (typeof wrapOrId === 'string') { + wrap = this.__uuidMap.get(wrapOrId) + if (!wrap) { + console.warn(`InstanceMeshManager: Wrap with UUID ${wrapOrId} not found`) + return + } + } else { + wrap = wrapOrId + if (!wrap || !this.__uuidMap.has(wrap.uuid)) { + console.warn(`InstanceMeshManager: Wrap ${wrap.uuid} not found`) + return + } + } + const block = this.blocks[wrap.blockIndex] if (!block) { console.warn(`InstanceMeshManager: Block ${wrap.blockIndex} not found for wrap ${wrap.uuid}`) @@ -102,10 +118,12 @@ export default class InstanceMeshManager { console.warn(`InstanceMeshManager: Block ${wrap.blockIndex} not found!`) return } - this.__uuidMap.set(wrap.uuid, wrap) + + if (!block.__indexIdMap.has(wrap.meshIndex)) { + this.__uuidMap.set(wrap.uuid, wrap) + wrap.parent = block.instancedMesh + } block.instancedMesh.setMatrixAt(wrap.meshIndex, matrix) - wrap.parent = block.instancedMesh - wrap.visible = true // 默认可见 block.instancedMesh.instanceMatrix.needsUpdate = true } @@ -139,7 +157,7 @@ export class InstanceMeshWrap { this.blockIndex = blockIndex } - syncMatrix(matrix: THREE.Matrix4): InstanceMeshWrap { + setMatrix4(matrix: THREE.Matrix4): InstanceMeshWrap { this.manager.setBlockMatrixAt(this, matrix) return this } diff --git a/src/modules/way/WayRenderer.ts b/src/modules/way/WayRenderer.ts index 58207fd..d6ab967 100644 --- a/src/modules/way/WayRenderer.ts +++ b/src/modules/way/WayRenderer.ts @@ -1,13 +1,12 @@ import * as THREE from 'three' import BaseRenderer from '@/core/base/BaseRenderer.ts' import MoveLinePointPng from '@/assets/images/moveline_point.png' -import { getLineId, getMatrixFromTf, linkPlaneByPoint } from '@/core/ModelUtils.ts' +import { getLineId, linkPlaneByPoint } from '@/core/ModelUtils.ts' import Constract from '@/core/Constract.ts' import InstancePointManager, { PointManageWrap } from '@/core/manager/InstancePointManager.ts' import type { Object3DLike } from '@/types/ModelTypes.ts' import TriangleUrl from '@/assets/images/conveyor/shapes/triangle.png' -import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial' -import LineSegmentManager from '@/core/manager/LineSegmentManager.ts' +import InstanceMeshManager from '@/core/manager/InstanceMeshManager.ts' /** * AGV行走路线渲染器 point 是二维码站点 @@ -136,7 +135,7 @@ export default class WayRenderer extends BaseRenderer { if (object.userData.dirWraps) { // 清空之前的箭头 object.userData.dirWraps.forEach((uuid: string) => { - this.dirPointManager.deletePoint(uuid) + this.dirPointManager.delete(uuid) }) } @@ -147,18 +146,20 @@ export default class WayRenderer extends BaseRenderer { } else if (length < 3) { // 如果两点距离小于 3m,则在中间添加一个方向指示器 - const dirWrap = this.dirPointManager.createPointSimple(object.uuid + '_dir') - dirWrap.position.setFromMatrixPosition(matrix) - dirWrap.rotation.setFromRotationMatrix(matrix) - dirWrap.scale.set(0.4, 0.01, 0.2) - dirWrap.manager.syncMeshObject3D(dirWrap) - + const dirWrap = this.dirPointManager.create(object.uuid + '_dir') + + const dummy = new THREE.Object3D() + dummy.position.setFromMatrixPosition(matrix) + dummy.rotation.setFromRotationMatrix(matrix) + dummy.scale.set(0.4, 0.01, 0.2) + dummy.updateMatrix() + dirWrap.setMatrix4(dummy.matrix) object.userData.dirWraps = [dirWrap.uuid] } else { // 否则每隔 3m 添加一个方向指示器 for (let i = 0; i < length; i += 3) { - const dirWrap = this.dirPointManager.createPointSimple(object.uuid + '_dir_' + i) + const dirWrap = this.dirPointManager.create(object.uuid + '_dir_' + i) const position = startPosition.clone().lerp(endPosition, i / length) const dummy = new THREE.Object3D() dummy.position.copy(position) @@ -166,7 +167,7 @@ export default class WayRenderer extends BaseRenderer { dummy.scale.set(0.4, 0.01, 0.2) dummy.updateMatrix() - dirWrap.applyMatrix4(dummy.matrix) + dirWrap.setMatrix4(dummy.matrix) if (!object.userData.dirWraps) { object.userData.dirWraps = [] @@ -185,7 +186,7 @@ export default class WayRenderer extends BaseRenderer { if (object.userData.dirWraps) { // 清空之前的箭头 object.userData.dirWraps.forEach((uuid: string) => { - this.dirPointManager.deletePoint(uuid) + this.dirPointManager.delete(uuid) }) } } @@ -224,13 +225,13 @@ export default class WayRenderer extends BaseRenderer { ) } - get dirPointManager(): InstancePointManager { + get dirPointManager(): InstanceMeshManager { if (!this.tempViewport) { throw new Error('tempViewport is not set.') } - return this.tempViewport.getOrCreatePointManager(this.itemTypeName + '_dir', () => + return this.tempViewport.getOrCreateMeshManager(this.itemTypeName + '_dir', () => // 构建 InstanceMesh 代理对象 - InstancePointManager.create(this.itemTypeName + '_dir', + new InstanceMeshManager(this.itemTypeName + '_dir', this.tempViewport, this.dirGeometry, this.dirMaterial,