前言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端拖动鼠标来拆卸设备,然后通过一键还原将设备恢复到原始状态,或者您可以通过拆卸或恢复按钮查看设备的自动拆卸过程和拆卸后的自动恢复过程。考试制度:这部分是考查你对设备拆解的熟悉程度。在第一次三维训练后,您可以测试您对该系统的拆卸过程的理解。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节点。多个零件的数据节点后,设备零件可以移动或旋转。Data在HT中的具体含义请参考HTforWeb数据模型手册。导入场景中的obj模型如下:从上图可以看出,我们导入obj后,零件是散乱的,所以需要调整零件的初始位置,从而调整一个完整的设备组成许多部分。当然,调整是不能通过代码调整的,对应有一个3D编辑器可以调整,拖拽拼凑不同的部分,下面是组合后的整机:VRbuildVR场景建立在在第一步的基础上,以上只是在VR场景中显示的按钮,场景中也内置了。在正常场景下,我们可以隐藏相应的节点。node.s('3d.visible',false)上面的代码是把HT中的3D下面的3D节点隐藏起来的代码,因为在进入VR和离开VR的时候,HT都会发送一个相应的状态,告诉用户他有此时进入VR或离开VR。对应的伪代码如下:1//graph3dView是HT中的3D场景视图容器2//vr获取挂载在graph3dView上的vr对象3varvr=graph3dView.vr;4vr.mp(function(e){5//property对应vr事件类型,详细说明此时事件的状态6varproperty=e.property;7vardetail=e.newValue;8//present表示此时进入或离开VR场景9if(property==='present'){10//此时detail为true表示进入vr,false表示离开vr11if(detail){12//在displayvr场景中执行需要显示的节点操作13}else{14//在hiddenvr场景中执行需要隐藏的节点操作15}16}17});上述属性在HT中一共会派发以下几种,主要包括VR的状态和句柄的操作类型:enable:vr变化的开启信息present:vr变化的当前信息,表示进入和退出虚拟现实世界。,position,rotationgamepad.axes:转盘触摸点在手柄中间的变化,参数id,axes;axes的格式为:[0.2,0.7],分别表示水平和垂直的百分比gamepad.button.thumbpad:拇指板按钮被按下,参数id,state,其中state包括向下和向上gamepad.button.trigger:triggerbuttonispressed,参数id,state,其中state包括down和upgamepad.button.grips:grips按钮被按下,参数id,state,其中state包括down和up。gamepad.button.menu:菜单按钮被按下,参数id,state,其中state包括down和up。VR中的一个关键配置就是比例尺,因为VR里面的单位和现实中的长度单位是一样的。如果我们戴上头盔,向前走1m,那么在HT3D场景中,我们需要一个对应关系,就是我们需要向前走多远。HT提供的VR插件会提供一个measureOflength的配置项如下:1varvr_config={2measureOflength:0.01,3}上面的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设备信息和VR句柄信息,如果返回为空,则表示获取失败。HT可以通过执行graph3dView.vr.enable=true来开启VR。当然,用户不需要执行这段代码。HT提供的VR插件也会提供相应的配置项vrEnable:true表示开启VR。对应的配置也挂在了上面的vr_config对象中,如下:1varvr_config={2measureOflength:0.01,3vrEnable:true,//表示启用VR4}在这里展示的系统中,有直接切换场景的功能在VR中,因为每个场景的vr_config中的配置项值可能不同。例如,第一场景的measureOflength尺度为0.01,第二场景的measureOflength可以为0.02。所以VR插件提供了销毁前一场景资源的销毁函数。销毁场景的资源包括清除之前场景的所有节点,所以加载新场景时,不需要执行清除场景节点的操作,即不需要执行dataModel.clear(),因为VR提供的销毁函数已经被清除。handle和ray在场景中都是一个Data节点,所以新场景中handle和ray这两个节点不需要清空,插件帮你管理场景的节点。调用destroy函数后,可以调用graph3dView的序列化函数graph3dView.deserialize('场景资源json地址')序列化新的场景json文件。在序列化后的回调函数中,可以根据新的场景vr_config值修改本次,然后再次调用graph3dView.initVRForScene()再次初始化VR场景。相关步骤的伪代码如下:1//window.GVR是调用graph3dView.initVRForScene()后初始化的全局VR插件变量,供用户获取插件对象2window.GVR.destory();3//执行新场景序列化操作4graph3dView.deserialize('场景资源json地址',5function(json,dm,g3d,datas){6//修改新场景比例为0.027window.vr_config.measureOflength=0.02;8//修改新的VR场景初始化视角9window.vr_config.vrEye=ht.Default.clone(g3d.getEye());10//再次初始化VR场景11graph3dView.initVRForScene()12});当然,HT提供的VR插件中也有很多配置项,方便用户更好的调整VR场景,包括笔刷地形、场景移动模式、场景运行模式,都可以通过配置配置。使用HT构建VR的主要流程如下图所示:通过以上流程图,我们可以大致了解如何使用HT提供的VR插件快速构建VR场景。目前GoogleChrome和Firefox浏览器都友好支持VR,您可以通过Firefox官网提供的WebVRDemo在线体验官方提供的VR场景。拆解规则从文章前面的效果图中我们可以看出每个场景中的装备都进行了拆解,零件的数量,零件的位置,零件的拆解方向,以及零件的??长度每个设备的偏移量都不一致。所以,不可能通过代码把上面的偏移长度和偏移方向写死。我们需要制定一套反汇编规则,帮助我们更方便的制作各个场景的反汇编动画。这样,设计者只需要按照与程序约定好的反汇编规则,就可以为不同场景的不同设备配置反汇编动画。系统的拆解分为两种情况:单一移动:单个设备部件沿父节点位置与节点位置连线方向移动组合移动:多个设备部件组合沿某个方向,组合移动之后,设备部件可以在组合移动后的位置沿某个方向移动,并且可以无限嵌套,即组合后也可以组合移动,或者单个movement单体运动示意图如下:组合运动示意图如下:在HT中,可以通过data.setDisplayName('name')设置节点的名称。这里约定通过不同设备的名称获取不同设备的offset信息,如data.setDisplayName('1-0.5-1000')name是与设计者约定的配置规则。1代表拆解步骤的第一步。当然,场景中可以有多个1,即第一步同时拆解这些部件。0.5表示朝向父节点的方向。在自身位置和父节点位置之间移动连接线长度的50%。1000表示偏移过程持续1000毫秒。当然旋转、旋转角度等信息可以在后面约定。设计师知道这些配置规则后,就可以通过可视化编辑器对不同的部分进行配置,这样程序只需要写一套通用的逻辑就可以对不同的设备进行拆解和还原。系统维护一个队列和一个栈。队列用来记录拆解顺序,栈用来记录还原顺序。拆解过程通过配置的流水号依次推进队列。采用队列的数据结构是因为队列具有先进先出的特点。最先推入队列的部分先执行,最后推入队列的部分最后执行拆解序列。被拆解出队列的部件同时被压入栈中。之所以用栈来记录恢复顺序是因为先进后出的特性,即恢复时最先拆开的部分是最后执行恢复动作的。所以,上面采用的不同的数据结构,都是为了更好的记录数据。下面是相关的js伪代码:1//记录下拆的顺序2constqueue=[];3//记录恢复顺序4conststack=[];5//每次循环用于记录拆解队列的顺序6dataModel.each((node)=>{7constdisplayName=node.getDisplayName();8if(displayName){9const[index,distancePer,during]=displayName.split('-');10if(index!==void0){11if(queue[index]){12if(queue[index]instanceofArray){13queue[index].push(node);14}else{15consttempNode=queue[index];16queue[index]=[tempNode,node];17}18}else{19queue[index]=node;20}21}22}23});相关逻辑如下流程图:通过以上约定,设计者可以使用可视化编辑器配置不同部位的运动规则,大大提高了动画制作的效率。代码分析这部分主要分析拆解和还原动画的代码。它主要利用向量和偏三角函数的概念来计算三维空间中不同部分的位置。刚开始的时候需要记录下之前所有组合动作后各部分的位置。初始移动位置向量,和部件未组装移动前的初始位置向量,获取这两个位置向量的目的是将上述组合后的部件拆解移动,将部件恢复成一个完整的设备形态反汇编后的初始位置,两个位置向量都有重要作用,下面是相关伪代码:1//Vector3是HT封装的三维向量2constVector3=ht.Math.Vector3;3//记录第一个重要位置向量4node.a('relativeP3Vec',newVector3(node.p3()));5//节点当前部分node6//moveQueue是node之前的移动序列,是node节点的祖先节点7for(leti=0,l=moveQueue.length;i
