thee搭建3D仓库 添加货架货物增删改

因项目需求 需要自定义搭建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) 更新后是否需要更新拖拽组
            }
         }
     }
 })

你可能感兴趣的:(three)