羅立宏 譚夏梅
(廣東工業(yè)大學(xué)數(shù)字媒體系 廣東 廣州 510006)
多年來,虛擬現(xiàn)實一直是信息領(lǐng)域科技工作者和產(chǎn)業(yè)界研究者非常感興趣的題目。而近年來,隨著互聯(lián)網(wǎng)的飛速發(fā)展,基于互聯(lián)網(wǎng)的虛擬現(xiàn)實技術(shù)(Web3D)也越來越吸引人們的關(guān)注。
虛擬現(xiàn)實技術(shù)的基本原理就是在計算機(jī)中預(yù)先建好一組三維模型,組成一個三維場景。而在場景中有一個或者多個攝像機(jī)對象,這些攝像機(jī)在場景中的位置可以被用戶通過鼠標(biāo)、鍵盤等外部設(shè)備控制。這樣,當(dāng)用戶操作外部設(shè)備時,場景中的攝像機(jī)對象就會隨之移動、旋轉(zhuǎn)。計算機(jī)通過該攝像機(jī)進(jìn)行實時渲染,就得出一系列快速切換的屏幕圖像,使得用戶感覺就像在虛擬的場景中漫游一樣。然而,如果軟件系統(tǒng)僅僅給出一個三維場景讓用戶漫游,而沒有其他導(dǎo)航和方向指示手段,用戶在場景中會很容易迷失方位。就像一個人初到一個陌生的地方,走不了幾段路,就會分不清東南西北了。國內(nèi)外的可用性研究都表明,除了三維場景,額外給出一個平面地圖,并在地圖中加入一個實時反映攝像機(jī)位置方向的圖形,會使系統(tǒng)變得更加友好和容易使用[1-2]。如果是直接使用C++、Java、C#等語言開發(fā)的單機(jī)版系統(tǒng),為了實現(xiàn)地圖二維導(dǎo)航,一般會對系統(tǒng)界面進(jìn)行合理設(shè)計,在界面中分出一部分作為地圖區(qū)域,而另一部分作為三維場景區(qū)域,三維場景的攝像機(jī)位置與地圖中的指示圖標(biāo)相互影響[3]。如果引擎支持多通道的話,也可以在原本屬于三維場景的區(qū)域劃出一塊顯示俯視圖的通道[4]。遺憾的是,這些單機(jī)板系統(tǒng)的方法不適合目前大多數(shù)的Web3D應(yīng)用。C++、Java等語言不適合直接用來開發(fā)Web3D項目。目前開發(fā)者們通常使用專用的支持嵌入或可發(fā)布成網(wǎng)頁的Web3D引擎或軟件工具,如VRML、Virtools、Unity3D、HTML5/WebGL、TurnTool等。對于二維導(dǎo)航功能的實現(xiàn),使用不同的引擎和工具,采用的方法有所不同。其中文獻(xiàn)[5-6]中研究了在VRML的Web3D應(yīng)用中實現(xiàn)二維導(dǎo)航的方法,文獻(xiàn)[7]說明了在Virtools中的實現(xiàn)思路,文獻(xiàn)[8]則討論了在Unity3D網(wǎng)絡(luò)游戲中的導(dǎo)航問題,而文獻(xiàn)[9]則提及了在WebGL中的實現(xiàn)方法。
另一方面,TurnTool也是一種強(qiáng)大的Web3D引擎,其功能豐富、互動性強(qiáng)、色彩還原性好[10]。與其他引擎相比,其最顯著的優(yōu)勢在于其壓縮比高。在Web3D應(yīng)用中,場景文件下載時間長短往往是用戶感受好壞的關(guān)鍵。而一個大型的場景,使用TurnTool制作一般都不會超過1.5M,下載時間的大幅縮短大大提升了用戶體驗。因此,在許多場合下,尤其強(qiáng)調(diào)色彩效果(如藝術(shù)應(yīng)用)或需要運(yùn)行大場景的Web3D應(yīng)用(如城市規(guī)模的Web3D應(yīng)用),TurnTool都是一個非常好的選擇[11]。然而,TurnTool是一個單通道的引擎,在其窗口范圍內(nèi)難以用另一個攝像機(jī)再開辟出一個區(qū)域用于二維導(dǎo)航,已有的研究在這方面也較少。本文在該方面進(jìn)行研究,提出一種使用外部Flash對象作為導(dǎo)航圖,依靠JavaScript實現(xiàn)對象間通信的方法,實現(xiàn)TurnTool Web3D應(yīng)用的二維導(dǎo)航。
帶有指示圖標(biāo)的導(dǎo)航圖實際上就是兩張圖片(指示圖標(biāo)圖片和地圖圖片)疊加在一起,其中指示圖標(biāo)圖片可在地圖上移動、旋轉(zhuǎn)。因為HTML中不允許兩張圖片疊在一起,因此需另想他法??梢栽O(shè)計一個Flash對象,在Flash中把圖片疊加在一起。其中指示圖標(biāo)圖片的位置和旋轉(zhuǎn)角可由ActionScript腳本語言實時控制。Flash可通過內(nèi)部函數(shù)和JavaScript與網(wǎng)頁實現(xiàn)通信[12]。具體方法有:(1) 通過GetURL動作加載外部頁面;(2) 通過fsCommand動作實現(xiàn)變量向外部傳遞;(3) 通過SetVariable()函數(shù)實現(xiàn)從外部傳入數(shù)據(jù)。所幸的是,大部分的Web3D引擎和插件都支持JavaScript的接口,通過JavaScript,可以獲取和控制場景中攝像機(jī)的行為。這樣,通過Flash與網(wǎng)頁JavaScript通信,就可以實現(xiàn)三維場景中攝像機(jī)對象參數(shù)的傳遞,從而使場景攝像機(jī)和導(dǎo)航圖的指示圖標(biāo)的行為相互影響。數(shù)據(jù)流如圖1所示。
圖1 二維導(dǎo)航數(shù)據(jù)流
因此,在網(wǎng)頁的設(shè)計中,頁面至少要包含兩個界面元素:三維場景對象和Flash導(dǎo)航圖對象。其他界面元素可根據(jù)實際需要而增加。對于用戶,需要先安裝瀏覽三維場景的插件,而導(dǎo)航圖所需的Flash Player插件則是一般計算機(jī)上都已安裝有的。
Flash導(dǎo)航圖的設(shè)計并不復(fù)雜,主要是要做好變量的傳遞和接收的準(zhǔn)備工作。
在Flash中,導(dǎo)入地圖和指示圖標(biāo)圖片,分別放在兩個層中。確保指示圖標(biāo)在地圖的上面。把指示圖標(biāo)圖片轉(zhuǎn)換為影片剪輯,為該影片剪輯的實例起個名字,如“Ptr”,以方便在程序中引用。另外利用文本工具創(chuàng)建三個文本框,同樣為每個文本框命名,如“TextX”、“TextY”、“TextR”,并設(shè)置三個變量與他們關(guān)聯(lián),如設(shè)置三個命名為PosX、PosY、Rot的變量。三個文本框用來接收外部傳入的數(shù)據(jù)。之所以為三個,是因為二維導(dǎo)航圖需要接收三維場景攝像機(jī)的x、y坐標(biāo)以及xy平面上的旋轉(zhuǎn)方向角。設(shè)置好后,在時間軸第一幀進(jìn)行如下設(shè)置:
TextX._visible = false;
TextY._visible = false;
TextR._visible = false;
this.onEnterFrame = function(){
Ptr._rotation = Rot;
Ptr._x = PosX;
Ptr._y = PosY;
}
其中前三行是把三個文本框隱藏起來,因為三個文本框只是接收數(shù)據(jù)所用,是不需用戶看見的。后五行是使指示圖標(biāo)的位置調(diào)整,圖標(biāo)的位置和旋轉(zhuǎn)方向角根據(jù)PosX、PosY、Rot的值而定。代碼把函數(shù)設(shè)置成為進(jìn)入幀的響應(yīng)函數(shù),F(xiàn)lash影片又設(shè)置為循環(huán)播放的,因此,程序段會不斷地被調(diào)用,達(dá)到實時更新的目的。
前文Flash中PosX、PosY、Rot三個變量的值是多少,是由頁面的JavaScript去決定的。首先JavaScript需通過場景引擎或插件的接口函數(shù)取得攝像機(jī)的數(shù)據(jù)。TurnTool與JavaScript通信的方法是利用string TNTDoCommand(string cmd)方法。其中參數(shù)cmd是形如“object.method(arg1,arg2,...,argn)”的TurnTool內(nèi)部函數(shù),string是方法的返回值。TNTDoCommand()的意義在于:從JavaScript中傳入命令,由TurnTool場景去執(zhí)行,執(zhí)行的結(jié)果又通過返回值string返回給JavaScript。如此,就實現(xiàn)了JavaScript和TurnTool插件對象的通信。
Web3D系統(tǒng)一般要做到這樣的效果:鼠標(biāo)左鍵一按下,場景漫游就開始,F(xiàn)lash導(dǎo)航圖的指示圖標(biāo)就隨著攝像機(jī)移動;鼠標(biāo)左鍵松開,攝像機(jī)和指示圖標(biāo)就不再動。為了實現(xiàn)這樣的效果,需要在JavaScript中開設(shè)一個定時器,鼠標(biāo)一按下,定時器就開始,鼠標(biāo)一松開,定時器就結(jié)束。利用定時器,JavaScript定時做數(shù)據(jù)查詢和發(fā)送工作。定時器的開設(shè)和運(yùn)行的過程可以按圖2所示的流程圖實現(xiàn)。
圖2 定時器設(shè)置與運(yùn)行流程
在定時進(jìn)行的數(shù)據(jù)處理的工作中,主要包含攝像機(jī)參數(shù)獲取,數(shù)據(jù)轉(zhuǎn)換和數(shù)據(jù)發(fā)送的工作,TurnTool場景可在定時流程中“數(shù)據(jù)處理”步驟位置插入如圖3所示的處理流程。
圖3 攝像機(jī)參數(shù)獲取流程
上述流程中,取得場景攝像機(jī)的x、y坐標(biāo)和旋轉(zhuǎn)角r的步驟需要利用TNTDoCommand方法與TurnTool進(jìn)行通信,以文本方式傳入要執(zhí)行的命令。查詢的結(jié)果返回JavaScript保存在x、y、r變量中。然后利用地圖的東南西北邊界坐標(biāo)和地圖的長寬像素計算指示圖標(biāo)在地圖中的相對位置。東南西北邊界坐標(biāo)和地圖寬高要根據(jù)實際情況賦值。視點(diǎn)在地圖中相對位置relX和relY的計算方法為:
(1)
(2)
式中:Xeast、Xwest、Ysouth、Ynorth為地圖的東西南北邊界坐標(biāo),Wm和Hm是地圖的寬和高。
JavaScript把relX、relY傳入Flash的步驟要使用SetVariable()方法。如前所述,PosX、PosY、Rot是Flash導(dǎo)航圖對象中三個隱藏文本框的對應(yīng)變量,通過這樣傳入數(shù)據(jù)后,三個變量就會取得新值,F(xiàn)lash進(jìn)行幀循環(huán)時,就會依照前面的ActionScript代碼更新指示圖標(biāo)的位置和旋轉(zhuǎn)角,從而使得導(dǎo)航圖的圖標(biāo)能跟著攝像機(jī)的運(yùn)動而實時變化。
如前所述的是三維場景攝像機(jī)位置控制導(dǎo)航圖指示圖標(biāo)。而二維導(dǎo)航圖一般還有另一功能,就是讓指示圖標(biāo)反過來也可以決定場景攝像機(jī)的位置。例如可以這樣設(shè)計:讓用戶在二維導(dǎo)航圖上雙擊某個感興趣的位置,指示圖標(biāo)馬上跳到這里,三維場景中的攝像機(jī)位置也隨之變化,跳轉(zhuǎn)到與指示圖標(biāo)相對應(yīng)的位置,用戶在場景中觀察到新的物體。
反向定位是與導(dǎo)航數(shù)據(jù)流相反的過程??梢赃@樣實現(xiàn):(1) 在Flash對象中增加一個響應(yīng)鼠標(biāo)雙擊的函數(shù),在函數(shù)中獲取指示圖標(biāo)的_x、_y屬性。然后用fscommand ()函數(shù)把屬性值發(fā)送到JavaScript。(2) 在JavaScript中創(chuàng)建和實現(xiàn)Flash_DoFSCommand(command, args)函數(shù),其中args參數(shù)就是傳過來的值。接收完_x、_y之后,利用已知的地圖東南西北邊界值反算出攝像機(jī)在三維空間中的對應(yīng)x、y坐標(biāo)。(3) JavaScript利用TNTDoCommand方法與TurnTool進(jìn)行通信,更新攝像機(jī)的位置。TNTDoCommand的參數(shù)是根據(jù)前面算出的x、y坐標(biāo)構(gòu)造的字串。由于篇幅所限,反向定位的詳細(xì)流程分析從略。
圖4是筆者利用上述方法實現(xiàn)的一個項目實例。程序總體構(gòu)架是一個HTML網(wǎng)頁,頁面的交互用JavaScript實現(xiàn),網(wǎng)頁打開時隱藏了IE的菜單和工具欄。如圖,網(wǎng)頁界面上有多種元素,除了左上方的三維場景對象和右下方的導(dǎo)航地圖對象外,還有提示文本、菜單按鈕、鏈接圖片等內(nèi)容。其中三維場景是TurnTool對象,導(dǎo)航地圖是Flash對象。在導(dǎo)航地圖中的右上角,白色眼睛形狀的圖標(biāo)就是導(dǎo)航指示標(biāo)志,眼睛的位置與三維場景中攝像機(jī)的位置對應(yīng),眼睛的開口朝向與攝像機(jī)的觀察方向?qū)?yīng)。如圖4所示,從指示標(biāo)志在地圖的方位可知,攝像機(jī)的當(dāng)前位置在三維場景的東北角,正朝西南方向觀察。該實例中也支持反向定位功能,在地圖中雙擊某處,指示圖標(biāo)將跳轉(zhuǎn)到該處,同時三維場景中的攝像機(jī)也跳轉(zhuǎn)至相應(yīng)的位置。
圖4 二維導(dǎo)航應(yīng)用實例
本文提出一種利用場景外部Flash作導(dǎo)航地圖,利用JavaScript進(jìn)行對象間通信實現(xiàn)了TurnTool Web3D場景的二維導(dǎo)航的方法。該方法能解決TurnTool引擎中難以實現(xiàn)二維導(dǎo)航功能的問題。另外,該方法還有一定的通用性,除了適用于TurnTool之外,只要某種Web3D引擎提供了和JavaScript通信的方式,就可以利用本文的方法實現(xiàn)場景的外部二維導(dǎo)航。
[1] 胡良柏, 王志紅, 韓立欽, 等. 網(wǎng)絡(luò)三維虛擬校園建設(shè)及應(yīng)用[J]. 測繪科學(xué), 2013, 38(1):168-170.
[2] Kim H K, Song T S, Choy Y C, et al. Guided Navigation Techniques for 3D Virtual Environment Based on Topic Map.[C]// Computational Science and ITS Applications-Iccsa 2005, International Conference, Singapore, May 9-12, 2005, Proceedings. DBLP, 2005:847-856.
[3] 王偉, 袁海峰, 陳桂蘭. 基于VRML的虛擬社區(qū)與二維地圖互響應(yīng)的研究[J]. 計算機(jī)仿真, 2009, 26(6):281-284.
[4] 陳勇, 馬純永, 陳戈. 基于VC/OpenGL的虛擬海大校園導(dǎo)航系統(tǒng)[J]. 計算機(jī)輔助設(shè)計與圖形學(xué)學(xué)報, 2007, 19(2):263-267.
[5] 劉小英,張健.三維校園虛擬現(xiàn)實平臺的設(shè)計與實現(xiàn)[J].湖北農(nóng)業(yè)科學(xué),2014,53(12):2909-2912.
[6] 劉碩,穆森,李蜀瑜.基于VRML的3D校園漫游導(dǎo)航系統(tǒng)的設(shè)計實現(xiàn)[J].計算機(jī)應(yīng)用與軟件,2013,30(1):196-199.
[7] Liu Y, Hu J W, Cui P Z. An Implementation Approach for Interoperation Between Virtools and HLA/RTI in Distributed Virtual Reality System[M]// Proceedings of the 6th International Asia Conference on Industrial Engineering and Management Innovation. Atlantis Press, 2016.
[8] Messaoudi F, Simon G, Ksentini A. Dissecting games engines: The case of Unity3D[C]// 2015 International Workshop on Network and Systems Support for Games (Net Games). Zagreb, CROATIA. 2015, 12, 03-04.
[9] 陳勇,張燦燦,劉洲, 等.WebGL在網(wǎng)頁室內(nèi)房型展示中的應(yīng)用[J].物聯(lián)網(wǎng)技術(shù),2016,6(11):74-75.
[10] Zhang Feng, Wang Weiwei. Research of Product Virtual Digital Model Design Based on TurnTool[C]// 2nd International Conference on Engineering Design and Optimization (ICEDO 2011). Zhejiang Univ, Ningbo Inst Technol, Ningbo, China.2011.8.
[11] Hwan Kim Jeong.A Study on a Technology of Building Experiment 3D Model House by Experience in Cyberspace of Virtual Reality[J].The Korean Journal of Art and Media, 2011,10(1):25-35.
[12] Reimers Stian, Stewart Neil. Presentation and response timing accuracy in Adobe Flash and HTML5/JavaScript Web experiments[J]. Behavior Research Methods, 2015, 47(2): 309-327.