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

基于HTML5和WebGL的3D网络拓扑图

时间:2023-04-05 14:03:33 HTML5

现在,3D模型已经被应用到各个领域。它们在医疗行业用于制作精确的器官模型;电影业将它们用于移动角色、物体和逼真的电影;视频游戏行业将它们用作计算机和视频游戏的资源;科学领域将它们用作化合物的精确模型;建筑行业使用它们来展示拟建的建筑或景观图;工程界使用它们来设计新设备、车辆、结构和其他应用程序;此外,3D模型通常是动画的,例如,在故事片以及广泛使用3D模型的计算机和视频游戏中。它们可以在3D建模工具中使用,也可以单独使用。为了方便地形成动画,通常会在模型中添加一些额外的数据。例如,一些人或动物的3D模型具有完整的骨骼系统,这样运动看起来更逼真,并且可以通过关节和骨骼来控制运动。这些都让我们前端开发者觉得,如果不用学习unity3d或者其他游戏开发工具也能实现3D效果,并且能够通过代码准确控制移动或者方向,那该多好啊。..所以我使用HTForWeb中的3D组件实现了一个小例子,使用了HT中3D组件的大部分功能。这个例子是为了掌握3D组件,尽量把它们放到一个例子中。有需要的可以参考一下,但是因为之前没有实现过3D效果,现在手册也不是很全,所以这个例子对我来说还是有点难度。本例位置:http://www.hightopo.com/demo/...先来看看整体实现效果图:使用HTforWeb,制作三层底板不成问题有了现有的3D模板,问题是如何把图中一楼的“电脑”和“机柜组件”放上去?我从网上下载了obj格式的文件,然后使用HT中的ht.Default.loadObj(objUrl,mtlUrl,params)函数加载模型。params部分可以参考http://www.hightopo。com/guide...,代码如下:ht.Default.loadObj('obj/cabinetcomponent1.obj','obj/cabinetcomponent1.mtl',{cube:true,center:true,shape3d:'box',finishFunc:function(modelMap,array,rawS3){window.rawS3=rawS3; if(modelMap){ device2=createNode('box',floor1);    device2.p3([x1-120,y1+13,z1+60]);    device2.s3(rawS3);    createEdge(device1,device2);    device3=createNode('box',floor1);.s3(rawS3);    device3.p3([x1+120,y1+13,z1+60]);    createEdge(device1,device3); }}});“电脑”上方有一个红色的立体“警告”,可以旋转。它是通过ht.Default.setShape3dModel函数注册的3D模型(HTforWebModelingManual)。ht中封装了很多建模函数,比较基础。是球体、圆柱体、立方体等。这里我使用createRingModel方法构造一个环,生成最外层的“warning”环。感叹号的上半部分是createSmoothSphereModel结构体创建的球体,感叹号下方是createSmoothCylinderModel构造的圆柱体。一开始直接用的是封装在3D模型中的函数,所以不知道函数中使用的参数是干什么用的,对3D也不懂。模型是怎么组成的,再重新看之前的《模型基础》,才知道原来3D模型用的是一个面,最基本的是一个三角面,复杂的面也是由多个三角面组成.然后绕特定轴旋转后形成。当然,这个轴由你决定。不同的轴可以生成不同的形状。颜色等样式设置请参考HTforWebStyle手册。至于如何旋转3D模型,ht封装了addScheduleTask(Task)方法,我在第三层Task中调用了ht封装的一个旋转函数setRotation来设置旋转的顺序和方向,指定旋转的对象。以下是自定义“warning”3D模型的方法(注意:因为本例中的模型是自定义组合,如果要设置整体模型的颜色,需要使用“all.blend”样式属性):varringModel=ht.Default.createRingModel([8,1,10,1,10,-1,8,-1,8,1],null,null,false,false,100);varsphereModel=ht.Default.createSmoothSphereModel(8,8,0,Math.PI*2,0,Math.PI,2);varcylinderModel=ht.Default.createSmoothCylinderModel(8,true,true,1,2,0,Math.PI*2,8);vararr=[{r3:[Math.PI/2,0,0],颜色:'red'},{shape3d:sphereModel,t3:[0,4,0],颜色:'red'},{shape3d:cylinderModel,t3:[0,-3,0],color:'red'}];ht.Default.setShape3dModel('alarm',{shape3d:arr});在3D界面上显示2d图片,按照通常的Walking即可,因为在ht中Graph3dView等组件的根都是div,而原生的js,在div上使用newImage()生成图片,然后是图像的src和大小被分配并添加到3d面板就是这样。请注意,这是添加到3d的底部div。您需要使用g3d.getView().appendChild来添加它。我们还可以看到管道上有虚线流动的痕迹。这是通过不断改变“shape3d.uv.offset”参数来实现管道流的特殊效果,详见HTforWebShape手册。要在3d管道上移动2d图像,请使用g3d.toViewPosition(position)获取3d模型的2D坐标。此函数中的参数是3d模型的3d坐标。我们可以直接将折线管道上的点传入toViewPosition函数中,这里的管道上的点已经用getLineCacheInfo、getLineLength、getLineOffset三个函数封装在ht中,这样就可以直接获取二维坐标,以及然后可以设置img的坐标。下面是img代码在管道上移动的图像:vardelta=10;params={frames:Infinity,interval:50,action:function(v,t){varlength=(polyline.a('total')||0)%polyline.a('length')+delta;varcache=ht.Default.getLineCacheInfo(polyline.getPoints(),polyline.getSegments());varlineLength=ht.Default.getLineLength(缓存);varoffset=ht.Default.getLineOffset(cache,length);arr=[offset.point.x,offset.point.y,offset.point.z];varposition=g3d.toViewPosition(arr);img.style.left=(position.x-5)+'px';img.style.top=(position.y-5)+'px';polyline.a('总计',长度);}};anim=ht.Default.startAnim(params);可以看到图中第二层的看台盒子上有“SDH”字样。我是通过设置shape3d.top.img:imgURL来实现的。这里的imgURL可以是图片的相对路径,也可以是ht中声明的img和ht.Default.setImage,也可以是json格式构造的图片。在ht中,如果2D文字显示在3D上,字体周围会出现“锯齿”。这时只要设置“label.transparent:true”即可。我们还可以看到第二层有两个特殊的多边形“平行四边形”和“梯形”,因为之前有客户说不知道怎么使用模型函数createExtrusionModel(HTforWebModelingManual),所以我简单的写了一会儿,平行四边形是基于createParallelogramModel模型函数。这个功能比较简单。createExtrusionModel(array,segments,top,bottom,resolution,repeatUVLength,tall,elevation),array是你要形成的图的坐标点,这个只是针对xz轴绘制的平面图,segments是指如何连接这些坐标点,你可以参考HTforWebshape的手册,top和bottom是你选择有没有top或者bottom,分辨率微分段的个数,我们画曲线的时候可以确定几个单独的点,然后在每两个点之间的连线上分成多段,这条线段就会变得平滑。ht被封装,方便用户操作这些线段如果设置了这个参数,repeatUVLength默认为空。设置该值后,顶部和底部纹理将按照指定的长度值重复。tall模型的高度默认为5。高程模型中心的y轴位置默认为0。设置此A值,使平面绕y轴在xz上旋转。底层环的效果是通过算法实现的。环要先确认环上有多少个元素,然后计算每两个之间的夹角,通过sin和cos计算出每个元素的位置,得到添加如下代码:names=['Device2','设备3','设备4','设备5','设备6','设备7','设备8','设备9'];名字。forEach(function(name,index){    x=400,y=200,angle=45,r=120;    x=x3+Math.sin((2*Math.PI/360)*角度*索引)*r;    y=z3+Math.cos((2*Math.PI/360)*角度*索引)*r;    device=createRect([x,y3+15,y],[w*0.1,15,h*0.1],'','',floor3);    createEdge(device5,device);});