因項目需求 需要自定義搭建3D庫房,並配置貨架和貨物的位置等等。這裏貼出部分關鍵代碼
詳細代碼較多 可參見示例 @躍焱邵隼 下的簡單案例 > 3d倉庫
const warehouse = new YsWarehouse(app) // 添加地面 const floorTexture = textureLoader.load("../../images/ysThree/warehouse/floor.jpg") const floorMaterial = new THREE.MeshBasicMaterial({map: floorTexture,side: THREE.DoubleSide }) floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping floorTexture.repeat.set(10, 10) const floor = warehouse.createFloor({ material: floorMaterial, width: 2600, height: 1400, name: '地面' }) // 添加普通牆 const wallMaterial = [ new THREE.MeshPhongMaterial({color: 0xafc0ca}), //前 0xafc0ca :灰色 new THREE.MeshPhongMaterial({color: 0x9cb2d1}), //後 0x9cb2d1:淡紫 new THREE.MeshPhongMaterial({color: 0xd6e4ec}), //上 0xd6e4ec: 偏白色 new THREE.MeshPhongMaterial({color: 0xd6e4ec}), //下 new THREE.MeshPhongMaterial({color: 0xafc0ca}), //左 0xafc0ca :灰色 new THREE.MeshPhongMaterial({color: 0xafc0ca}), //右 ] const wall1 = warehouse.createCube({ width: 10, height: 200, depth: 1400, name: '牆', angle: 1, material: wallMaterial, position: [-1295, 100, 0] }) const wall2 = warehouse.createCube({ width: 10, height: 200, depth: 1400, name: '牆', angle: 0, material: wallMaterial, position: [1295, 100, 0] }) const wall3 = warehouse.createCube({ width: 10, height: 200, depth: 2600, name: '牆', angle: 1.5, material: wallMaterial, position: [0, 100, -700] }) scene.add(floor,wall1,wall2,wall3) // 創建牆 並在這個牆上 挖門和窗戶 const wall4 = warehouse.createCube({ width: 2600, height: 200, depth: 10, name: '牆', angle: 0, position: [0, 100, 700] }) const window_door = [ warehouse.createCube({ width: 200, height: 180, depth: 10, name: '門1', angle: 0, position: [-600, 90, 700] }), warehouse.createCube({ width: 200, height: 180, depth: 10, name: '門2', angle: 0, position: [600, 90, 700] }), warehouse.createCube({ width: 100, height: 100, depth: 10, name: '窗1', angle: 0, position: [-900, 90, 700] }), warehouse.createCube({ width: 100, height: 100, depth: 10, name: '窗2', angle: 0, position: [900, 90, 700] }), warehouse.createCube({ width: 100, height: 100, depth: 10, name: '窗3', angle: 0, position: [-200, 90, 700] }), warehouse.createCube({ width: 100, height: 100, depth: 10, name: '窗4', angle: 0, position: [200, 90, 700] }) ] const wall_window_door_material = new THREE.MeshPhongMaterial({ color: 0x9cb2d1, specular: 0x9cb2d1, shininess: 30, transparent: true, opacity: 1 }) const wallWithWindow_door = warehouse.createBsp(wall4, window_door, wall_window_door_material) scene.add(wallWithWindow_door) //添加門窗 並給他們添加貼圖材質 const left_door_material = new THREE.MeshBasicMaterial({ map: textureLoader.load("../../images/ysThree/warehouse/door_left.png"), transparent:true, color: 0xffffff }); const right_door_material = new THREE.MeshBasicMaterial({ map: textureLoader.load("../../images/ysThree/warehouse/door_right.png"), transparent:true, color: 0xffffff }); const window_material = new THREE.MeshBasicMaterial({ map: textureLoader.load("../../images/ysThree/warehouse/window.png"), transparent:true, color: 0xffffff }); const window_door_real = [ warehouse.createCube({ width: 100, height: 180, depth: 2, name: '門_left_1', angle: 0, material: left_door_material, position: [ -700, -10, 0] }), warehouse.createCube({ width: 100, height: 180, depth: 2, name: '門_left_2', angle: 0, material: right_door_material, position: [ -500, -10, 0] }), warehouse.createCube({ width: 100, height: 180, depth: 2, name: '門_right_1', angle: 0, material: left_door_material, position: [500, -10, 0] }), warehouse.createCube({ width: 100, height: 180, depth: 2, name: '門_right_2', angle: 0, material: right_door_material, position: [700, -10, 0] }), warehouse.createCube({ width: 100, height: 100, depth: 2, name: '窗1', angle: 0, material: window_material, position: [-900, -10, 0] }), warehouse.createCube({ width: 100, height: 100, depth: 2, name: '窗2', angle: 0, material: window_material, position: [900, -10, 0] }), warehouse.createCube({ width: 100, height: 100, depth: 2, name: '窗3', angle: 0, material: window_material, position: [-200, -10, 0] }), warehouse.createCube({ width: 100, height: 100, depth: 2, name: '窗4', angle: 0, material: window_material, position: [200, -10, 0] }) ] window_door_real.forEach(e => wallWithWindow_door.add(e)) //添加貨架 const data = warehouseData //在data/ysThree/warehouseData.js中 const rackT1 = textureLoader.load( `../../images/ysThree/warehouse/rack_left.png` ) const rackT2 = textureLoader.load( `../../images/ysThree/warehouse/rack_front.png` ) const rackT3 = textureLoader.load( `../../images/ysThree/warehouse/rack_bottom.png` ) const rackMaterial = [ new THREE.MeshBasicMaterial({ map: rackT1, transparent: true, side: THREE.DoubleSide }), // 左 side: THREE.DoubleSide new THREE.MeshBasicMaterial({ map: rackT1, transparent: true, side: THREE.DoubleSide }), // 右 new THREE.MeshBasicMaterial({ map: rackT2, transparent: true, side: THREE.DoubleSide }), // 前 new THREE.MeshBasicMaterial({ map: rackT2, transparent: true, side: THREE.DoubleSide }), // 後 new THREE.MeshBasicMaterial({ map: rackT3, transparent: true, opacity: 0 }), // 上 new THREE.MeshBasicMaterial({ map: rackT3, side: THREE.DoubleSide }) // 下 ] const boxMaterial = new THREE.MeshBasicMaterial({ map: textureLoader.load(`../../images/ysThree/warehouse/crate.gif`) }) const rackGroupResult = warehouse.initRackGroup({ rack: { width: 40, height: 32, depth: 32 }, box: { width: 32, height: 24, depth: 24 }, rackMaterial: rackMaterial, boxMaterial: boxMaterial, data: data }) const rackGroupList = rackGroupResult.rackGroupList // list const rackGroupAll = rackGroupResult.rackGroupAll // group // 初始化拖拽插件 let isDrag = false let currentDrag let currentHoverRack let canDrag = false function initDragControls(dragObjects, type) { // 添加平移控件 const transformControls = new THREE.TransformControls( camera, renderer.domElement ) scene.add(transformControls) // 初始化拖拽控件 const dragControls = new THREE.DragControls(dragObjects, camera, renderer.domElement, type) // 鼠標略過事件 dragControls.addEventListener('hoveron', function(event) { if(!canDrag) return // 讓變換控件對象和選中的對象綁定 transformControls.attach(event.object) // 設置三維座標軸的大小,這個座標軸不會隨着模型的縮放而縮放 transformControls.setSize(0.000001) }) // 開始拖拽 dragControls.addEventListener('dragstart', function(event) { if(!canDrag) return controls.enabled = false // 拖拽的時候 controls禁止 isDrag = true currentDrag = event.object }) // 拖拽結束 dragControls.addEventListener('dragend', function(event) { if(!canDrag) return transformControls.detach() controls.enabled = true isDrag = false if(currentDrag.userData.isBox ) { const dragBox = currentDrag const dragRack = currentDrag.parent if(currentHoverRack && currentHoverRack.userData.isEmpty) { warehouse.addBox(currentHoverRack, { name: dragBox.name, displayName: dragBox.userData.displayName, picList: dragBox.userData.picList }) dragRack.remove(dragBox) dragRack.userData.isEmpty = true currentHoverRack.userData.isEmpty = false }else { ys.messageBox({ icon: 'cry', msg: '當前貨架已經有貨物了,請重新放置' }) currentDrag.position.set(0,0,0) } } currentHoverRack = null }) return dragControls } const dragControls = initDragControls(rackGroupList, 1) dragControls.enabled = false // 精準放入 box document.addEventListener('mousemove',function (e) { const objList = app.getIntersectObject(el,e,rackGroupAll,true).objectList //如果 開始了拖拽 if(canDrag) { if(isDrag && currentDrag.userData.isBox) { const currentHoverList = objList.filter(e => e.object.userData.isRack && e.object.userData.isEmpty) if(currentHoverList && currentHoverList.length >0) { currentHoverRack = currentHoverList[0].object } } } }) document.addEventListener('click',function (e) { const objList = app.getIntersectObject(el,e,rackGroupAll,true).objectList //如果 開始了拖拽 if(!canDrag) { if(objList.length > 0){ console.log(objList[0]) if(objList[0].object.userData.isRack && objList[0].object.userData.isEmpty) { //是空貨架孔 ys.messageBox({ msg: '添加一個貨架' }) //dragControls.updateObjects(rackGroupList) 更新後是否需要更新拖拽組 }else if (objList[0].object.userData.isRack && !objList[0].object.userData.isEmpty) { //是箱子 ys.messageBox({ msg: '查看該貨架消息,並選擇更新' }) //dragControls.updateObjects(rackGroupList) 更新後是否需要更新拖拽組 } } } })