前言智能楼宇与人们的生活息息相关。建筑智能化的提升将大大提高人们的生活质量。在当前的工业互联网背景下受到了极大的关注。.目前,智能建筑视觉监控的主要优势包括:智能——智能建筑是一个像人一样具有感知、自我判断和控制能力的生态系统。绿色化——绿色建筑实现能耗、产能、能源管理的绿色化,楼宇安防实现绿色监控。运营成本可控——基于可持续发展的要求,现代建筑和商业建筑需要运营50年以上。建筑物在运行过程中的能源消耗是巨大的。如何降低运营成本,让建筑在低碳环保的状态下健康运行。传统的智能建筑/楼宇自动化/楼宇安防/智慧园区往往使用BIM(建筑信息模型)软件,例如Autodesk的Revit或Bentley等建筑和工程软件,但这些BIM建模模型的数据往往过于臃肿,大多数详细信息的详细信息对楼宇自动化意义不大,反而影响了业界WebSCADA或Web配置监控的趋势,因此我们采用海拓的HTforWeb产品的轻量级HTML5/WebGL建模方案,实现快速建模、轻量级runtime,即使是移动端浏览器也能在3D可视化运维上取得不错的效果。本文讲解了智能楼宇的建模、页面动画效果的实现以及页面的主要功能点,帮助大家了解如何使用HT实现对智能楼宇的简单可视化监控,帮助大家了解智能楼宇和楼宇自动化。优势。预览网址:基于HTML5的WebGL楼宇自控3D可视化监控http://www.hightopo.com/demo/...界面介绍及效果预览界面通过将2d图纸叠加在3d上实现2d界面与3d场景的融合场景。2d界面通过自动布局的机制实现了移动端和电脑端的响应式呈现。界面初始化效果界面初始化过程中的动画包括地面路径实时渲染、楼层展开、楼层发光扫描、楼层报警点动态水波、楼层监控数据面板实时变化等。监控界面效果监控界面包括对进楼人员的实时监控,进楼人员头像、当前楼内人数等实时信息在面板上动态刷新。实时监控楼内电梯运行情况,系统显示电梯当前运行位置、是否运行等信息。实时监测建筑物特定楼层的监控数据,以柱状图的形式显示当前楼层特定信息的大小。楼宇管线实时监控,显示智慧楼宇所有管线的当前运行状态。智能建筑建模这个3D场景中的所有模型都是由线段和六面体构成的。与通过3dMax建模然后通过obj导入相比,场景中的三角面会少很多,而且轻量化,比如场景中建筑物的地板,通过ht.Shape类,记录了三角面的信息floorpoints和ht.List类型的segment数组信息,segments表示点的连接方式,用来告诉ht.Shape使用点信息绘制二次贝塞尔曲线或者三次贝塞尔曲线等信息曲线或直线,具体说明请参考HTforWeb的形状手册。图层模型都是一样的,只是y轴的值不同,几层叠加就能形成一个建筑物的轮廓。如果用户需要建设智慧园区、智慧楼宇等场景,可以使用这种基于HTML5/WebGL的建模方案,减少使用BIM建模模型的考虑。场景中的管道和背景地图路线由点和线组成,线或面的样式仅通过修改线的颜色粗细或贴图来修改。场景中的电梯是一个黄色的简单六面体,电梯线也只是一条线段,所以场景中的模型都是轻量级模型,使得3D场景渲染更流畅,提升了用户体验.场景关键动画代码分析1.地图路线动画代码分析通过上面智能建筑建模的分析,我们可以知道,线是为连接点而生成的,所以我们在绘制地图的路径时,可以得到所有的点信息,如果直线AB是地图中的一条线段,那么我们可以知道A点和B点的坐标,然后我们可以计算出AB线段上任意一点C的坐标,然后将A点和C点连接起来形成一条与AB线段位置和方向相同但比AB线段短的直线,直到AC线段的长度等于AB线段的长度,才绘制下一个路径动画。下面是关键的伪代码展示://currentIndex是当前路径绘制的点的索引//points是当前路径所有点的信息currentPoints是绘制过程中点的信息//segments是当前路径所有点的连接方式信息currentSegments是绘制过程中点的连接方式信息//即上述A点此时的信息letfromPoint=points[currentIndex];//即上述此时的B点信息lettoPoint=points[currentIndex+1];//AB方向的向量由AB的两个点组成letpointVector=newht.Math.Vector2(toPoint.x-fromPoint.x,toPoint.y-fromPoint.y);//记录向量的长度,用于判断AC是否大于等于ABletpointVectorLength=pointVector.length();让currentPoints=[],currentSegments=[];for(leti=0;ipointVectorLength){nextVectorLength=pointVectorLength;currentIndex+1;}pointVector.setLength(nextVectorLength);//是点C的坐标tempPoint={x:pointVector.x+fromPoint.x,y:pointVector.y+fromPoint.y};//将C点添加到currentPoints坐标currentPoints.push(tempPoint);//将C点连接添加到currentSegments。在这个程序中,是直线连接,所以值为2currentSegments.push(2);//roadNode是重置ht的ht.Shape类。RoadNode.setPoints(currentPoints);//重置ht.Shape点的连接信息roadNode.setSegments(currentSegments);下面是动画代码执行流程图:下面是绘制路线动画的截图:程序中通过向量的计算不断得到C点的坐标,当然也可以计算C点的坐标以其他方式2.水波和扫描动画代码分析通过修改HT提供的图标矩形框信息api来控制水波和扫描动画。通过调度不断修改图标矩形框的大小,产生水波和扫描动画效果。具体调度使用请参考HTforWeb的调度手册。下面是水波动画的关键伪代码://waterWaveNodes所有水波节点letwaterWaveTask={interval:100,//表示每100ms调用一次action函数action:function(data){//判断waterWaveNodes是否包含dataif(waterWaveNodes.indexOf(data)>-1){//此时获取图标矩形框信息circleRect是一个长度为4的数组,分别代表x,y,width,heightletcircleRect=data.a('circleRect');if(circleRect){//通过修改高度来增加水波的大小letnextHeight=circleRect[3]+10;//最大高度为250if(nextHeight<250){//对应修改y的大小,y的增量为高度的一半circleRect[1]=circleRect[1]-5;circleRect[3]=nextHeight;data.a('circleRect',circleRect);data.a('borderColor','rgba(255,133,133,'+(1-circleRect[3]/250)+')');}else{data.a('circleRect',[-0.5,128,257,0]);data.a('borderColor','rgba(255,133,133)');}}else{data.a('circleRect',[-0.5,128,257,0]);}}}};dm3d.addScheduleTask(waterWaveTask);//添加这个调度任务下图是2d的水波截图:3.数值变化动画代码分析从程序截图中我们可以看到,数字在2d面板和3d场景中是动态变化的。这部分主要是通过数据绑定动态修改数值的大小。数据绑定可以参考HTWeb的数据绑定手册,也是通过调度不断修改值的大小。在程序中,我封装了生成随机数的代码,用于每次生成随机数后绑定到对应的节点上。下面是2d面板修改上面数字的伪代码://numNode(1-7)是2d面板中数字对应的节点//data.a('ht.value',number)是动态修改attr上的ht.value信息,然后Drawings会自动更新新赋值的值//getRandomValue封装了自己生成随机数的方法this.change2dNumTask={interval:1000,action:(data)=>{if(data===numNode1||data===numNode2){data.a('ht.value',util.getRandomValue([500,999],5));}如果(数据===numNode3||data===numNode4){data.s('text',util.getRandomValue([0,30],2)+'%');}if(data===numNode5){data.a('ht.value',util.getRandomValue([0,99999],5,3));}if(data===numNode6){data.a('ht.value',util.getRandomValue([0,100],2));}if(data===numNode7){data.a('ht.value',util.getRandomValue([0,100],2));}}};dm2d.addScheduleTask(this.change2dNumTask);//添加这个调度任务。通过上面的代码可以知道,修改值就是通过修改节点的attr和style对象的一个??属性值来动态改变值。当然,2dpanel可能仍然隐藏在程序中。此时,定时任务不需要执行,可以调用removeScheduleTask方法移除定时任务4.条形图高度动画代码分析在3D场景下,柱子也是六面体,只是渐变图周围用到了,顶面用贴图构造了纯色贴图,每个六面体都有高度信息。在HT中,当前六面体的高度值是通过node.getTall()获取的。根据上一节提到的数据绑定,我们可以在显示直方图的时候循环获取所有柱状节点的高度值如果取名为tall,则通过node.a('tall',tall),然后可以在columnar初始化高度值的时候不断修改动态改变高度,当高度值大于node.a('tall')时,表示高度当前列初始化已经完成。以下是相关的伪代码:charts.forEach((chart)=>{!chart.a('tall')&&chart.a('tall',chart.getTall());//将高度存储在attr图表中.setTall(0);//设置初始高度为0});this.chartAnimteTask={interval:25,action:function(data){if(charts.indexOf(data)>-1){if(finishNum!==chartLength){if(data.getTall()!==data.a('tall')){让nextTall=data.getTall()+deep;//deep是每次增加的高度lettall=data.一个('高');//获取初始高度//判断下一个高度是否大于初始高度if(nextTall