序:

  还是要抽出时间看书的,迷上了豆豆的作品,最近在看《天幕红尘》,书中主人公的人生价值观以及修为都是让我惊为叹止。很想成为那样的人,但是再看看自己每天干的事,与时间的支配情况,真是十分的汗颜。除了为了生活所必须的工作时间外,还有大部分零散的时间不是给了短视频,就是给了短讯文章,简讯媒介,不说是毫无意义吧,但也着实是浮躁虚夸了。

  用豆豆作品里的话术,"透视社会依次有三个层面:技术、制度和文化。小到一个人,大到一个国家一个民族,任何一种命运归根到底都是那种文化属性的产物"。 我终究是干技术的,还是无法洞察其中奥义,只是熟悉了几门糊口的技巧而已,究竟其本质便无所得之了,或者说依然没找到那安身立命的意义。长路漫漫,且寻着吧。人生也许也像某个技术门类,需要不断的回顾,记录,总结。才能真正发现一些实质性的东西。究竟涅槃,如来?

  本想谈技术,话题终究是扯远了,但总归要扯点啥吧,练练文笔也好,述述心态也罢,反正也少有人看写在前面的废话,这任算是,无伤技术之大雅,无关文章之紧要了。

  还是闲话少序,切入正题吧。

前言:

  前面的课程介绍过定位相关的技术解决方案,《webgl(three.js)实现室内定位,楼宇bim、实时定位三维可视化解决方案——第五课》 ,从硬件到可视化,都已经比较全面的讲述了一遍,这边文章相当于那篇文件的一个改进版本,主要是在可视化呈现方面,根据具体的实施项目,在可视化方面做一个比较全面的技术剖析。

关于硬件采集端技术,因为精度要求不高,任然采用的是:低功耗有源RFID+读卡器基地器+智能分析。

关于室内定位市场前景,那篇文章也做了一些分析,这里不做赘述。

一、整体效果

还是先看整体效果,再探具体实现技术的究竟

上图展示整体园区以及周边的科技感效果。

上图展示近距离整体园区建设风貌。

二、功能展示

2.1、展开楼层

楼层展开实现比较简单,首先再建模的时候讲究分离模型,不能讲楼层内部,楼层外墙一股脑做成一个模型,需要讲模型分解,分开建模,

实现楼层展开就比较方便了,只需要控制外墙模型隐藏,然后控制每个楼层的的高度位置就可以。

实现代码如下:

ModelBussiness.prototype.tempNameList = [];
ModelBussiness.prototype.tempDataList = [];
ModelBussiness.prototype.videoDataCache = {};
ModelBussiness.prototype.showFloorState = "close";
//显示楼层内部情况
ModelBussiness.prototype.showBuildFloors = function (buildnub, callBack) {
var _this = this
_this.showFloorState = "open";
var builds = WT3DObj.commonFunc.findObjectsByNames(["wjwb1_232", "wjwbuilds_55"]);
//隐藏大楼
WT3DObj.commonFunc.setSkinColorByname("wjwb1_232", 0x00ffff);
WT3DObj.commonFunc.changeCameraPosition({ x: 3652.5144280174954, y: 990.805706980618, z: 5107.394022507952 }, { x: 1914.4771268074287, y: -723.8717024746979, z: 2181.6118222317314 }, 500,
function () { });
WT3DModel.commonFunc.changeObjsOpacity(builds, 1, 0.1, 500, function (obj) {
var _obj = WT3DObj.commonFunc.findObject("wjwb1_232");
if (typeof (_obj.oldPositionY) == 'undefined') {
_obj.oldPositionY = _obj.position.y
}
_obj.position.y = 1000000;
_obj.visible = false; WT3DObj.commonFunc.changeCameraPosition({ x: 3247.2796000738454, y: 2191.5405041410445, z: 5229.077446579187 }, { x: 2719.261239206996, y: 80.49406057323252, z: 3015.8739289848077 }, 500,
function () { }); var names = ["floor_1", "floor_2", "floor_3", "floor_4", "floor_5", "floor_6"];
var floors = WT3DObj.commonFunc.findObjectsByNames(names);
modelBussiness.openFloors(floors, function () {
if (callBack) {
callBack();
}
});
}); }
//隐藏楼层内部情况
ModelBussiness.prototype.hideBuildFloors = function (buildnub, callBack) {
var _this = this
_this.showFloorState = "close";
var names = ["floor_1", "floor_2", "floor_3", "floor_4", "floor_5", "floor_6"];
var builds = WT3DObj.commonFunc.findObjectsByNames(["wjwb1_232", "wjwbuilds_55"]);
var floors = WT3DObj.commonFunc.findObjectsByNames(names);
this.closeFloors(floors, function () {
$.each(builds, function (_index, _obj) {
if (typeof (_obj.oldPositionY) == 'undefined') {
_obj.oldPositionY = _obj.position.y
}
_obj.position.y = _obj.oldPositionY;
_obj.visible = true;
})
WT3DModel.commonFunc.changeObjsOpacity(builds, 0, 1, 1000, function (obj) {
WT3DObj.commonFunc.setSkinColorByname("wjwb1_232", 0x000000);
});
if (callBack) {
callBack();
}
}) }
//显示楼层
ModelBussiness.prototype.openFloors = function (floors, callBack) {
//显示楼层
$.each(floors, function (_index, _obj) {
if (typeof (_obj.oldPositionY) == 'undefined') {
_obj.oldPositionY = _obj.position.y
}
if (_obj.position.y > 100000) {
_obj.position.y -= 1000000;
}
_obj.visible = true;
});
setTimeout(function () {
$.each(floors, function (_index, _obj) {
//展开楼层
_obj.floorPosition = _obj.position.y;
var floor = parseInt(_obj.name.split("_")[1]);
height = (floor - 1) * 300 +50;
new Tn(_obj.position).to({//补充间隔动画
y: height
}, 500).start();
});
setTimeout(function () { if (callBack) {
callBack()
}
},600);
}, 500) }

2.2、绘制定位路径

绘制定位路径,相比楼层展开要复杂一些,这里要用到定位设备与虚拟模型之间的关联与绑定,然后标记跟着模型运动

主要分为以下几步:

  第一、建模

  第二、建立虚拟模型,绑定设备id

  第三、数据id转换为模型id

  第四、寻址,找到对应的虚拟模型列表、并且获取各自位置

  第五、根据位置画线、移动标签

三、具体实现

3.1、创建周遭环境模型,特效模型等

建模代码如下:

[{"show":true,"uuid":"","name":"cube2_6","objType":"cube2","length":200,"width":200,"height":200,"x":0,"y":200,"z":0,"style":{"skinColor":16777215,"skin":{"skin_up":{"skinColor":16777215,"imgurl":"../../img/3dImg/rack_inside.jpg","materialType":"basic","side":1,"opacity":1},"skin_down":{"skinColor":16777215},"skin_fore":{"skinColor":16777215},"skin_behind":{"skinColor":16777215},"skin_left":{"skinColor":16777215},"skin_right":{"skinColor":16777215}}},"showSortNub":6},{"show":true,"uuid":"","name":"wjwbuilds_270","objType":"GroupObj","scale":{"x":1,"y":1,"z":1},"position":{"x":0,"y":0,"z":0},"rotation":[{"direction":"x","degree":0}],"modelGroupName":"wjwbuilds","modelSrc":"../js/msj3D/sourse/customModels/models/wjwbuilds.json?v1.50.4428873971970626","srcType":"filePath","showSortNub":270}]

3.2、创建外墙模型

单独创建需要裂解的大楼外墙模型,具体如下:

[{"show":true,"uuid":"","name":"cube2_6","objType":"cube2","length":200,"width":200,"height":200,"x":0,"y":200,"z":0,"style":{"skinColor":16777215,"skin":{"skin_up":{"skinColor":16777215,"imgurl":"../../img/3dImg/rack_inside.jpg","materialType":"basic","side":1,"opacity":1},"skin_down":{"skinColor":16777215},"skin_fore":{"skinColor":16777215},"skin_behind":{"skinColor":16777215},"skin_left":{"skinColor":16777215},"skin_right":{"skinColor":16777215}}},"showSortNub":6},{"show":true,"uuid":"","name":"wjwb1_7","objType":"GroupObj","scale":{"x":1,"y":1,"z":1},"position":{"x":0,"y":0,"z":0},"rotation":[{"direction":"x","degree":0}],"modelGroupName":"wjwb1","modelSrc":"../js/msj3D/sourse/customModels/models/wjwb1.json?v1.50.7245325959034448","srcType":"filePath","showSortNub":7}]

3.3、其它细节楼宇模型

作为辅助美观模型,单独创建模型如下:

[{"show":true,"uuid":"","name":"wjwb2_38","objType":"GroupObj","scale":{"x":1,"y":1,"z":1},"position":{"x":0,"y":0,"z":0},"rotation":[{"direction":"x","degree":0}],"modelGroupName":"wjwb2","modelSrc":"../js/msj3D/sourse/customModels/models/wjwb2.json?v1.50.2327047742615571","srcType":"filePath","showSortNub":38}]

3.4、楼层模型

各楼层模型单独创建,便于控制与展示

[{"show":true,"uuid":"","name":"wjwf1_40","objType":"GroupObj","scale":{"x":1,"y":1,"z":1},"position":{"x":0,"y":0,"z":0},"rotation":[{"direction":"x","degree":0}],"modelGroupName":"wjwf1","modelSrc":"../js/msj3D/sourse/customModels/models/wjwf1.json?v1.50.13740666293081194","srcType":"filePath","showSortNub":40}]

多角度观察一下楼层模型:

单元测试楼宇模型裂解效果

四、定位详解

本想放到第三章一起讲解,但这部分实现比较重要,所以单独一章讲解

如上图,粉色的点位表示房间门内的辅助点,亮绿色的点位表示设备所对应的门外辅助点

我们这里只需要绑定门外的辅助点到对应的设备就可以

当再某处停留事件过长,我们通常判断已经进入房间,直接讲门外门内两个点链接,即可。

4.1、存储虚拟点位

//使用二叉树储存法,将辅助点与设备id进行绑定。
{
"cp": { "x": 2898.062281840033, "y": 726.9857194504245, "z": 4474.268417657025 },
     "ct": { "x": 2919.5843654655655, "y": -325.13303496900545, "z": 3386.2841814639646 },
line: [2010, 2002, 2016, 2028, 2018, 2032, ["h1", 2038], 2026, 2022, 2036, 2020, [2000, 2034], 2004, 2014],//二叉树存储数据
Points: [{ "name": "f2d_2010", "position": { "x": 2824.843, "y": 82.926, "z": 3874.214 } }, { "name": "f2d_2016", "position": { "x": 2824.843, "y": 82.926, "z": 3977.133 } }, { "name": "f2d_2028", "position": { "x": 2824.843, "y": 82.926, "z": 4010.544 } }, { "name": "f2d_2018", "position": { "x": 2824.843, "y": 82.926, "z": 4084.157 } }, { "name": "f2d_2032", "position": { "x": 2824.843, "y": 82.926, "z": 4110.372 } }, { "name": "f2d_2038", "position": { "x": 2824.843, "y": 82.926, "z": 4191.56 } }, { "name": "f2d_h1", "position": { "x": 2824.843, "y": 82.926, "z": 4145.947 } }, { "name": "f2d_2026", "position": { "x": 2894.811, "y": 82.926, "z": 4142.355 } }, { "name": "f2d_2022", "position": { "x": 2929.456, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2036", "position": { "x": 2993.039, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2020", "position": { "x": 3127.172, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2000", "position": { "x": 3138.358, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2014", "position": { "x": 3196.413, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2004", "position": { "x": 3159.209, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2034", "position": { "x": 3140.007, "y": 82.926, "z": 4238.683 } }, { "name": "f2d_2010_room", "position": { "x": 2794.836, "y": 82.926, "z": 3874.214 } }, { "name": "f2d_2002", "position": { "x": 2820.207, "y": 82.926, "z": 3901.037 } }, { "name": "f2d_2002_room", "position": { "x": 2794.657, "y": 82.926, "z": 3901.037 } }, { "name": "f2d_2016_room", "position": { "x": 2795.467, "y": 82.926, "z": 3977.133 } }, { "name": "f2d_2028_room", "position": { "x": 2790.713, "y": 82.926, "z": 4010.544 } }, { "name": "f2d_2018_room", "position": { "x": 2797.472, "y": 82.926, "z": 4074.339 } }, { "name": "f2d_2032_room", "position": { "x": 2798.134, "y": 82.926, "z": 4110.372 } }, { "name": "f2d_2038_room", "position": { "x": 2796.368, "y": 82.926, "z": 4191.56 } }, { "name": "f2d_2026_room", "position": { "x": 2894.811, "y": 82.926, "z": 4076.308 } }, { "name": "f2d_2022_room", "position": { "x": 2929.456, "y": 82.926, "z": 4107.921 } }, { "name": "f2d_2036_room", "position": { "x": 2993.039, "y": 82.926, "z": 4103.112 } }, { "name": "f2d_2020_room", "position": { "x": 3127.172, "y": 82.926, "z": 4110.79 } }, { "name": "f2d_2000_room", "position": { "x": 3138.358, "y": 82.926, "z": 4156.895 } }, { "name": "f2d_2004_room", "position": { "x": 3159.209, "y": 82.926, "z": 4156.794 } }, { "name": "f2d_2014_room", "position": { "x": 3196.413, "y": 82.926, "z": 4157.111 } }, { "name": "f2d_2034_room", "position": { "x": 3165.756, "y": 82.926, "z": 4238.683 } }]
}
//存储辅助点模型位置到数组中,方便快速查找。
[{ "name": "f2d_2010", "position": { "x": 2824.843, "y": 82.926, "z": 3874.214 } }, { "name": "f2d_2016", "position": { "x": 2824.843, "y": 82.926, "z": 3977.133 } }, { "name": "f2d_2028", "position": { "x": 2824.843, "y": 82.926, "z": 4010.544 } }, { "name": "f2d_2018", "position": { "x": 2824.843, "y": 82.926, "z": 4084.157 } }, { "name": "f2d_2032", "position": { "x": 2824.843, "y": 82.926, "z": 4110.372 } }, { "name": "f2d_2038", "position": { "x": 2824.843, "y": 82.926, "z": 4191.56 } }, { "name": "f2d_h1", "position": { "x": 2824.843, "y": 82.926, "z": 4145.947 } }, { "name": "f2d_2026", "position": { "x": 2894.811, "y": 82.926, "z": 4142.355 } }, { "name": "f2d_2022", "position": { "x": 2929.456, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2036", "position": { "x": 2993.039, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2020", "position": { "x": 3127.172, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2000", "position": { "x": 3138.358, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2014", "position": { "x": 3196.413, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2004", "position": { "x": 3159.209, "y": 82.926, "z": 4137.219 } }, { "name": "f2d_2034", "position": { "x": 3140.007, "y": 82.926, "z": 4238.683 } }, { "name": "f2d_2010_room", "position": { "x": 2794.836, "y": 82.926, "z": 3874.214 } }, { "name": "f2d_2002", "position": { "x": 2820.207, "y": 82.926, "z": 3901.037 } }, { "name": "f2d_2002_room", "position": { "x": 2794.657, "y": 82.926, "z": 3901.037 } }, { "name": "f2d_2016_room", "position": { "x": 2795.467, "y": 82.926, "z": 3977.133 } }, { "name": "f2d_2028_room", "position": { "x": 2790.713, "y": 82.926, "z": 4010.544 } }, { "name": "f2d_2018_room", "position": { "x": 2797.472, "y": 82.926, "z": 4074.339 } }, { "name": "f2d_2032_room", "position": { "x": 2798.134, "y": 82.926, "z": 4110.372 } }, { "name": "f2d_2038_room", "position": { "x": 2796.368, "y": 82.926, "z": 4191.56 } }, { "name": "f2d_2026_room", "position": { "x": 2894.811, "y": 82.926, "z": 4076.308 } }, { "name": "f2d_2022_room", "position": { "x": 2929.456, "y": 82.926, "z": 4107.921 } }, { "name": "f2d_2036_room", "position": { "x": 2993.039, "y": 82.926, "z": 4103.112 } }, { "name": "f2d_2020_room", "position": { "x": 3127.172, "y": 82.926, "z": 4110.79 } }, { "name": "f2d_2000_room", "position": { "x": 3138.358, "y": 82.926, "z": 4156.895 } }, { "name": "f2d_2004_room", "position": { "x": 3159.209, "y": 82.926, "z": 4156.794 } }, { "name": "f2d_2014_room", "position": { "x": 3196.413, "y": 82.926, "z": 4157.111 } }, { "name": "f2d_2034_room", "position": { "x": 3165.756, "y": 82.926, "z": 4238.683 } }]

4.2、具体实现画线定位

实现画线定位是利用设备id找到对应辅助点,然后将辅助点链接起来的方式

定位标签移动,使用补间动画移动效果即可。

//显示路径
function drawLineFunc(floor, start, end, timeLong, startOut, endIn) {
//drawLineDataList.push({
// floor: 楼层,
// start: 开始设备点id,
// end: 结束设备点id,
// timeLong: 移动时长,
// startOut: 是否是从房间里出来,
// endIn: 是否进入房间
//}); WT3DObj.commonFunc.changeCameraPosition(ConfigData["f" + floor].cp, ConfigData["f" + floor].ct, 300,
function () { });
//生成路径节点数组
var startindex = -1;
var startindex2 = -1;
var endindex = -1;
var endindex2 =-1;
var linedata = ConfigData["f" + floor].line;
$.each(linedata, function (_index, _obj) {
if (_obj instanceof Array) {
$.each(_obj, function (_cindex, _cobj) {
if (_cobj + "" == start + "") {
startindex = _index;
startindex2 = _cindex;
}
if (_cobj + "" == end + "") {
endindex = _index;
endindex2 = _cindex;
}
})
} else {
if (_obj + "" == start + "") {
startindex = _index;
}
if (_obj + "" == end + "") {
endindex = _index;
}
}
});
var pointPath = [];
if (startindex < endindex) {
for (var i = startindex; i <= endindex; i++) {
var pointnub = linedata[i];
if (pointnub instanceof Array) {
pointPath.push(pointnub[0]);
} else {
pointPath.push(pointnub);
}
}
}
else if (startindex > endindex) {
for (var i = startindex; i >= endindex; i--) {
var pointnub = linedata[i];
if (pointnub instanceof Array) {
pointPath.push(pointnub[0]);
} else {
pointPath.push(pointnub);
}
}
}
if (endindex2 > 0) {
var pointnub = linedata[endindex];
for (var i = 1; i <= endindex2; i++) {
pointPath.push(pointnub[i]);
}
}
if (startindex2 != -1) {
var startarray = [];
var pointnub = linedata[startindex];
for (var i = startindex2; i >0; i--) {
startarray.push(pointnub[i]);
}
pointPath = startarray.concat(pointPath);
}
var linePositionArray = ConfigData["f" + floor].Points;
var lineObjs = {}
$.each(linePositionArray, function (_index, _obj) {
lineObjs[_obj.name] = _obj.position;
});
var pathpoints = [];
var positiony = WT3DObj.commonFunc.findObject("floor_" + floor).position.y ;
$.each(pointPath, function (_index, _obj) { if (lineObjs["f" + floor + "d_" + _obj]) {
pathpoints.push({
x: lineObjs["f" + floor + "d_" + _obj].x,
y: positiony ,
z: lineObjs["f" + floor + "d_" + _obj].z,
type: "nomal"
});
} });
if (startOut) {
$.each(linePositionArray, function (_index, _obj) {
if (_obj.name == "f" + floor + "d_" + start + "_room") {
pathpoints = [{
x: _obj.position.x,
y: positiony,
z: _obj.position.z,
type: "nomal"
}].concat(pathpoints);
}
});
}
if (endIn) {
if (end) { $.each(linePositionArray, function (_index, _obj) {
if (_obj.name == "f" + floor + "d_" + end +"_room") {
pathpoints.push({
x: _obj.position.x,
y: positiony,
z: _obj.position.z,
type: "nomal"
})
}
});
}
};
  //创建节点模型
var modelsNames = modelBussiness.createRoadLine(pathpoints, new Date().getTime(), timeLong);
CModelNames = CModelNames.concat(modelsNames);
}

画线与移动具体实现如下:

ModelBussiness.prototype.Drawing = false;
ModelBussiness.prototype.createRoadLine = function (points, index, timeLong) {
if (modelBussiness.Drawing) {
return;
}
modelBussiness.Drawing = true;
var addModelNames = [];
//points.push({
// x: _pobj[1],
// y: 0,
// z: _pobj[2],
// type: "nomal"
//});
  //创建移动标签模型代码
var moveobj = {
"name": "moveObj", "objType": "picIdentification", "size": { "x": 30, "y": 30 }, "position": {
x: points[0].x,
y: points[0].y+30,
z: points[0].z
}, "imgurl": "../img/3dImg/xhd.png", "showSortNub":1, "show": true, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "wx": null, "wy": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null
}; var models = [];
var moveObjModel = WT3DObj.commonFunc.findObject("moveObj");
if (!moveObjModel) {
models.push(moveobj);
addModelNames.push("moveObj");
}
//创建线模型代码
var model = { "show": true, "uuid": "", "name": "splinecurve_7", "objType": "SplineCurve", "segments": 24, "points": [{ "x": 0, "y": 300, "z": 0 }, { "x": 100, "y": 250, "z": 100 }, { "x": 100, "y": 400, "z": 400 }], "style": { "skinColor": 0xDFFD6 }, "LineStyle": "LinePieces", "position": { "x": 0, "y":0, "z": 0 }, "scale": { "x": 1, "y": 1, "z": 1 }, "rotation": [{ "direction": "x", "degree": 0 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "showSortNub": 1, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }
model.name = "Line" + index;
addModelNames.push("Line" + index);
model.segments = points.length - 1; var newpoints = [];
var pointlength = [];//单段长度数组
var allLength = 0;//总长度
for (var i = 0; i < points.length; i++) {
newpoints.push(points[0]);
if (i < points.length - 1) {
var length= Math.sqrt((points[i + 1].x - points[i].x) * (points[i + 1].x - points[i].x)
+ (points[i + 1].y - points[i].y) * (points[i + 1].y - points[i].y)
+ (points[i + 1].z - points[i].z) * (points[i + 1].z - points[i].z))
pointlength.push(length);
allLength += length;
}
} model.points = newpoints;
models.push(model);
var modelnames = [];
for (var i = 0; i < points.length - 1; i++) {
if (points[i].x == points[i + 1].x && points[i].z == points[i + 1].z) {
continue;
}
var position = {
x: (points[i].x + points[i + 1].x) / 2,
y: points[i].y,
z: (points[i].z + points[i + 1].z) / 2
}
var rotaiionz = this.getAngle(points[i].x, points[i].z, points[i + 1].x, points[i + 1].z) / 180 * Math.PI + Math.PI / 2;
models.push({ "show": true, "uuid": "", "name": model.name + "_" + i, "objType": "Lathe", "position": position, "points": [{ "x": 0, "y": 0, "z": 0 }, { "x": 2, "y": 10, "z": 0 }], "style": { "skinColor": 1433087, "side": 2, "opacity": 1 }, "segments": 12, "radialSegments": 12, "closed": true, "phiStart": 0, "phiLength": 6.283185307179586, "showSortNub": 7, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": Math.PI / 2 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": rotaiionz }], "radius": null, "scale": { "x": 1, "y": 1, "z": 1 }, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null });
modelnames.push(model.name + "_" + i);
addModelNames.push(model.name + "_" + i);
}
  //加载模型
WT3DObj.commonFunc.loadModelsByJsons(models, { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0 }, true, function () {
if (!moveObjModel) {
moveObjModel = WT3DObj.commonFunc.findObject("moveObj");
}
var _obj = WT3DObj.commonFunc.findObject(model.name);
var _objfores = WT3DObj.commonFunc.findObjectsByNames(modelnames);
$.each(_objfores, function (_findex, _fobj) {
_fobj.visible = false;
});
if (!timeLong) {
timeLong = 0;
}
var runTime = 0;
for (var i = 0; i < points.length - 1; i++) {
(function (_index) {//创建闭包
        
//获取小节点之间的运动时长
var stepTime = pointlength[_index] / allLength * timeLong; 
setTimeout(function () {
  //创建路径运动延迟等待 


new Tn(_obj.geometry.vertices[_index+1]).to({ x: points[_index + 1].x, y: points[_index + 1].y, z: points[_index + 1].z, },
 stepTime).onUpdate(function () { for (var j = _index+1; j < points.length; j++) 
{ _obj.geometry.vertices[j].x = this.x; _obj.geometry.vertices[j].y = this.y;
_obj.geometry.vertices[j].z = this.z; }; moveObjModel.position.x = this.x;
moveObjModel.position.y = this.y+30; moveObjModel.position.z = this.z;
_obj.geometry.verticesNeedUpdate = true; }).start();
setTimeout(function () { $.each(_objfores,

function (_findex, _fobj) { if (_fobj.name == model.name + "_" + _index) { _fobj.visible = true; } }); }, stepTime / 2); }, runTime); runTime += stepTime+20; })(i); }

// WT3DObj.scene.children[305].geometry.vertices[22].z = 41400 //WT3DObj.scene.children[305].geometry.verticesNeedUpdate = true;
setTimeout(function () { modelBussiness.Drawing = false; }, timeLong) console.log("drawLine"); }); return addModelNames; }

由于篇幅原因,这一课先介绍到这里

后面我将继续讲解用webgl 建立 3D隧道、3D桥梁、webgl实现三维隧道桥梁、three.js实现三维隧道桥梁、桥梁隧道三维应用炫酷效果等等

技术交流 1203193731@qq.com

交流微信:

    

如果你有什么要交流的心得 可邮件我或者微我

其它相关文章:

如何用three.js(webgl)搭建3D粮仓、3D仓库、3D物联网设备监控-第十二课

如何用webgl(three.js)搭建处理3D隧道、3D桥梁、3D物联网设备、3D高速公路、三维隧道桥梁设备监控-第十一课

如何用three.js实现数字孪生、3D工厂、3D工业园区、智慧制造、智慧工业、智慧工厂-第十课

使用webgl(three.js)创建3D机房,3D机房微模块详细介绍(升级版二)

如何用webgl(three.js)搭建一个3D库房-第一课

如何用webgl(three.js)搭建一个3D库房,3D密集架,3D档案室,-第二课

使用webgl(three.js)搭建一个3D建筑,3D消防模拟——第三课

使用webgl(three.js)搭建一个3D智慧园区、3D建筑,3D消防模拟,web版3D,bim管理系统——第四课

如何用webgl(three.js)搭建不规则建筑模型,客流量热力图模拟

使用webgl(three.js)搭建一个3D智慧园区、3D建筑,3D消防模拟,web版3D,bim管理系统——第四课(炫酷版一)

使用webgl(three.js)搭建3D智慧园区、3D大屏,3D楼宇,智慧灯杆三维展示,3D灯杆,web版3D,bim管理系统——第六课

如何用webgl(three.js)搭建处理3D园区、3D楼层、3D机房管线问题(机房升级版)-第九课(一)

webgl(three.js)实现室内三维定位,3D定位,3D楼宇bim、实时定位三维可视化解决方案——第十四课(定位升级版)的更多相关文章

  1. webgl(three.js)3D光伏,3D太阳能能源,3D智慧光伏、光伏发电、清洁能源三维可视化解决方案——第十六课

    序: 能源是文明和发展的重要保障,人类命运不可避开的话题,无论是战争还是发展,都有它存在的身影.从石器时代到现代文明,人类的能源应用在进步,也在面临能源枯竭的危机与恐惧,而开发与应用可再生能源才是解决 ...

  2. NeHe OpenGL教程 第四十四课:3D光晕

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  3. webgl(three.js)实现室内定位,楼宇bim、实时定位三维可视化解决方案

    (写在前面,谈谈物联网展会)上次深圳会展中心举行物联网展会,到了展会一看,80%以上的物联网应用都是在搞RFID,室内定位,我一度怀疑物联网落地方案的方向局限性与市场导向,后来多方面了解才明白,展会上 ...

  4. 第十四课:js操作节点的插入,复制,移除

    节点插入 appendChild方法,insertBefore方法是常用的两个节点插入方法,具体实现,请看js高级程序设计,或者自行百度. 这里提一下面试时经常会问到的问题,插入多个节点时,你是怎么插 ...

  5. 潭州课堂25班:Ph201805201 爬虫基础 第十四课 js破解 (课堂笔记)

    打断点 找要的数据 鼠标的点击事件 新浪微博登录 表单提交分析 : 先佃输入错误密码开始调式 f10 往下走, f11 进入函数 sh + f11 跳出函数 # -*- coding: utf-8 - ...

  6. 如何用webgl(three.js)搭建一个3D库房,3D仓库3D码头,3D集装箱,车辆定位,叉车定位可视化孪生系统——第十五课

    序 又是快两个月没写随笔了,长时间不总结项目,不锻炼文笔,一开篇,多少都会有些生疏,不知道如何开篇,如何写下去.有点江郎才尽,黔驴技穷的感觉. 写随笔,通常三步走,第一步,搭建框架,先把你要写的内容框 ...

  7. 如何使用webgl(three.js)实现3D储能,3D储能站,3D智慧储能、储能柜的三维可视化解决方案——第十七课

    前言 上节课我们讲了<3D光伏发电>,与之配套的就是能量存储 这节课我们主要讲讲储能,储能站,在分布式能源系统中起到调节用对电的尖峰平谷进行削峰填谷的作用.特别是小型储能站,更加灵活,因地 ...

  8. 如何用webgl(three.js)搭建一个3D库房,3D仓库,3D码头,3D集装箱可视化孪生系统——第十五课

    序 又是快两个月没写随笔了,长时间不总结项目,不锻炼文笔,一开篇,多少都会有些生疏,不知道如何开篇,如何写下去.有点江郎才尽,黔驴技穷的感觉. 写随笔,通常三步走,第一步,搭建框架,先把你要写的内容框 ...

  9. 如何用webgl(three.js)搭建处理3D隧道、3D桥梁、3D物联网设备、3D高速公路、三维隧道桥梁设备监控-第十一课

    开篇废话: 跟之前的文章一样,开篇之前,总要写几句废话,大抵也是没啥人看仔细文字,索性我也想到啥就聊啥吧. 这次聊聊疫情,这次全国多地的疫情挺严重的,本人身处深圳,深圳这几日报导都是几十几十的新增病例 ...

随机推荐

  1. 这不会又是一个Go的BUG吧?

    hello,大家好呀,我是小楼. 最近我又双叒叕写了个BUG,一个线上服务死锁了,不过幸亏是个新服务,没有什么大影响. 出问题的是Go的读写锁,如果你是写Java的,不必划走,更要看看本文,本文的重点 ...

  2. 教你如何用网页开发APP

    用到的工具: HBuilderX app开发版1.首先你得网站必须是上线的,然后明确这一点后,点击打开HBuilderX.在文件里找到新建项目,选择wap2App,将下面信息填写完整,然后创建. 2. ...

  3. SAP PP- OPK8生产订单打印 配置Smart form.

    OPK8 正常情况下是不可以配置Smart form 的 OPK8进入工单打印配置界面,选择Forms, 你会发现只有Script form 和PDF form(Adobe form)可选的,没有配置 ...

  4. SAP APO-PP / DS

    在SAP APO中,使用生产计划/详细计划(Production Planning/Detailed Scheduling)生成满足生产要求的采购建议. 此组件还用于定义资源计划和订单明细. 您还可以 ...

  5. 数字格式化的 js 库

    数字格式化的 js 库 Numeral.js,是一个用于格式化数字和处理数字的 js 库. Tip:目前 Star 有 9.2k,5年以前就没有在更新.其文档写得不很清晰,比如它提供了多语言,但如何切 ...

  6. Object类中wait带参方法和notifyAll方法和线程间通信

    notifyAll方法: 进入到Timed_Waiting(计时等待)状态有两种方式: 1.sleep(long m)方法,在毫秒值结束之后,线程睡醒,进入到Runnable或BLocked状态 2. ...

  7. 无用的IP黑名单

    无效的IP黑名单,有些还没有收集,在阿里云或者腾讯云的安全组里面设置,拦截不必要的IP,免得遭到攻击,也避免的CPU和内存过高 来源 备注82.102.21.217 拒绝 随机访问目录攻击,频繁69. ...

  8. 千万不要把Request传递到异步线程里面!有坑!

    你好哇,我是歪歪. 前几天在网上冲浪的时候看到一篇技术文章,讲的是他把一个 request 请求传递到了线程池里面,然后遇到了一个匪夷所思的情况. 他写了这篇文章,把自己针对这个问题的探索过程分享了出 ...

  9. [SWPU2019]Web1-1|SQL注入

    1.打开之后界面如下: 2.查看源代码.登录注入等未发现有用信息,结果如下: 3.进行注册试试,注册时发现admin账户已被注册,随便注册一个账户并登录,结果如下: 申请发布广告页面如下: 4.发布广 ...

  10. ROS机械臂 Movelt 学习笔记3 | kinect360相机(v1)相关配置

    目标是做一个机械臂视觉抓取的demo,在基地里翻箱倒柜,没有找到学长所说的 d435,倒是找到了一个老古董 kinect 360. 前几天就已经在旧电脑上配置好了,现在记录在新电脑上的配置过程. 1. ...