首页 > temp > JavaScript教程 >
-
如何用webgl(three.js)搭建处理3D园区、3D楼层、3D机房管线问题(机房升级版)-第
写在前面的话:
说点啥好呢?就讲讲前两天的小故事吧,让我确实好好反省了一下。
前两天跟朋友一次技术对话,对方问了一下Geometry与BufferGeometry的具体不同,我一下子脑袋短路,没点到重点定义,被朋友嘲笑一番,亏还搞了three.js 这么久,这么简单的基础知识尽然不能对答如流,原来都是假把式。着实尴尬至极,尴尬至极....
朋友间的调侃,本是玩笑,但认真思考,不无道理。正所谓温故而知新,也是我们程序员的必须课程,不仅仅是学习利用新技术,对自己常用的老技术也要时长翻看一下,加强记忆,加深理解。
后来我还真好好的整理总结了一下Geometry与BufferGeometry,查漏补缺,也算为时未晚也。
一句话,这两个对象的主要区别:主要在数据结构上,BufferGeometry非常高效,主要是因为数据直接放在一个连续的GPU内存空间中,有效减少向 GPU 传输上述数据所需的开销,而three.js后期版本中的geometry最终都转化为bufferGeometry,但始终是比bufferGeomerty多了一步,而且还是从CPU的geometry对象传输到GPU的bufferGeometry对象的一个夸硬件传递过程,所以后期也不建议用geometry了。
序:
在三维机房管理系统中,我们已经可以看到很多实现3d机房的可视化管理方案,常见的功能有动力环境管理、安防监控、资产管理与运维,包括我的前面的文章也有过常规3D机房方案的介绍,可以看我前面的文章(使用webgl(three.js)创建科技版3D机房,3D机房微模块详细介绍(升级版三)—— 1)。
再很多3D机房方案中,管线管理.一直是无法切实解决的痛点。主要原因有如下几个:
1、种类繁杂,机房管线线路繁杂,光是线路类型就包括了强电,弱电走线、光纤网线、消防管线、甚至包括国防线(政策上是规避展示的)
2、施工图纸整理繁杂,涉及到各种类型的线路,施工图都来源一大堆,着实无法入手
3、建模工作量大,线路的建模,是最繁杂的,除了线路多,走势还错综复杂
那么针对上面的痛点,我们又该如何解决。
首先是素材来源问题,记得高中学过,唯物主义辨证方法论的思想,牵牛我们要牵牛鼻子,既然线路繁杂,何不挑重点先解决,数据中心这个行业,管线最关心的还是光纤网络线路,而且是只正对数据服务器的网络线路,其它什么强电弱电,甚至是机房内部的动环系统传感器走线,都不是那么重要。所以我们先提出主要矛盾。重点解决机房数据业务的网络走线即可。
然后是技术实现方面:
有三种方案选择:
1、全程建模,通过建模的方式实现走线展示,这虽然准确,但哪有那么多的人力物力去建模,还有建模过程中,也不能确保没有遗漏与错搭。
2、数据节点驱动:只保存每条线路的关键节点,使用代码生成的线路方式。这很大程度上减少了工作量,但是整理的工作量也不小。
3、逻辑线路:只记住起点与经过的设备节点以及终点,自动智能化生成线路。线路不按照实际走向,只记录描述线路上设备的逻辑点位。
我们的解决方案是采用后面两种,虚实结合。
好了 闲话少叙,归入正题:
一、定义:
管道:顾名思义,就知道是指放线缆的固定建筑,有时候是铁管道,有时候是水泥管道
井:每隔一段管道就会有一个便于施工人员维护的井出现
线缆:通常情况下,是放在管道里面的粗黑粗黑的电缆。
电路:是指在线缆里面的一根一根的电线,通常一根电缆里面有几根或者十几根电路
光纤:在电路里面的光纤
二、效果与代码实现:
1、整体园区效果,我们还是采用深色科技蓝风格(科技的主流风)。模型我们还是采用代码创建的方式,楼宇标号采用精灵模型。这里的井盖采用黄色标亮,便于识别。
全场景实现主要代码如下:
2、显示地下所有管道,实现方式也比较简单,只需要隐藏上方的建筑与园区地面,把管道显现出来即可。这里可以看到一个园区渐变隐藏的效果。
代码实现:
//隐藏园区模型 ModelBussiness.prototype.hideYuanquModel = function (cb) { if (!this.helpBuildModels) { this.helpBuildModels = WT3DObj.commonFunc.findObjectsByNames(this.helpBuildNames); } // WT3DObj.commonFunc.changeObjsOpacity(this.helpBuildModels, 0,0.5, 1000, function () {}); WT3DObj.commonFunc.changeObjsOpacity(this.m_yuanquModels, 1,0.2, 1000, function () { modelBussiness.hideDistance() WT3DObj.commonFunc.findObject("backGround").visible = false; cb&&cb() }); } ModelBussiness.prototype.showYuanquModel = function (cb) { if (!this.helpBuildModels) { this.helpBuildModels = WT3DObj.commonFunc.findObjectsByNames(this.helpBuildNames); } WT3DObj.commonFunc.changeObjsOpacity(this.helpBuildModels, 0.5, 0, 1000, function () {}); WT3DObj.commonFunc.changeObjsOpacity(this.m_yuanquModels, 0.2, 1, 1000, function () { cb&&cb() }); }
3、井下走线方式展现,可以查看井下每条线路的信息,便于运维人员运维查看管理
主要代码逻辑:
4、双击管线,查看管线内部光纤信息,快速掌握光纤走向与状态。
var _this = this; if(_obj.name.indexOf('jing_line_')>-1){//显示详细线缆 $("#guangLan").hide() _this.inVisibleJing(function () { $(".cableImg").css("transform", "scale(1)"); })
5、展现所有线缆信息,标注线缆,以及点击查看线缆信息。
这里主要用精灵模型,精灵贴图的方式。
6、双击线缆,查看线缆内的光纤数据信息。
7、标注井深与管深。便于施工与土建规避。知道深度,能有效辅助运维人员下井准备,而且再土建施工时,能有效规避风险,不会有挖断线缆情况发生。
代码实现:
//显示管道 ModelBussiness.prototype.showGD = function (cb) { this.hideDistance() var guandao = WT3DObj.commonFunc.findObject("yqgx_guandao"); guandao.position.y =0; guandao.visible = true; WT3DObj.commonFunc.changeObjsOpacity([guandao], 0.1, 1, 500, function () { cb&&cb() }); } //隐藏管道 ModelBussiness.prototype.hideGD = function (cb) { var guandao = WT3DObj.commonFunc.findObject("yqgx_guandao"); WT3DObj.commonFunc.changeObjsOpacity([guandao], 1, 0.1, 500, function () { guandao.position.y = -100000; guandao.visible = false; cb&&cb() }); } // 显示深度 ModelBussiness.prototype.showDeep=function(cb){ modelBussiness.showDistance() // 缓存相机位置 this.cameraPostion_cache=JSON.parse(JSON.stringify(WT3DObj.getCameraPosition())); this.cameraTarget_cache=JSON.parse(JSON.stringify(WT3DObj.getCameraTarget())); var position={x: -520.4091455366863, y: 144.35504820242926, z: 627.9302907417292}; var positionTarget={x: -263.56663925875796, y: -150.20066997406482, z: 240.69791289652335}; WT3DObj.commonFunc.changeCameraPosition(position,positionTarget,1000,function(){cb&&cb()}) } //隐藏深度 ModelBussiness.prototype.hideDeep = function (cb) { var yuanqu=WT3DObj.commonFunc.findObject(["zysjzx_yuanqu_7"]); WT3DObj.commonFunc.changeObjsOpacity([yuanqu],0.1,1,500,function(){ modelBussiness.hideDistance() WT3DObj.commonFunc.findObject(["backGround"]).visible=true; WT3DObj.commonFunc.changeCameraPosition(roomConfig.cameraPostion,roomConfig.cameraTarget,1000) cb&&cb() }) }
// 显示井深、管道深尺寸标注 ModelBussiness.prototype.showDistance=function(){ var that=this; WT3DObj.commonFunc.findObject("backGround").visible=false; WT3DObj.commonFunc.findObject("zysjzx_yuanqu_7").visible=false; WT3DObj.commonFunc.changeObjsOpacity(this.m_shenduModels,0.2,1,1000,function(){ for(var i=0;i<that.m_shenduModels.length;i++){ that.m_shenduModels[i].visible=true; } }) } // 隐藏井深、管道深尺寸标注 ModelBussiness.prototype.hideDistance=function(){ WT3DObj.commonFunc.findObject("backGround").visible=true; WT3DObj.commonFunc.findObject("zysjzx_yuanqu_7").visible=true; for(var i=0;i<this.m_shenduModels.length;i++){ this.m_shenduModels[i].visible=false; } }
8、线缆检索。能够根据线缆属性,快熟定位查看线缆走势与信息。
ModelBussiness.prototype.showAllFloorLinesModel = function (callBack) { var _this = this; this.openFloors(function () { if (!_this.FloorLines) { var linesname = []; for (var i = 1; i <= 3; i++) { linesname.push("zb_f" + i + "_H1xi"); linesname.push("zb_f" + i + "_H2xi"); linesname.push("zb_f" + i + "_Ixi"); linesname.push("zb_f" + i + "_H1cu"); linesname.push("zb_f" + i + "_H2cu"); linesname.push("zb_f" + i + "_Icu"); } _this.FloorLines = WT3DObj.commonFunc.findObjectsByNames(linesname); } var outlines = []; if (_this.FloorLines.length > 0) { $.each(_this.FloorLines, function (_index, _obj) { _obj.visible = true; if (_obj.name.indexOf("cu") >= 0) { outlines.push(_obj); } }); } var vmodes = []; $.each(WT3DObj.scene.children, function (_index, _obj) { if (_obj.name.indexOf("r1_11_1") >= 0 || _obj.name.indexOf("r1_11_2") >= 0 ) { vmodes.push(_obj); } }); vmodes = vmodes.concat(_this.FloorLines); _this.VitureAllFloors(function () { WT3DObj.commonFunc.changeObjsOpacity(vmodes, 0.1, 1, 100, function () { WT3DObj.commonFunc.changeObjsOpacity(outlines, 1, 0.1, 500, function () { if (callBack) { callBack(); } }); }); }); }) } ModelBussiness.prototype.showAllFloorOutLinesModel = function (callBack) { var _this = this; this.openFloors(function () { if (!_this.FloorLines) { var linesname = []; for (var i = 1; i <= 3; i++) { linesname.push("zb_f" + i + "_H1xi"); linesname.push("zb_f" + i + "_H2xi"); linesname.push("zb_f" + i + "_Ixi"); linesname.push("zb_f" + i + "_H1cu"); linesname.push("zb_f" + i + "_H2cu"); linesname.push("zb_f" + i + "_Icu"); } _this.FloorLines = WT3DObj.commonFunc.findObjectsByNames(linesname); } var outlines = []; if (_this.FloorLines.length > 0) { $.each(_this.FloorLines, function (_index, _obj) { if (_obj.name.indexOf("cu") >= 0) { _obj.visible = true; outlines.push(_obj); } }); } var vmodes = []; $.each(WT3DObj.scene.children, function (_index, _obj) { if (_obj.name.indexOf("r1_11_1") >= 0 || _obj.name.indexOf("r1_11_2") >= 0 || _obj.name.indexOf("zb_f1_jigui") >= 0) { vmodes.push(_obj); } }); vmodes = vmodes.concat(_this.FloorLines); _this.VitureAllFloors(function () { WT3DObj.commonFunc.changeObjsOpacity(vmodes, 0.1, 1, 100, function () { WT3DObj.commonFunc.changeObjsOpacity(outlines, 0.1, 1, 500, function () { if (callBack) { callBack(); } }); }); }); }) }
9、设备检索,端口检索,能快速定位到具体设备。查看设备信息状态,位置信息等。
主要思路:
//搜索 ModelBussiness.prototype.showPostionState = false; ModelBussiness.prototype.showPosition = function (cabid, serverid, portId) { var _this = this; if (window.location.href.indexOf("index.html") >= 0) { var serchParam = cabid + "_search_" + serverid; if (portId) { serchParam += "_search_" + portId; } _this.dbClickSelect(WT3DObj.commonFunc.findObject("build_1"),null, null, serchParam); } if (window.location.href.indexOf("floor.html")>=0) { WT3DObj.commonFunc.flashObjsGradualByName(["zb_3f1_546", "zb_3f2_1320"], "floor3_flash1", "000000", "0000ff", 7, 1000, 10, 0); setTimeout(function () { var serchParam = cabid + "_search_" + serverid; if (portId) { serchParam += "_search_" + portId; } _this.dbClickSelect(WT3DObj.commonFunc.findObject("zb_3f1_546"),null, null, serchParam); }, 2000); } } // 隐藏所有模型 ModelBussiness.prototype.cacheAllModels = function(cb){ this.m_allNames=[].concat(this.m_yuanquNames,this.m_guandaoNames,this.m_xianlanNames,this.m_shenduNames,this.m_buildInfoNames) if(!this.m_allModels.length){ var models=WT3DObj.scene.children for(var i=0;i<models.length;i++){ var item=models[i]; if(this.m_yuanquNames.indexOf(item.name)>-1){this.m_yuanquModels.push(item)} if(this.m_guandaoNames.indexOf(item.name)>-1){this.m_guandaoModels.push(item)} if(this.m_xianlanNames.indexOf(item.name)>-1){this.m_xianlanModels.push(item)} if(this.m_shenduNames.indexOf(item.name)>-1){this.m_shenduModels.push(item)} if(this.m_buildInfoNames.indexOf(item.name)>-1){this.m_buildInfoModels.push(item)} } this.m_allModels=[].concat(this.m_yuanquModels,this.m_guandaoModels,this.m_xianlanModels,this.m_shenduModels,this.m_buildInfoModels) } }
10、电路检索,线缆中包含很多电路,支持电路检索,能快速定位相应的电路。
主要代码:
//隐藏显示线 ModelBussiness.prototype.Lines = null; ModelBussiness.prototype.hideAllLinesModels = function (cb) { var _this = this; WT3DObj.commonFunc.changeObjsOpacity(this.m_xianlanModels, 1, 0.1, 500, function () { $.each(_this.m_xianlanModels, function (_index, _obj) { _obj.visible = false; _obj.position.y=-1000000; }); cb&&cb() }); } ModelBussiness.prototype.showAllLineModels = function (cb) { var line = []; $.each(this.m_xianlanModels, function (_index, _obj) { _obj.visible = true; _obj.position.y=0; if (_obj.name.indexOf("cuxian")>0) { line.push(_obj); } }) WT3DObj.commonFunc.changeObjsOpacity(this.m_xianlanModels, 0.1, 1, 500, function () { // WT3DObj.commonFunc.changeObjsOpacity(line, 1, 1, 500, function () { cb&&cb() // }); }); } ModelBussiness.prototype.showLines = function(callback){ var guandao=WT3DObj.commonFunc.findObject('yqgx_guandao'); var backGround=WT3DObj.commonFunc.findObject('backGround'); guandao.position.y=-1000000; backGround.position.y=-1000000; $.each(this.m_xianlanModels, function (_index, _obj) { _obj.visible = true; if (_obj.name.indexOf("cuxian")>0) { _obj.position.y=0; // if(_obj.resourcePosition){ // _obj.position.y=_obj.resourcePosition.y; // } } }) WT3DObj.commonFunc.changeObjsOpacity(this.m_xianlanModels, 0.1, 1, 500, function () { }); } //虚化某一根线 ModelBussiness.prototype.visLine = function (name, callBack) { if (!this.Lines) { this.Lines = WT3DObj.commonFunc.findObjectsByNames( ["yqgx_cuxian1_11", "yqgx_cuxian2_15", "yqgx_cuxian3_19", "yqgx_cuxian4_23", "yqgx_cuxian5_27", "yqgx_cuxian6_31", "yqgx_cuxian7_35", "yqgx_cuxian8_39", "yqgx_cuxian9_46", "yqgx_cuxian10_50", "yqgx_xixian1_54", "yqgx_xixian2_54", "yqgx_xixian3_62", "yqgx_xixian4_66", "yqgx_xixian5_70", "yqgx_xixian6_72", "yqgx_xixian7_76", "yqgx_xixian8_80", "yqgx_xixian9_86", "yqgx_xixian10_92"]); } var line = []; $.each(this.Lines, function (_index, _obj) { if (_obj.name == name) { line.push(_obj); } }) WT3DObj.commonFunc.changeObjsOpacity(line,1, 0.5, 500, function () { if (callBack) { callBack(); } }); } //显示单根线 ModelBussiness.prototype.showSingleLines = function (name,callBack) { if (!this.Lines) { this.Lines = WT3DObj.commonFunc.findObjectsByNames( ["yqgx_cuxian1_11", "yqgx_cuxian2_15", "yqgx_cuxian3_19", "yqgx_cuxian4_23", "yqgx_cuxian5_27", "yqgx_cuxian6_31", "yqgx_cuxian7_35", "yqgx_cuxian8_39", "yqgx_cuxian9_46", "yqgx_cuxian10_50", "yqgx_xixian1_54", "yqgx_xixian2_54", "yqgx_xixian3_62", "yqgx_xixian4_66", "yqgx_xixian5_70", "yqgx_xixian6_72", "yqgx_xixian7_76", "yqgx_xixian8_80", "yqgx_xixian9_86", "yqgx_xixian10_92"]); } var line = []; $.each(this.Lines, function (_index, _obj) { _obj.position.y=-1000000; if (_obj.name == name) { line.push(_obj); _obj.visible = true; _obj.position.y=0; } }) WT3DObj.commonFunc.changeObjsOpacity(line, 0.3, 1, 500, function () { if (callBack) { callBack(); } }); }
由于篇幅过长,我们下节课详细描述楼层内部以及机房内部的线路方案。
来源:https://www.cnblogs.com/yeyunfei/p/15578120.html