Browse Source

carton 纸箱模型

master
修宁 6 months ago
parent
commit
faeaa55386
  1. BIN
      src/assets/Models/carton.glb
  2. BIN
      src/assets/Models/carton.jpg
  3. 333
      src/components/Model3DView.vue
  4. 48
      src/core/ModelUtils.ts
  5. 2
      src/core/manager/WorldModel.ts
  6. 2
      src/example/ExampleUtil.js
  7. 8
      src/example/example1.js
  8. 5
      src/modules/carton/CartonEntity.ts
  9. 22
      src/modules/carton/CartonInteraction.ts
  10. 20
      src/modules/carton/CartonPropertySetter.ts
  11. 83
      src/modules/carton/CartonRenderer.ts
  12. 15
      src/modules/carton/index.ts
  13. 9
      src/types/ModelTypes.ts

BIN
src/assets/Models/carton.glb

Binary file not shown.

BIN
src/assets/Models/carton.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

333
src/components/Model3DView.vue

@ -2,7 +2,7 @@
<div class="model3d-view">
<el-space :gutter="10" class="toolbar">
<el-upload :on-change="handleFileChange"
:show-file-list="false" accept=".fbx,.obj,.mtl,.3ds" action="" :auto-upload="false">
:show-file-list="false" accept=".fbx,.obj,.mtl,.3ds,.glb,.gltf" action="" :auto-upload="false">
<el-button type="primary">打开模型</el-button>
</el-upload>
<el-upload :on-change="handleTextureUpload"
@ -80,15 +80,16 @@ import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'
import { TDSLoader } from 'three/examples/jsm/loaders/TDSLoader'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import * as dat from 'three/examples/jsm/libs/lil-gui.module.min.js'
import Stats from 'three/examples/jsm/libs/stats.module'
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'
import Split from '@/components/split/split.vue'
import SplitArea from '@/components/split/split-area.vue'
import { renderIcon } from '@/utils/webutils.js'
import rackPlatUrl from "@/assets/images/conveyor/shapes/RackPlatform.png";
import rackBlue from "@/assets/images/conveyor/shapes/Rack-blue.png";
import triangleUrl from "@/assets/images/conveyor/shapes/triangle.png";
import rackPlatUrl from '@/assets/images/conveyor/shapes/RackPlatform.png'
import rackBlue from '@/assets/images/conveyor/shapes/Rack-blue.png'
import triangleUrl from '@/assets/images/conveyor/shapes/triangle.png'
// DOM refs
const canvasContainer = ref(null)
@ -168,118 +169,120 @@ watch(() => restate.mode, (newVal) => {
tcontrols.setMode(newVal)
}
})
function addConveyor(){
const conveyorLength = 10; //
const conveyorWidth = 0.8; //
const conveyorHeight = 0.08; //
const wallHeight = conveyorHeight + 0.15; // 线 0.2
const legWidth = 0.1; // X
const legDepth = 0.1; // Z
const legHeight = 0.8; // Y
function addConveyor() {
const conveyorLength = 10 //
const conveyorWidth = 0.8 //
const conveyorHeight = 0.08 //
const wallHeight = conveyorHeight + 0.15 // 线 0.2
const legWidth = 0.1 // X
const legDepth = 0.1 // Z
const legHeight = 0.8 // Y
// 线
const conveyorGeometry = new THREE.BoxGeometry(conveyorWidth, conveyorHeight, conveyorLength);
const conveyorMaterial = new THREE.MeshBasicMaterial({ color: 0x6a6a6a });
const conveyor = new THREE.Mesh(conveyorGeometry, conveyorMaterial);
conveyor.position.y = conveyorHeight / 2;
const conveyorGeometry = new THREE.BoxGeometry(conveyorWidth, conveyorHeight, conveyorLength)
const conveyorMaterial = new THREE.MeshBasicMaterial({ color: 0x6a6a6a })
const conveyor = new THREE.Mesh(conveyorGeometry, conveyorMaterial)
conveyor.position.y = conveyorHeight / 2
//
const wallWidth = 0.05;
const wallGeometry = new THREE.BoxGeometry(wallWidth, wallHeight, conveyorLength);
const wallMaterial = new THREE.MeshBasicMaterial({ color: 0x6a6a6a });
const wallWidth = 0.05
const wallGeometry = new THREE.BoxGeometry(wallWidth, wallHeight, conveyorLength)
const wallMaterial = new THREE.MeshBasicMaterial({ color: 0x6a6a6a })
const leftWall = new THREE.Mesh(wallGeometry, wallMaterial);
leftWall.position.set(-(conveyorWidth / 2 + wallWidth / 2), wallHeight / 2, 0);
const leftWall = new THREE.Mesh(wallGeometry, wallMaterial)
leftWall.position.set(-(conveyorWidth / 2 + wallWidth / 2), wallHeight / 2, 0)
const rightWall = new THREE.Mesh(wallGeometry, wallMaterial);
rightWall.position.set((conveyorWidth / 2 + wallWidth / 2), wallHeight / 2, 0);
const rightWall = new THREE.Mesh(wallGeometry, wallMaterial)
rightWall.position.set((conveyorWidth / 2 + wallWidth / 2), wallHeight / 2, 0)
//
const legGeometry = new THREE.BoxGeometry(legWidth, legHeight, legDepth);
const legMaterial = new THREE.MeshBasicMaterial({ color: 0x6a6a6a }); //
const legGeometry = new THREE.BoxGeometry(legWidth, legHeight, legDepth)
const legMaterial = new THREE.MeshBasicMaterial({ color: 0x6a6a6a }) //
const legPositions = [
[conveyorWidth / 2 - legWidth / 2, -(conveyorLength / 2 - legDepth / 2)], //
[-conveyorWidth / 2 + legWidth / 2, -(conveyorLength / 2 - legDepth / 2)], //
[conveyorWidth / 2 - legWidth / 2, +(conveyorLength / 2 - legDepth / 2)], //
[-conveyorWidth / 2 + legWidth / 2, +(conveyorLength / 2 - legDepth / 2)] //
];
]
const legs = [];
const legs = []
legPositions.forEach(pos => {
const leg = new THREE.Mesh(legGeometry, legMaterial);
const leg = new THREE.Mesh(legGeometry, legMaterial)
leg.position.set(
pos[0],
-legHeight / 2,
pos[1]
);
legs.push(leg);
});
)
legs.push(leg)
})
// ====== ======
const beamWidth = conveyorWidth; // 线0.8
const beamLength = conveyorLength-conveyorHeight/2;// 线10
const beamHeight = 0.08; // 0.1
const beamWidth = conveyorWidth // 线0.8
const beamLength = conveyorLength - conveyorHeight / 2// 线10
const beamHeight = 0.08 // 0.1
// Shape
const shape = new THREE.Shape();
const shape = new THREE.Shape()
const radius = beamHeight / 2; // =
const radius = beamHeight / 2 // =
//
shape.absarc(-beamLength / 2, 0, radius, Math.PI / 2, -Math.PI / 2, false);
shape.absarc(-beamLength / 2, 0, radius, Math.PI / 2, -Math.PI / 2, false)
//
shape.absarc(beamLength / 2, 0, radius, -Math.PI / 2, Math.PI / 2, false);
shape.absarc(beamLength / 2, 0, radius, -Math.PI / 2, Math.PI / 2, false)
shape.closePath(); //
shape.closePath() //
//
const extrudeSettings = {
depth: beamWidth,
steps: 16,
bevelEnabled: false
};
}
const beamGeometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
const beamMaterial = new THREE.MeshBasicMaterial({ color: 0x032702 }); //
const beamGeometry = new THREE.ExtrudeGeometry(shape, extrudeSettings)
const beamMaterial = new THREE.MeshBasicMaterial({ color: 0x032702 }) //
const beam = new THREE.Mesh(beamGeometry, beamMaterial);
beam.rotation.x = Math.PI / 2;
const beam = new THREE.Mesh(beamGeometry, beamMaterial)
beam.rotation.x = Math.PI / 2
beam.rotation.z = Math.PI / 2
beam.rotation.y = Math.PI / 2
beam.position.y = beamHeight+conveyorHeight/2; // 线
beam.position.x = -beamWidth/2;
addMarkerAt(0, legHeight+beamHeight+conveyorHeight,0,triangleUrl,1,false);
addMarkerAt(beamWidth/2+wallWidth+0.01, legHeight+wallHeight/2,0,triangleUrl,.5,true);
addMarkerAt(beamWidth/2+wallWidth+0.01, legHeight+wallHeight/2,conveyorLength/4,triangleUrl,.5,true);
addMarkerAt(beamWidth/2+wallWidth+0.01, legHeight+wallHeight/2,-conveyorLength/4,triangleUrl,.5,true);
addMarkerAt(-(beamWidth/2+wallWidth+0.01), legHeight+wallHeight/2,0,triangleUrl,.5,true);
addMarkerAt(-(beamWidth/2+wallWidth+0.01), legHeight+wallHeight/2,conveyorLength/4,triangleUrl,.5,true);
addMarkerAt(-(beamWidth/2+wallWidth+0.01), legHeight+wallHeight/2,-conveyorLength/4,triangleUrl,.5,true);
beam.position.y = beamHeight + conveyorHeight / 2 // 线
beam.position.x = -beamWidth / 2
addMarkerAt(0, legHeight + beamHeight + conveyorHeight, 0, triangleUrl, 1, false)
addMarkerAt(beamWidth / 2 + wallWidth + 0.01, legHeight + wallHeight / 2, 0, triangleUrl, .5, true)
addMarkerAt(beamWidth / 2 + wallWidth + 0.01, legHeight + wallHeight / 2, conveyorLength / 4, triangleUrl, .5, true)
addMarkerAt(beamWidth / 2 + wallWidth + 0.01, legHeight + wallHeight / 2, -conveyorLength / 4, triangleUrl, .5, true)
addMarkerAt(-(beamWidth / 2 + wallWidth + 0.01), legHeight + wallHeight / 2, 0, triangleUrl, .5, true)
addMarkerAt(-(beamWidth / 2 + wallWidth + 0.01), legHeight + wallHeight / 2, conveyorLength / 4, triangleUrl, .5, true)
addMarkerAt(-(beamWidth / 2 + wallWidth + 0.01), legHeight + wallHeight / 2, -conveyorLength / 4, triangleUrl, .5, true)
//
const group = new THREE.Group();
group.add(conveyor);
group.add(leftWall);
group.add(rightWall);
legs.forEach(leg => group.add(leg));
group.add(beam); //
const group = new THREE.Group()
group.add(conveyor)
group.add(leftWall)
group.add(rightWall)
legs.forEach(leg => group.add(leg))
group.add(beam) //
// 沿Z 1
group.position.y = legHeight; //
scene.add(group);
group.position.y = legHeight //
scene.add(group)
}
function addMarkerAt(x, y,z,textUrl, scale = 1,lip) {
const loader = new THREE.TextureLoader();
function addMarkerAt(x, y, z, textUrl, scale = 1, lip) {
const loader = new THREE.TextureLoader()
loader.load(textUrl, (texture) => {
//
let markerGeometry
if(lip){
markerGeometry=new THREE.PlaneGeometry(.25 * scale, .25 * scale);
}else{
markerGeometry = new THREE.PlaneGeometry(.45 * scale, .3 * scale); //
if (lip) {
markerGeometry = new THREE.PlaneGeometry(.25 * scale, .25 * scale)
} else {
markerGeometry = new THREE.PlaneGeometry(.45 * scale, .3 * scale) //
}
const markerMaterial = new THREE.MeshBasicMaterial({
@ -288,193 +291,193 @@ function addMarkerAt(x, y,z,textUrl, scale = 1,lip) {
opacity: 1,
depthWrite: false,
side: THREE.DoubleSide
});
})
const marker = new THREE.Mesh(markerGeometry, markerMaterial);
let yHeight=y+0.01
const marker = new THREE.Mesh(markerGeometry, markerMaterial)
let yHeight = y + 0.01
// 线Y线
marker.position.set(x, yHeight, z); // Y = 线 +
marker.position.set(x, yHeight, z) // Y = 线 +
// X/Z 线
marker.rotation.x = -Math.PI / 2; // conveyorBelt
marker.rotation.z = Math.PI / 2; // 90
if(lip){
marker.rotation.y = Math.PI / 2; // 90
}else{
marker.rotation.y = Math.PI;
marker.rotation.x = -Math.PI / 2 // conveyorBelt
marker.rotation.z = Math.PI / 2 // 90
if (lip) {
marker.rotation.y = Math.PI / 2 // 90
} else {
marker.rotation.y = Math.PI
}
scene.add(marker);
});
scene.add(marker)
})
}
function createShelf(){//
const shelfLength = 5;
const shelfWidth = 0.8;
const shelfThickness = 0.02;
const rows = 3;
const columns = 4;
const spacingY = 1; //
const gapBetweenPlanks = 0.1; //
const baseHeight = 0; // 0
function createShelf() {//
const shelfLength = 5
const shelfWidth = 0.8
const shelfThickness = 0.02
const rows = 3
const columns = 4
const spacingY = 1 //
const gapBetweenPlanks = 0.1 //
const baseHeight = 0 // 0
const unitLength = (shelfLength - (columns - 1) * gapBetweenPlanks) / columns;
const unitLength = (shelfLength - (columns - 1) * gapBetweenPlanks) / columns
const textureLoader = new THREE.TextureLoader();
const textureLoader = new THREE.TextureLoader()
const shelfTexture = textureLoader.load(rackPlatUrl, () => {
renderer.render(scene, camera);
});
renderer.render(scene, camera)
})
const redPoleTexture = textureLoader.load(rackBlue, () => {
renderer.render(scene, camera); //
});
renderer.render(scene, camera) //
})
shelfTexture.wrapS = THREE.RepeatWrapping;
shelfTexture.wrapT = THREE.RepeatWrapping;
shelfTexture.repeat.set(1, 20);
shelfTexture.rotation = Math.PI / 2;
shelfTexture.wrapS = THREE.RepeatWrapping
shelfTexture.wrapT = THREE.RepeatWrapping
shelfTexture.repeat.set(1, 20)
shelfTexture.rotation = Math.PI / 2
const shelfMaterial = new THREE.MeshPhongMaterial({
map: shelfTexture,
color: 0x999999,
shininess: 60
});
})
//
const poleMaterial = new THREE.MeshPhongMaterial({
map: shelfTexture,
color: 0x333333,
shininess: 60
});
})
//
const poleSize = gapBetweenPlanks; //
const totalHeight = rows * spacingY; //
const poleSize = gapBetweenPlanks //
const totalHeight = rows * spacingY //
for (let row = 0; row < rows; row++) {
let currentXOffset = -shelfLength / 2;
let currentXOffset = -shelfLength / 2
for (let col = 0; col < columns; col++) {
const geometry = new THREE.BoxGeometry(unitLength, shelfThickness, shelfWidth);
const mesh = new THREE.Mesh(geometry, shelfMaterial);
const geometry = new THREE.BoxGeometry(unitLength, shelfThickness, shelfWidth)
const mesh = new THREE.Mesh(geometry, shelfMaterial)
const x = currentXOffset + unitLength / 2;
const x = currentXOffset + unitLength / 2
// Y 使
const y = baseHeight + row * spacingY + shelfThickness / 2;
const z = 0;
const y = baseHeight + row * spacingY + shelfThickness / 2
const z = 0
mesh.position.set(x, y, z);
scene.add(mesh);
mesh.position.set(x, y, z)
scene.add(mesh)
if (row === 0) { //
//
if (col === 0) {
const leftPoleX = currentXOffset - poleSize / 2;
const leftPoleY = baseHeight + totalHeight / 2;
const leftPoleZ = z - shelfWidth / 2 + poleSize / 2;
const leftPoleX = currentXOffset - poleSize / 2
const leftPoleY = baseHeight + totalHeight / 2
const leftPoleZ = z - shelfWidth / 2 + poleSize / 2
//
const leftPole = new THREE.Mesh(
new THREE.BoxGeometry(poleSize, totalHeight, poleSize),
poleMaterial
);
leftPole.position.set(leftPoleX, leftPoleY, leftPoleZ);
scene.add(leftPole);
)
leftPole.position.set(leftPoleX, leftPoleY, leftPoleZ)
scene.add(leftPole)
// //
const redLeftPoleZ = z + shelfWidth / 2 - poleSize / 2;
const redLeftPoleZ = z + shelfWidth / 2 - poleSize / 2
const redLeftPole = new THREE.Mesh(
new THREE.BoxGeometry(poleSize, totalHeight, poleSize),
new THREE.MeshPhongMaterial({
map: redPoleTexture,
color: 0xffffff, //
shininess: 60,
transparent: true,
transparent: true
})
// new THREE.MeshPhongMaterial({ color: 0xff0000, shininess: 60 })
);
redLeftPole.position.set(leftPoleX, leftPoleY, redLeftPoleZ);
scene.add(redLeftPole);
)
redLeftPole.position.set(leftPoleX, leftPoleY, redLeftPoleZ)
scene.add(redLeftPole)
}
//
if (col < columns - 1) {
const gapStartX = currentXOffset + unitLength;
const gapStartX = currentXOffset + unitLength
//
const poleX = gapStartX + poleSize / 2;
const poleY = baseHeight + totalHeight / 2;
const poleZ = z- shelfWidth / 2+poleSize/2;
const poleX = gapStartX + poleSize / 2
const poleY = baseHeight + totalHeight / 2
const poleZ = z - shelfWidth / 2 + poleSize / 2
const pole = new THREE.Mesh(
new THREE.BoxGeometry(poleSize, totalHeight, poleSize),
poleMaterial
);
pole.position.set(poleX, poleY, poleZ);
scene.add(pole);
)
pole.position.set(poleX, poleY, poleZ)
scene.add(pole)
//
const redPoleX = poleX; // X
const redPoleY = poleY; // Y
const redPoleZ = z + shelfWidth / 2-poleSize/2; //
const redPoleX = poleX // X
const redPoleY = poleY // Y
const redPoleZ = z + shelfWidth / 2 - poleSize / 2 //
const redPoleMaterial = new THREE.MeshPhongMaterial({
color: 0xff0000,
shininess: 60
});
})
const redPole = new THREE.Mesh(
new THREE.BoxGeometry(poleSize, totalHeight, poleSize),
redPoleMaterial
);
redPole.position.set(redPoleX, redPoleY, redPoleZ);
scene.add(redPole);
)
redPole.position.set(redPoleX, redPoleY, redPoleZ)
scene.add(redPole)
}
//
if (col === columns - 1) {
const rightPoleX = currentXOffset + unitLength + gapBetweenPlanks - poleSize / 2;
const rightPoleY = baseHeight + totalHeight / 2;
const rightPoleZ = z - shelfWidth / 2 + poleSize / 2;
const rightPoleX = currentXOffset + unitLength + gapBetweenPlanks - poleSize / 2
const rightPoleY = baseHeight + totalHeight / 2
const rightPoleZ = z - shelfWidth / 2 + poleSize / 2
//
const rightPole = new THREE.Mesh(
new THREE.BoxGeometry(poleSize, totalHeight, poleSize),
poleMaterial
);
rightPole.position.set(rightPoleX, rightPoleY, rightPoleZ);
scene.add(rightPole);
)
rightPole.position.set(rightPoleX, rightPoleY, rightPoleZ)
scene.add(rightPole)
//
const redRightPoleZ = z + shelfWidth / 2 - poleSize / 2;
const redRightPoleZ = z + shelfWidth / 2 - poleSize / 2
const redRightPole = new THREE.Mesh(
new THREE.BoxGeometry(poleSize, totalHeight, poleSize),
new THREE.MeshPhongMaterial({ color: 0xff0000, shininess: 60 })
);
redRightPole.position.set(rightPoleX, rightPoleY, redRightPoleZ);
scene.add(redRightPole);
)
redRightPole.position.set(rightPoleX, rightPoleY, redRightPoleZ)
scene.add(redRightPole)
}
}
currentXOffset += unitLength + gapBetweenPlanks;
currentXOffset += unitLength + gapBetweenPlanks
}
}
//
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(5, 10, 7);
scene.add(directionalLight);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
scene.add(ambientLight)
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
directionalLight.position.set(5, 10, 7)
scene.add(directionalLight)
}
function createGroundStore() {
const planeGeometry = new THREE.PlaneGeometry(1, 1);
const planeGeometry = new THREE.PlaneGeometry(1, 1)
const material = new THREE.MeshBasicMaterial({
color: 0x00ff00,
side: THREE.DoubleSide // :ml-citation{ref="5,8" data="citationList"}
});
const planeMesh = new THREE.Mesh(planeGeometry, material);
})
const planeMesh = new THREE.Mesh(planeGeometry, material)
planeMesh.rotateX(Math.PI / 2)
scene.add(planeMesh);
scene.add(planeMesh)
}
function initThree() {
@ -837,7 +840,6 @@ function handleFileChange(file) {
system.clearLoading()
}
reader.readAsArrayBuffer(file)
} else if (fileName.endsWith('.obj')) {
reader.readAsText(file)
@ -861,11 +863,26 @@ function handleFileChange(file) {
system.clearLoading()
}
reader.readAsArrayBuffer(file)
} else if (fileName.endsWith('.glb') || fileName.endsWith('.gltf')) {
reader.onload = () => {
const loader = new GLTFLoader()
const arrayBuffer = reader.result
//@ts-ignore
loader.parseAsync(arrayBuffer, '').then((content) => {
debugger
addGroupToScene(content.scene)
})
system.clearLoading()
}
} else {
alert('不支持的文件类型!')
return
}
reader.readAsArrayBuffer(file)
}

48
src/core/ModelUtils.ts

@ -10,6 +10,7 @@ import axios from 'axios'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import { TDSLoader } from 'three/examples/jsm/loaders/TDSLoader'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
export function setUserDataForItem(item: ItemJson, object: Object3DLike) {
if (!object.name && item.name) {
@ -494,6 +495,14 @@ export async function loadByUrl(url): Promise<any> {
})
}
export async function loadGlbModule(url: string): Promise<THREE.Group> {
const response = await axios.get(url, {
responseType: 'arraybuffer'
})
const rt = await new GLTFLoader().parseAsync(response.data, '')
return rt.scene
}
export function loadTexture(url: string) {
return new THREE.TextureLoader().loadAsync(url)
}
@ -519,3 +528,42 @@ export function load3DModule(arrayBuffer: ArrayBuffer | string, ext: string) {
return null
}
}
export async function generateMaterialWithTexture(color: number, quality: number, info: any, textureInfos: any) {
let materialClone
let url = color?.toString() + ' ' + JSON.stringify(textureInfos) + ' ' + quality + ' ' + (info == undefined ? '' : JSON.stringify(info))
if (!this.materialsWithTextureMap[url]) {
let meterialTmp = await this.generateMaterial(color, quality, info)
for (let textureInfo of textureInfos) {
if (textureInfo.path != undefined && textureInfo.repeatX != undefined && textureInfo.repeatY != undefined) {
let textureTmp = await this.generateTexture(textureInfo.path, textureInfo.repeatX, textureInfo.repeatY)
if (textureInfo.rotation != undefined) {
textureTmp.rotation = textureInfo.rotation
}
if (textureInfo.normalMapType != undefined) {
textureTmp.normalMapType = textureInfo.normalMapType
}
if (textureInfo.type == Model.TextureTypeEnum.NormalMap) {
if (quality != Model.MaterialQualityEnum.Low) {
meterialTmp.normalMap = textureTmp
}
} else if (textureInfo.type == Model.TextureTypeEnum.AlphaMap) {
meterialTmp.alphaMap = textureTmp
} else if (textureInfo.type == Model.TextureTypeEnum.Map) {
meterialTmp.map = textureTmp
} else {
meterialTmp.map = textureTmp
}
meterialTmp.needsUpdate = true
}
}
this.materialsWithTextureMap[url] = meterialTmp
}
materialClone = this.materialsWithTextureMap[url]
return materialClone
}

2
src/core/manager/WorldModel.ts

@ -7,6 +7,7 @@ import Gstore from '@/modules/gstore'
import Rack from '@/modules/rack'
import Pallet from "@/modules/pallet"
import Tote from "@/modules/tote"
import Carton from "@/modules/carton"
import Ptr from "@/modules/ptr"
import Clx from "@/modules/clx"
import Charger from "@/modules/charger"
@ -74,6 +75,7 @@ export default class WorldModel {
Rack,
Pallet,
Tote,
Carton,
Ptr,
Clx,
Charger

2
src/example/ExampleUtil.js

@ -18,7 +18,7 @@ export function buildPointPerformanceData(t, rows, cols) {
node.tf[0][1] = 0.01
node.tf[0][2] = col * spacingZ
node.tf[1] = [0, 0, 0]
node.tf[2] = [1, 0.01, 1]
node.tf[2] = [1, 0.4, 1]
data.set(node.id, node)
}
}

8
src/example/example1.js

@ -326,10 +326,10 @@ export default {
catalogCode: 'f3', t: 'floor',
items: [
{
id: 'tote1',
t: 'pallet',
id: 'carton1',
t: 'carton',
v: true,
tf: [[0, 0.1, 0], [0, 0, 0], [1.0, 0.1, 1.0]],
tf: [[0, 0.1, 0], [0, 0, 0], [1.0, 1.0, 1.0]],
dt: { in: [], out: [], center: [], storeWidth: 1.4, storeDepth: 1.4 }
}
]
@ -340,7 +340,7 @@ export default {
},
{
catalogCode: '__f2', t: 'floor',
items: buildPointPerformanceData('gstore', 100, 100)
items: buildPointPerformanceData('carton', 100, 100)
}
],
elevator: [], // 电梯

5
src/modules/carton/CartonEntity.ts

@ -0,0 +1,5 @@
import BaseEntity from '@/core/base/BaseItemEntity.ts'
export default class PalletEntity extends BaseEntity {
}

22
src/modules/carton/CartonInteraction.ts

@ -0,0 +1,22 @@
import BaseInteraction from '@/core/base/BaseInteraction.ts'
import * as THREE from 'three'
export default class PalletInteraction extends BaseInteraction {
get isSinglePointMode(): boolean {
return true
}
constructor(itemTypeName: string) {
super(itemTypeName)
}
createPointOfItem(item: ItemJson, point: THREE.Vector3): ItemJson {
item = super.createPointOfItem(item, point)
// 创建一个地堆货架
item.dt.palletWidth = 1 // 宽度
item.dt.palletDepth = 1.2 // 深度
return item
}
}

20
src/modules/carton/CartonPropertySetter.ts

@ -0,0 +1,20 @@
import type { PropertySetter } from "@/core/base/PropertyTypes.ts";
import { basicFieldsSetter } from "@/editor/widgets/property/PropertyPanelConstant.ts";
const propertySetter: PropertySetter = {
flatten: {
fields: [
...basicFieldsSetter,
{
dataPath: 'dt.palletWidth', label: '托盘宽度', input: 'InputNumber',
inputProps: {},
},
{
dataPath: 'dt.palletDepth', label: '托盘深度', input: 'InputNumber',
inputProps: {},
},
],
},
};
export default propertySetter;

83
src/modules/carton/CartonRenderer.ts

@ -0,0 +1,83 @@
import * as THREE from 'three'
import BaseRenderer from '@/core/base/BaseRenderer.ts'
import Constract from '@/core/Constract.ts'
import InstancePointManager from '@/core/manager/InstancePointManager.ts'
import type { Object3DLike } from '@/types/ModelTypes.ts'
import MODULE_GLB_File from '@/assets/Models/carton.glb?url'
import MODULE_3DS_TEX from '@/assets/Models/carton.jpg?url'
import { load3DModule, loadByUrl, loadGlbModule, loadTexture } from '@/core/ModelUtils.ts'
/**
*
*/
export default class PalletRenderer extends BaseRenderer {
static POINT_NAME = 'carton_point'
/**
* ,
*/
readonly defulePositionY: number = Constract.HEIGHT_WAY
readonly defaultScale: THREE.Vector3 = new THREE.Vector3(1, 1, 1)
readonly defaultRotation: THREE.Vector3 = new THREE.Vector3(0, 0, 0)
readonly defaultUserData = {
color: 0xc29a70
}
cartonGeometry: THREE.BufferGeometry
cartonMaterial: THREE.Material
init() {
return Promise.all([
super.init(),
loadGlbModule(MODULE_GLB_File),
loadTexture(MODULE_3DS_TEX)
]).then(([_, glbGroup, cartonTexture]) => {
const mesh = glbGroup.children[0] as THREE.Mesh
this.cartonGeometry = mesh.geometry
this.cartonMaterial = new THREE.MeshPhongMaterial({ color: 0xc29a70 }) // mesh.material as THREE.Material
this.cartonGeometry.scale(0.01, 0.01, 0.01)
this.cartonGeometry.rotateX(Math.PI / 2)
cartonTexture.wrapS = THREE.RepeatWrapping
cartonTexture.wrapT = THREE.RepeatWrapping
cartonTexture.repeat.set(1, 1)
//@ts-ignore
this.cartonMaterial.map = cartonTexture
//@ts-ignore
this.cartonMaterial.color.set(this.defaultUserData.color)
this.cartonMaterial.needsUpdate = true
})
}
createPointBasic(item: ItemJson, option?: RendererCudOption): Object3DLike {
return this.pointManager.createPoint(item)
}
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.cartonGeometry,
this.cartonMaterial,
Constract.MAX_PALLET_INSTANCES)
)
}
dispose() {
super.dispose()
if (this.cartonGeometry) {
this.cartonGeometry.dispose()
this.cartonGeometry = undefined
}
if (this.cartonMaterial) {
this.cartonMaterial.dispose()
this.cartonMaterial = undefined
}
}
}

15
src/modules/carton/index.ts

@ -0,0 +1,15 @@
import { defineModule } from '@/core/manager/ModuleManager.ts'
import CartonRenderer from './CartonRenderer.ts'
import CartonEntity from './CartonEntity.ts'
import CartonInteraction from './CartonInteraction.ts'
import propertySetter from "./CartonPropertySetter.ts";
export const ITEM_TYPE_NAME = 'carton'
export default defineModule({
name: ITEM_TYPE_NAME,
renderer: new CartonRenderer(ITEM_TYPE_NAME),
interaction: new CartonInteraction(ITEM_TYPE_NAME),
setter: propertySetter,
entity: CartonEntity,
})

9
src/types/ModelTypes.ts

@ -72,3 +72,12 @@ export type Object3DLike = Object3D | LineManageWrap | PointManageWrap
* , THREE.Vector3
*/
export type Vector3Like = THREE.Vector3 | number[]
/**
*
*/
export const MaterialQualityEnum = {
High: 0,
Middle: 1,
Low: 2,
};

Loading…
Cancel
Save