前言2019年,VR、AR、XR、5G、工业互联网等词汇频频出现在我们的视野中。工业互联网是新一代信息通信技术升级换代的重要方向,是制造业转型升级的发展趋势。本文所说的VR,是机械制造行业与设备的另一种交流。当新技术新星遇上制造潮流,无疑将成为制造、工控等行业数字化转型的重要推动力。“5G+VR+工业互联网”必将成为新一年不变的话题。如何通过虚拟现实结合当前行业中遇到的问题,让我们更近距离的交流,感受技术带给我们的感受。改变。在今年的苹果发布会上,相信大家都知道苹果的5G手机还没有问世,这说明5G的应用和发展还处于高速发展阶段,但是结合AR功能的手机APP已经已经出来了,5G速度加上AR、VR的沉浸,不仅让我们感受到了技术的革新,也让我们感受到了技术在不同领域的实际应用场景。相信2020年新的一年一定是“5G+VR+工业互联网”又一个新的应用开始。下面的文章会讲一下HTforWeb结合WebVR开发的具体应用案例。系统预览预览地址:基于HTML5WebGL和WebVR3D虚拟现实的可视化训练系统http://www.hightopo.com/demo/vr-training/VR拆解还原VR操作VR场景切换PC拆解还原PC测试系统介绍系统分为三个实际应用层面:3D训练:用户可以通过手指在mb端触摸或在pc端拖动鼠标来拆卸设备,然后通过一键还原将设备恢复到原始状态,或者您可以通过拆卸或恢复按钮查看设备的自动拆卸过程和拆卸后的自动恢复过程。考试制度:这部分是考查你对设备拆解的熟悉程度。完成第一步3D培训后,您可以测试您对该系统中的拆卸过程的理解。VR模式:这部分是3D场景结合WebVR的具体实现和应用。进入VR后,您可以通过操作VR手柄进行拆卸和还原设备。文章第三部分主要讲解VR模式,让我们了解如何结合HT构建VR场景。VR中的主要操作如下所述。不进入VR时,不会出现下面提到的六个按键操作。当你点击进入WebVR时,系统会自动显示VR场景中的六个操作按钮。否则当你退出VR时,系统也会自动隐藏3D中的六个操作按钮。VR中的主要操作如下:设备切换:顾名思义,可以使用手柄射线对准场景左侧的列表,按下扳机切换场景设备。操作切换:VR中对设备有以下两种操作,点击右下角的模式按钮可以切换。平移模式:在此模式下,用户可以对齐设备并按下触发器将设备从一个位置移动到另一个位置,并且可以通过触摸触摸板放大和缩小设备部件。抓取模式:在此模式下,用户可以对齐设备并按下触发器来抓取设备。抓取后,用户可以通过触摸触摸板旋转和放大或缩小部件。一键还原:将设备的所有部件还原到原来的位置。拆卸动画:通过事先预定的位置,一步步拆卸设备的各个部分。还原动画:这个操作可以理解为反汇编动画,即倒序还原反汇编过程。线框切换:HT支持显示设备节点的三角面,可以详细查看设备的线框轮廓。系统开发3D场景HT支持导入obj模型。VR场景中出现的装备部件都是obj模型。由于后期需要拆卸设备,所以建模时需要对设备的各个部分分别进行建模。而不是对整个设备进行建模,如果对整个设备进行建模,那么它就是HT场景中的一个Data节点,这样零件就无法拆解了。如果反汇编的话,那么HT里面可以加载多个objs。有多个数据节点。多个零件的数据节点后,设备零件可以移动或旋转。Data在HT中的具体含义请参考HTforWeb数据模型手册。导入场景中的obj模型如下:从上图可以看出,我们导入obj之后,零件是散乱的,所以需要调整零件的初始位置,从而调整组成一个完整的设备许多部分。当然,调整不能通过代码来调整。对应有一个3D编辑器,可以调整,拖拽拼凑不同的部分,下面是组合后的整体装置:VR搭建VR场景是在第一步的基础上搭建的,以上只在VR场景中显示的按钮也是场景内置的。在正常场景下,我们可以隐藏相应的节点。node.s('3d.visible',false)上面的代码是将HT中的3D下的3D节点隐藏起来,因为在进入VR和离开VR时,HT会发送一个相应的状态,告诉用户此时已经进入VR或者离开VR。对应的伪代码如下://graph3dView是HT中的3D场景视图容器//vr获取挂载在graph3dView上的vr对象varvr=graph3dView.vr;vr.mp(function(e){//属性对应到vr事件类型,详细说明此时事件的状态varproperty=e.property;vardetail=e.newValue;//present表示此时进入或离开VR场景if(property==='present'){//此时detail为true表示进入vr,false表示离开vrif(detail){//实现显示vr场景中需要显示的节点操作}else{//执行vr场景中需要隐藏的隐藏节点操作}}});上述属性在HT中一共会发出以下类型,主要包括VR状态和句柄操作类型:enable:vr变化的使能信息present:vr变化的当前信息,表示进入和退出vr世界Bit更改、参数ID、轴;其中axes的格式为:[0.2,0.7],分别表示水平和垂直的百分比buttonispressed,参数id,state,其中state包括down和up两种,参数id,state,其中state包括down和up。VR中的一个关键配置是比例尺,因为VR中的单位与现实中的长度单位是一致的,我们戴上头盔向前走1m,那么我们需要一个对应关系对应我们在HT3D场景中需要向前走多远。HT提供的VR插件会提供一个measureOflength配置项,如下:varvr_config={measureOflength:0.01,}上面的0.01表示HT场景中的单位长度1代表真实场景中的0.01米,所以如果此时你戴上头盔在真实场景中向前移动1m,那么HT中相应的视角会向前移动100所以如果你需要搭建一个VR场景,要注意模型建模的区别场景与现实世界的比例,按照统一的比例建模。否则会出现VR场景中设备尺寸不同的问题,从而导致错觉,比如在下面的对比图中,左边的比例为0.01,光线的点非常小,而右边的比例为0.001,导致光线的点变大。HT封装了浏览器提供的WebVR相关接口的API,包括获取设备navigator.getVRDisplays(),这是进入VR世界的第一步。如果此时执行这段代码返回的结果为空,则表示获取VR设备失败,所以先不说获取句柄信息navigator.getGamepads(),用户可以查看浏览器是否获取到VR设备information和VR通过在浏览器控制台输入以上两行代码来处理信息。如果返回为空,则表示获取失败。HT可以通过执行graph3dView.vr.enable=true来开启VR。当然,用户不需要执行这段代码。HT提供的VR插件也会提供相应的配置项vrEnable:true表示开启VR。对应的配置也挂在了上面的vr_config对象中,如下:varvr_config={measureOflength:0.01,vrEnable:true,//表示开启VR}在展示的系统中,有VR中直接切换场景的功能,因为每个场景中的vr_config配置项的值可能不同。例如,第一场景的measureOflength尺度为0.01,第二场景的measureOflength可以为0.02。所以VR插件提供了销毁函数来销毁之前的。场景的资源,销毁场景的资源包括清空之前场景的所有节点,所以在加载新场景的时候,不需要执行清空场景节点的操作,也就是没有必要执行dataModel.clear(),因为VR提供的destruction函数已经清空了,handle和ray都是场景中的Data节点,所以不需要清空handle和ray这两个节点在场景中新场景,所以插件可以帮助您管理场景的节点。调用destroy函数后,可以调用graph3dView的序列化函数graph3dView.deserialize('场景资源json地址')序列化新的场景json文件。在序列化后的回调函数中,可以根据新的场景vr_config值修改本次,然后再次调用graph3dView.initVRForScene()再次初始化VR场景。相关步骤的伪代码如下://window.GVR是调用graph3dView.initVRForScene()后初始化的全局VR插件变量,供用户获取插件对象window.GVR.destory();//执行新场景序列化操作graph3dView.deserialize('场景资源json地址',function(json,dm,g3d,datas){//修改新场景的比例为0.02window.vr_config.measureOflength=0.02;//修改新场景VR场景初始化视角窗口.vr_config.vrEye=ht.Default.clone(g3d.getEye());//初始化VR场景graph3dView.initVRForScene()});当然,HT提供的VR插件有很多配置项,更方便用户对VR场景的调整,包括地形刷刷、场景移动方式、场景运行方式都可以通过配置进行配置。使用HT搭建VR的主要流程如下图所示:通过上面的流程图,我们可以大致了解HT提供的配合VR插件是如何快速搭建VR场景的。目前GoogleChrome和Firefox浏览器都友好支持VR,您可以通过Firefox官网提供的WebVRDemo在线体验官方提供的VR场景。拆解规则从文章前面的效果图中我们可以看出每个场景中的装备都进行了拆解,零件的数量,零件的位置,零件的拆解方向,以及零件的??长度每个设备的偏移量都不一致。所以,不可能通过代码把上面的偏移长度和偏移方向写死。我们需要制定一套反汇编规则,帮助我们更方便的制作各个场景的反汇编动画。这样,设计者只需要按照与程序约定好的反汇编规则,就可以为不同场景的不同设备配置反汇编动画。系统的拆解分为两种情况:单一移动:单个设备部件沿父节点位置与节点位置连线方向移动组合移动:多个设备部件组合沿某个方向移动方向,组合移动之后,设备部件可以在组合移动后的位置沿一定方向移动,可以无限嵌套,即组合后也可以组合移动,或者单机移动。单个动作示意图如下:组合动作示意图如下:在HT中,可以通过data.setDisplayName('name')设置节点的名称。这里约定通过不同设备的名称获取不同设备的offset信息,如data.setDisplayName('1-0.5-1000')name是与设计者约定的配置规则。1代表拆解步骤的第一步。当然,场景中可以有多个1,即第一步同时拆解这些部件。0.5表示朝向父节点的方向。在自身位置和父节点位置之间移动连接线长度的50%。1000表示偏移过程持续1000毫秒。当然旋转、旋转角度等信息也可以事后约定。设计师知道这些配置规则后,就可以通过可视化编辑器对不同的部分进行配置,这样程序只需要写一套通用的逻辑就可以对不同的设备进行拆解和还原。系统维护一个队列和一个栈。队列用来记录拆解顺序,栈用来记录还原顺序。拆解过程通过配置的流水号依次推进队列。采用队列的数据结构是因为队列具有先进先出的特点。最先推入队列的部分先执行,最后推入队列的部分最后执行拆解序列。被拆解出队列的部件同时被压入栈中。之所以用栈来记录恢复顺序是因为先进后出的特性,即恢复时最先拆开的部分是最后执行恢复动作的。所以,上面采用的不同的数据结构,都是为了更好的记录数据。下面是相关的js伪代码://记录拆解序列constqueue=[];//记录恢复序列conststack=[];//每次循环用于记录拆解队列队列顺序dataModel.each((node)=>{constdisplayName=node.getDisplayName();if(displayName){const[index,distancePer,during]=displayName.split('-');if(index!==void0){if(queue[index]){if(queue[index]instanceofArray){queue[index].push(node);}else{consttempNode=queue[index];queue[index]=[tempNode,node];}}else{队列[索引]=节点;}}}});相关逻辑如下:通过上述约定,设计者可以使用可视化编辑器配置不同部位的运动规则,大大提高了动画制作效率。代码分析这部分主要分析拆解和还原动画的代码。它主要利用向量和偏三角函数的概念来计算三维空间中不同部分的位置。刚开始的时候需要记录下之前所有组合动作后各部分的位置。初始移动位置向量,和部件未组装移动前的初始位置向量,获取这两个位置向量的目的是将上述组合后的部件拆解移动,将部件恢复成一个完整的设备形态反汇编后的初始位置,两个位置向量都有重要作用,下面是相关伪代码://Vector3是HT封装的三维向量constVector3=ht.Math.Vector3;//记录第一个重要位置向量node.a('relativeP3Vec',newVector3(node.p3()));//节点当前部分节点//moveQueue是节点之前的移动序列,是节点的祖先节点nodefor(leti=0,l=moveQueue.length;i
