Browse Source

Merge remote-tracking branch 'origin/master'

master
yuliang 6 months ago
parent
commit
5696b34c04
  1. 6
      src/core/Constract.ts
  2. 2
      src/core/ModelUtils.ts
  3. 74
      src/core/manager/InstanceMeshBlock.ts
  4. 151
      src/core/manager/InstanceMeshManager.ts
  5. 166
      src/core/manager/InstancePointManager.ts
  6. 1
      src/example/ExampleUtil.js
  7. 2
      src/example/example1.js
  8. 2
      src/modules/carton/CartonRenderer.ts
  9. 2
      src/modules/gstore/GstoreRenderer.ts
  10. 2
      src/modules/measure/MeasureRenderer.ts
  11. 2
      src/modules/pallet/PalletRenderer.ts
  12. 246
      src/modules/rack/RackRenderer.ts
  13. 2
      src/modules/tote/ToteRenderer.ts
  14. 6
      src/modules/way/WayRenderer.ts

6
src/core/Constract.ts

@ -32,11 +32,5 @@ const Constract = Object.freeze({
HEIGHT_WAY: 0.01, HEIGHT_WAY: 0.01,
HEIGHT_WAY_LABEL: 0.03, HEIGHT_WAY_LABEL: 0.03,
HEIGHT_WAY_LINE: 0.02, HEIGHT_WAY_LINE: 0.02,
MAX_WAY_INSTANCES: 10000,
MAX_WAY_LINE_INSTANCES: 40000,
MAX_MEASURE_INSTANCES: 1000,
MAX_GSTORE_INSTANCES: 10000,
MAX_PALLET_INSTANCES: 10000
}) })
export default Constract export default Constract

2
src/core/ModelUtils.ts

@ -147,7 +147,7 @@ export function getClosestObject(viewport: Viewport, object: THREE.Object3D, ins
if (object.userData && object.userData.t && object.userData.entityId) { if (object.userData && object.userData.t && object.userData.entityId) {
// 找到第一个有效的业务 Object3D // 找到第一个有效的业务 Object3D
if (object instanceof THREE.InstancedMesh && instanceId >= 0) { if (object instanceof THREE.InstancedMesh && instanceId >= 0) {
return viewport.pointManagerMap.get(object.userData.t)?.findByMeshInstanceId(instanceId) return viewport.pointManagerMap.get(object.userData.t)?.findByMeshInstanceId(object.userData.blockIndex, instanceId)
} }
return object return object
} }

74
src/core/manager/InstanceMeshBlock.ts

@ -0,0 +1,74 @@
import * as THREE from 'three'
import type Viewport from '@/core/engine/Viewport.ts'
export default class InstanceMeshBlock {
public readonly name: string
public readonly blockIndex: number
public readonly viewport: Viewport
public readonly instancedMesh: THREE.InstancedMesh
public readonly freeIndices: number[] = []
// instanceId -> itemId
public readonly __indexIdMap = new Map<number, string>()
getFreeMeshIndex(): number {
if (this.freeIndices.length === 0) {
return -1 // No free index available
}
return this.freeIndices.pop() // Return the last free index
}
constructor(itemTypeName: string, allowSelect: boolean, allowDrag: boolean, viewport: Viewport,
geometry: THREE.BufferGeometry, material: THREE.Material,
blockIndex: number, capacity: number) {
this.name = itemTypeName
this.blockIndex = blockIndex
this.viewport = viewport
this.instancedMesh = new THREE.InstancedMesh(geometry, material, capacity)
this.instancedMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)
console.log('createBlock: ' + itemTypeName + '[' + blockIndex + '] capacity:', capacity)
viewport.scene.add(this.instancedMesh)
if (allowSelect) {
this.viewport.entityManager._selectableObjects.push(this.instancedMesh)
}
if (allowDrag) {
this.viewport.entityManager._draggableObjects.push(this.instancedMesh)
}
this.instancedMesh.userData.t = itemTypeName
this.instancedMesh.userData.entityId = 'InstanceMeshBlock_' + itemTypeName + '_' + blockIndex
_.extend(this.instancedMesh.userData,{
t: itemTypeName,
blockIndex: blockIndex
})
const dummy = new THREE.Object3D()
dummy.scale.set(0, 0, 0)
dummy.updateMatrix()
for (let i = 0; i < capacity; i++) {
this.instancedMesh.setMatrixAt(i, dummy.matrix)
this.freeIndices.push(i)
}
this.instancedMesh.instanceMatrix.needsUpdate = true
}
dispose() {
this.viewport.scene.remove(this.instancedMesh)
this.instancedMesh.geometry.dispose()
if (this.instancedMesh.material) {
if (Array.isArray(this.instancedMesh.material)) {
this.instancedMesh.material.forEach(mat => mat.dispose())
} else {
this.instancedMesh.material.dispose()
}
}
this.instancedMesh.dispose()
this.__indexIdMap.clear()
this.freeIndices.length = 0
}
}

151
src/core/manager/InstanceMeshManager.ts

@ -0,0 +1,151 @@
import * as THREE from 'three'
import type Viewport from '@/core/engine/Viewport.ts'
import InstanceMeshBlock from '@/core/manager/InstanceMeshBlock.ts'
import { PointManageWrap } from '@/core/manager/InstancePointManager.ts'
export default class InstanceMeshManager {
private __uuidMap = new Map<string, InstanceMeshWrap>()
public readonly name: string
public readonly viewport: Viewport
public readonly allowSelect: boolean
public readonly allowDrag: boolean
public readonly blockCapacity: number = 1000 // 每个 block 的容量
public readonly blocks: InstanceMeshBlock[] = []
private readonly geometry: THREE.BufferGeometry
private readonly material: THREE.Material
private readonly dummy: THREE.Object3D = new THREE.Object3D()
constructor(name: string, viewport: Viewport, allowSelect: boolean, allowDrag: boolean,
geometry: THREE.BufferGeometry, material: THREE.Material) {
this.name = name
this.viewport = viewport
this.allowSelect = allowSelect
this.allowDrag = allowDrag
this.geometry = geometry
this.material = material
}
/**
*
*/
findByMeshInstanceId(blockIndex: number, instanceId: number): InstanceMeshWrap {
if (!this.blocks[blockIndex]) {
console.error('InstancePointManager: Invalid blockIndex', blockIndex)
return null
}
const uuid = this.blocks[blockIndex].__indexIdMap.get(instanceId)
if (!uuid) return
return this.__uuidMap.get(uuid)
}
create(entityId: string): InstanceMeshWrap {
let meshIndex = -1
let blockIndex = -1
for (const block of this.blocks) {
meshIndex = block.getFreeMeshIndex()
if (meshIndex >= 0) {
blockIndex = block.blockIndex
break
}
}
// 所有 block 都没有空闲索引,创建新的 block
if (meshIndex < 0) {
const block = this.createBlock()
meshIndex = block.getFreeMeshIndex()
blockIndex = block.blockIndex
}
if (meshIndex < 0) {
system.showErrorDialog('InstancePointManager: No free index available after creating new block')
return null
}
return new InstanceMeshWrap(entityId, this, blockIndex, meshIndex)
}
delete(wrap: InstanceMeshWrap) {
const block = this.blocks[wrap.blockIndex]
if (!block) {
console.warn(`InstanceMeshManager: Block ${wrap.blockIndex} not found for wrap ${wrap.uuid}`)
return
}
// 隐藏实例
this.dummy.scale.set(0, 0, 0)
this.dummy.updateMatrix()
block.instancedMesh.setMatrixAt(wrap.meshIndex, this.dummy.matrix)
block.instancedMesh.instanceMatrix.needsUpdate = true
// 回收索引
block.freeIndices.push(wrap.meshIndex)
this.__uuidMap.delete(wrap.uuid)
block.__indexIdMap.delete(wrap.meshIndex)
wrap.dispose()
}
// 创建新的 InstanceMeshBlock
createBlock(): InstanceMeshBlock {
const blockIndex = this.blocks.length
const block = new InstanceMeshBlock(this.name, this.allowSelect, this.allowDrag,
this.viewport, this.geometry, this.material,
blockIndex, this.blockCapacity)
this.blocks.push(block)
return block
}
setBlockMatrixAt(wrap: InstanceMeshWrap, matrix: THREE.Matrix4) {
const block = this.blocks[wrap.blockIndex]
if (!block) {
console.warn(`InstanceMeshManager: Block ${wrap.blockIndex} not found!`)
return
}
this.__uuidMap.set(wrap.uuid, wrap)
block.instancedMesh.setMatrixAt(wrap.meshIndex, matrix)
wrap.parent = block.instancedMesh
wrap.visible = true // 默认可见
block.instancedMesh.instanceMatrix.needsUpdate = true
}
dispose() {
for (const block of this.blocks) {
block.dispose()
}
this.blocks.length = 0 // 清空 blocks 数组
this.geometry.dispose() // 释放几何体资源
this.material.dispose() // 释放材质资源
console.log(`InstanceMeshManager ${this.name} disposed.`)
}
}
export class InstanceMeshWrap {
readonly entityId: string
readonly manager: InstanceMeshManager
readonly blockIndex: number
readonly meshIndex: number
uuid: string
parent: THREE.Object3D | null = null
name: string
visible: boolean
constructor(entityId: string, manager: InstanceMeshManager, blockIndex: number, meshIndex: number) {
this.uuid = system.createUUID()
this.entityId = entityId
this.manager = manager
this.meshIndex = meshIndex
this.blockIndex = blockIndex
}
syncMatrix(matrix: THREE.Matrix4): InstanceMeshWrap {
this.manager.setBlockMatrixAt(this, matrix)
return this
}
dispose() {
this.manager.delete(this)
this.parent = null
}
}

166
src/core/manager/InstancePointManager.ts

@ -1,23 +1,25 @@
import * as THREE from 'three' import * as THREE from 'three'
import type Viewport from '@/core/engine/Viewport.ts' import type Viewport from '@/core/engine/Viewport.ts'
import { Vector3 } from 'three/src/math/Vector3' import { Vector3 } from 'three/src/math/Vector3'
import InstanceMeshBlock from '@/core/manager/InstanceMeshBlock.ts'
/** /**
* *
* 使 InstanceMesh
*/ */
export default class InstancePointManager { export default class InstancePointManager {
public readonly name: string
public readonly viewport: Viewport public readonly viewport: Viewport
public readonly instancedMesh: THREE.InstancedMesh public readonly allowSelect: boolean
public readonly allowDrag: boolean
public readonly blockCapacity: number = 1000 // 每个 block 的容量
private readonly freeIndices: number[] = [] public readonly blocks: InstanceMeshBlock[] = []
private readonly maxInstanceCount: number
private readonly geometry: THREE.BufferGeometry private readonly geometry: THREE.BufferGeometry
private readonly material: THREE.Material private readonly material: THREE.Material
private readonly dummy: THREE.Object3D = new THREE.Object3D() private readonly dummy: THREE.Object3D = new THREE.Object3D()
// itemId -> instanceId // itemId -> data
private __uuidMap = new Map<string, PointManageWrap>() private __uuidMap = new Map<string, PointManageWrap>()
// instanceId -> itemId
private __indexIdMap = new Map<number, string>()
createPointSimple(id: string): PointManageWrap { createPointSimple(id: string): PointManageWrap {
//@ts-ignore //@ts-ignore
@ -38,21 +40,39 @@ export default class InstancePointManager {
* @returns ID (-1) * @returns ID (-1)
*/ */
createPoint(item: ItemJson): PointManageWrap { createPoint(item: ItemJson): PointManageWrap {
if (this.freeIndices.length === 0) { // Try existing blocks
system.showErrorDialog('InstancePointManager is full') let meshIndex = -1
let blockIndex = -1
for (const block of this.blocks) {
meshIndex = block.getFreeMeshIndex()
if (meshIndex >= 0) {
blockIndex = block.blockIndex
break
}
}
// 所有 block 都没有空闲索引,创建新的 block
if (meshIndex < 0) {
const block = this.createBlock()
meshIndex = block.getFreeMeshIndex()
blockIndex = block.blockIndex
}
if (meshIndex < 0) {
system.showErrorDialog('InstancePointManager: No free index available after creating new block')
return null return null
} }
const meshIndex = this.freeIndices.pop()! return new PointManageWrap(this, blockIndex, meshIndex, {
return new PointManageWrap(this, {
uuid: item.id, uuid: item.id,
name: item.name, name: item.name,
blockIndex: blockIndex,
meshIndex: meshIndex, meshIndex: meshIndex,
visible: item.v !== false, visible: item.v !== false,
//@ts-ignore //@ts-ignore
userData: { userData: {
t: item.t, t: item.t,
createType: 'point', createType: 'point',
blockIndex: blockIndex,
meshIndex: meshIndex,
entityId: item.id entityId: item.id
} }
}) })
@ -103,8 +123,12 @@ export default class InstancePointManager {
/** /**
* *
*/ */
findByMeshInstanceId(instanceId: number): PointManageWrap { findByMeshInstanceId(blockIndex: number, instanceId: number): PointManageWrap {
const uuid = this.__indexIdMap.get(instanceId) if (!this.blocks[blockIndex]) {
console.error('InstancePointManager: Invalid blockIndex', blockIndex)
return null
}
const uuid = this.blocks[blockIndex].__indexIdMap.get(instanceId)
if (!uuid) return if (!uuid) return
return this.__uuidMap.get(uuid) return this.__uuidMap.get(uuid)
} }
@ -123,13 +147,14 @@ export default class InstancePointManager {
} }
this.dummy.updateMatrix() this.dummy.updateMatrix()
const block = this.blocks[wrap.blockIndex]
if (!wrap.parent) { if (!wrap.parent) {
wrap.parent = this.instancedMesh wrap.parent = block.instancedMesh
this.__uuidMap.set(wrap.uuid, wrap) this.__uuidMap.set(wrap.uuid, wrap)
this.__indexIdMap.set(wrap.meshIndex, wrap.uuid) block.__indexIdMap.set(wrap.meshIndex, wrap.uuid)
} }
this.instancedMesh.setMatrixAt(wrap.meshIndex, this.dummy.matrix) block.instancedMesh.setMatrixAt(wrap.meshIndex, this.dummy.matrix)
this.instancedMesh.instanceMatrix.needsUpdate = true block.instancedMesh.instanceMatrix.needsUpdate = true
} }
/** /**
@ -138,18 +163,27 @@ export default class InstancePointManager {
*/ */
deletePoint(id: string): void { deletePoint(id: string): void {
const wrap = this.__uuidMap.get(id) const wrap = this.__uuidMap.get(id)
if (wrap === undefined) return if (!wrap) {
console.warn(`InstanceMeshManager: Wrap with id ${id} not found`)
return
}
const block = this.blocks[wrap.blockIndex]
if (!block) {
console.warn(`InstanceMeshManager: Block ${wrap.blockIndex} not found for wrap ${id}`)
return
}
// 隐藏实例 // 隐藏实例
this.dummy.scale.set(0, 0, 0) this.dummy.scale.set(0, 0, 0)
this.dummy.updateMatrix() this.dummy.updateMatrix()
this.instancedMesh.setMatrixAt(wrap.meshIndex, this.dummy.matrix) block.instancedMesh.setMatrixAt(wrap.meshIndex, this.dummy.matrix)
this.instancedMesh.instanceMatrix.needsUpdate = true block.instancedMesh.instanceMatrix.needsUpdate = true
// 回收索引 // 回收索引
this.freeIndices.push(wrap.meshIndex) block.freeIndices.push(wrap.meshIndex)
this.__uuidMap.delete(id) this.__uuidMap.delete(id)
this.__indexIdMap.delete(wrap.meshIndex) block.__indexIdMap.delete(wrap.meshIndex)
wrap.dispose() wrap.dispose()
} }
@ -159,59 +193,70 @@ export default class InstancePointManager {
viewport: Viewport, viewport: Viewport,
geometry: THREE.BufferGeometry, geometry: THREE.BufferGeometry,
material: THREE.Material, material: THREE.Material,
maxInstances: number = 20000 allowSelect: boolean, allowDrag: boolean
): InstancePointManager { ): InstancePointManager {
return new InstancePointManager(name, viewport, geometry, material, maxInstances) return new InstancePointManager(name, allowSelect, allowDrag, viewport, geometry, material)
} }
private constructor(name: string, viewport: Viewport, geometry: THREE.BufferGeometry, material: THREE.Material, maxInstances: number) { private createBlock(): InstanceMeshBlock {
const block = new InstanceMeshBlock(
this.name, this.allowSelect, this.allowDrag, this.viewport,
this.geometry,
this.material, this.blocks.length, this.blockCapacity
)
this.blocks.push(block)
return block
}
private constructor(name: string, allowSelect: boolean, allowDrag: boolean, viewport: Viewport, geometry: THREE.BufferGeometry, material: THREE.Material) {
this.name = name
this.allowSelect = allowSelect
this.allowDrag = allowDrag
this.viewport = viewport this.viewport = viewport
this.geometry = geometry this.geometry = geometry
this.material = material this.material = material
this.maxInstanceCount = maxInstances
this.instancedMesh = new THREE.InstancedMesh(geometry, material, maxInstances)
this.instancedMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)
this.instancedMesh.name = name
console.log('InstancePointManager: [' + name + '] created with maxInstances:', maxInstances)
viewport.scene.add(this.instancedMesh)
this.viewport.entityManager._selectableObjects.push(this.instancedMesh)
this.viewport.entityManager._draggableObjects.push(this.instancedMesh)
this.instancedMesh.userData.t = name
this.instancedMesh.userData.entityId = 'InstancePointManager'
this.dummy.scale.set(0, 0, 0)
for (let i = 0; i < maxInstances; i++) {
this.dummy.updateMatrix()
this.instancedMesh.setMatrixAt(i, this.dummy.matrix)
this.freeIndices.push(i)
}
this.instancedMesh.instanceMatrix.needsUpdate = true // 创建第一个 block
this.createBlock()
// this.instancedMesh = new THREE.InstancedMesh(geometry, material, maxInstances)
// this.instancedMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)
// this.instancedMesh.name = name
// console.log('InstancePointManager: [' + name + '] created with maxInstances:', maxInstances)
// viewport.scene.add(this.instancedMesh)
// if (allowSelect) {
// this.viewport.entityManager._selectableObjects.push(this.instancedMesh)
// }
// if (allowDrag) {
// this.viewport.entityManager._draggableObjects.push(this.instancedMesh)
// }
// this.instancedMesh.userData.t = name
// this.instancedMesh.userData.entityId = 'InstancePointManager'
//
// this.dummy.scale.set(0, 0, 0)
// for (let i = 0; i < maxInstances; i++) {
// this.dummy.updateMatrix()
// this.instancedMesh.setMatrixAt(i, this.dummy.matrix)
// this.freeIndices.push(i)
// }
//
// this.instancedMesh.instanceMatrix.needsUpdate = true
} }
dispose() { dispose() {
this.viewport.scene.remove(this.instancedMesh) for (const block of this.blocks) {
this.instancedMesh.geometry.dispose() block.dispose()
if (this.instancedMesh.material) {
if (Array.isArray(this.instancedMesh.material)) {
this.instancedMesh.material.forEach(mat => mat.dispose())
} else {
this.instancedMesh.material.dispose()
} }
}
this.instancedMesh.dispose()
this.__uuidMap.clear() this.__uuidMap.clear()
this.__indexIdMap.clear() this.blocks.length = 0
this.freeIndices.length = 0
} }
} }
export class PointManageWrap { export class PointManageWrap {
readonly manager: InstancePointManager readonly manager: InstancePointManager
meshIndex: number = -1 readonly blockIndex: number = -1
readonly meshIndex: number = -1
parent: THREE.Object3D | null = null parent: THREE.Object3D | null = null
uuid: string uuid: string
@ -234,8 +279,9 @@ export class PointManageWrap {
return false return false
} }
constructor(pointManager: InstancePointManager, data: any, meshIndex: number = -1) { constructor(pointManager: InstancePointManager, blockIndex: number, meshIndex: number, data: any) {
this.manager = pointManager this.manager = pointManager
this.blockIndex = blockIndex
this.meshIndex = meshIndex this.meshIndex = meshIndex
_.extend(this, data) _.extend(this, data)
} }
@ -243,7 +289,6 @@ export class PointManageWrap {
dispose() { dispose() {
this.manager.deletePoint(this.uuid) this.manager.deletePoint(this.uuid)
this.parent = null this.parent = null
this.meshIndex = -1
} }
applyMatrix4(matrix: THREE.Matrix4): PointManageWrap { applyMatrix4(matrix: THREE.Matrix4): PointManageWrap {
@ -260,7 +305,8 @@ export class PointManageWrap {
} }
createBox3(): THREE.Box3 { createBox3(): THREE.Box3 {
const instancedMesh = this.manager.instancedMesh const instancedMesh = this.manager.blocks[this.blockIndex]?.instancedMesh
const matrix = new THREE.Matrix4() const matrix = new THREE.Matrix4()
instancedMesh.getMatrixAt(this.meshIndex, matrix) instancedMesh.getMatrixAt(this.meshIndex, matrix)
// 创建包围盒并应用矩阵 // 创建包围盒并应用矩阵

1
src/example/ExampleUtil.js

@ -83,7 +83,6 @@ export function buildRackPerformanceData(rows, cols) {
} }
} }
debugger
return Array.from(data.values()) return Array.from(data.values())
} }

2
src/example/example1.js

@ -395,7 +395,7 @@ export default {
}, },
{ {
catalogCode: '__f2', t: 'floor', catalogCode: '__f2', t: 'floor',
items: buildPointPerformanceData('carton', 100, 100) items: buildPointPerformanceData('carton', 200, 500)
}, },
{ {
catalogCode: '__f3', t: 'floor', catalogCode: '__f3', t: 'floor',

2
src/modules/carton/CartonRenderer.ts

@ -69,7 +69,7 @@ export default class PalletRenderer extends BaseRenderer {
this.tempViewport, this.tempViewport,
this.cartonGeometry, this.cartonGeometry,
this.cartonMaterial, this.cartonMaterial,
Constract.MAX_PALLET_INSTANCES) true, true)
) )
} }

2
src/modules/gstore/GstoreRenderer.ts

@ -55,7 +55,7 @@ export default class GstoreRenderer extends BaseRenderer {
this.tempViewport, this.tempViewport,
this.pointGeometry, this.pointGeometry,
this.pointMaterial, this.pointMaterial,
Constract.MAX_GSTORE_INSTANCES) true, true)
) )
} }

2
src/modules/measure/MeasureRenderer.ts

@ -93,7 +93,7 @@ export default class MeasureRenderer extends BaseRenderer {
this.tempViewport, this.tempViewport,
this.pointGeometry, this.pointGeometry,
this.pointMaterial, this.pointMaterial,
Constract.MAX_MEASURE_INSTANCES) true, true)
) )
} }

2
src/modules/pallet/PalletRenderer.ts

@ -57,7 +57,7 @@ export default class PalletRenderer extends BaseRenderer {
this.tempViewport, this.tempViewport,
this.palletGeometry, this.palletGeometry,
this.palletMaterial, this.palletMaterial,
Constract.MAX_PALLET_INSTANCES) true, true)
) )
} }

246
src/modules/rack/RackRenderer.ts

@ -1,16 +1,14 @@
import * as THREE from 'three' import * as THREE from 'three'
import { BufferGeometry } from 'three'
import BaseRenderer from '@/core/base/BaseRenderer.ts' import BaseRenderer from '@/core/base/BaseRenderer.ts'
import { Line2 } from 'three/examples/jsm/lines/Line2.js'
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'
import * as BufferGeometryUtils from "three/addons/utils/BufferGeometryUtils.js";
import { decimalSumBy } from '@/core/ModelUtils' import { decimalSumBy } from '@/core/ModelUtils'
import Constract from '@/core/Constract.ts' import Constract from '@/core/Constract.ts'
import Plastic_Rough_JPG from '@/assets/Models/Plastic_Rough.jpg' import Plastic_Rough_JPG from '@/assets/Models/Plastic_Rough.jpg'
import {BufferGeometry} from "three"; import storageBar_PNG from '@/assets/Models/storageBar.png'
import storageBar_PNG from "@/assets/Models/storageBar.png"; import { Material } from 'three/src/materials/Material'
import {Material} from "three/src/materials/Material"; import { InstancedMesh } from 'three/src/objects/InstancedMesh'
import {InstancedMesh} from "three/src/objects/InstancedMesh"; //@ts-ignore
import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js'
/** /**
* *
@ -127,7 +125,7 @@ export default class RackRenderer extends BaseRenderer {
// group.add(lineT as THREE.Object3D) // group.add(lineT as THREE.Object3D)
// } // }
const meshes = this.createRack(item, option); const meshes = this.createRack(item, option)
meshes.forEach(mesh => { meshes.forEach(mesh => {
group.add(mesh) group.add(mesh)
@ -212,10 +210,10 @@ export default class RackRenderer extends BaseRenderer {
createVerticalBar(x, y, z, length): THREE.BufferGeometry { createVerticalBar(x, y, z, length): THREE.BufferGeometry {
// 创建一个形状 柱子的截面形状 // 创建一个形状 柱子的截面形状
const shape = new THREE.Shape(); const shape = new THREE.Shape()
shape.moveTo(this.barSectionPoints[0].x, this.barSectionPoints[0].y); shape.moveTo(this.barSectionPoints[0].x, this.barSectionPoints[0].y)
for (let i = 1; i < this.barSectionPoints.length; i++) { for (let i = 1; i < this.barSectionPoints.length; i++) {
shape.lineTo(this.barSectionPoints[i].x , this.barSectionPoints[i].y); shape.lineTo(this.barSectionPoints[i].x, this.barSectionPoints[i].y)
} }
// 拉伸轨迹线 // 拉伸轨迹线
@ -224,18 +222,18 @@ export default class RackRenderer extends BaseRenderer {
false, // 闭合曲线 false, // 闭合曲线
'catmullrom', 'catmullrom',
0 0
); )
// 挤出几何图形 参数 // 挤出几何图形 参数
const options = { const options = {
steps: 1, steps: 1,
bevelEnabled: false, bevelEnabled: false,
extrudePath: curve, // 设置挤出轨迹 extrudePath: curve // 设置挤出轨迹
}; }
// 创建挤出几何体 // 创建挤出几何体
const geometry = new THREE.ExtrudeGeometry(shape, options); const geometry = new THREE.ExtrudeGeometry(shape, options)
// 调整uv方便正确贴图 // 调整uv方便正确贴图
this.resetUVs(geometry); this.resetUVs(geometry)
return geometry return geometry
} }
@ -244,29 +242,29 @@ export default class RackRenderer extends BaseRenderer {
let textureLoader = new THREE.TextureLoader() let textureLoader = new THREE.TextureLoader()
// 加载纹理 // 加载纹理
const textureHole = textureLoader.load(storageBar_PNG); // 孔洞 const textureHole = textureLoader.load(storageBar_PNG) // 孔洞
const textureMaterial = textureLoader.load(Plastic_Rough_JPG); // 表面材质 const textureMaterial = textureLoader.load(Plastic_Rough_JPG) // 表面材质
textureHole.repeat.set(10, 18); // X轴重复,Y轴重复 textureHole.repeat.set(10, 18) // X轴重复,Y轴重复
textureMaterial.repeat.set(2, 2); // X轴重复,Y轴重复 textureMaterial.repeat.set(2, 2) // X轴重复,Y轴重复
// textureHole.offset.set(0.5, 0) // textureHole.offset.set(0.5, 0)
// textureHole.center.set(0.5, 0) // textureHole.center.set(0.5, 0)
// 必须设置包裹模式为重复 // 必须设置包裹模式为重复
textureHole.wrapS = THREE.RepeatWrapping; textureHole.wrapS = THREE.RepeatWrapping
textureHole.wrapT = THREE.RepeatWrapping; textureHole.wrapT = THREE.RepeatWrapping
textureMaterial.wrapS = THREE.RepeatWrapping; textureMaterial.wrapS = THREE.RepeatWrapping
textureMaterial.wrapT = THREE.RepeatWrapping; textureMaterial.wrapT = THREE.RepeatWrapping
const material = new THREE.MeshPhongMaterial(); const material = new THREE.MeshPhongMaterial()
material.alphaMap = textureHole; material.alphaMap = textureHole
material.normalMap = textureMaterial; material.normalMap = textureMaterial
material.color.setHex(this.rackVerticalBarColor, "srgb"); material.color.setHex(this.rackVerticalBarColor, 'srgb')
material.specular.setHex(0xff6d6d6d, 'srgb'); material.specular.setHex(0xff6d6d6d, 'srgb')
material.transparent = true; material.transparent = true
material.needsUpdate = true; material.needsUpdate = true
return material; return material
} }
createLinkBar(x, y, z, vBarLength, depth, bottomDistance, topDistance): THREE.BufferGeometry { createLinkBar(x, y, z, vBarLength, depth, bottomDistance, topDistance): THREE.BufferGeometry {
@ -274,10 +272,10 @@ export default class RackRenderer extends BaseRenderer {
const bgs: BufferGeometry[] = [] const bgs: BufferGeometry[] = []
const top = vBarLength - topDistance const top = vBarLength - topDistance
// 创建一个形状 柱子的截面形状 // 创建一个形状 柱子的截面形状
const shape = new THREE.Shape(); const shape = new THREE.Shape()
shape.moveTo(this.linkBarSectionPoints[0].x, this.linkBarSectionPoints[0].y); shape.moveTo(this.linkBarSectionPoints[0].x, this.linkBarSectionPoints[0].y)
for (let i = 1; i < this.linkBarSectionPoints.length; i++) { for (let i = 1; i < this.linkBarSectionPoints.length; i++) {
shape.lineTo(this.linkBarSectionPoints[i].x, this.linkBarSectionPoints[i].y); shape.lineTo(this.linkBarSectionPoints[i].x, this.linkBarSectionPoints[i].y)
} }
// 拉伸轨迹线 横向 底部 // 拉伸轨迹线 横向 底部
@ -286,14 +284,14 @@ export default class RackRenderer extends BaseRenderer {
false, // 闭合曲线 false, // 闭合曲线
'catmullrom', 'catmullrom',
0 0
); )
// 挤出几何图形 参数 // 挤出几何图形 参数
const optionsHBottom = { const optionsHBottom = {
steps: 1, steps: 1,
bevelEnabled: false, bevelEnabled: false,
extrudePath: curveHBottom, // 设置挤出轨迹 extrudePath: curveHBottom // 设置挤出轨迹
}; }
// 拉伸轨迹线 横向 底部 // 拉伸轨迹线 横向 底部
const curveHTop = new THREE.CatmullRomCurve3( const curveHTop = new THREE.CatmullRomCurve3(
@ -301,18 +299,18 @@ export default class RackRenderer extends BaseRenderer {
false, // 闭合曲线 false, // 闭合曲线
'catmullrom', 'catmullrom',
0 0
); )
// 挤出几何图形 参数 // 挤出几何图形 参数
const optionsHTop = { const optionsHTop = {
steps: 1, steps: 1,
bevelEnabled: false, bevelEnabled: false,
extrudePath: curveHTop, // 设置挤出轨迹 extrudePath: curveHTop // 设置挤出轨迹
}; }
// 创建挤出几何体 // 创建挤出几何体
const geometryHBottom = new THREE.ExtrudeGeometry(shape, optionsHBottom); const geometryHBottom = new THREE.ExtrudeGeometry(shape, optionsHBottom)
const geometryHTop = new THREE.ExtrudeGeometry(shape, optionsHTop); const geometryHTop = new THREE.ExtrudeGeometry(shape, optionsHTop)
bgs.push(geometryHBottom, geometryHTop) bgs.push(geometryHBottom, geometryHTop)
let remainingHeight = vBarLength - bottomDistance - topDistance let remainingHeight = vBarLength - bottomDistance - topDistance
@ -327,47 +325,46 @@ export default class RackRenderer extends BaseRenderer {
false, // 闭合曲线 false, // 闭合曲线
'catmullrom', 'catmullrom',
0 0
); )
const optionsD = { const optionsD = {
steps: 1, steps: 1,
bevelEnabled: false, bevelEnabled: false,
extrudePath: curveD, // 设置挤出轨迹 extrudePath: curveD // 设置挤出轨迹
}; }
const geometryD = new THREE.ExtrudeGeometry(shape, optionsD); const geometryD = new THREE.ExtrudeGeometry(shape, optionsD)
bgs.push(geometryD) bgs.push(geometryD)
} }
if (vBarLength - bottomDistance - topDistance > depth) { if (vBarLength - bottomDistance - topDistance > depth) {
} }
// 调整uv方便正确贴图 // 调整uv方便正确贴图
// this.resetUVs(geometry); // this.resetUVs(geometry);
return BufferGeometryUtils.mergeGeometries(bgs) return mergeGeometries(bgs)
} }
createLinkBarMaterial(): THREE.Material { createLinkBarMaterial(): THREE.Material {
const material = new THREE.MeshPhongMaterial(); const material = new THREE.MeshPhongMaterial()
material.color.setHex(this.rackLinkBarColor, "srgb"); material.color.setHex(this.rackLinkBarColor, 'srgb')
material.specular.setHex(0xff6d6d6d, 'srgb'); material.specular.setHex(0xff6d6d6d, 'srgb')
material.transparent = true; material.transparent = true
material.needsUpdate = true; material.needsUpdate = true
return material; return material
} }
createHorizontalBar(x, y, z, length): THREE.BufferGeometry { createHorizontalBar(x, y, z, length): THREE.BufferGeometry {
// 创建一个形状 柱子的截面形状 // 创建一个形状 柱子的截面形状
const shape = new THREE.Shape(); const shape = new THREE.Shape()
shape.moveTo(this.barSectionPoints[0].x, this.barSectionPoints[0].y); shape.moveTo(this.barSectionPoints[0].x, this.barSectionPoints[0].y)
for (let i = 1; i < this.barSectionPoints.length; i++) { for (let i = 1; i < this.barSectionPoints.length; i++) {
shape.lineTo(this.barSectionPoints[i].x , this.barSectionPoints[i].y); shape.lineTo(this.barSectionPoints[i].x, this.barSectionPoints[i].y)
} }
// 拉伸轨迹线 // 拉伸轨迹线
@ -376,24 +373,24 @@ export default class RackRenderer extends BaseRenderer {
false, // 闭合曲线 false, // 闭合曲线
'catmullrom', 'catmullrom',
0 0
); )
// 挤出几何图形 参数 // 挤出几何图形 参数
const options = { const options = {
steps: 1, steps: 1,
bevelEnabled: false, bevelEnabled: false,
extrudePath: curve, // 设置挤出轨迹 extrudePath: curve // 设置挤出轨迹
}; }
// 创建挤出几何体 // 创建挤出几何体
const geometry = new THREE.ExtrudeGeometry(shape, options); const geometry = new THREE.ExtrudeGeometry(shape, options)
const linkShapeL = new THREE.Shape(); const linkShapeL = new THREE.Shape()
const linkShapeR = new THREE.Shape(); const linkShapeR = new THREE.Shape()
linkShapeL.moveTo(this.linkSectionPoints[0].x, this.linkSectionPoints[0].y); linkShapeL.moveTo(this.linkSectionPoints[0].x, this.linkSectionPoints[0].y)
linkShapeR.moveTo(this.linkSectionPoints[0].x + (length), this.linkSectionPoints[0].y); linkShapeR.moveTo(this.linkSectionPoints[0].x + (length), this.linkSectionPoints[0].y)
for (let i = 1; i < this.linkSectionPoints.length; i++) { for (let i = 1; i < this.linkSectionPoints.length; i++) {
linkShapeL.lineTo(this.linkSectionPoints[i].x , this.linkSectionPoints[i].y); linkShapeL.lineTo(this.linkSectionPoints[i].x, this.linkSectionPoints[i].y)
linkShapeR.lineTo(this.linkSectionPoints[i].x + (length), this.linkSectionPoints[i].y); linkShapeR.lineTo(this.linkSectionPoints[i].x + (length), this.linkSectionPoints[i].y)
} }
// 拉伸轨迹线 // 拉伸轨迹线
@ -402,36 +399,35 @@ export default class RackRenderer extends BaseRenderer {
false, // 闭合曲线 false, // 闭合曲线
'catmullrom', 'catmullrom',
0 0
); )
// 挤出几何图形 参数 // 挤出几何图形 参数
const linkOptions = { const linkOptions = {
steps: 1, steps: 1,
bevelEnabled: false, bevelEnabled: false,
extrudePath: linkCurve, // 设置挤出轨迹 extrudePath: linkCurve // 设置挤出轨迹
}; }
// 创建挤出几何体 // 创建挤出几何体
const linkGeometryL = new THREE.ExtrudeGeometry(linkShapeL, linkOptions); const linkGeometryL = new THREE.ExtrudeGeometry(linkShapeL, linkOptions)
linkGeometryL.rotateZ(-Math.PI / 2) linkGeometryL.rotateZ(-Math.PI / 2)
const linkGeometryR = new THREE.ExtrudeGeometry(linkShapeR, linkOptions); const linkGeometryR = new THREE.ExtrudeGeometry(linkShapeR, linkOptions)
linkGeometryR.rotateX(-Math.PI) linkGeometryR.rotateX(-Math.PI)
linkGeometryR.rotateZ(-Math.PI / 2) linkGeometryR.rotateZ(-Math.PI / 2)
// 调整uv方便正确贴图 // 调整uv方便正确贴图
// this.resetUVs(geometry); // this.resetUVs(geometry);
return BufferGeometryUtils.mergeGeometries([geometry, linkGeometryL, linkGeometryR]) return mergeGeometries([geometry, linkGeometryL, linkGeometryR])
} }
createHorizontalBarMaterial(): THREE.Material { createHorizontalBarMaterial(): THREE.Material {
const material = new THREE.MeshPhongMaterial(); const material = new THREE.MeshPhongMaterial()
material.color.setHex(this.rackHorizontalBarColor, "srgb"); material.color.setHex(this.rackHorizontalBarColor, 'srgb')
material.specular.setHex(0xff6d6d6d, 'srgb'); material.specular.setHex(0xff6d6d6d, 'srgb')
material.transparent = true; material.transparent = true
material.needsUpdate = true; material.needsUpdate = true
return material; return material
} }
createRack(item: ItemJson, option?: RendererCudOption): InstancedMesh[] { createRack(item: ItemJson, option?: RendererCudOption): InstancedMesh[] {
@ -455,12 +451,12 @@ export default class RackRenderer extends BaseRenderer {
const rackHeight = _.max(heights) const rackHeight = _.max(heights)
// 计算立住坐标点和长度 // 计算立住坐标点和长度
const vBarMatrix: {x: number, y: number, z: number, sx: number, sy: number, sz: number, rx: number, ry: number, rz: number, l: number}[] = []; const vBarMatrix: { x: number, y: number, z: number, sx: number, sy: number, sz: number, rx: number, ry: number, rz: number, l: number }[] = []
// 计算 // 计算
const linkBarMatrix: {x: number, y: number, z: number, sx: number, sy: number, sz: number, rx: number, ry: number, rz: number, l: number}[] = []; const linkBarMatrix: { x: number, y: number, z: number, sx: number, sy: number, sz: number, rx: number, ry: number, rz: number, l: number }[] = []
let distanceX = 0, distanceY = 0; let distanceX = 0, distanceY = 0
for (let i = -1; i < item.dt.bays.length; i++) { for (let i = -1; i < item.dt.bays.length; i++) {
if (i >= 0) { if (i >= 0) {
@ -506,10 +502,10 @@ export default class RackRenderer extends BaseRenderer {
} }
// 计算横梁数量 // 计算横梁数量
const hBarMatrix: {x: number, y: number, z: number, sx: number, sy: number, sz: number, rx: number, ry: number, rz: number, l: number}[] = []; const hBarMatrix: { x: number, y: number, z: number, sx: number, sy: number, sz: number, rx: number, ry: number, rz: number, l: number }[] = []
distanceX = 0; distanceX = 0
for (let i = 0; i < item.dt.bays.length; i++) { for (let i = 0; i < item.dt.bays.length; i++) {
distanceY = this.bottomBarHeight; distanceY = this.bottomBarHeight
const bay = item.dt.bays[i] const bay = item.dt.bays[i]
for (let j = 0; j < bay.levelHeight.length; j++) { for (let j = 0; j < bay.levelHeight.length; j++) {
const levelHeight = bay.levelHeight[j] const levelHeight = bay.levelHeight[j]
@ -545,7 +541,7 @@ export default class RackRenderer extends BaseRenderer {
distanceX += bay.bayWidth distanceX += bay.bayWidth
} }
const meshes: InstancedMesh[] = []; const meshes: InstancedMesh[] = []
if (vBarMatrix.length > 0) { if (vBarMatrix.length > 0) {
if (!this.rackVerticalBarGeometry) { if (!this.rackVerticalBarGeometry) {
@ -554,15 +550,15 @@ export default class RackRenderer extends BaseRenderer {
if (!this.rackVerticalBarMaterial) { if (!this.rackVerticalBarMaterial) {
this.rackVerticalBarMaterial = this.createVerticalBarMaterial() this.rackVerticalBarMaterial = this.createVerticalBarMaterial()
} }
const dummy = new THREE.Object3D(); const dummy = new THREE.Object3D()
const vBarMesh = new THREE.InstancedMesh(this.rackVerticalBarGeometry, this.rackVerticalBarMaterial, vBarMatrix.length); const vBarMesh = new THREE.InstancedMesh(this.rackVerticalBarGeometry, this.rackVerticalBarMaterial, vBarMatrix.length)
for (let i = 0; i < vBarMatrix.length; i++) { for (let i = 0; i < vBarMatrix.length; i++) {
const vp = vBarMatrix[i] const vp = vBarMatrix[i]
dummy.position.set(vp.x, vp.y, vp.z); dummy.position.set(vp.x, vp.y, vp.z)
dummy.rotation.set(vp.rx, vp.ry, vp.rz); dummy.rotation.set(vp.rx, vp.ry, vp.rz)
dummy.scale.set(vp.sx, vp.sy, vp.sz); dummy.scale.set(vp.sx, vp.sy, vp.sz)
dummy.updateMatrix(); dummy.updateMatrix()
vBarMesh.setMatrixAt(i, dummy.matrix); vBarMesh.setMatrixAt(i, dummy.matrix)
} }
meshes.push(vBarMesh) meshes.push(vBarMesh)
} }
@ -574,15 +570,15 @@ export default class RackRenderer extends BaseRenderer {
if (!this.rackLinkBarMaterial) { if (!this.rackLinkBarMaterial) {
this.rackLinkBarMaterial = this.createLinkBarMaterial() this.rackLinkBarMaterial = this.createLinkBarMaterial()
} }
const dummy = new THREE.Object3D(); const dummy = new THREE.Object3D()
const linkBarMesh = new THREE.InstancedMesh(this.rackLinkBarGeometry, this.rackLinkBarMaterial, linkBarMatrix.length); const linkBarMesh = new THREE.InstancedMesh(this.rackLinkBarGeometry, this.rackLinkBarMaterial, linkBarMatrix.length)
for (let i = 0; i < linkBarMatrix.length; i++) { for (let i = 0; i < linkBarMatrix.length; i++) {
const lp = linkBarMatrix[i] const lp = linkBarMatrix[i]
dummy.position.set(lp.x, lp.y, lp.z); dummy.position.set(lp.x, lp.y, lp.z)
dummy.rotation.set(lp.rx, lp.ry, lp.rz); dummy.rotation.set(lp.rx, lp.ry, lp.rz)
dummy.scale.set(lp.sx, lp.sy, lp.sz); dummy.scale.set(lp.sx, lp.sy, lp.sz)
dummy.updateMatrix(); dummy.updateMatrix()
linkBarMesh.setMatrixAt(i, dummy.matrix); linkBarMesh.setMatrixAt(i, dummy.matrix)
} }
meshes.push(linkBarMesh) meshes.push(linkBarMesh)
} }
@ -594,51 +590,51 @@ export default class RackRenderer extends BaseRenderer {
if (!this.rackHorizontalBarMaterial) { if (!this.rackHorizontalBarMaterial) {
this.rackHorizontalBarMaterial = this.createHorizontalBarMaterial() this.rackHorizontalBarMaterial = this.createHorizontalBarMaterial()
} }
const dummy = new THREE.Object3D(); const dummy = new THREE.Object3D()
const hBarMesh = new THREE.InstancedMesh(this.rackHorizontalBarGeometry, this.rackHorizontalBarMaterial, hBarMatrix.length); const hBarMesh = new THREE.InstancedMesh(this.rackHorizontalBarGeometry, this.rackHorizontalBarMaterial, hBarMatrix.length)
for (let i = 0; i < hBarMatrix.length; i++) { for (let i = 0; i < hBarMatrix.length; i++) {
const hp = hBarMatrix[i] const hp = hBarMatrix[i]
dummy.position.set(hp.x, hp.y, hp.z); dummy.position.set(hp.x, hp.y, hp.z)
dummy.rotation.set(hp.rx, hp.ry, hp.rz); dummy.rotation.set(hp.rx, hp.ry, hp.rz)
dummy.scale.set(hp.sx, hp.sy, hp.sz); dummy.scale.set(hp.sx, hp.sy, hp.sz)
dummy.updateMatrix(); dummy.updateMatrix()
hBarMesh.setMatrixAt(i, dummy.matrix); hBarMesh.setMatrixAt(i, dummy.matrix)
} }
meshes.push(hBarMesh) meshes.push(hBarMesh)
} }
return meshes; return meshes
} }
resetUVs(geometry) { resetUVs(geometry: THREE.ExtrudeGeometry) {
if (geometry == undefined) return; if (geometry == undefined) return
const pos = geometry.getAttribute("position"), const pos = geometry.getAttribute('position'),
nor = geometry.getAttribute("normal"), nor = geometry.getAttribute('normal'),
uvs = geometry.getAttribute("uv"); uvs = geometry.getAttribute('uv')
for (let i = 0; i < pos.count; i++) { for (let i = 0; i < pos.count; i++) {
let x = 0, y = 0; let x = 0, y = 0
const nx = Math.abs(nor.getX(i)), ny = Math.abs(nor.getY(i)), nz = Math.abs(nor.getZ(i)); const nx = Math.abs(nor.getX(i)), ny = Math.abs(nor.getY(i)), nz = Math.abs(nor.getZ(i))
// if facing X // if facing X
if (nx >= ny && nx >= nz) { if (nx >= ny && nx >= nz) {
x = pos.getZ(i); x = pos.getZ(i)
y = pos.getY(i); y = pos.getY(i)
} }
// if facing Y // if facing Y
if (ny >= nx && ny >= nz) { if (ny >= nx && ny >= nz) {
x = pos.getX(i); x = pos.getX(i)
y = pos.getZ(i); y = pos.getZ(i)
} }
// if facing Z // if facing Z
if (nz >= nx && nz >= ny) { if (nz >= nx && nz >= ny) {
x = pos.getX(i); x = pos.getX(i)
y = pos.getY(i); y = pos.getY(i)
} }
uvs.setXY(i, x, y); uvs.setXY(i, x, y)
} }
} }

2
src/modules/tote/ToteRenderer.ts

@ -59,7 +59,7 @@ export default class PalletRenderer extends BaseRenderer {
this.tempViewport, this.tempViewport,
this.toteGeometry, this.toteGeometry,
this.toteMaterial, this.toteMaterial,
Constract.MAX_PALLET_INSTANCES) true, true)
) )
} }

6
src/modules/way/WayRenderer.ts

@ -206,7 +206,7 @@ export default class WayRenderer extends BaseRenderer {
this.tempViewport, this.tempViewport,
this.lineGeometry, this.lineGeometry,
this.lineMaterial, this.lineMaterial,
Constract.MAX_WAY_LINE_INSTANCES) false, false)
) )
} }
@ -220,7 +220,7 @@ export default class WayRenderer extends BaseRenderer {
this.tempViewport, this.tempViewport,
this.pointGeometry, this.pointGeometry,
this.pointMaterial, this.pointMaterial,
Constract.MAX_WAY_INSTANCES) true, true)
) )
} }
@ -234,7 +234,7 @@ export default class WayRenderer extends BaseRenderer {
this.tempViewport, this.tempViewport,
this.dirGeometry, this.dirGeometry,
this.dirMaterial, this.dirMaterial,
Constract.MAX_WAY_LINE_INSTANCES) false, false)
) )
} }
} }

Loading…
Cancel
Save