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,源码和模型

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

在线预览:左本的博客 (zuoben.top)

  • 3
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
### 回答1: three.js物联网3d可视化是一种现代化的技术,利用三维模型和图形化界面来展示物联网设备的数据和状态。对于粮仓等储藏性质的设备而言,可采用这种技术进行实时的监控和管理,从而极大的提升了粮仓的运维效率和安全性。 粮仓案例源码是基于three.js物联网3d可视化技术开发的,利用现代化的WebGL技术,实现了粮仓3d可视化界面的设计和搭建。该源码采用基于前端技术的开发方式,充分发挥Web端数据和可视化交互性的优势。 该源码提供了丰富的功能模块,包括粮仓结构的构建、粮仓温湿度数据的采集、数据的可视化展示和粮仓灾害预警等功能。通过该源码,用户可以实现多种交互式操作,包括缩放、旋转、拖拽等,来实时查看粮仓内部的情况,提高数据的可视化程度。 综上所述,粮仓案例源码为用户提供了一种高效、可靠的监控和管理方式,有助于提升粮仓运维的效率、安全性和可靠性。该技术在粮仓等储藏性质的行业应用广泛。 ### 回答2: 物联网3D可视化技术在实际应用中,与人们的生活息息相关。其中,粮仓案例源码是一个非常实用的应用案例。 该案例源码基于Three.js开发,可以在浏览器中通过3D可视化展示粮食仓库的储存情况。通过该案例,我们可以清晰地了解到每一个仓库中的粮食储量情况,从而可以方便地管理粮食的存储、领取以及补充等方面。 在该案例中,设计师采用了人性化的UI设计,使得用户可以轻松地进行各项操作。同时,其交互操作也非常简单自然。不仅如此,该案例的源码还非常规范,代码结构相当清晰,便于阅读与修改。值得一提的是,该案例也有详细的开发文档,为有意愿学习或者开发的用户提供了很好的指导。 总体来说,该粮仓案例源码是一个具有实践意义的案例,其代码规范、可读性以及人性化的UI,都体现了其开发者的专业素养和工作态度,是物联网3D可视化技术方面的一个难得的优秀案例。 ### 回答3: 粮仓案例是利用three.js技术实现的一种物联网3D可视化方案。这种方案主要是针对对粮仓的物理参数进行数据采集和计算,然后通过传感器将数据发送到控制器,控制器可将数据转换为3D可视化图像。这种方案可用于实时监测粮仓内温度、湿度、质量等参数,及时发现异常情况并进行处理。 源码方面,这个项目主要使用了JavaScript编程语言和three.js库进行开发。整个项目代码非常详细,包括三维建模、数据采集、传感器接口配置、数据可视化等多个部分。此外,源码还提供了详细的说明和注释,方便技术人员进行开发和调试。 这个案例的优势在于它结合了物联网3D可视化技术。通过物联网,可以实现对粮仓内多参数的实时监测和数据采集;而通过three.js库,可以将这些采集到的数据转换为生动的3D模型,提供更好的可视化效果。此外,这个案例还具有高度的可扩展性和可定制性,可以针对不同行业和应用场景进行定制开发。 总之,这个案例是物联网3D可视化技术的有力实践,推动了这两种技术的结合与发展,对于实现智能化系统具有重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

左本Web3D

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值