2019 年 VR, AR, XR, 5G, 工業互聯網等名詞頻繁出如今咱們的視野中,信息的分享與虛實的結合已經成爲大勢所趨,5G 是新一代信息通訊技術升級的重要方向,工業互聯網是製造業轉型升級的發展趨勢。本文所講的 VR 是機械製造業與設備的又一次交流,當技術新星趕上製造潮流,無疑將成爲製造業,工控業等行業數字化轉型的重要驅動力。「5G + VR + 工業互聯網」必將成爲新的一年不變的話題,如何將當前工業中遇到的問題經過虛擬現實結合起來,讓咱們能夠更近的去交流,去感覺技術帶給咱們的變化。在今年蘋果的發佈會上,相信你們都知道蘋果的 5G 手機沒有問世,說明 5G 的應用和發展還處在快速發展的階段,可是手機結合 AR 功能的 APP 已經早就問世,5G 的速度加上 AR, VR 的身臨其境,讓咱們感覺到的不只僅是技術的革新,更是讓咱們感覺到技術在不一樣領域的實際應用場景,我相信 2020 年新的一年一定是 「5G + VR + 工業互聯網」 應用的又一個新的開始,本文接下來所講的就是 HT for Web 結合 WebVR 開發的具體應用案例。javascript
預覽地址:基於 HTML5 WebGL 與 WebVR 3D 虛擬現實的可視化培訓系統 http://www.hightopo.com/demo/...html
該系統共分爲三個實際應用層面:java
文章主要講解第三部分的 VR 模式,讓咱們瞭解如何結合 HT 來搭建 VR 場景。下面描述了 VR 中的主要操做,沒有進入 VR 的時候不會出現以下所說的六個按鈕操做,在點擊進入 WebVR 時,系統自動顯示出 VR 場景裏的六個操做按鈕,反之退出 VR 時,系統也會自動隱藏三維中的六個操做按鈕,VR 中的主要操做以下:node
操做切換: VR 中對設備有以下兩種操做,能夠經過右下角的模式按鈕點擊切換。git
HT 支持 obj 模型的導入,VR 場景所出現的設備零件均爲 obj 模型,因爲須要在以後進行設備的拆解,因此建模的時候須要分別對設備的各部分零件進行建模,而不是對設備總體進行建模,若是對設備總體建模那麼在 HT 的場景中就是一個 Data 節點,從而不能對零件進行拆解,若是拆解開來,那麼在 HT 中能夠加載多個 obj 則就有多個 Data 節點,有多個零件的 Data 節點以後就能夠對設備零件進行移動或者其它旋轉操做,具體的 Data 在 HT 的含義能夠參考 HT for Web 數據模型手冊github
以下爲導入場景中的 obj 模型:web
從上圖能夠看出咱們導入 obj 以後零件之間是分散的,因此須要對零件的初始位置進行調整,從而調整出一個由許多零件構成的完整設備,固然調整不可能經過代碼來調整,對應的有三維編輯器能夠調整,進行拖拖拽拽將不一樣零件拼湊起來,以下爲組合以後的設備總體:json
VR 場景的搭建是在第一步的基礎上進行搭建,上面所說的只在 VR 場景中顯示的按鈕也是在場景中進行搭建,在正常的場景時候咱們能夠隱藏掉對應的節點,node.s('3d.visible', false) 上面的代碼就是 HT 中在三維下面隱藏三維節點的代碼,由於進入 VR 和離開 VR 的時候,HT 內部會派發出對應的狀態告訴用戶此時已經進入 VR 或者此時已經離開 VR,相應僞代碼以下:瀏覽器
// graph3dView 爲 HT 中的三維場景視圖容器 // vr 獲取掛載在 graph3dView 上的 vr 對象 var vr = graph3dView.vr; vr.mp(function (e) { // property 對應的 vr 事件類型,detail 此時事件的狀態 var property = e.property; var detail = e.newValue; // present 表明此時進入或者離開 VR 場景 if (property === 'present') { // 此時 detail 爲 true 表示進入 vr,false 表示離開 vr if (detail) { // 執行顯示 vr 場景中須要顯示的節點操做 } else { // 執行隱藏 vr 場景中須要隱藏的節點操做 } } });
上面 property 在 HT 總共會派發出如下幾種類型,主要是包括 VR 的狀態和手柄的操做類型:安全
VR 中有一個關鍵的配置就是比例尺,由於 VR 裏面的單位是和現實中的長度單位是一致的,咱們戴着頭盔往前走 1m 那麼對應在 HT 三維場景中須要往前走多遠這須要一個對應關係,HT 提供的 VR 插件中會提供一個 measureOflength 的配置項,以下:
var vr_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 設備信息和 VR 手柄信息,若是返回爲空則說明獲取失敗。HT 只要經過執行 graph3dView.vr.enable = true 就能夠開啓 VR,固然用戶不用執行該代碼,HT 提供的 VR 插件也會提供對應的配置項 vrEnable: true 來表明開啓 VR,對應的配置也掛在在上面的 vr_config 對象內,以下:
var vr_config = { measureOflength: 0.01, vrEnable: true, // 表明開啓 VR }
在該展現的系統中有直接在 VR 中切換場景的功能,因爲每一個場景的 vr_config 中的配置項值可能會有差異,例如第一個場景的 measureOflength 比例尺的大小爲 0.01,可能第二個場景的比例尺大小 measureOflength 就變成了 0.02,因此 VR 插件提供一個銷燬的功能,用來銷燬上一個場景的資源,銷燬場景的資源包括清空上一個場景的全部節點,因此在加載新的場景時,不須要再執行清空場景節點的操做,即不須要執行 dataModel.clear(),由於 VR 提供的銷燬功能已經都清空了,手柄和射線都是場景中的一個 Data 節點,因此在新的場景不須要額外的清除手柄和射線這兩個節點,故插件幫你管理場景的節點。在調用銷燬功能以後,能夠調用 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.02 window.vr_config.measureOflength = 0.02; // 修改新的 VR 場景初始化視角 window.vr_config.vrEye = ht.Default.clone(g3d.getEye());; // 再次初始化 VR 場景 graph3dView.initVRForScene() });
固然 HT 提供的 VR 插件還有不少的配置項,方便用戶更好的調整 VR 場景,包括刷地形,場景移動方式,場景操做方式均可以經過配置進行配置,利用 HT 進行 VR 搭建主要流程以下流程圖所示:
經過上面的流程圖,咱們大致能夠了解配合 HT 提供的 VR 插件如何進行快速的搭建 VR 場景。
目前谷歌瀏覽器和火狐瀏覽器都很友好的支持 VR,能夠經過火狐官網提供的 WebVR Demo 在線感覺下官方提供的 VR 場景。
從文章前面的部分效果圖能夠看到咱們每一個場景的設備都有拆解,而且每一個設備的零件數量,零件位置,零件拆解的方向,偏移的長短都是不一致的,因此不可能經過代碼來將上面的偏移長短,偏移方向寫死,須要制定一套拆解規則來幫助咱們能夠更方便製做每一個場景的拆解動畫,這樣只須要設計師根據與程序約定好的拆解規則進行配置就能夠配置出不一樣場景不一樣設備的拆解動畫。該系統的拆解分爲兩種狀況:
單體移動示意圖以下:
組合移動示意圖以下:
在 HT 中能夠經過 data.setDisplayName('名稱') 來給節點設置名稱,這裏約定經過不一樣設備的名稱,來獲取到不一樣設備的偏移信息,例如 data.setDisplayName('1-0.5-1000') 該名稱就是和設計師約定好的配置規則,1 表明拆解步驟的第一步執行,固然場景中能夠有多個 1,即第一步同時拆解這些零件。0.5 表明朝着父節點的方向偏移本身位置和父節點位置鏈接線長度的 50%。1000 表明偏移的過程持續 1000 毫秒,固然以後能夠約定旋轉以及旋轉的角度等信息。設計師知道這些配置規則以後即可以經過可視化編輯器進行不一樣零件的配置,這樣程序方面只須要寫一套通用的邏輯就能夠對不一樣的設備進行拆解和還原。
系統中維護了一個隊列和一個棧,隊列用來記錄拆解順序,棧用來記錄還原順序。拆解的過程經過配置的序號,按順序推動隊列,採用隊列的數據結構即是由於隊列先進先出的特色,第一個壓入隊列的零件則第一個執行,最後壓入隊列的零件最後一個執行拆解順序。拆解出隊列的零件則同時壓入棧,採用棧記錄還原順序是由於先進後出的特色,即第一個執行完拆解的零件,在還原的時候倒是最後一個執行還原的動做。因此上述採用的不一樣數據結構即是爲了更好的記錄數據。如下爲相關 js 僞代碼:
// 記錄拆解順序 const queue = []; // 記錄還原順序 const stack = []; // each 循環中用來記錄拆解隊列 queue 順序 dataModel.each((node) => { const displayName = node.getDisplayName(); if (displayName) { const [ index, distancePer, during ] = displayName.split('-'); if (index !== void 0) { if (queue[index]) { if (queue[index] instanceof Array) { queue[index].push(node); } else { const tempNode = queue[index]; queue[index] = [ tempNode, node ]; } } else { queue[index] = node; } } } });
相關邏輯以下流程圖:
經過上面的約定,設計師可使用可視化編輯器來配置不一樣零件的移動規則,大大提升了動畫的製做效率。
該部分主要對拆解還原動畫的代碼進行分析,主要採用向量和部分三角函數的概念來計算不一樣零件在三維空間的位置,初始的時候須要記錄下每一個零件在前面全部組合移動以後的初始移動位置向量,以及零件沒有組合移動以前的初始位置向量,獲取這兩個位置向量目的是一是爲了零件拆解在前面所說組合以後移動,和零件在拆解以後恢復到一整個設備形態的初始位置,兩個位置向量都有重要的做用,如下爲相關僞代碼:
// Vector3 爲 HT 封裝的三維向量 const Vector3 = ht.Math.Vector3; // 記錄第一個重要位置向量 node.a('relativeP3Vec', new Vector3(node.p3())); // node 當前零件節點 // moveQueue 爲移動順序在 node 以前的,而且爲 node 節點的祖先節點 for (let i = 0, l = moveQueue.length; i < l; i++) { const moveNode = moveQueue[i], parentMoveNode = moveNode.getParent(); if (parentMoveNode) { const[ , distancePer ] = moveNode.getDisplayName().split('-'); moveNode.a('defP3', moveNode.p3()) moveNode.p3(new Vector3().lerpVectors(new Vector3(moveNode.p3()), new Vector3(parentMoveNode.p3()), distancePer).toArray()); } } // 記錄組合節點移動以後的第二個重要相對位置向量 node.a('relativeP3Vec', new Vector3(node.p3())); // 逆序還原組合的父節點位置 for (let i = moveQueue.length - 1; i >= 0; i--) { const moveNode = moveQueue[i]; moveNode.p3(moveNode.a('defP3')); moveNode.a('defP3', undefined); }
因爲在場景拆解過程當中須要設置設備零件節點不可選擇,因此須要記錄下不可選擇以前的零件是否可選擇狀態,用來恢復節點初始狀態,相關僞代碼以下:
dm3d.each((node) = >{ node.a('defSelectable', node.s('3d.selectable')); });
文中所示的線框效果爲 HT 核心包支持的線框模式,能夠經過以下代碼進行配置:
dm3d.each((data) = >{ if (data.s('shape3d') && data.s('shape3d').startsWith('models/')) { data.s({ 'shape3d.transparent': true, 'shape3d.opacity': 0, // 目的爲隱藏本來的模型 'wf.geometry': true, // 開啓線框模式 'wf.combineTriangle': 2, // 線框三角面合併類型 'wf.color': 'rgba(96,172,252,0.3)' // 線框顏色 }); } });
上述 wf.combineTriangle 主要包括
本系統採用的 VR 硬件設備爲 HTC VIVE 接下來說的是安裝 HTC VIVE 的過程和步驟。
到 HTC 官網找到鏈接指南,而後按照步驟安裝便可,咱們只需看如下截圖部分的目錄便可。
到 Steam 官網下載 Steam,下載完 Steam 能夠在 Steam 中下載 Stream VR。
打開 Stream VR,會出現如下畫面,這是用來表示 HTC VIVE 頭顯的工做狀態的,經過圖標咱們便可查看頭顯、手柄控制器和定位器等配件的工做狀況。
若是您的房間位置比較大能夠選擇第一項,我選擇的模式爲第二項,站立模式。建議選擇一種房間規模,能夠完整的進行設置。
該步爲設置頭盔默認的朝向。
將兩個手柄控制器放置在定位器可視範圍內,而後點擊電腦屏幕上的按鈕「校準地面」,等待系統校準
設置完畢以後能夠進入 Steam VR 自帶的房間進行體驗。
當人們談起 5G 時代的新應用,VR、AR 老是一大熱門話題。4G 時代移動網絡已經足以承載起高清視頻,那麼 5G 時代理所固然就能傳輸數據量更大的沉浸式 VR、AR 影像。所以,很多人將 5G 視爲 VR、AR 崛起的踏板,隨時隨地身臨天涯海角,彷佛並不是是高不可攀的夢。當前 4G 網絡應用在 VR/AR 上會帶來大約 70ms 的時延,這個時延會致使體驗者存在眩暈感,而 5G 數據傳輸的延遲可達到毫秒級,能夠有效解決數據時延帶來的眩暈感,有助於 VR/AR 的大規模應用。目前隨着 5G 網絡的逐漸普及,VR/AR 產業正逐步走向復甦,市場熱情在逐漸升溫,虛擬現實遊戲、虛擬現實現場直播等都是 5G 在 VR/AR 上的具體應用。在科技進步的今天,安全也是一個重要的話題,VR 結合仿真的應用也是大勢所趨,仿真可讓用戶真實切身感覺,例如消防預警,管道預警,可讓用戶在 VR 世界中體驗消防滅火等消防員的操做,讓用戶沉浸在 VR 世界中感覺到火災來臨時怎麼進行實際操做。因此 VR 帶來的應用遠遠不止仿真,模擬等體驗,更多帶來的是能爲人們提供真實的實際做用,而不是噱頭。
程序手機端運行截圖: