2

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课

 1 year ago
source link: https://blog.51cto.com/yeyunfei/7086675
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课

精选 原创

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生、物联网3D、物业3D监控、物业基础设施可视化运维、3D定位、三维室内定位、3d建筑,3d消防,消防演习模拟,3d库房,webGL,threejs,3d机房,bim管理系统

  老子云:有道无术,术尚可求,有术无道,止于术。

  咱开篇引用老子的话术,也没其它意思,只是最近学习中忽有感悟,索性就写了上来。

这句话用现代辩证思维理解,这里的”道“ 大抵是指方法论,解决大部分问题的一般发展规律,例如学习的方法,解决问题的方法,获取知识的方法。而这里的”术“就可以理解为解决具体问题的技术,例如,一门手艺,一项专业,一个技能等。老子的意思是要掌握一般事物的发展规律...

学习技术,也是一样,比如咱最近专注的3D技术,往行而上了说,道在于实践中求知的方法论,术在于熟练并应用技术的能力。而往行而下了讲,道在于3D具体执行的原理(了解掌握webgl),术则在于封装好的库的应用(了解掌握three.js)

不过现在静下心,看文字的很少了,上面说教了这么一堆废话,我也全当一说,你如读了,也权当一乐。要是有那么一点赞同,姑且也就这么滴吧。

  最近也很长时间没有记一些博文了,翻了一下之前的项目,重新以现在的角度审度之前的代码,看看有没有啥可以提炼,可以改进的点。温故而知新吗。

  看自己之前写的代码,有些地方能发现一些惊喜,但大部分都是惊吓,都是写了啥啊,咋当时就这么写了,大多时候都是满脸的鄙夷。

  这个项目还是好久前的项目,具体时候,不太记得了,是给杭州的一个泵业小镇做的智慧楼宇。当时说是智慧楼宇,但是监控的设备,并没有那么多。估计也是一个试点项目吧。

一、整体效果

  首先我们先看一下整体的建模项目效果,如下:

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_threejs

 二、功能展示

  功能还是比较简单的,无非是一些多角度展示与简单几种设备检测

2.1、视角切换

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_webGL_02

 视角切换比较再技术上实现比较简单,主要是改变主摄像机camera的属性

在场景中调整几个固定的角度,然后提取摄像机的属性值,再跟视角按钮做关联,这样就可以简单实现外场的视角切换了。

2.2、楼层切换

楼层切换稍微复杂一些,这里主要使用了按需加载,建模时也要考虑到具体场景的应用

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_3d建筑_03

 楼层切换,首先考虑的是楼层再何时加载,如果一开始全部预加载好,这无疑是对性能与速度的浪费,其次是加载后是否需要销毁。

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim管理系统_04

 例如上图,场景复原后,内部楼层是否再可视范围内,对于webgl来说,在场景内的模型,都是需要进行计算绘制的,不管是否被遮挡。

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim管理系统_05

 再如上图,再次调用打开楼层时,如何处理动画,如何节约资源。这些都是主要的技术点。我们后面节点着重讲解方法。这里着重介绍功能

 2.3、设备监控

智慧楼宇,数字孪生,主要核心在于采集端数据跟展示端数据的关联控制。

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_3d建筑_06

如上图 设备与楼层关联,定位某种类型设备时,自动展开楼层。

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim管理系统_07

三、技术讲解

 3.1、建模

  建模除了固有的特效模型需要处理外,其它的就需要根据业务逻辑对模型进行分解,归类,本着不浪费新能,极致加载的原则。例如这个项目,我们模型分解如下:

  3.1.1外立面模型框架

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim管理系统_08

初见的场景,只做外立面模型,不做内部模型

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim技术_09

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim管理系统_10

{ "show": true, "uuid": "", "name": "bout_f13_0", "objType": "ExtrudeGeometry", "position": { "x": 2117.824, "y": 5950.545, "z": 2309.159 }, "style": { "skinColor": 16711680, "skin": { "skin_up": { "skinColor": 3911420, "materialType": "lambert", "side": 1, "opacity": 1, "imgurl": "../img/3dImg/floor.jpg", "repeatx": true, "width": 0.005, "repeaty": true, "height": 0.005, "envMap": { "name": "skybox", "reflectivity": 0.4, "refractionRatio": 0.4, "combine": "" } }, "skin_down": { "skinColor": 16711680, "side": 1, "opacity": 1 }, "skin_side": { "skinColor": 846790, "side": 2, "opacity": 1 } } }, "scale": { "x": 1, "y": 1, "z": 1 }, "shapeParm": { "points": [{ "x": 0, "y": 0, "type": "nomal" }, { "x": 0, "y": 100, "type": "nomal" }, { "x": 100, "y": 100, "type": "nomal" }, { "x": 100, "y": 2300, "type": "nomal" }, { "x": -50, "y": 2300, "type": "nomal" }, { "x": -50, "y": 2450, "type": "nomal" }, { "x": -2500, "y": 2450, "type": "nomal" }, { "x": -2500, "y": 2300, "type": "nomal" }, { "x": -2650, "y": 2300, "type": "nomal" }, { "x": -2650, "y": 100, "type": "nomal" }, { "x": -2500, "y": 100, "type": "nomal" }, { "x": -2500, "y": 0, "type": "nomal" }], "holes": [] }, "extrudeSettings": { "amount": 1, "curveSegments": 6, "steps": 1, "bevelEnabled": false, "bevelThickness": 1, "bevelSize": 1, "bevelSegments": 1, "extrudePathPoints": [] }, "showSortNub": 5, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": -1.5707963267948966 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }

View Code

3.1.2、独立楼层模型

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim管理系统_11

 楼层模型按需加载,即用到时再加载,看不到时直接不加载或者隐藏,模型代码如下:

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim技术_09

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim管理系统_10

[{"show":true,"uuid":"","name":"build_f2_4","objType":"ExtrudeGeometry","position":{"x":-994.227,"y":810,"z":-54.692},"style":{"skinColor":16711680,"skin":{"skin_up":{"skinColor":3911935,"side":0,"opacity":0},"skin_down":{"skinColor":16711680,"side":1,"opacity":1},"skin_side":{"skinColor":2279636,"side":2,"opacity":0.8,"imgurl":"../img/3dImg/dl01.png","repeatx":true,"width":0.0001,"repeaty":true,"height":0.003}}},"scale":{"x":0.35,"y":0.35,"z":1},"shapeParm":{"points":[{"x":-11200,"y":4620,"type":"nomal"},{"x":-11580,"y":4620,"type":"absarc","radius":400,"startAngle":0,"endAngle":1.3962634015954636,"Clockwise":false},{"x":-13000,"y":5380,"type":"nomal"},{"x":-13300,"y":4600,"type":"absarc","radius":810,"startAngle":1.5707963267948966,"endAngle":2.2689280275926285,"Clockwise":false},{"x":-15400,"y":3780,"type":"nomal"},{"x":-15000,"y":3260,"type":"absarc","radius":620,"startAngle":2.6179938779914944,"endAngle":3.9269908169872414,"Clockwise":false},{"x":-13700,"y":1200,"type":"nomal"},{"x":-13150,"y":1710,"type":"absarc","radius":700,"startAngle":4.363323129985823,"endAngle":5.93411945678072,"Clockwise":false},{"x":-12170,"y":2240,"type":"nomal"}],"holes":[]},"extrudeSettings":{"amount":400,"curveSegments":6,"steps":1,"bevelEnabled":false,"bevelThickness":1,"bevelSize":1,"bevelSegments":1,"extrudePathPoints":[]},"showSortNub":6,"customType1":"","customType2":"","animation":null,"dbclickEvents":null,"rotation":[{"direction":"x","degree":-1.5707963267948963},{"direction":"y","degree":0},{"direction":"z","degree":0}],"BindDevId":null,"BindDevName":null,"devInfo":null,"BindMeteId":null,"BindMeteName":null},{"show":true,"uuid":"","name":"build_f1","objType":"ExtrudeGeometry","position":{"x":7715.604,"y":30,"z":2309.159},"style":{"skinColor":16711680,"skin":{"skin_up":{"skinColor":1129349,"side":0,"opacity":0.8,"imgurl":"../img/3dImg/floor1.jpg","repeatx":true,"width":0.001,"repeaty":true,"height":0.001},"skin_down":{"skinColor":16711680,"side":1,"opacity":1},"skin_side":{"skinColor":16777215,"side":2,"opacity":0.8,"imgurl":"../img/3dImg/dl01.png","repeatx":true,"width":0.0001,"repeaty":true,"height":0.003}}},"scale":{"x":1,"y":1,"z":1},"shapeParm":{"points":[{"x":0,"y":0,"type":"nomal"},{"x":0,"y":5000,"type":"nomal"},{"x":-7500,"y":5000,"type":"nomal"},{"x":-7500,"y":4600,"type":"nomal"},peParm":{"points":[{"x":0,"y":0,"type":"nomal"},{"x":0,"y":100,"type":"nomal"},{"x":100,"y":100,"type":"nomal"},{"x":100,"y":2300,"type":"nomal"},{"x":-50,"y":2300,"type":"nomal"},{"x":-50,"y":2450,"type":"nomal"},{"x":-2500,"y":2450,"type":"nomal"},{"x":-2500,"y":2300,"type":"nomal"},{"x":-2650,"y":2300,"type":"nomal"},{"x":-2650,"y":100,"type":"nomal"},{"x":-2500,"y":100,"type":"nomal"},{"x":-2500,"y":0,"type":"nomal"}],"holes":[]},"extrudeSettings":{"amount":300,"curveSegments":6,"steps":1,"bevelEnabled":false,"bevelThickness":1,"bevelSize":1,"bevelSegments":1,"extrudePathPoints":[]},"showSortNub":5,"customType1":"","customType2":"","animation":null,"dbclickEvents":null,"rotation":[{"direction":"x","degree":-1.5707963267948963},{"direction":"y","degree":0},{"direction":"z","degree":0}],"BindDevId":null,"BindDevName":null,"devInfo":null,"BindMeteId":null,"BindMeteName":null},{"show":true,"uuid":"","name":"build_f5","objType":"ExtrudeGeometry","position":{"x":2117.824,"y":2080,"z":2309lickEvents":null,"rotation":[{"direction":"x","degree":-1.5707963267948963},{"direction":"y","degree":0},{"direction":"z","degree":0}],"BindDevId":null,"BindDevName":null,"devInfo":null,"BindMeteId":null,"BindMeteName":null},{"show":true,"uuid":"","name":"build_f13","objType":"ExtrudeGeometry","position":{"x":1557.594,"y":6080,"z":1780.258},"style":{"skinColor":16711680,"skin":{"skin_up":{"skinColor":1129349,"side":0,"opacity":0.8,"imgurl":"../img/3dImg/floor1.jpg","repeatx":true,"width":0.001,"repeaty":true,"height":0.001},"skin_down":{"skinColor":16711680,"side":1,"opacity":1},"skin_side":{"skinColor":16777215,"side":2,"opacity":0.8,"imgurl":"../img/3dImg/dl01.png","repeatx":true,"width":0.0001,"repeaty":true,"height":0.003}}},"scale":{"x":1,"y":1,"z":1},"shapeParm":{"points":[{"x":0,"y":1500,"type":"nomal"},{"x":-1500,"y":1500,"type":"nomal"},{"x":-1500,"y":0,"type":"nomal"},{"x":0,"y":0,"type":"nomal"}],"holes":[]},"extrudeSettings":{"amount":300,"curveSegments":6,"steps":1,"bevelEnabled":false,"bevelThickness":1,"bevelSize":1,"bevelSegments":1,"extrudePathPoints":[]},"showSortNub":5,"customType1":"","customType2":"","animation":null,"dbclickEvents":null,"rotation":[{"direction":"x","degree":-1.5707963267948963},{"direction":"y","degree":0},{"direction":"z","degree":0}],"BindDevId":null,"BindDevName":null,"devInfo":null,"BindMeteId":null,"BindMeteName":null}]

View Code

3.1.3、具体楼层房间模型

这部分模型主要是对楼层模型进行分隔,楼层外围可以复制,内部不同,这样我们既可以通过分开建模的方式,实现控制

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_webGL_14

 模型代码如下:

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim技术_09

使用three.js(webgl)搭建智慧楼宇、设备检测、数字孪生——第十三课_bim管理系统_10

[ { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" }, "skin_left": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" }, "skin_right": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" } } }, "showSortNub": 19, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": 0 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "thick": null, "scale": { "x": 1, "y": 1, "z": 1 }, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }, { "show": true, "uuid": "", "name": "br_f1_w_17", "objType": "cube2", "length": 900, "width": 15, "height": 300, "x": 889.653, "y": 136.966, "z": -315.791, "style": { "skinColor": 16777215, "skin": { "skin_up": { "skinColor": 50175, "side": 1, "opacity": 1 }, "skin_down": { "skinColor": 50175, "side": 1, "opacity": 1 }, "skin_fore": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" }, "skin_behind": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" }, "skin_left": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" }, "skin_right": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" } } }, "showSortNub": 19, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": 0 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "thick": null, "scale": { "x": 1, "y": 1, "z": 1 }, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteNa 1 }, " mgurl": "../img/3dImg/inside_lightmap.jpg" } } }, "showSortNub": 19, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": 0 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "thick": null, "scale": { "x": 1, "y": 1, "z": 1 }, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }, { "show": true, "uuid": "", "name": "br_f1_w_36", "objType": "cube2", "length": 700, "width": 15, "height": 300, "x": 5979.223, "y": 136.966, "z": -2274.46, "style": { "skinColor": 16777215, "skin": { "skin_up": { "skinColor": 50175, "side": 1, "opacity": 1 }, "skin_down": { "skinColor": 50175, "side": 1, "opacity": 1 }, "skin_fore": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" }, "skin_behind": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" }, "skin_left": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" }, "skin_right": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" } } }, "showSortNub": 19, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": 0 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "thick": null, "scale": { "x": 1, "y": 1, "z": 1 }, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }, { "show": true, "uuid": "", "name": "br_f1_w_37", "objType": "cube2", "length": 15, "width": 400, "height": 300, "x": 6328.26, "y": 136.966, "z": -2469.455, "style": { "skinColor": 16777215, "skin": { "skin_up": { "skinColor": 50175, "side": 1, "opacity": 1 }, "skin_down": { "skinColor": 50175, "side": 1, "opacity": 1 }, "skin_fore": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" }, "skin_behind": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.jpg" }, "skin_left": { "skinColor": 50175, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/inside_lightmap.j egree": 0 }], "thick": null, "scale": { "x": 1, "y": 1, "z": 1 }, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }, { "name": "dev_f1_wsd_2OBJCREN1", "objType": "cylinder", "radiusTop": 16, "radiusBottom": 20, "height": 100, "segmentsX": 24, "segmentsY": 0, "openEnded": false, "position": { "x": -61.251, "y": 120.45, "z": 5.971 }, "scale": { "x": 1, "y": 1, "z": 1 }, "rotation": [{ "direction": "x", "degree": 0 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "style": { "skinColor": 16776960, "skin": { "skin_up": { "skinColor": 16777215, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/wsd/wsd_3.jpg" }, "skin_down": { "skinColor": 16777215, "side": 1, "opacity": 1 }, "skin_side": { "skinColor": 16777215, "opacity": 1, "imgurl": "../img/3dImg/wsd/wsd_4.jpg", "repeatx": true, "width": 3, "repeaty": true, "height": 1 } } }, "showSortNub": 7, "show": true, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }, { "show": true, "uuid": "", "name": "dev_f1_wsd_2OBJCREN2", "objType": "cube2", "length": 210, "width": 20, "height": 160, "x": 0, "y": 0, "z": -61.333, "style": { "skinColor": 16777215, "skin": { "skin_up": { "skinColor": 16777215, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/wsd/wsd_3.jpg" }, "skin_down": { "skinColor": 16777215, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/wsd/wsd_3.jpg" }, "skin_fore": { "skinColor": 16777215, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/wsd/wsd_1.jpg" }, "skin_behind": { "skinColor": 16777215, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/wsd/wsd_1.jpg" }, "skin_left": { "skinColor": 16777215, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/wsd/wsd_1.jpg" }, "skin_right": { "skinColor": 16777215, "side": 1, "opacity": 1, "imgurl": "../img/3dImg/wsd/wsd_1.jpg" } } }, "showSortNub": 6, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": 0 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "thick": null, "scale": { "x": 1, "y": 1, "z": 1 }, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }], "showSortNub": 43, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }]

View Code

3.2、逻辑代码

 上面讲过模型建模时的注意事项,下面就是对分解好的模型进行应用。

  3.2.1、视角切换

主要调用切换视角得方法WT3DObj.commonFunc.changeCameraPosition

$(".floorNub").click(function () {//2D页面按钮事件绑定
        $(".floorNub").attr("class", "floorNub")
        $(this).attr("class", "floorNub action");
        var id= $(this).attr("id");
        if(indexpage.btn_action){
            layer.msg("动画执行中...");
            return;
        }
        indexpage.btn_action = true;
        switch (id) {
            case "Btn_1"://视角一
                {
                    WT3DObj.commonFunc.changeCameraPosition( {x: 9487.603167348385, y: 8719.775524425808, z: 10591.130126266144},{x: 4356.640551613654, y: 4840.572823023986, z: 3600.0637528600773}, 1000,
                         function () {
                             indexpage.btn_action = false;
                         });
                }
                break;}}

  3.2.2、楼层分解

    //出发切换楼层方法

case "Btn_5"://楼层一
                {

                    modelBussiness.backToAllBuild(function () {
                        modelBussiness.showFloor(1);
                        setTimeout(function () {
                            indexpage.btn_action = false;
                        }, 1000);
                    });
                }
                break;

  调用showFloor方法,方法具体如下

ModelBussiness.prototype.showFloor = function (floornub) {

    modelBussiness.currentState = "rooms";
    WT3DObj.IsStepFirstBackSide = true;
    //显示楼层
    modelBussiness.clickFloorAnimation(floornub);
    layer.closeAll();
}

这里主要调用clickFloorAnimation方法,并且记录当前状态

ModelBussiness.prototype.clickFloorAnimation = function (_floorNub) {
    modelBussiness.loadFloorRooms(_floorNub);//加载楼层
     modelBussiness.showFloorAnimation(_floorNub);//显示楼层
    var floors = modelBussiness.InfloorBuildCache;
  
    var position = { y: 1}
    new showSlowly(position).to({
        y: 500,
    }, 500).onUpdate(function () {
        var _this = this;
        $.each(floors, function (_i, _o) {
            var _fnub = parseInt(_o.name.replace("build_f", ""));
            if (_fnub > _floorNub) {
            _o.position.y = _o.oldPositiony + (_fnub - _floorNub) * _this.y;
            }
        })
    }).onComplete(function () {
        var oobjs = [];
        $.each(floors, function (_i, _o) {
            var _fnub = parseInt(_o.name.replace("build_f", ""));
            if (_fnub > _floorNub) {
                oobjs.push(_o);
            }
        });
        WT3DObj.commonFunc.changeObjsOpacity(oobjs, 1, 0.01, 1000, function () {
            $.each(oobjs, function (_i, _o) {
                _o.visible = false;
                _o.position.y = 100000;
            });
        });
        if(_floorNub<=3){
            WT3DObj.commonFunc.changeCameraPosition({ x: 3873, y: 8547 + (_floorNub - 1) * 400, z: 5275 },
                  { x: 3639, y: 3780 + (_floorNub - 1) * 400, z: 2556 }, 1000, function () { });
        } else {
            WT3DObj.commonFunc.changeCameraPosition({ x: 756.8552720903069, y: 4080 + (_floorNub - 1) * 400, z: 3005.0971402300224 }, { x: 778.609209478186, y: (_floorNub - 1) * 400, z: 1208.2712831508117 }, 1000,
             function () {
             });
        }
        var position = { y: 500 }
        new showShowly(position).to({
            y: 2000,
        }, 1000).onUpdate(function () {
            var _this = this;
            $.each(floors, function (_i, _o) {
                var _fnub = parseInt(_o.name.replace("build_f", ""));
                if (_fnub > _floorNub) {
                _o.position.y = _o.oldPositiony + (_fnub - _floorNub) * _this.y;
                _o.step2Positiony = _o.oldPositiony + (_fnub - _floorNub) * _this.y;
                }
            });
        }).onComplete(function () {
            

        }).start();
    }).start();
}

按需加载得方法,对不同楼层 按需加载对应得模型

ModelBussiness.prototype.loadFloorRooms = function (nub, floor) {
    var floorname = "build_f" + nub;
    if (nub == 2) {
        floorname += "_1";
    }
    var floor = WT3DObj.commonFunc.findObject(floorname);
    if (modelBussiness.RoomModels["f" + nub]){
        $.each(modelBussiness.RoomModels["f" + nub], function (_index, _obj) {
            _obj.visible = true;
            _obj.position.y = _obj.oldPositiony;
        });
        return;
    }
    if (nub >= 5) {
        var models = getF5Rooms();
        $.each(models, function (_index, _obj) {
            _obj.name = _obj.name.replace("br_f4_", "br_f" + nub+"_");
            if (_obj.name.indexOf("text") >= 0) {
                _obj.position.y = floor.position.y + 550;
            } else {
                if (_obj.position) {
                    _obj.position.y = floor.position.y+500;
                } else {
                    _obj.y = floor.position.y+150;
                }
            }
        });
        WT3DObj.commonFunc.loadModelsByJsons(models, { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0 }, true, function () {
            modelBussiness.RoomModels["f" + nub] = [];
            $.each(WT3DObj.scene.children, function (_index, _obj) {
                if (_obj.name.indexOf("br_f" + nub + "_w_") == 0 || _obj.name.indexOf("br_f" + nub + "_r_") == 0) {
                    _obj.oldPositiony = _obj.position.y;
                    modelBussiness.RoomModels["f" + nub].push(_obj);
                };
            });
        });
    } else {
        var models = window["getF"+nub+"Rooms"]();
        WT3DObj.commonFunc.loadModelsByJsons(models, { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0 }, true, function () {
            modelBussiness.RoomModels["f" + nub] = [];
            $.each(WT3DObj.scene.children, function (_index, _obj) {
                if (_obj.name.indexOf("br_f" + nub + "_w_") == 0 || _obj.name.indexOf("br_f" + nub + "_r_") == 0) {
                    _obj.oldPositiony = _obj.position.y;
                    modelBussiness.RoomModels["f" + nub].push(_obj);
                }
            });
        });
    }
}

楼层展开,虚化等动画统一展示方法:

ModelBussiness.prototype.showFloorAnimation = function (floornub) {
    modelBussiness.hidemodelsCache = null;
    modelBussiness.scaleModels = null;
    var hidemodeNames = ["bout_f13_2", "bout_f13_1", "bout_f13_1", "bout_f13_0", "bout_flow2_1", "bout_flow2_2", "bout_flow2_3"];
    for (var i = 1; i <= 12; i++) {

        hidemodeNames.push("build_out"+i);
    }
        var hidemodeModels = WT3DObj.commonFunc.findObjectsByNames(hidemodeNames);
        $.each(hidemodeModels, function (_index, _obj) {
            _obj.oldPositiony = _obj.position.y;
            _obj.visible = false;
            _obj.position.y = 200000;
        });
        var scaleModelNames = ["bout_39", "bout0_11", "bout_42", "bout_38", "bout_45", "bout_40", "bout_44", "bout_41", "bout_43"];
        var scaleModels = WT3DObj.commonFunc.findObjectsByNames(scaleModelNames);
        WT3DObj.commonFunc.changeObjsOpacity(scaleModels, 1, 0.01, 1000, function () {
            $.each(scaleModels, function (_index, _obj) {
                _obj.oldScaleX = _obj.scale.x;
                _obj.oldScaleY = _obj.scale.y;
                _obj.oldScaleZ = _obj.scale.z;
                if (["bout_39", "bout_38", "bout_40", "bout_41"].indexOf(_obj.name) >= 0) {
                    _obj.scale.y = floornub / 14
                }
                if (["bout_42", "bout_45", "bout_44", "bout_43", "bout0_11"].indexOf(_obj.name) >= 0) {
                    _obj.scale.z = floornub / 14
                }
                if ("bout0_11" == _obj.name) {
                    _obj.scale.z = (floornub - 3) / 11
                }
            });
            WT3DObj.commonFunc.changeObjsOpacity(scaleModels, 0.01, 1, 10, function () {
            });
        });
        modelBussiness.hidemodelsCache = hidemodeModels;
        modelBussiness.scaleModels = scaleModels;
        
}

3.2.3、设备定位

  定位具体设备,将楼层展开与主摄像机位置调整并用起来调用

modelBussiness.backToAllBuild(function () {
                        modelBussiness.showFloor(4);//展开楼层4
                        setTimeout(function () {
                  //调整摄像机位置
                            WT3DObj.commonFunc.changeCameraPosition({x: 853.7726152337735, y: 3002.9928530489865, z: 2579.4120334043137},{x: 1732.9469861751966, y: 1855.692424929085, z: 1402.3507946674324}, 1000,
                    function () {
                        indexpage.btn_action = false;

                    });
                        }, 1000);
                    });

3.3、数据对接、展示

  数据对接,主要是讲模型与设备数据id进行绑定,并且根据api进行调用

function W3DShowApi() { }
 
//显示设备自定义框
W3DShowApi.prototype.showDevWin = function (modelname) {
    console.log("显示楼层数字的自定义框");
    //这里的showHtml可以自定义
   
    var showHtml = "<div style='font-size:32px;color:white;text-align:center;line-height:90px;'>自定义内容:" + modelname + "</div > ";
    //这里的显示框大小可以自定义
    var area = ['auto', "100px"];//宽 高
    return {
        html: showHtml,
        area: area
    }
}
W3DShowApi.prototype.dbclickDevWin = function (modelname) {
    console.log("显示楼层数字的自定义框");
    //这里的showHtml可以自定义
    layer.msg("显示双击设备自定义框:" + modelname);
}

var w3DShowApi = new W3DShowApi();

我们这里弹窗使用了layerui的插件

ModelBussiness.prototype.showRoomMsg = function (_obj) {
    var showWindow = false;
    var showHtml = "<div></div>";
    var area = ["350px", "200px"];
    if (w3DShowApi) {
        var wparam = w3DShowApi.showDevWin(_obj.name);
        if (wparam) {
            showHtml = wparam.html;
            area = wparam.area;
            showWindow = true;
        }
    }
    if (!showWindow) {
        return;
    }
    modelBussiness.hasshowRoomMessage = false;
    modelBussiness.currentShowRoomText = _obj;
    //获取位置
    var position = {
        x: _obj.position.x,
        y: _obj.position.y,
        z: _obj.position.z,
    };
    //position.y += 150;
    var screenPostion = WT3DObj.transToScreenCoord(position);
    $("#MarkMessageHelper").remove();
    $("body").append("<div id='MarkMessageHelper' style='position:absolute;left:" + (screenPostion.x) + "px;top:" + screenPostion.y + "px;height:2px;width:2px;z-index:1000;'></div>");
    layer.closeAll();
   
    modelBussiness.currentShowRoomTipIndex = layer.tips(showHtml, '#MarkMessageHelper', {
        closeBtn: 1,
        shade: false,
        shadeClose: true,
        skin:"customskin",
        area: area,
        time: 0,//是否定时关闭,0表示不关闭
        cancel: function (index, layero) {
            modelBussiness.hasshowRoomMessage = false;
            layer.close(index);
            if (closeFunc) {
                closeFunc();
            }
        },
        success: function () {
            setTimeout(function () {
            modelBussiness.hasshowRoomMessage = true;
            }, 150);
        },
        tips: [1, "rgba(0,0,0,0.1)"] //还可配置颜色
    });
}
  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK