前言在数据量大的2D场景中,很难找到具体的模型,只能显示模型的某一部分,显示不直观足够的。快速构建3D场景的需求很大。然而,构建3D应用场景需要专业的3D设计师使用3dsMax或Maya进行建模,Unity3D引擎进行图形渲染等,这对用户来说是一个挑战!而HT提供了从建模到渲染的一站式解决方案,包括2D组件渲染和数据融合。HT基于WebGL的3D技术图形组件ht.graph3dView组件封装了WebGL的底层技术。与其他HT组件一样,它基于HT统一的DataModel数据模型来驱动图形显示,大大降低了3D图形技术开发的门槛。一般程序员在熟悉HT数据模型的基础上,只需1小时的学习就可以上手3D图形开发。好了,废话不多说,先附上demo:http://www.hightopo.com/demo/blog_3dedge_20170630/index.html当然,这里我只是用简单的图形来表示设备,你脑洞大当然它可以换成更有趣的模型。3D场景搭建1.准备工作:3D和2DAPI设计保持了很大的一致性。3D视图组件为ht.graph3d.Graph3dView,2D视图组件为ht.graph.GraphView。两者可以共享同一个数据模型DataModel。在HT中,为了获得接近真实三维物体的视觉效果,我们采用透视投影,使远处的物体变小,近处的物体变大,平行线会出现先相交的现象,也就是离物体更近人眼视觉效果:如上图所示,透视投影最终显示在屏幕上的只是截锥体的内容,所以GraphView提供了eye、center、up、far、near、fovy和aspect参数来控制具体的截头体的范围。我们在实际应用中多用了eye和center:getEye()|setEye([x,y,z]),确定眼睛(或Camera)的位置,默认值为[0,300,1000];获取中心()|setCenter([x,y,z]),确定目标中心点(或Target),默认值为[0,0,0];有关详细信息,请参阅HTforWeb3D手册。dataModel=newht.DataModel();g3d=newht.graph3d.Graph3dView(dataModel);g3d.setEye(1800,800,1000);g3d.setCenter(0,100,0);g3d.setDashDisabled(false);g3d.getView().style.background='rgb(10,20,36)';g3d.addToDOM();2.创建一个设备:服务器。Demo中的服务端其实是通过addStyleIcon在服务端的位置添加图片的。详见HTforWeb入门手册://注册图片ht.Default.setImage('server','server.png');varserver=newht.Node();服务器.s3(0,0,0);服务器.p3(0,60,0);server.addStyleIcon('icon',{position:0,width:200,autorotate:true,transparent:true,height:200,names:['server']});dataModel.add(服务器);Workbench,这里的工作台其实是用一个三维的圆柱体来表示的。HT在GraphView的二维图形上。各种图形的呈现方式是由style的shape属性决定的。类似于HT在3D中提供了shape3d属性,预定义了多种3D形状。详情请参见HTforWeb3D手册。不过这里我没有使用预定义的图形,而是通过ht.Default.createRingModel的方式创建圆柱体,这种方法可以根据xy平面的曲线围绕一个圆形成3D模型,因此可以用来定义各种圆形3D模型。vardesktop=newht.Node();desktop.s({'3d.selectable':false,'shape3d':ht.Default.createRingModel([0,40,450,40,450,0,0,40],null,20,false,false,50),'shape3d.color':'#003333'});desktop.s3(1,1,1);dataModel.add(桌面);平台上的设备,我们一共创建了32个设备:varcount=32;半径=400;索引=计数/2;对于(vari=1;i<=count/2;i++){vardevice1_angle1=Math.PI*2*(index-i)/count,device1_angle2=Math.PI*2*(index+i)/count,device1_angle3=Math.PI*2*index/count;vardevice1_1=createDevice(device1_angle1,radius,60),device1_2=createDevice(device1_angle2,radius,60),device1_3=createDevice(device1_angle3,radius,60);layoutDevice1(device1_1,device1_angle1);vardevice1_edge1=createEdge(device1_1,server,'line1');device1_edge1.s({'shape3d.color':'rgb(205,211,34)'});dataModel.add(device1_1);dataModel.add(device1_edge1);layoutDevice1(device1_2,device1_angle2);vardevice1_edge2=createEdge(device1_2,server,'line1');device1_edge2.s({'shape3d.color':'rgb(205,211,34)'});dataModel.add(device1_2);dataModel.add(device1_edge2);layoutDevice1(device1_3,device1_angle3);vardevice1_edge3=createEdge(device1_3,server,'line1');device1_edge3.s({'shape3d.color':'rgb(205,211,34)'});dataModel.add(device1_3);dataModel.add(device1_edge3);}为了让创建的设备在平台上的布局更加合理,根据索引计算设备放置角度,根据圆柱心、圆盘半径和角度位置:函数createDevice(角度,x,y){ varnode=newht.Node(); cos=Math.cos(角度); sin=Math.sin(角度); node.p3(x*sin,y,x*cos); returnnode;}otherdevices,varnum=18;varh=[800,900,1000,1100,1200];varv=[40,60,80,100];var颜色=['#fcfc63','#00E1E4'];对于(varj=0;j
