IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> blender+Three.js 三维数据可视化 -> 正文阅读

[游戏开发]blender+Three.js 三维数据可视化

接到了一个需求,一个物联网的电力保障系统实时监控。实施用到了Web 3D技术,以前用过一段时间的Three.js,因为太耗资源,没怎么铺开,现在硬件条件好了,就拿出来试试。

环境:blender-2.93.6-windows-x64+Three.js?0.91.0+Echart2.0

我习惯不用最新版本的软件做开发,一方面新版的稳定性不如旧版,主要是基于js的前端开发,新版大部分对IE都不友好,国内的需求现状就是,问就是随便,验收就拿IE说事,所以多一事不如少一事,就用旧的成熟版本对付了。

首先是3D建模,打开blender,一通XJB操作,做出模型长这样:

然后把工业电区和农用电区分开,按照硬件的分布编好号(部分检测设备在一层并且比较近,就编在一起,报警时候单独处置)。

然后建一个html,按照监控屏的分辨率1920*1080设置一个画布、背景?什么的,建一个对象叫做three,作为我们绘制模型的容器。

#three{width:1920px;height:1080px;position:absolute;z-index:1}

<div id="three"></div>

建一个js文件,加载模型,按照不同的供电方式设置材质:

function init() {

?? ?var container = document.getElementById("three");

?? ?camera = new THREE.PerspectiveCamera( 45, sceneWidth / sceneHeight, 1, 4000 );
?? ?//camera.position.set(900, 400, 900);
?? ?camera.position.set(300, 600, -1400);
?? ?scene = new THREE.Scene();
?? ?//scene.rotation.set(0,Math.PI,0);
?? ?scene.rotation.y = 0.5;
?? ?
?? ?scene.background = new THREE.Color('#394855');
?? ?scene.fog = new THREE.Fog('#394855', 2000, 2500 );
?? ?
?? ?var hemiLight = new THREE.HemisphereLight( 0xFFFFFF, 0x444444);
?? ?hemiLight.position.set( 0, 500, -300 );
?? ?scene.add( hemiLight );

?? ?var dirLight = new THREE.DirectionalLight('#FFFFFF');
?? ?dirLight.position.set( 100, 300, 200 );
?? ?dirLight.castShadow = true;
?? ?dirLight.shadow.camera.top = 1000;
?? ?dirLight.shadow.camera.bottom = - 1000;
?? ?dirLight.shadow.camera.left = - 1000;
?? ?dirLight.shadow.camera.right = 1000;?? ?
?? ?dirLight.shadow.camera.far=1000;
?? ?dirLight.shadow.mapSize.width = 1024;
?? ?dirLight.shadow.mapSize.height = 1024;
?? ?scene.add( dirLight );

?? ?//scene.add(new THREE.CameraHelper( dirLight.shadow.camera ) );

?? ?//地板
?? ?//var textureLoader=new THREE.TextureLoader();
?? ?//var texture = textureLoader.load("../images/ground.png");
?? ?//var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( {map:texture,color: '#2B3745', depthWrite: false } ) );
?? ?var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 8000, 8000 ), new THREE.MeshBasicMaterial( {color: '#394855', depthWrite:false } ) );
?? ?mesh.rotation.set(- Math.PI / 2,0,0);
?? ?mesh.receiveShadow = true;
?? ?scene.add( mesh );

?? ?var grid = new THREE.GridHelper(8000, 200, '#556B80','#556B80');
?? ?grid.material.opacity = 0.2;
?? ?grid.material.transparent = true;
?? ?//grid.rotation.set(0,100,0);
?? ?scene.add(grid);
?? ?
?? ?var loader = new THREE.FBXLoader();?? ??? ??? ??? ?
?? ?loader.load('/object/factory.fbx', function ( object ) {?? ?
?? ??? ?object.traverse( function ( child ) {
?? ??? ??? ?if ( child.isMesh ) {?? ??? ??? ??? ?
?? ??? ??? ??? ?var material =new THREE.MeshPhongMaterial( {color: '#2F3C46' ,opacity:1,transparent:true})
?? ??? ??? ??? ?var material2 =new THREE.MeshStandardMaterial({color: '#394855' ,opacity:0.8,transparent:true})?? ??? ??? ??? ?
?? ??? ??? ??? ?var material1=new THREE.LineBasicMaterial( {
?? ??? ??? ??? ??? ?color: 0xffffff,
?? ??? ??? ??? ??? ?linewidth: 1,
?? ??? ??? ??? ??? ?linecap: 'round',
?? ??? ??? ??? ??? ?linejoin: ?'round'
?? ??? ??? ??? ?} );?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?
?? ??? ??? ??? ?child.material =material;?? ??? ??? ??? ?
?? ??? ??? ??? ?child.castShadow = true;
?? ??? ??? ??? ?child.receiveShadow = true;
?? ??? ??? ??? ?
?? ??? ??? ??? ?if(child.name=="ground") //地板
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?child.material=material2;?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?}?? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?else if(child.name=="wall") //外墙
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?var textureLoader = new THREE.TextureLoader();?? ?
?? ??? ??? ??? ??? ?var alphaMap = textureLoader.load( 'images/alphaMap.png' );
?? ??? ??? ??? ??? ?var wallMaterial=new THREE.MeshBasicMaterial({
?? ??? ??? ??? ??? ??? ?color: 0x005E9B,
?? ??? ??? ??? ??? ??? ?side:THREE.DoubleSide,
?? ??? ??? ??? ??? ??? ?transparent: true,
?? ??? ??? ??? ??? ??? ?depthWrite: false,
?? ??? ??? ??? ??? ??? ?alphaMap: alphaMap,
?? ??? ??? ??? ??? ?});
?? ??? ??? ??? ??? ?child.material=wallMaterial;
?? ??? ??? ??? ??? ?child.receiveShadow = false;
?? ??? ??? ??? ??? ?child.castShadow = false;?? ??? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?}?? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?else if(child.name.indexOf("HF")==0) //民用电?? ?
?? ??? ??? ??? ?{?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?child.material.color.set('#00538A');
?? ??? ??? ??? ??? ?if(child.name.indexOf("HF18")==0 )?
?? ??? ??? ??? ??? ?{?? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ??? ?var fined=false;
?? ??? ??? ??? ??? ??? ?for(var i=0;i<selectNodes.length;i++)
?? ??? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ??? ?if(selectNodes[i].name==child.name)
?? ??? ??? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ??? ??? ?fined=true;
?? ??? ??? ??? ??? ??? ??? ??? ?break;?? ?
?? ??? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?//if(!fined) selectNodes.push(child);
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}?? ??? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?else if(child.name.indexOf("TF")==0) //工业电
?? ??? ??? ??? ?{?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?child.material.color.set('#917000');
?? ??? ??? ??? ??? ?//var text=createTitle(child.name);
?? ??? ??? ??? ??? ?//text.position.set(child.position.x,child.position.y+35,child.position.z);
?? ??? ??? ??? ??? ?//scene.add(text);
?? ??? ??? ??? ?}?? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?else if(child.name.indexOf("F")==0) //冷凝罐?? ??? ??? ??? ?
?? ??? ??? ??? ?{?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?child.material.color.set('#0099FF');
?? ??? ??? ??? ??? ?//var text=createTitle(child.name);
?? ??? ??? ??? ??? ?//text.position.set(child.position.x,child.position.y+25,child.position.z);
?? ??? ??? ??? ??? ?//scene.add(text);
?? ??? ??? ??? ?}?? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?else if(child.name.indexOf("NO")==0) //氮气
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?child.material.color.set('#FF0000');
?? ??? ??? ??? ??? ?//var text=createTitle(child.name);
?? ??? ??? ??? ??? ?//text.position.set(child.position.x,child.position.y+25,child.position.z);
?? ??? ??? ??? ??? ?//scene.add(text);
?? ??? ??? ??? ?}?? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?else if(child.name.indexOf("NH")==0) //氨气
?? ??? ??? ??? ?{?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?child.material.color.set('#0000FF');
?? ??? ??? ??? ??? ?//var text=createTitle(child.name);
?? ??? ??? ??? ??? ?//text.position.set(child.position.x,child.position.y+25,child.position.z);
?? ??? ??? ??? ??? ?//scene.add(text);
?? ??? ??? ??? ?}?? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?else if(child.name.indexOf("YH")==0) //液化气
?? ??? ??? ??? ?{?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?child.material.color.set('#00FF00');
?? ??? ??? ??? ??? ?//var text=createTitle(child.name);
?? ??? ??? ??? ??? ?//text.position.set(child.position.x,child.position.y+25,child.position.z);?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?//scene.add(text);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?
?? ??? ??? ??? ?//console.log(child.name);
?? ??? ??? ??? ?
?? ??? ??? ?}
?? ??? ?} );?? ??? ?
?? ??? ?scene.add( object );
?? ?} );?? ??? ??? ??? ??? ?

?? ?renderer = new THREE.WebGLRenderer( { antialias: true,alpha:true } );
?? ?//renderer.setPixelRatio( window.devicePixelRatio );
?? ?renderer.setSize( sceneWidth, sceneHeight );
?? ?renderer.shadowMap.enabled = true;
?? ?renderer.shadowMap.type = THREE.PCFSoftShadowMap;
?? ?container.appendChild( renderer.domElement );

?? ?var controls = new THREE.OrbitControls(camera, renderer.domElement);
?? ?controls.target.set( 0, 0, 0 );
?? ?controls.update();

?? ?window.addEventListener( 'resize', onWindowResize );
}

一通操作以后,模型加载进来,页面长这样:

然后上面再加一个效果层,就是一个摄像机一样的东东,禁止它的鼠标响应。把要显示的东西都加上,页面长这样:

数据的刷新分两部分,常规的数据库信息(人员,统计指标什么的)就JQuery加载进来。监控的实时信息,引入MQTT.js和代理服务做个长连接,实时读取显示就行了,数据异常,就弹出个报警框然后发声音什么的。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章           查看所有文章
加:2021-12-24 18:50:05  更:2021-12-24 18:52:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 20:21:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码