当前位置: 首页 > Web前端 > HTML5

基于HTML5的WebGL3D智能楼宇监控系统

时间:2023-04-06 00:24:36 HTML5

前言智能监控领域已经涉及到工控、电信、电力、轨道交通、航空航天等各个领域。监控系统必不可少。之前写过一篇文章,二维智能地铁监控系统广受好评。突然觉得既然2D这么火,3D的需求量肯定很大。毕竟3D比2D更直观,所以才有了Thisexample和这篇文章。除了3D机房,智能监控系统在3D方面应用比较广泛,我觉得是楼宇的监控,但是之前做过很多关于机房的demo,所以最后还是决定做一个3D楼监视系统。代码生成场景搭建整个场景使用HTforWeb(http://hightopo.com/)的3D组件搭建。左边有listView列表组件,你可以通过点击listView列表组件在各个item之间自由切换。监控楼层和楼宇场景:dm=newht.DataModel();g3d=newht.graph3d.Graph3dView(dm);relativeLayout=newht.ui.RelativeLayout();//相对布局器可以布局界面varht3dView=newht.ui.HTView(g3d);//放置3d组件relativeLayout.addView(ht3dView,{//添加组件显示relativelayouter,参数1为组件名,参数2可以设置宽高和对齐方式等属性width:'match_parent',height:'match_parent'});varlistView=window.list=newht.ui.ListView();//列表组件for(vari=1;i<=15;i++){vardata=newht.Data();//创建节点数据.setName('floor'+i);//设置节点名称listView.dm().add(data);//添加节点到list组件中}relativeLayout.addView(listView,{//添加listView组件到thelayoutalign:'left',//设置左对齐vAlign:'top',//设置垂直对齐为上对齐marginTop:120,//设置上边距为120像素marginLeft:60,//设置左边距为60像素width:80,//设置宽度为80height:480,//设置高度为480index:100//设置元素的堆叠顺序});relativeLayout.addToDOM();//添加组件到body,加载模型到页面显示是整个城市的场景,通过ht.Default.loadObj方法加载obj模型:varloadCity=function(){ht.Default.loadObj('obj/city.obj','obj/city.mtl',{//loadModelcenter:true,//模型是否居中,默认为false,设置为true会移动模型位置使其内容居中cube:true,//是否将模型缩放到尺寸unit1的范围,默认为falseprefix:'obj/',//图片路径前缀,即在map_kd值前添加的前缀,如果是相对路径,则加载obj的html页面路径为用作参考shape3d:'city',//如果指定了shape3d名称,则HT会自动将所有材质模型加载解析后构建成一个数组,并以此名称注册finishFunc:function(modelMap,array,rawS3){//用于加载obj模型后的回调处理city.rawS3=rawS3;//设置变量city对象的rawS3属性,该函数中的rawS3属性为obj模型的原始大小showCity();//创建一个节点,设置节点的shape3d为city,显示city.obj和city.mtl的内容}});}工控层模型的加载也类似,这里不再赘述直接在场景中添加组件不会有相关操作。您必须监控事件的触发,然后才能执行后续操作。这里,可以监听数据选择容器中选中的变化事件://listclicklistView.dm().sm().ms(function(e){//监听选中的变化事件if(e.kind==='set'){//设置监听事件showFloor();//显示楼层}});call为了简单起见,这里的model只设置了一个工控层的obj模型。通过调用不同的obj模型,可以展示不同的工控楼层场景。也就是说,我们可以通过ht.Default.loadObj方法自行加载模型,设置工控层模型。shape3d属性,然后将其设置为要修改的节点的shape3d属性;或者直接把节点的shape3d属性设置成json格式的obj文件,这里还是第一种方式:varshowFloor=function(){g3d.setCenter([210,0,210]);//设置“center"positionofthe3dcomponentdm.clear();//清除数据容器中的所有节点varrawS3=floor.rawS3,//获取obj模型的原始大小node=newht.Node();//创建anewnodenode.s({//设置节点的style属性'shape3d':'floor',//这个设置的值在ht.Default.loadObj中设置shape3d属性的值'wf.visible':'selected',//设置节点外的线框在节点被选中时显示'3d.selectable':false//设置节点不可选});node.s3(rawS3[0]/10,rawS3[1]/10,rawS3[2]/10);//设置节点大小为原来大小的十分之一node.p3(140,0,230);//设置节点的位置dm.add(node);//将节点添加到数据容器中//添加四个“相机”节点createNode([0,20,0]);创建节点([110、20、220]);创建节点([330、20、420]);创建节点([210、20、120]);创建节点([420、20、120]);};这里顺便说一句调用obj模型的另一种方便的方法是直接将节点的shape3d属性设置为导入的json格式文件:varnode=newht.Node();node.s("shape3d","./符号/city.json");但是这个json的内容必须有如下元素:{"modelType":"obj",//这个属性必须设置为objformat"obj":"./obj/city.obj",//必须设置theobjattribute"mtl":"./obj/city.mtl"//这一项可写可不写,如果需要设置obj模型的样式(如颜色等),必须设置此项item}但是这种模式不适合这种场景,因为我的模型有点大,需要调用obj模型原始大小的rawS3属性,按一定比例划分后显示。片”类型的节点。所谓“面片”就是只有一张面。通过这种在平面上显示矢量图的方法,结果会比在六面体上显示图形更好。当3D场景简单时,效果可能不可见。如果场景冻结,您可以立即看到它。利用“表面切片”:functioncreateNode(p3,s3){varnode=newht.Node();//创建一个新节点node.p3(p3);//设置节点的位置//节点.s3(s3);node.s({'shape3d':'billboard',//设置节点的shape3d类型为billboard类型,显示为“facet”'shape3d.image':'./symbols/intelligentbuilding/camera.json',//3d图形整体纹理'shape3d.image.cache':true,//如果纹理是向量,是否缓存(缓存后性能会有所提升)'shape3d.autorotate':true,//是否缓存自动正对摄像头'shape3d.transparent':true,//判断3d图形是否透明//'shape3d.alwaysOnTop':true,//是否一直在顶部'shape3d.fixSizeOnScreen':[38,47]//是否缩放Far和near,在屏幕上呈现一个固定大小,值可以是true(使用图片或vector本身的大小)/false,或者[100,200](对应width和身高)});dm.add(node);//将节点添加到数据容器中g3d.invalidateShape3dCachedImage(node);//缓存的代价是这里需要更新返回节点;}事件交互然后我在想,既然展示了地板的3D模型,如何返回呢?哪种退货方式最好?想来想去,还是点击列表组件没有违和感比较好,所以我选择了最上面的列表组件:listView.getView().addEventListener('click',function(e){//监听点击事件e.preventDefault();//阻止禁用默认操作if(e.clientY-120<50){showCity();//显示初始3D建筑场景listView.dm().sm().cs();//列表设置清除所有选中元素}});所有代码结束!综上所述,这套3D智能楼宇监控系统非常简单,对技术人员来说完全没有挑战。主要工作内容为美术。这样,如果要增加更复杂的需求,技术人员可以全身心投入。总而言之,我觉得这个demo很有代表性,所以想分享给大家,一起探讨一下前端趋势。http://hightopo.com/demo/inte...