最近在研究Babylon.js三维可视化过程中,发现很多三维的应用场景,实现起来比较复杂,了解到three.js比较容易实现,就开展了利用three.js实现智慧养殖场物联网三维可视化的程序。
先说明一下,我的开发环境:vue-2.5.2,Three.js-0.126.0,开发工具webstorm2021.2.3。
智慧养殖场物联网三维可视化程序,包括开发的3d展示引擎,结合养殖场的3d模型,打造出全新的智慧养殖场平台,3D可视化来管理养殖场运转流程。支持对单个场地参数及过程控制参数的监测、信号采集、传输等自动化技术及基础自动化设备的应用范围。构建实时感知、数字化及工业互联网系统,及时采集数量、能耗、加工和设备状态等数据
这里只介绍Web3D可视化实现部分,主要使用Threejs3D引擎实现3D效果。首先对根据场区地形和装置进行建模,建模需要专业的建模工程师进行建模,建模软件主要用3Dmax和blender建模软件或者其他建模软件也可以,需要导出Threejs支持的格式,Threejs支持的模型格式主要常用的有obj+mtl,gltf/glb,dae,json等。模型中使用了压缩,将原模型和材质文件从84M压缩至8.5M,极大地提高页面加载渲染速度,也在交互上进行友好处理,比如显示进度条,loading窗口等。
建模完成后用Threejs加载模型,具体步骤如下:
(一)引擎加载(引擎场景、灯光、相机)
import * as THREE from "three";
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import {DRACOLoader} from 'three/examples/jsm/loaders/DRACOLoader'
import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader";
// 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。
scene = new THREE.Scene();
const cubeLoader = new THREE.CubeTextureLoader();
scene.background = cubeLoader.load(urls);
// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景
renderer = new THREE.WebGLRenderer({
antialias: true,
logarithmicDepthBuffer: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color("#0e0934"));
// 添加环境光
scene.add(new THREE.AmbientLight("#ffffff", 1.5));
document.getElementById("container").appendChild(renderer.domElement);
// 创建一个摄像机,它定义了我们正在看的地方
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 30000);
// 将摄像机对准场景的中心
camera.position.x = -400;
camera.position.y = 5200;
camera.position.z = 9000;
camera.lookAt(scene.position);
// 鼠标控件
controls = new OrbitControls(camera, renderer.domElement)
// 自动旋转7秒
controls.autoRotate = true;
setTimeout(function () {
controls.autoRotate = false;
}, 7000)
// 渲染
this.renderScene()
// 监听鼠标点击事件,点击到监控摄像头后打开实时监控视频
window.addEventListener('click', this.onDocumentMouseDown, false);
(二)加载 farm.glb 养殖场模型
// 模型加载进度管理
let manager = new THREE.LoadingManager();
manager.onStart = (url, loaded, total) => {};
manager.onLoad = () => {
console.log('Loading complete!');
};
const _this = this;
manager.onProgress = async (url, loaded, total) => {
if (Math.floor(loaded / total * 100) === 100) {
this.loadingProcessTimeout && clearTimeout(this.loadingProcessTimeout);
this.loadingProcessTimeout = setTimeout(() => {
_this.state.loadingProcess = Math.floor(loaded / total * 100)
}, 800);
} else {
_this.state.loadingProcess = Math.floor(loaded / total * 100)
}
}
const gltfLoader = new GLTFLoader(manager);
// 加载模型
gltfLoader.load("../../static/models/farm.glb", (gltf) => {
scene.add(gltf.scene);
});
(三)渲染
renderScene() {
// 更新控制器
controls.update(clock.getDelta());
// 使用requestAnimationFrame函数进行渲染
requestAnimationFrame(this.renderScene);
renderer.render(scene, camera);
}