Threejs物联网,工厂3D可视化

简介: Threejs物联网,工厂3D可视化

1,介绍


该示例使用的是 r95版本Three.js库。主要实现功能:引用模型进行工厂布局展示并贴图,使用粒子实现天气和火焰效果。效果图如下:

2,主要说明


下雨下雪火焰说明可以查看上一篇文章。

工厂布局主要使用OBJLoader加载模型,使用TextureLoader加载纹理,使用MeshBasicMaterial材质进行渲染,并设置展示的位置。


创建厂房和大小圆仓方式差不多,创建厂房代码如下:


// 创建房屋
function createBoxGeometryBasicMaterial() {
  var objLoader = new THREE.OBJLoader();
  objLoader.load('assets/textures/particles/003.obj', function(obj) {
    var mesh = obj.children[0];
    mesh.material = new THREE.MeshBasicMaterial({
      map: new THREE.TextureLoader().load('assets/textures/particles/003.png'),
    });
    mesh.scale.set(1.3, 1.4, 1.5);
    mesh.position.set(11, 0, -85);
    for (let i = 0; i < 2; i++) {
      for (let j = 0; j < 3; j++) {
        var mc = mesh.clone();
        mc.translateX(i * 52);
        mc.translateZ(j * 83);
        scene.add(mc);
      }
    }
  });
}


3,源码


<!DOCTYPE html>
<html>
  <head>
    <title>物联网,工厂3D可视化系统</title>
    <script type="text/javascript" src="libs/three.js"></script>
    <script type="text/javascript" src="libs/OrbitControls.js"></script>
    <script type="text/javascript" src="libs/OBJLoader.js"></script>
    <script type="text/javascript" src="libs/other/Tween.min.js"></script>
    <script type="text/javascript" src="libs/dat.gui.js"></script>
    <style>
      body {
        margin: 0;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div id="dom"></div>
    <script type="text/javascript">
      var camera;
      var renderer;
      var cloud;
      var rainy_sw = 3; // 1雨2雪3晴4阴
      var flame_sw = true;
      //初始化一个空容器,装载粒子
      var krq = new THREE.Object3D();
      var textureLoader = new THREE.TextureLoader();
      var group3 = new THREE.Group();
      function init() {
        // 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。
        var scene = new THREE.Scene();
        var urls = [
          'assets/textures/cubemap/flowers/posx.jpg',
          'assets/textures/cubemap/flowers/negx.jpg',
          'assets/textures/cubemap/flowers/posy.jpg',
          'assets/textures/cubemap/flowers/negy.jpg',
          'assets/textures/cubemap/flowers/posz.jpg',
          'assets/textures/cubemap/flowers/negz.jpg'
        ];
        var urls1 = [
          'assets/textures/cubemap/flowers/posx1.jpg',
          'assets/textures/cubemap/flowers/negx1.jpg',
          'assets/textures/cubemap/flowers/posy1.jpg',
          'assets/textures/cubemap/flowers/negy1.jpg',
          'assets/textures/cubemap/flowers/posz1.jpg',
          'assets/textures/cubemap/flowers/negz1.jpg'
        ];
        var cubeLoader = new THREE.CubeTextureLoader();
        scene.background = cubeLoader.load(urls);
        // 创建一个摄像机,它定义了我们正在看的地方
        camera = new THREE.PerspectiveCamera(65, window.innerWidth / window.innerHeight, 0.1, 20000);
        // 将摄像机对准场景的中心
        camera.position.x = 180;
        camera.position.y = 80;
        camera.position.z = 90;
        camera.lookAt(scene.position);
        var orbit = new THREE.OrbitControls(camera);
        // 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景
        renderer = new THREE.WebGLRenderer({
          antialias: true,
          logarithmicDepthBuffer: true,
        });
        renderer.setClearColor(new THREE.Color(0x121A39));
        renderer.setSize(window.innerWidth, window.innerHeight);
        var alight = new THREE.AmbientLight("#ffffff", 1);
        alight.name = "aLight";
        scene.add(alight);
        // 在屏幕上显示坐标轴
        var axes = new THREE.AxesHelper(100);
        // scene.add(axes);
        // 将平面添加到场景中
        createPlaneGeometryBasicMaterial();
        // 立方体
        createBoxGeometryBasicMaterial();
        creatRoadSurface();
        createRoundGeometryBasicMaterialMax();
        createRoundGeometryBasicMaterialMin();
        crateWall();
        // 将呈现器的输出添加到HTML元素
        document.getElementById("dom").appendChild(renderer.domElement);
        // 使用GUI调试库
        var controls = new function() {
          this.rainy = function() {
            scene.remove(scene.getObjectByName("particles_snowy"));
            if (rainy_sw != 1) {
              rainy_sw = 1;
              scene.background = cubeLoader.load(urls1);
              scene.getObjectByName("aLight").intensity = 0.6;
              createPointRainy();
            }
          }
          this.snowy = function() {
            scene.remove(scene.getObjectByName("particles_rainy"));
            if (rainy_sw != 2) {
              rainy_sw = 2;
              scene.background = cubeLoader.load(urls1);
              scene.getObjectByName("aLight").intensity = 2;
              createPointRainy();
            }
          }
          this.sunny = function() {
            if (rainy_sw != 3) {
              scene.remove(scene.getObjectByName("particles_rainy"));
              scene.remove(scene.getObjectByName("particles_snowy"));
              scene.background = cubeLoader.load(urls);
              scene.getObjectByName("aLight").intensity = 1.2;
              rainy_sw = 3;
            }
          }
          this.cloudy = function() {
            if (rainy_sw != 4) {
              scene.remove(scene.getObjectByName("particles_rainy"));
              scene.remove(scene.getObjectByName("particles_snowy"));
              scene.background = cubeLoader.load(urls1);
              scene.getObjectByName("aLight").intensity = 1;
              rainy_sw = 4;
            }
          }
          this.flame = function() {
            if (flame_sw) {
              initFlame();
              flame_sw = !flame_sw;
            }
          }
        }
        var gui = new dat.GUI();
        gui.add(controls, 'rainy'); // 雨
        gui.add(controls, 'snowy'); // 雪
        gui.add(controls, 'sunny'); // 晴
        gui.add(controls, 'cloudy'); // 阴
        gui.add(controls, 'flame'); // 火焰
        // 启动动画
        renderScene();
        function createPointRainy() {
          var img = rainy_sw == 1 ? "raindrop-4.png" : rainy_sw == 2 ? "snowflake3.png" : "";
          var name = rainy_sw == 1 ? "particles_rainy" : rainy_sw == 2 ? "particles_snowy" : "";
          var texture = new THREE.TextureLoader().load("assets/textures/particles/" + img);
          var geom = new THREE.Geometry();
          var material = new THREE.PointsMaterial({
            size: 1.5,
            transparent: true, // 是否设置透明度
            opacity: 1, // 透明
            map: texture, // 粒子材质
            blending: THREE.AdditiveBlending,
            sizeAttenuation: true, // 是否相同尺寸
            color: 0xffffff
          });
          var range = 350;
          for (var i = 0; i < 3500; i++) {
            var particle = new THREE.Vector3(
              Math.random() * range - range / 2,
              Math.random() * range * 1.5,
              1 + (i / 10 - 180)
            )
            if (rainy_sw == 2) {
              // 定义雨滴以多快的速度落下,纵向运动速度的范围是0.1~0.3
              particle.velocityY = (0.1 + Math.random() / 5) - 0.1;
              // 定义粒子(雨滴)如何水平移动,横向运动速度的范围是-0.16~+0.16
              particle.velocityX = ((Math.random() - 0.5) / 3) - 0.05;
            } else {
              particle.velocityY = 0.15 + Math.random() / 5;
              particle.velocityX = (Math.random() - 0.5) / 3;
            }
            geom.vertices.push(particle);
          }
          cloud = new THREE.Points(geom, material);
          cloud.sortParticles = true;
          cloud.name = name;
          scene.add(cloud);
        }
        // 添加火焰
        function initFlame() {
          var texture = new THREE.TextureLoader().load("assets/textures/particles/flamex.png");
          //sprite材质
          var material = new THREE.SpriteMaterial({
            //以canvas作为纹理
            map: texture,
            //混合度 加法混合
            blending: THREE.AdditiveBlending
          });
          //循环1000  添加粒子
          for (var i = 0; i < 2000; i++) {
            var particle = new THREE.Sprite(material);
            initParticle(particle, i);
            krq.add(particle);
            krq.name = "particles_flame";
          }
          scene.add(krq);
        }
        /**
         * 粒子 延迟发散
         * @param particle
         * @param delay
         */
        function initParticle(particle, delay) {
          particle.position.set(0, Math.random() + 12, 0);
          particle.scale.x = particle.scale.y = Math.random() * 13;
          //下面是一系列的动画
          var xx = Math.random() * 40 - 20;
          var yy = Math.cos((Math.PI / 100) * xx) * 80;
          //位移
          new TWEEN.Tween(particle.position)
            .delay(delay)
            .to({
              x: xx,
              y: yy,
              z: Math.random() * 40 - 20
            }, 2000)
            .onComplete(function() {
              initParticle(particle, delay);
            })
            .start();
          // 大小
          new TWEEN.Tween(particle.scale)
            .delay(delay)
            .to({
              x: 0.01,
              y: 0.01
            }, 1000)
            .start();
        }
        // 创建圆仓大
        function createRoundGeometryBasicMaterialMax() {
          var objLoader = new THREE.OBJLoader();
          objLoader.load('assets/textures/particles/gong001.obj', function(obj) {
            var mesh = obj.children[0];
            // mesh.rotateZ(Math.PI);
            mesh.material = new THREE.MeshBasicMaterial({
              map: new THREE.TextureLoader().load('assets/textures/particles/d001.png'),
              transparent: true,
              side: THREE.DoubleSide,
              clipIntersection: true,
            });
            mesh.rotateZ(Math.PI);
            mesh.position.set(-40, 36, -105);
            for (let i = 0; i < 2; i++) {
              for (let j = 0; j < 3; j++) {
                var mc = mesh.clone();
                mc.translateX(i * 28);
                mc.translateZ(j * 20);
                scene.add(mc);
              }
            }
          });
        }
        // 创建圆仓小
        function createRoundGeometryBasicMaterialMin() {
          var objLoader = new THREE.OBJLoader();
          objLoader.load('assets/textures/particles/002.obj', function(obj) {
            var mesh = obj.children[0];
            mesh.material = new THREE.MeshBasicMaterial({
              map: new THREE.TextureLoader().load('assets/textures/particles/002.png'),
              transparent: true,
              side: THREE.DoubleSide,
              clipIntersection: true,
            });
            mesh.rotateZ(Math.PI);
            mesh.position.set(-40, 20, -19);
            for (let i = 0; i < 2; i++) {
              for (let j = 0; j < 6; j++) {
                var mc = mesh.clone();
                mc.translateX(i * 28);
                mc.translateZ(j * 24);
                scene.add(mc);
              }
            }
          });
        }
        // 创建围栏
        function crateWall() {
          var objLoader = new THREE.OBJLoader();
          objLoader.load('assets/textures/particles/wall.obj', function(obj) {
            obj.scale.set(0.98, 0.6, 1);
            var texLan = new THREE.TextureLoader().load('assets/textures/particles/lan2.png');
            // 纹理重复
            texLan.wrapS = THREE.RepeatWrapping;
            texLan.wrapT = THREE.RepeatWrapping;
            texLan.repeat.set(40, 1);
            obj.children[0].material = new THREE.MeshBasicMaterial({
              side: THREE.DoubleSide,
              map: texLan,
              transparent: true,
            });
            obj.children[1].material = new THREE.MeshBasicMaterial({
              map: new THREE.TextureLoader().load('assets/textures/particles/door.png'),
              side: THREE.DoubleSide,
              transparent: true,
            });
            scene.add(obj)
          });
        }
        // 创建房屋
        function createBoxGeometryBasicMaterial() {
          var objLoader = new THREE.OBJLoader();
          objLoader.load('assets/textures/particles/003.obj', function(obj) {
            var mesh = obj.children[0];
            mesh.material = new THREE.MeshBasicMaterial({
              map: new THREE.TextureLoader().load('assets/textures/particles/003.png'),
            });
            mesh.scale.set(1.3, 1.4, 1.5);
            mesh.position.set(11, 0, -85);
            for (let i = 0; i < 2; i++) {
              for (let j = 0; j < 3; j++) {
                var mc = mesh.clone();
                mc.translateX(i * 52);
                mc.translateZ(j * 83);
                scene.add(mc);
              }
            }
          });
        }
        /**
         * 创建地面并添加材质
         * wrapS属性定义的是纹理沿x轴方向的行为,而warpT属性定义的是纹理沿y轴方向的行为。
         * Three.js为这些属性提供了如下两个选项:
         * ·THREE.RepeatWrapping允许纹理重复自己。
         * ·THREE.ClampToEdgeWrapping是属性的默认值。
         * 属性值为THREE.ClampToEdgeWrapping时,那么纹理的整体不会重复,只会重复纹理边缘的像素来填满剩下的空间。
         */
        function createPlaneGeometryBasicMaterial() {
          var cubeMaterial = new THREE.MeshStandardMaterial({
            map: textureLoader.load("assets/textures/particles/floor3.png"),
            transparent: true,
            side: THREE.DoubleSide,
          });
          // 创建地平面并设置大小
          var planeGeometry = new THREE.PlaneGeometry(270, 260);
          var plane = new THREE.Mesh(planeGeometry, cubeMaterial);
          // 设置平面位置并旋转
          plane.rotation.x = -0.5 * Math.PI;
          plane.position.y = -0.1;
          scene.add(plane);
        }
        function creatRoadSurface() {
          var textureLoader = new THREE.TextureLoader();
          var geometry = new THREE.PlaneGeometry(24, 280);
          var texture = textureLoader.load('assets/textures/particles/road2.png');
          texture.wrapS = THREE.RepeatWrapping;
          texture.wrapT = THREE.RepeatWrapping;
          texture.repeat.set(1, 10);
          var material = new THREE.MeshBasicMaterial({
            map: texture,
            side: THREE.DoubleSide,
          });
          var mesh = new THREE.Mesh(geometry, material);
          scene.add(mesh);
          mesh.rotateX(-Math.PI / 2);
          mesh.position.x = 105.5
        }
        function renderScene() {
          orbit.update(); // 拖动
          TWEEN.update();
          if (cloud) {
            var vertices = cloud.geometry.vertices;
            vertices.forEach(function(v) {
              v.y = v.y - (v.velocityY);
              v.x = v.x - (v.velocityX);
              if (v.y <= 0) v.y = 60;
              if (v.x <= -20 || v.x >= 20) v.velocityX = v.velocityX * -0.8;
            });
            cloud.geometry.verticesNeedUpdate = true;
          }
          // 使用requestAnimationFrame函数进行渲染
          requestAnimationFrame(renderScene);
          renderer.render(scene, camera);
        }
        // 渲染的场景
        renderer.render(scene, camera);
      }
      window.onload = init;
      // 随着窗体的变化修改场景
      function onResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
      }
      // 监听窗体调整大小事件
      window.addEventListener('resize', onResize, false);
    </script>
  </body>
</html>


4,源码和模型


需要完整代码、模型或者其他源码,请进入博客首页查看其他文章或者留言

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
目录
相关文章
|
4月前
|
人工智能 数据可视化 安全
Java带可视化数据大屏的物联网智慧工地系统源码
通过现场AI智能视频监控、临时设施动态管理,实时检测场地空间、资源、设施的运行状况,及时发现场地安全隐患,确保为工人营造一个安全、文明的场地作业环境。
61 0
|
19天前
|
人工智能 监控 数据可视化
Springcloud可视化物联网智慧工地云SaaS平台源码 支持二开和私有化部署
Springcloud可视化物联网智慧工地云SaaS平台源码 支持二开和私有化部署
87 0
|
8月前
|
监控 数据可视化 物联网
Java可视化物联网智慧工地SaaS平台源码:人脸识别考勤
基于微服务+Java+Spring Cloud Vue +UniApp +MySql实现的智慧工地云平台源码
90 1
|
9月前
|
数据采集 JSON 监控
Zabbix物联网可视化开发文档
Zabbix物联网可视化开发文档
91 1
|
数据可视化 物联网
Threejs物联网,养殖场3D可视化(三)模型展示,轨道控制器设置,模型沿着路线运动,模型添加边框,自定义样式显示标签,点击模型获取信息
Threejs物联网,养殖场3D可视化(三)模型展示,轨道控制器设置,模型沿着路线运动,模型添加边框,自定义样式显示标签,点击模型获取信息
764 0
Threejs物联网,养殖场3D可视化(三)模型展示,轨道控制器设置,模型沿着路线运动,模型添加边框,自定义样式显示标签,点击模型获取信息
|
传感器 监控 数据可视化
IoT Studio 物联网可视化应用搭建开发实践
阿里云 IoT Studio 物联网可视化应用搭建开发实践
22593 4
IoT Studio 物联网可视化应用搭建开发实践
|
数据可视化 物联网
Threejs物联网,工厂3D可视化,加载模型,水流监测,标签动态数据展示
Threejs物联网,工厂3D可视化,加载模型,水流监测,标签动态数据展示
653 0
Threejs物联网,工厂3D可视化,加载模型,水流监测,标签动态数据展示
|
数据可视化 物联网
Threejs物联网,养殖场3D可视化(二)
Threejs物联网,养殖场3D可视化(二)
317 0
Threejs物联网,养殖场3D可视化(二)
|
数据可视化 物联网
Threejs物联网,养殖场3D可视化(一)
Threejs物联网,养殖场3D可视化(一)
352 0
Threejs物联网,养殖场3D可视化(一)
EMQ
|
SQL 消息中间件 数据采集
全新物联网数据集成 :Flow 可视化编排 & 双向数据桥接
最新发布的EMQX 5.0针对数据集成相关功能进行了深度的重构和优化,并提供了数据集成可视化查看能力(Flows),本文将为读者详细展示EMQX这一重要能力的价值与应用。
EMQ
343 0
全新物联网数据集成 :Flow 可视化编排 & 双向数据桥接

相关产品

  • 物联网平台