diff --git a/src/core/manager/LineSegmentManager.ts b/src/core/manager/LineSegmentManager.ts index c011da0..db7eb40 100644 --- a/src/core/manager/LineSegmentManager.ts +++ b/src/core/manager/LineSegmentManager.ts @@ -26,11 +26,12 @@ export default class LineSegmentManager { * @param color 线段颜色 (可选) * @param userData 自定义数据 (可选) */ - createLine(lineId: string, start: THREE.Vector3 | [number, number, number], end: Vector3Like, color?: THREE.Color | number | string, userData: Partial = {}): LineManageWrap { + createLine(lineId: string, start: Vector3Like, end: Vector3Like, color?: THREE.Color | number | string, userData: Partial = {}): LineManageWrap { const segment = this.segments.get(lineId) if (segment) { - console.error(`LineSegmentManager: Line with id ${lineId} already exists.`) - return + // console.error(`LineSegmentManager: Line with id ${lineId} already exists.`) + // 如果线段已存在,则更新其起点、终点和颜色 + return this.updateLine(lineId, start, end, color) } const startVec = start instanceof THREE.Vector3 diff --git a/src/example/example1.js b/src/example/example1.js index 09396f5..ca55eff 100644 --- a/src/example/example1.js +++ b/src/example/example1.js @@ -97,31 +97,31 @@ export default { id: '6UhIIw9QPYh6acwyW8OSGs', t: 'gstore', v: true, - tf: [[-1, 0.1, 0.55], [0, 0, 0], [1.5, 1.2, 0.1]], - dt: { in: [], out: [], center: [], storeWidth: 1.4, storeDepth: 1.4 } + tf: [[-1, 0.1, 0.55], [0, 0, 0], [1.5, 0.1, 1.5]], + dt: { in: [], out: [], center: [] } }, { id: '1D0WSRPj8JJJwIcmA0UMqG', t: 'gstore', v: true, - tf: [[0.75, 0.1, 0.55], [0, 0, 0], [1.5, 1.2, 0.1]], - dt: { in: [], out: [], center: [], storeWidth: 1.4, storeDepth: 1.4 } + tf: [[0.75, 0.1, 0.55], [0, 0, 0], [1.5, 0.1, 1.5]], + dt: { in: [], out: [], center: [] } }, { - id: 'gstore3', + id: 'gstore333', t: 'gstore', v: true, - tf: [[3, 0.1, 0.55], [0, 0, 0], [1.5, 1.2, 0.1]], - dt: { in: [], out: [], center: [], storeWidth: 1.4, storeDepth: 1.4 } + tf: [[3, 0.1, 0.55], [0, 0, 0], [1.5, 0.1, 1.5]], + dt: { in: [], out: [], center: [] } }, { id: 'pallet1', t: 'pallet', v: true, - tf: [[0.75, 0.075, 0.55], [0, 0, 0], [1.5, 1.2, 0.1]], + tf: [[0.75, 0.075, 0.55], [0, 0, 0], [1.0, 0.1, 1.2]], dt: { in: [], out: [], center: [], palletWidth: 1, palletDepth: 1.2 } }, { id: 'pallet2', t: 'pallet', v: true, - tf: [[3, 0.075, 0.55], [0, 0, 0], [1.5, 1.2, 0.1]], + tf: [[3, 0.075, 0.55], [0, 0, 0], [1.0, 0.1, 1.2]], dt: { in: [], out: [], center: [], palletWidth: 1, palletDepth: 1.2 } }, { id: 'ptr1', @@ -139,13 +139,13 @@ export default { id: 'pallet3', t: 'pallet', v: true, - tf: [[3, 0.175, 1.88], [0, 0, 0], [1.5, 1.2, 0.1]], + tf: [[3, 0.175, 1.88], [0, 0, 0], [1.5, 0.1, 1.2]], dt: { in: [], out: [], center: [], palletWidth: 1, palletDepth: 1.2 } }, { id: 'pallet4', t: 'pallet', v: true, - tf: [[0.75, 0.175, 3.5], [0, 0, 0], [1.5, 1.2, 0.1]], + tf: [[0.75, 0.175, 3.5], [0, 0, 0], [1.5, 0.1, 1.2]], dt: { in: [], out: [], center: [], palletWidth: 1, palletDepth: 1.2 } } ] diff --git a/src/modules/gstore/GstoreRenderer.ts b/src/modules/gstore/GstoreRenderer.ts index 562f47e..55e3453 100644 --- a/src/modules/gstore/GstoreRenderer.ts +++ b/src/modules/gstore/GstoreRenderer.ts @@ -2,6 +2,9 @@ import * as THREE from 'three' import BaseRenderer from '@/core/base/BaseRenderer.ts' import Constract from '@/core/Constract.ts' import { type Object3DLike } from '@/types/ModelTypes.ts' +import InstancePointManager from '@/core/manager/InstancePointManager.ts' +import LineSegmentManager from '@/core/manager/LineSegmentManager.ts' +import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial' /** * 地堆货位渲染器 @@ -10,8 +13,6 @@ import { type Object3DLike } from '@/types/ModelTypes.ts' export default class GstoreRenderer extends BaseRenderer { static POINT_NAME = 'ground_store' - pointMaterial: THREE.Material - /** * 默认点的高度, 防止和地面重合 */ @@ -24,105 +25,77 @@ export default class GstoreRenderer extends BaseRenderer { width: 1.5, depth: 1.3, strokeColor: 0x038217, - strokeWidth: 0.15 + strokeWidth: 0.08 } - centerMaterial = new THREE.MeshBasicMaterial({ + pointGeometry = new THREE.PlaneGeometry( + 1, 1 + ).rotateX(-Math.PI / 2) + pointMaterial: THREE.Material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.5 }) - getColorOfMaterial(strokeColor: number): THREE.MeshBasicMaterial { - return new THREE.MeshBasicMaterial({ - color: strokeColor, - transparent: true, - opacity: 0.9 - }) - } - - edgeMaterial = this.getColorOfMaterial(this.defaultPointOption.strokeColor) - - createPoint(item: ItemJson, option?: RendererCudOption): Object3DLike { - const point = this.createMesh(item.tf[2][0], item.tf[2][2], item.dt.strokeWidth, item.dt.strokeColor) - point.position.set(item.tf[0][0], item.tf[0][1], item.tf[0][2]) + strokeMaterial = new LineMaterial({ + color: this.defaultPointOption.strokeColor, + transparent: false, + linewidth: this.defaultPointOption.strokeWidth, + gapSize: 0, + worldUnits: true + }) - point.rotation.set( - THREE.MathUtils.degToRad(item.tf[1][0]), - THREE.MathUtils.degToRad(item.tf[1][1]), - THREE.MathUtils.degToRad(item.tf[1][2]) + get pointManager(): InstancePointManager { + if (!this.tempViewport) { + throw new Error('tempViewport is not set.') + } + return this.tempViewport.getOrCreatePointManager(this.itemTypeName, () => + // 构建 InstanceMesh 代理对象 + InstancePointManager.create(this.itemTypeName, + this.tempViewport, + this.pointGeometry, + this.pointMaterial, + Constract.MAX_MEASURE_INSTANCES) ) - return point } - updatePoint(item: ItemJson, object: THREE.Group, option?: RendererCudOption): Object3DLike { - // 如果 object.userData.strokeWidth 没有变化,并且 scale.x/z 没有变化, 则只平移位置 - if (!object || - (object.userData.strokeWidth !== item.dt.strokeWidth && item.dt.strokeWidth) || - (object.userData.strokeColor !== item.dt.strokeColor && item.dt.strokeColor) || - (object.userData.width !== item.tf[2][0] || object.userData.depth !== item.tf[2][2])) { - - // 线宽度 / 大小 / 颜色发生变化. 重新创建一个新的点 - object = this.createPoint(item) as THREE.Group + get lineSegmentManager(): LineSegmentManager { + if (!this.tempViewport) { + throw new Error('tempViewport is not set.') } - - object.rotation.set( - THREE.MathUtils.degToRad(item.tf[1][0]), - THREE.MathUtils.degToRad(item.tf[1][1]), - THREE.MathUtils.degToRad(item.tf[1][2]) + return this.tempViewport.getOrCreateLineManager(this.itemTypeName, () => + // 构建 LineSegment.points 代理对象 + LineSegmentManager.create(this.itemTypeName, + this.tempViewport, + this.strokeMaterial) ) - object.position.set(item.tf[0][0], item.tf[0][1], item.tf[0][2]) - return object } - createMesh(totalWidth: number, totalDepth: number, strokeWidth = 0.15, strokeColor = this.defaultPointOption.strokeColor): Object3DLike { - // === 边框部分(使用 Shape + Hole 构建)=== - const shape = new THREE.Shape() - shape.moveTo(-totalWidth / 2, -totalDepth / 2) - shape.lineTo(totalWidth / 2, -totalDepth / 2) - shape.lineTo(totalWidth / 2, totalDepth / 2) - shape.lineTo(-totalWidth / 2, totalDepth / 2) - shape.closePath() - - const hole = new THREE.Path() - hole.moveTo(-totalWidth / 2 + strokeWidth, -totalDepth / 2 + strokeWidth) - hole.lineTo(totalWidth / 2 - strokeWidth, -totalDepth / 2 + strokeWidth) - hole.lineTo(totalWidth / 2 - strokeWidth, totalDepth / 2 - strokeWidth) - hole.lineTo(-totalWidth / 2 + strokeWidth, totalDepth / 2 - strokeWidth) - hole.closePath() - - shape.holes.push(hole) - - // ExtrudeGeometry 默认是沿 Z 轴拉伸 → 我们需要让它朝 Y 轴拉伸 - const edgeGeometry = new THREE.ExtrudeGeometry(shape, { - depth: 0.02, - bevelEnabled: false - }) - edgeGeometry.rotateX(-Math.PI / 2) - edgeGeometry.translate(0, 0.01, 0) - - const centerGeometry = new THREE.PlaneGeometry(totalWidth, totalDepth) - centerGeometry.rotateX(-Math.PI / 2) - - // === 网格组合 === - const edgeMesh = new THREE.Mesh(edgeGeometry, - (this.defaultPointOption.strokeColor === strokeColor) ? this.edgeMaterial : this.getColorOfMaterial(strokeColor) - ) - const centerMesh = new THREE.Mesh(centerGeometry, this.centerMaterial) - - const group = new THREE.Group() - group.add(edgeMesh) - if (this.defaultPointOption.strokeColor !== strokeColor) { - // this.centerMaterial.color.set(strokeColor) - edgeMesh.material.color.set(strokeColor) - } - group.add(centerMesh) + createPointBasic(item: ItemJson, option?: RendererCudOption): Object3DLike { + return this.pointManager.createPoint(item) + } - group.userData.strokeWidth = strokeWidth - group.userData.strokeColor = strokeColor - group.userData.width = totalWidth - group.userData.depth = totalDepth - return group + afterCreateOrUpdatePoint(item: ItemJson, option: RendererCudOption, object: Object3DLike) { + super.afterCreateOrUpdatePoint(item, option, object) + + const center = [item.tf[0][0], item.tf[0][2]] + const h = item.tf[0][1] || this.defulePositionY + const widthHalf = item.tf[2][0] / 2 + const depthHalf = item.tf[2][2] / 2 + const lwHalf = (item.dt.strokeWidth || this.defaultPointOption.strokeWidth) / 2 + // 左上角 + const p1 = [center[0] - widthHalf + lwHalf, h, center[1] - depthHalf + lwHalf] + // 右上角 + const p2 = [center[0] + widthHalf - lwHalf, h, center[1] - depthHalf + lwHalf] + // 右下角 + const p3 = [center[0] + widthHalf - lwHalf, h, center[1] + depthHalf - lwHalf] + // 左下角 + const p4 = [center[0] - widthHalf + lwHalf, h, center[1] + depthHalf - lwHalf] + + this.lineSegmentManager.createLine(item.id + '_l1', p1, p2, this.strokeMaterial.color) + this.lineSegmentManager.createLine(item.id + '_l2', p2, p3, this.strokeMaterial.color) + this.lineSegmentManager.createLine(item.id + '_l3', p3, p4, this.strokeMaterial.color) + this.lineSegmentManager.createLine(item.id + '_l4', p4, p1, this.strokeMaterial.color) } createLineBasic(start: ItemJson, end: ItemJson, type: LinkType): THREE.Object3D { @@ -135,6 +108,8 @@ export default class GstoreRenderer extends BaseRenderer { dispose() { super.dispose() - this.pointMaterial?.dispose() + this.pointGeometry.dispose() + this.pointMaterial.dispose() + this.strokeMaterial.dispose() } }