ThreeJs模拟工厂生产过程八

这节算是给这个车间场景收个尾,等了几天并没有人发设备模型给我,只能自己找了一个凑合用了。加载模型之前,首先要把货架上的料箱合并,以防加载模型之后因模型数量多出现卡顿,方法和之前介绍的合并传送带方法相同,代码如下:

 //初始化料箱
    initCube(){
      let cubeList = [];
      const textureLoader = new THREE.TextureLoader();
      let texture = textureLoader.load("/static/images/box.png",)
      const material = new THREE.MeshBasicMaterial({map: texture});
      for(let q=0; q<this.shelfList.length;q++){
        for(let i=0;i<this.layerNum;i++){
          for(let j=0;j<this.columnNum;j++){
            let x = this.shelfList[q].positionX;
            let y = this.shelfList[q].positionY + 2 + j * (this.plane.planeLength / 3)
            let z = this.shelfList[q].positionZ + i * (this.holder.holderHeight + this.plane.planeHeight)-9
            cubeList.push(this.addCube(x - 2, y, z));
            cubeList.push(this.addCube(x + 2, y, z));
          }
        }
      }
      const bayGeometry = mergeGeometries(cubeList);//合并模型数组
      let cubeModelMesh = new THREE.Mesh(bayGeometry, material);//生成一整个新的模型
      this.scene.add(cubeModelMesh);
    },
    //新增料箱
    addCube(x,y,z){
      let geometry = new THREE.BoxGeometry(3,3,2)
      let material = new THREE.MeshBasicMaterial({color: 0x00ff00});
        let mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(x,y,z);
        mesh.updateMatrix();//更新模型变换矩阵
        return mesh.geometry.applyMatrix4(mesh.matrix);//启动并应用变换矩阵
    },

然后开始替换模型。首先我们下载好模型放到本地,我下载的是gltf的格式,之前用引入人的模型已经导入此组件,不用再次导入了,我们只需要在绘制模型的外面加载模型,并在循环中克隆加载到的模型,并根据模型的大小进行缩放和位置偏移。为了方便查看替换过程,我把for循环分开写了。代码如下:

initMachine(){ // 初始哈设备
      this.initPerson(this.begin.x,this.begin.y,this.begin.z);
      const loader = new GLTFLoader()
      let addressY = this.begin.y
      loader.load("/static/models/device/scene.gltf", (gltf) => {
        let machine =  gltf.scene
        machine.scale.set(0.08,0.08,0.8)
        machine.rotation.x = Math.PI/2
        machine.rotation.y = Math.PI/2
        for (let i = 0; i < 5; i++) {
          for (let i = 0; i < this.machineList.length; i++) {
            let temp = machine.clone();
            temp.position.set(this.begin.x+20+45*i,addressY+2,this.begin.z-10)
            this.scene.add(temp);//添加到场景中
          }
          addressY = addressY +60
        }
      })
      for (let i = 0; i < 5; i++) {
        for (let i = 0; i < this.machineList.length; i++) {
          this.initMachineName(this.begin.x+20+45*i,this.begin.y,10,this.machineList[i])
          this.initConveyor(this.begin.x+(this.conveyor.lang/2),this.begin.y,this.begin.z,6,this.conveyor.lang);//前三个参数是xyz,后面两个一个是传送带宽度,一个是传送带长度
          this.addWarning(this.begin.x-5,this.begin.y,this.begin.z-9,2,30);//添加警戒线
        }
        this.begin.y = this.begin.y +60
      }
    },

这样我们就得到这样的效果

总的来说比之前好看一些了,但是数字孪生的场景是为了模拟真实情况并查看数据的,所以我们要给设备加点数据才行,之前用了精灵组件简单的做了个设备工序名,这里为了显示更复杂的样式引用CSS2DRender,他的好处是可以做一个html的div显示在设备上,样式与原生的方法一样,这样就可以设置好看的标签样式了。

首先我们需要引入两个组件CSS2DRenderer, CSS2DObject,然后我们用js创建一个div,并根据自己的需求做一个好看的div样式和数据,然后把div塞到CSS2DObject中,并设置这个对象的位置,然后加载到场景中。

 const earthDiv = document.createElement('div');
      earthDiv.className = "label";
      earthDiv.innerHTML = "<div style='border:1px #FFFFFF solid;border-radius: 3px;'>" +
          "<span style='font-size: 12px;'>"+machine.name+"</span><br/>" +
          "<span style='font-size: 12px;'>PASS:100 个</span><br/>" +
          "<span style='color:red;font-size: 12px;'>NG:2 个</span>" +
          "</div>";
      const earthLabel = new CSS2DObject(earthDiv);
      earthLabel.position.set(x,y,z);//相对于父级元素的位置
      this.scene.add(earthLabel);

      this.labelRenderer = new CSS2DRenderer();
      this.labelRenderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(this.labelRenderer.domElement)

不过要注意的是这个CSS2DObject需要用CSS2DRenderer才能渲染,所以我们需要再创建CSS2DRenderer渲染器,并放到控制器和动画绘制中,保证CSS2DObject能够正常渲染

 this.labelRenderer = new CSS2DRenderer();
      this.labelRenderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(this.labelRenderer.domElement)
      //设置样式
      this.labelRenderer.domElement.style.position = 'fixed';
      this.labelRenderer.domElement.style.top = '0px';
      this.labelRenderer.domElement.style.left = '0px';
      this.labelRenderer.domElement.style.zIndex = '10';//设置层级

this.controls = new OrbitControls(this.camera, this.labelRenderer.domElement);//创建控制器

 this.labelRenderer.render(this.scene,this.camera);

我们可以看下效果

我审美有限,大家可以根据需求和选择适合的模型和绘制更美观的标签Label,完整效果如下:

车间视频end

整个生产车间的数字孪生就到这里,需要源码的可以在评论区给我留下邮箱地址,我发给你,如果觉得有哪里不足的地方也可以给我留言,可以根据需求后续再添加章节完善这个场景。

相关推荐
幻梦丶海炎5 天前
【Threejs进阶教程-着色器篇】1. Shader入门(ShadertoyShader和ThreejsShader入门)
webgl·threejs·着色器·shadertoy·glsl
Champion.XL9 天前
Node.js 渲染三维模型并导出为图片
node.js·webgl·threejs·服务端渲染三维模型·gl
天外天-亮16 天前
ThreeJS-截屏下载pdf或者图片时白屏
前端·javascript·pdf·threejs
Xqqqqq.24 天前
three.js纹理贴图褪色失真问题解决
前端·webgl·threejs
很甜的西瓜1 个月前
一个简单的threejs盒剖切功能
前端·3d·webgl·canvas·js·threejs
allenjiao2 个月前
办公园区建筑科技风效果(html+threejs)
前端·科技·webgl·threejs·三维·园区·办公楼
nuise_2 个月前
Threejs 学习笔记 | 灯光与阴影
前端·笔记·学习·threejs
夏暖冬凉2 个月前
Three.js纹理贴图
前端·threejs
是席木木啊2 个月前
ThreeJS:项目搭建
webgl·threejs·web3d