呂建軍, 徐仁桐, 鄭菊艷
(上海船舶工藝研究所, 上海 200032)
隨著信息技術(shù)的發(fā)展,虛擬仿真實(shí)訓(xùn)在教育培訓(xùn)行業(yè)的應(yīng)用越來越廣泛。近年來,國內(nèi)許多高校都建立了虛擬仿真實(shí)驗(yàn)室[1],用于教學(xué)、培訓(xùn)和展示。利用虛擬仿真技術(shù)搭建具備視、聽、觸等多種感知的虛擬試驗(yàn)環(huán)境,培訓(xùn)人員可通過使用交互設(shè)備進(jìn)行試驗(yàn)?zāi)M,與虛擬對象實(shí)時(shí)交互,有效地提高實(shí)訓(xùn)效果。然而,目前大部分虛擬試驗(yàn)都在實(shí)驗(yàn)室進(jìn)行,實(shí)驗(yàn)室場地和設(shè)備有限,實(shí)訓(xùn)教學(xué)的廣度和深度易受限制。如果采用網(wǎng)絡(luò)方式,將虛擬試驗(yàn)發(fā)布到網(wǎng)絡(luò)端,學(xué)員就可以隨時(shí)隨地地參與到仿真試驗(yàn)中,快速地獲取專業(yè)知識和技能,且可在試驗(yàn)后臺評定成績,有效監(jiān)控實(shí)訓(xùn)效果。
Unity 3D作為一款市場占有率較高的仿真引擎,主要應(yīng)用于PC端和移動端。新版Unity 3D提供了對WebGL技術(shù)的支持,能夠?qū)C端和移動端的軟件遷移至WebGL網(wǎng)頁端,但網(wǎng)頁端對模型的數(shù)量要求苛刻,模型面片達(dá)到一定數(shù)量就會卡頓。本文采用內(nèi)存分配優(yōu)化技術(shù)進(jìn)行模型動態(tài)加載,可大幅提升軟件性能。利用Unity 3D開發(fā)一套基于WebGL的網(wǎng)絡(luò)版海洋平臺虛擬仿真系統(tǒng)[2],以海洋石油981數(shù)字樣船為建造對象,進(jìn)行海洋平臺組立建造、分段建造、總段建造、搭載、下水、試驗(yàn)等網(wǎng)絡(luò)模塊的開發(fā),通過后臺服務(wù)器管理系統(tǒng)控制仿真任務(wù)內(nèi)容和仿真工藝信息,便于統(tǒng)一管理。
系統(tǒng)主要針對海洋平臺建造場景及交互對象進(jìn)行三維建模[3],根據(jù)建造工藝規(guī)則,將船體零部件按照工藝順序進(jìn)行節(jié)點(diǎn)拆解,設(shè)計(jì)數(shù)字樣機(jī)控制工藝步驟,同時(shí)控制場景模型的動作,并借助人機(jī)交互界面,進(jìn)行工藝信息的介紹,幫助培訓(xùn)人員熟悉建造工藝細(xì)節(jié)。
系統(tǒng)主要功能[4]包括用戶信息管理、仿真任務(wù)管理、三維建造交互等。
(1) 用戶信息管理。對用戶權(quán)限進(jìn)行管理,主要包括管理員、教師、培訓(xùn)人員。用戶個(gè)人信息主要記錄用戶仿真操作的歷史成績及每個(gè)步驟的細(xì)節(jié)。
(2) 仿真任務(wù)管理。教師可控制仿真任務(wù)數(shù)量,讓培訓(xùn)人員登錄至指定模塊,便于教學(xué)管理。
(3) 三維建造交互??刂屏悴考?jié)點(diǎn)按照正確的順序進(jìn)行建造仿真。在建造過程中,可彈出關(guān)聯(lián)性的考題供測評。在仿真任務(wù)完成后,彈出操作成績及工藝流程圖。
該系統(tǒng)基于B/S架構(gòu)開發(fā),主要由服務(wù)端和Web客戶端組成。服務(wù)端主要負(fù)責(zé)海洋平臺仿真數(shù)據(jù)和虛擬場景管理。Web客戶端用于仿真實(shí)訓(xùn)操作。系統(tǒng)結(jié)構(gòu)如圖1所示。
圖1 系統(tǒng)結(jié)構(gòu)示例
設(shè)計(jì)一套用戶界面(User Interface,UI)框架,使所有面板繼承于公共基類BasePanel,并通過DoTween動畫組件控制界面切換的動態(tài)效果。BasePanel面板有頁面顯示、暫停、繼續(xù)、退出等4種狀態(tài)。將狀態(tài)函數(shù)寫成虛函數(shù)并在子類中實(shí)現(xiàn)。
通過UIManager對Panel進(jìn)行統(tǒng)一管理,其主要功能如下:
(1) 保存所有界面面板信息,通過Json讀取Panel的名稱、路徑、預(yù)設(shè)等信息;
(2) 進(jìn)行面板切換控制,運(yùn)用堆棧的PushPanel、PopPanel方法進(jìn)行頁面切換;
(3) 管理所有面板的動態(tài)實(shí)例。
系統(tǒng)界面邏輯設(shè)計(jì)如圖2所示。
圖2 界面邏輯設(shè)計(jì)
WebGL是一種三維繪圖協(xié)議,為網(wǎng)頁添加OpenGL特性支持,從而實(shí)現(xiàn)3D圖形渲染[5]。與使用WebPlayer需要先安裝瀏覽器插件相比,在使用WebGL時(shí),無需額外的插件支撐便可實(shí)現(xiàn)Web交互式三維渲染,提高軟件使用的便捷性。
在Unity中,WebGL通過il2cpp.exe將.NET IL中間語言編譯成C++源碼,然后通過各平臺的C++編譯器進(jìn)行編譯,達(dá)到跨平臺訪問的目的。對于C++源碼,Unity支持asm.js和WebAssembly(或稱“wasm”)兩種轉(zhuǎn)化方式,asm.js 是文本格式,wasm是二進(jìn)制格式。考慮到二進(jìn)制運(yùn)行速度更快、體積更小,采用wasm方式進(jìn)行轉(zhuǎn)化。wasm是基于堆棧虛擬機(jī)的二進(jìn)制格式,通過編譯程序源碼可將程序部署在Web端。以Windows平臺為例,利用底層虛擬機(jī)LLVM Emscripten編譯器將C++編譯成.wasm文件。wasm不能直接被瀏覽器識別,需要通過JavaScript接口進(jìn)行頁面加載,從而實(shí)現(xiàn)3D圖形網(wǎng)頁渲染。WebGL原理如圖3所示。
圖3 WebGL原理
海洋平臺建造仿真工藝信息是培訓(xùn)的重點(diǎn),在實(shí)際培訓(xùn)教學(xué)中,可能會根據(jù)需要進(jìn)行動態(tài)編輯修改,例如增加工藝細(xì)節(jié)、圖文描述、工藝知識點(diǎn)考題等,以達(dá)到多樣化教學(xué)的目的。針對海洋平臺建造對象和階段進(jìn)行分類,設(shè)計(jì)工藝編輯功能,可動態(tài)控制仿真邏輯工藝,Web前端可實(shí)時(shí)獲取最新的工藝數(shù)據(jù)。將仿真節(jié)點(diǎn)按照名稱進(jìn)行排列,并設(shè)定順序碼,添加工藝描述,或增加圖片路徑,然后存儲為Json格式文件。Web前端通過JsonUtility.ToJson解析Json文件,將其轉(zhuǎn)成目標(biāo)類,并根據(jù)名稱綁定至模型結(jié)構(gòu)樹相應(yīng)節(jié)點(diǎn),從而控制仿真工藝。具體流程如圖4所示。
圖4 工藝編輯流程
為便于控制船體零部件節(jié)點(diǎn),使不同種類的零部件操作具有相同的交互機(jī)制,需設(shè)計(jì)虛擬樣機(jī)。將Json數(shù)據(jù)和模型輸入虛擬樣機(jī),經(jīng)過模型、數(shù)據(jù)的關(guān)聯(lián)處理,產(chǎn)生交互式的建造邏輯[6],形成具有建造順序、吊裝路徑、吊裝動畫、工藝描述于一體的建造仿真流程[7],如圖5所示。
圖5 虛擬樣機(jī)建造仿真流程
在Unity發(fā)布程序至Web端時(shí),船體模型量巨大會導(dǎo)致程序包體積大,這樣在瀏覽器加載時(shí)易導(dǎo)致內(nèi)存消耗過大而崩潰。在Unity WebGL程序運(yùn)行時(shí),瀏覽器會分配多個(gè)內(nèi)存空間區(qū)域(見圖6),其中DOM、Unity堆、資源數(shù)據(jù)和代碼會在訪問網(wǎng)頁時(shí)一直存儲在內(nèi)存中,而其他的例如AssetBundle、WebAudio等資源會根據(jù)用戶選擇按需加載。為此,除了將資源數(shù)據(jù)和代碼量控制到最小外,通常還有減小Unity堆大小和數(shù)據(jù)動態(tài)加載2種方式優(yōu)化Unity內(nèi)存分配。
圖6 Unity WebGL程序內(nèi)存分配
2.4.1 Unity堆控制
Unity堆是用來存儲對象、組件、紋理材質(zhì)、Shader等的內(nèi)存,其內(nèi)存分配情況如圖7所示。
圖7 Unity堆內(nèi)存結(jié)構(gòu)
在程序運(yùn)行中,動態(tài)內(nèi)存區(qū)域會不斷地存儲數(shù)據(jù)和回收數(shù)據(jù)。在程序發(fā)布前,需要事先設(shè)定Unity堆的大小,其關(guān)鍵代碼為buffer=new ArrayBuffer(TOTAL_MEMORY),其中TOTAL_MEMORY為設(shè)定的大小。內(nèi)存設(shè)定過大,易造成內(nèi)存溢出;內(nèi)存設(shè)置過小,易造成程序執(zhí)行緩慢。為此,有必要設(shè)定一個(gè)合理的數(shù)值控制內(nèi)存量。考慮到Unity無法直接得知程序占用內(nèi)存大小,可采用Emscripten編譯器先獲取Unity堆內(nèi)存的實(shí)際大小,再設(shè)定一個(gè)合理的數(shù)值。其中,Emscripten編譯器采用jslib庫獲取內(nèi)存實(shí)際占用值(靜態(tài)內(nèi)存+棧內(nèi)存+動態(tài)內(nèi)存)。運(yùn)行過程如圖8所示。
圖8 Unity堆內(nèi)存大小獲取示例
2.4.2 數(shù)據(jù)動態(tài)加載
采用數(shù)據(jù)動態(tài)加載技術(shù)可直觀地減小場景數(shù)據(jù)資源包的大小,減少瀏覽器加載負(fù)擔(dān)。Unity動態(tài)加載資源有Resources和AssetBundle兩種方式。Resources資源只能打包至程序中發(fā)布,并不會減小場景數(shù)據(jù)資源包大小??刹捎肁ssetBundle作為數(shù)據(jù)加載資源,該方式的優(yōu)點(diǎn)是可將場景中的對象、組件、材質(zhì)、場景樹都打包為.assetbundle包,而不需要單獨(dú)加載各獨(dú)立元素再合并。可將不同場景數(shù)據(jù)分別打包為.assetbundle,并存放至服務(wù)端指定目錄下。Web前端在初始加載時(shí)只加載內(nèi)存較小的基礎(chǔ)程序,當(dāng)用戶選擇指定場景后,加載相應(yīng)的場景包,關(guān)鍵代碼如下:
//path為assetbundle的路徑
using (UnityEngine.Networking.UnityWebRequest uw =UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(path))
{
yield return uw.SendWebRequest();
if (uw.isNetworkError || uw.isHttpError)
{
print(uw.error);
}
else
{
AssetBundle ab = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(uw);//得到ab包
UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName);//sceneName為目標(biāo)場景名
ab.Unload(false);//釋放AssetBundle文件內(nèi)存鏡像
}
}
通過該代碼,可將不同場景數(shù)據(jù)資源包動態(tài)加載至本機(jī)內(nèi)存,實(shí)現(xiàn)按需加載,在加載完畢后及時(shí)釋放內(nèi)存。
為驗(yàn)證該系統(tǒng)的實(shí)際效果,將其應(yīng)用至高校的海洋平臺建造仿真實(shí)驗(yàn)室中。通過搭建校內(nèi)局域網(wǎng)、部署后臺服務(wù)端,用戶可直接通過網(wǎng)址訪問前后端程序。該系統(tǒng)加載快、運(yùn)行流暢、工藝流程清晰,能夠滿足教學(xué)培訓(xùn)要求。系統(tǒng)應(yīng)用效果如圖9和圖10所示。
圖9 服務(wù)端結(jié)構(gòu)樹
圖10 三維虛擬仿真界面
系統(tǒng)采用內(nèi)存分配后可進(jìn)行瀏覽器內(nèi)存優(yōu)化,但由于每個(gè)瀏覽器都有最大支持內(nèi)存限制,因此當(dāng)開啟多個(gè)WebGL仿真軟件時(shí),瀏覽器可能會出現(xiàn)崩潰現(xiàn)象。解決方法是建議從仿真模型本身著手,采用細(xì)節(jié)層次、低模高烘等技術(shù)優(yōu)化模型本身,再配合內(nèi)存分配優(yōu)化方法,可有效減少瀏覽器的程序包加載量,提升瀏覽器的整體流暢度。
以海洋石油981數(shù)字樣船建造為研究對象,基于Unity WebGL進(jìn)行網(wǎng)頁端仿真程序的開發(fā)。將復(fù)雜的船舶建造流程以三維可視化的方式模擬出來,有助于學(xué)員深入了解船舶整體結(jié)構(gòu)和建造工藝信息,從而快速掌握船舶建造知識。突破Web端開發(fā)過程中的WebGL渲染、內(nèi)存分配優(yōu)化等技術(shù)難點(diǎn),并針對海洋平臺建造仿真,創(chuàng)新性地設(shè)計(jì)工藝編輯器和虛擬樣機(jī),方便系統(tǒng)的開發(fā)和后期擴(kuò)展、維護(hù)。系統(tǒng)應(yīng)用后證明,Web端海洋平臺建造虛擬仿真系統(tǒng)能夠基本滿足教學(xué)要求[8],同時(shí)所提出的關(guān)鍵技術(shù)解決方案對Unity網(wǎng)頁端開發(fā)起到一定的參考作用。