diff --git a/src/example/example1.js b/src/example/example1.js index 6452663..a2f5d05 100644 --- a/src/example/example1.js +++ b/src/example/example1.js @@ -160,11 +160,11 @@ export default { id: 'rack1', t: 'rack', v: true, - tf: [[4.196, 0.1, 5.882], [0, 90, 0], [1, 1, 1]], + tf: [[4.196, 0.1, 5.882], [0, 90, 0], [0.1, 0.1, 1]], dt: { rackDepth: 1, - rackWidth: 5.1, - rackHeight: 4.2, + // rackWidth: 5.1, + // rackHeight: 4.2, levelCount: 3, bayCount: 4, hideFloor: false, @@ -374,39 +374,64 @@ export default { id: 'pallet1124', t: 'pallet', v: true, - tf: [[4.196, 1.65, 3.95], [0, 0, 0], [1.2, 0.15, 1]], - dt: { in: [], out: [], center: [] } + tf: [[0, 0, 0], [0, 0, 0], [1.2, 0.15, 1]], + dt: { in: [], out: [], center: [], storeAt: { item: 'rack1', bay: 0, level: 1, cell: 0 } } }, { id: 'pallet1125', t: 'pallet', v: true, - tf: [[4.196, 1.65, 5.225], [0, 0, 0], [1.2, 0.15, 1]], - dt: { in: [], out: [], center: [] } + tf: [[0, 0, 0], [0, 0, 0], [1.2, 0.15, 1]], + dt: { in: [], out: [], center: [], storeAt: { item: 'rack1', bay: 0, level: 2, cell: 0 } } }, { id: 'pallet1126', t: 'pallet', v: true, - tf: [[4.196, 1.65, 7.775], [0, 0, 0], [1.2, 0.15, 1]], - dt: { in: [], out: [], center: [] } + tf: [[0, 0, 0], [0, 0, 0], [1.2, 0.15, 1]], + dt: { in: [], out: [], center: [], storeAt: { item: 'rack1', bay: 2, level: 1, cell: 0 } } }, { id: 'pallet1127', t: 'pallet', v: true, - tf: [[4.196, 3.05, 3.95], [0, 0, 0], [1.2, 0.15, 1]], - dt: { in: [], out: [], center: [] } + tf: [[0, 0, 0], [0, 0, 0], [1.2, 0.15, 1]], + dt: { in: [], out: [], center: [], storeAt: { item: 'rack1', bay: 2, level: 2, cell: 0 } } }, { id: 'pallet1128', t: 'pallet', v: true, - tf: [[4.196, 3.05, 5.225], [0, 0, 0], [1.2, 0.15, 1]], - dt: { in: [], out: [], center: [] } + tf: [[0, 0, 0], [0, 0, 0], [1.2, 0.15, 1]], + dt: { in: [], out: [], center: [], storeAt: { item: 'rack1', bay: 3, level: 1, cell: 0 } } }, { id: 'pallet1129', t: 'pallet', v: true, - tf: [[4.196, 3.05, 7.775], [0, 0, 0], [1.2, 0.15, 1]], - dt: { in: [], out: [], center: [] } - }] + tf: [[0, 0, 0], [0, 0, 0], [1.2, 0.15, 1]], + dt: { in: [], out: [], center: [], storeAt: { item: 'rack1', bay: 3, level: 2, cell: 0 } } + }, { + id: 'carton0', + t: 'carton', + v: true, + tf: [[0, 0, 0], [0, 0, 0], [1.2, 1, 1]], + dt: { in: [], out: [], center: [], storeAt: { item: 'rack1', bay: 0, level: 0, cell: 0 } } + }, { + id: 'carton1', + t: 'carton', + v: true, + tf: [[0, 0, 0], [0, 0, 0], [1.2, 1, 1]], + dt: { in: [], out: [], center: [], storeAt: { item: 'rack1', bay: 1, level: 0, cell: 0 } } + }, { + id: 'carton2', + t: 'carton', + v: true, + tf: [[0, 0, 0], [0, 0, 0], [1.2, 1, 1]], + dt: { in: [], out: [], center: [], storeAt: { item: 'rack1', bay: 2, level: 0, cell: 0 } } + }, { + id: 'carton3', + t: 'carton', + v: true, + tf: [[0, 0, 0], [0, 0, 0], [1.2, 1, 1]], + dt: { in: [], out: [], center: [], storeAt: { item: 'rack1', bay: 3, level: 0, cell: 0 } } + } + ] }, { catalogCode: 'f3', t: 'floor', diff --git a/src/modules/rack/RackRenderer.ts b/src/modules/rack/RackRenderer.ts index 792e88c..68420e1 100644 --- a/src/modules/rack/RackRenderer.ts +++ b/src/modules/rack/RackRenderer.ts @@ -9,6 +9,7 @@ import { Material } from 'three/src/materials/Material' import { InstancedMesh } from 'three/src/objects/InstancedMesh' //@ts-ignore import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js' +import type Viewport from '@/core/engine/Viewport.ts' /** * 货架货位渲染器 @@ -56,6 +57,70 @@ export default class RackRenderer extends BaseRenderer { throw new Error('not allow store line.') } + /** + * 获取物品存放在货架后的位置和旋转角度 + * item.dt.storeAt 必须存在, 比如 { item:'货架ID', bay:0, level:1, cell:0 } + */ + getStorePlacement(viewport: Viewport, item: ItemJson): { position: [number, number, number], rotation: [number, number, number] } { + if (!item.dt?.storeAt?.item) { + // 没有定义存储位置,返回空对象 + //@ts-ignore + return {} + } + + const bay = item.dt?.storeAt?.bay || 0 + const level = item.dt?.storeAt?.level || 0 + // 暂时不用算格子 const cell = item.dt?.storeAt?.cell || 0 + + // 目标货架 + const rack = viewport.entityManager.findItemById(item.dt.storeAt.item) + const rackWidth = decimalSumBy(rack.dt.bays, (b: any) => b.bayWidth) + const bays = rack.dt.bays + const levelHeights = rack.dt.bays[bay]?.levelHeight + + // 局部坐标系下的偏移量 + let localX = 0 + for (let i = 0; i < bay; i++) { + localX += bays[i]?.bayWidth || 0 + } + localX += bays[bay].bayWidth / 2 // 居中 + + let localY = 0 + for (let i = 0; i < level; i++) { + localY += levelHeights[i] + } + + // 构建局部偏移向量 + const rackPos = new THREE.Vector3(...rack.tf[0]) + const offset = new THREE.Vector3( + localX - rackWidth / 2, // 相对坐标从最左边开始, + localY, 0) + + // 应用货架的旋转 + const q = new THREE.Quaternion() + q.setFromEuler(new THREE.Euler( + THREE.MathUtils.degToRad(rack.tf[1][0]), + THREE.MathUtils.degToRad(rack.tf[1][1]), + THREE.MathUtils.degToRad(rack.tf[1][2]) + )) + + offset.applyQuaternion(q) + const worldPosition = rackPos.clone().add(offset) + + return { + position: [ + worldPosition.x, + worldPosition.y + 0.15, // 加上横梁高度 + worldPosition.z + ], + rotation: [ + // 托盘旋转90度才能放进货架 + rack.tf[1][0], + rack.tf[1][1] + 90, + rack.tf[1][2] + ] + } + } createPoint(item: ItemJson, option?: RendererCudOption): THREE.Object3D { // 创建平面几何体 @@ -131,7 +196,6 @@ export default class RackRenderer extends BaseRenderer { group.add(mesh) }) - // 设置位置 group.position.set(item.tf[0][0], item.tf[0][1], item.tf[0][2]) @@ -141,9 +205,12 @@ export default class RackRenderer extends BaseRenderer { THREE.MathUtils.degToRad(item.tf[1][2]) ) - // item.dt.rackWidth = rackWidth item.dt.rackHeight = rackHeight + + item.tf[2][0] = rackWidth + item.tf[2][1] = rackHeight + return group } @@ -474,9 +541,9 @@ export default class RackRenderer extends BaseRenderer { distanceX += bay.bayWidth } vBarMatrix.push({ - x: distanceX - rackWidth/2, + x: distanceX - rackWidth / 2, y: 0, - z: -rackDepth/2, + z: -rackDepth / 2, sx: 0.8, sy: 1, sz: 1, @@ -486,9 +553,9 @@ export default class RackRenderer extends BaseRenderer { l: rackHeight }) vBarMatrix.push({ - x: distanceX - rackWidth/2, + x: distanceX - rackWidth / 2, y: 0, - z: item.dt.rackDepth - rackDepth/2, + z: item.dt.rackDepth - rackDepth / 2, sx: 0.8, sy: 1, sz: 1, @@ -498,9 +565,9 @@ export default class RackRenderer extends BaseRenderer { l: rackHeight }) linkBarMatrix.push({ - x: distanceX - rackWidth/2, + x: distanceX - rackWidth / 2, y: 0, - z: i % 2 == 0 ? (item.dt.rackDepth - rackDepth/2) : -rackDepth/2, + z: i % 2 == 0 ? (item.dt.rackDepth - rackDepth / 2) : -rackDepth / 2, sx: 1, sy: 1, sz: 1, @@ -523,9 +590,9 @@ export default class RackRenderer extends BaseRenderer { continue } hBarMatrix.push({ - x: distanceX - rackWidth/2, + x: distanceX - rackWidth / 2, y: distanceY, - z: -rackDepth/2, + z: -rackDepth / 2, sx: 1, sy: 0.8, sz: 1, @@ -535,9 +602,9 @@ export default class RackRenderer extends BaseRenderer { l: bay.bayWidth }) hBarMatrix.push({ - x: distanceX - rackWidth/2, + x: distanceX - rackWidth / 2, y: distanceY, - z: item.dt.rackDepth-rackDepth/2, + z: item.dt.rackDepth - rackDepth / 2, sx: 1, sy: 0.8, sz: 1, diff --git a/src/types/model.d.ts b/src/types/model.d.ts index 28ee083..46d2275 100644 --- a/src/types/model.d.ts +++ b/src/types/model.d.ts @@ -230,6 +230,11 @@ interface ItemJson extends ItemMetrix { cell?: number // 货架(地堆货位)的格 } + bays?: { + bayWidth: number, + levelHeight: number[] + }[] + /** * 其他自定义数据, 可以存储任何数据 */