李蘭
(山西師范大學(xué)現(xiàn)代文理學(xué)院,臨汾041004)
VRML 是跨平臺(tái)的虛擬現(xiàn)實(shí)建模語言,在網(wǎng)絡(luò)環(huán)境中構(gòu)建三維虛擬場(chǎng)景[1]。VRML 文件規(guī)模較小,可以直接嵌入到HTML 文件中去,在一般的瀏覽器中安裝適當(dāng)?shù)牟寮涂梢猿臻g的瀏覽行為仿真,因而在網(wǎng)絡(luò)制造、虛擬漫游以及計(jì)算機(jī)動(dòng)畫中得到廣泛的應(yīng)用[2]。
Java 是跨平臺(tái)的網(wǎng)絡(luò)分布式計(jì)算環(huán)境中廣泛使用的編程語言,具有強(qiáng)大的編程能力。Java Applet(Java小應(yīng)用程序)是一種可以加載到Web 頁面,由瀏覽器調(diào)用執(zhí)行的Java 程序,可使Web 頁面更加動(dòng)態(tài)、更具交互性[3]。VRML 與Java Applet 的結(jié)合能夠真正意義上實(shí)現(xiàn)動(dòng)態(tài)交互的虛擬場(chǎng)景[4]。
交互功能是VRML 的一個(gè)重要特點(diǎn),通過交互能使用戶在虛擬場(chǎng)景中有身臨其境的感覺。交互可通過三種方式實(shí)現(xiàn):傳感器節(jié)點(diǎn)的交互,Script 節(jié)點(diǎn)的交互及EAI 接口的交互。
VRML 中使用傳感器節(jié)點(diǎn)(時(shí)間傳感器除外)完成感知瀏覽者的操作或者在場(chǎng)景中的觀察位置,然后對(duì)此做出反應(yīng)的交互功能。常用的有觸摸傳感器Touch-Sensor 節(jié)點(diǎn)感知用戶鼠標(biāo)觸發(fā)動(dòng)作;平面?zhèn)鞲衅鱌lane-Sensor 節(jié)點(diǎn)感知用戶鼠標(biāo)拖曳動(dòng)作;圓柱體傳感器CylinderSensor 節(jié)點(diǎn)感知用戶繞中心軸拖拽旋轉(zhuǎn)的動(dòng)作;接近傳感器ProximitySensor 節(jié)點(diǎn)感知用戶所在方位;碰撞傳感器Collision 節(jié)點(diǎn)感知造型與用戶發(fā)生碰撞動(dòng)作,傳感器一旦感應(yīng)到事件的發(fā)生,將不斷輸出該事件到目標(biāo)節(jié)點(diǎn),從而觸發(fā)目標(biāo)的動(dòng)態(tài)效果,使虛擬現(xiàn)實(shí)效果更加逼真,但傳感器能感應(yīng)的事件有限,因而交互行為也有限[5]。
VRML 腳本節(jié)點(diǎn)Script 用以描述一個(gè)由用戶自定義的傳感器或插補(bǔ)器,通過URL 域包含一組瀏覽器支持的任何一種語言編寫的程序或叫腳本,在產(chǎn)生出事件之前執(zhí)行計(jì)算或處理,并將結(jié)果發(fā)送到VRML 場(chǎng)景,可以使交互更加靈活[6]。
Script 節(jié)點(diǎn)只能綁定程序按照預(yù)定規(guī)則改變場(chǎng)景,實(shí)現(xiàn)靜態(tài)虛擬效果及簡(jiǎn)單交互等功能。對(duì)虛擬場(chǎng)景與用戶的交互、多用戶間的交互及網(wǎng)絡(luò)通訊能力等更具一般性的行為,則需利用EAI 接口的交互實(shí)現(xiàn)。EAI的基本思想是外部程序能夠通過VRML 事件模型訪問VRML 場(chǎng)景節(jié)點(diǎn),從而控制VRML 場(chǎng)景,外部程序即Java Applet,它與VRML 同在HTML 頁面中,建立了與VRML 的通信接口,并可與外部數(shù)據(jù)庫建立連接,從而使用戶與虛擬場(chǎng)景實(shí)現(xiàn)動(dòng)態(tài)交互,真正成為VRML 中的一個(gè)角色,一個(gè)參與者[7]。
基于VRML 和Java Applet 相結(jié)合的動(dòng)態(tài)交互場(chǎng)景的整體架構(gòu)如圖1 所示。整個(gè)系統(tǒng)分為3 層:應(yīng)用層、實(shí)現(xiàn)層和資源層。其中應(yīng)用層是HTML 界面,VRML 和Java Applet 置于同Web 頁面,運(yùn)行時(shí)則在同一個(gè)瀏覽器環(huán)境中。VRML 提供虛擬現(xiàn)實(shí)的三維場(chǎng)景,Java Applet 則提供實(shí)現(xiàn)用戶交互的控件,用以控制場(chǎng)景和實(shí)時(shí)顯示動(dòng)態(tài)參數(shù);實(shí)現(xiàn)層用Java Applet 編制的程序作為仿真控制的引擎,一方面連接數(shù)據(jù)庫,把數(shù)據(jù)庫的數(shù)據(jù)傳送到場(chǎng)景中,另一方面建立與VRML 場(chǎng)景的接口,用來驅(qū)動(dòng)場(chǎng)景的動(dòng)態(tài)生成與用戶的交互等;資源層是用數(shù)據(jù)庫管理系統(tǒng)搭建的數(shù)據(jù)庫,可以存儲(chǔ)并更新場(chǎng)景的全部數(shù)據(jù)參數(shù)。其中Java Applet 與數(shù)據(jù)庫的連接接口用JDBC 來完成,Applet 與VRML 的接口用EAI 技術(shù)來實(shí)現(xiàn)。

圖1 動(dòng)態(tài)交互場(chǎng)景的整體架構(gòu)
系統(tǒng)采用的是瀏覽器/服務(wù)器模式,系統(tǒng)運(yùn)行用到的程序代碼和數(shù)據(jù)均在服務(wù)器上存放,客戶端只需要安裝瀏覽器和必要的VRML 插件。HTML 界面包括兩部分:VRML 場(chǎng)景和Java Applet 控件,其中Java Applet控件包括按鈕、文本框等。HTML 文檔中Java Applet程序.class 使用

圖2 工作流程
在用戶界面上,首先點(diǎn)擊“連接數(shù)據(jù)庫”按鈕進(jìn)行初始化,完成數(shù)據(jù)庫的連接操作,系統(tǒng)返回可供Java Applet 程序使用的靜態(tài)場(chǎng)景數(shù)據(jù)和動(dòng)態(tài)運(yùn)動(dòng)空間位置等參數(shù),并動(dòng)態(tài)生成靜態(tài)場(chǎng)景。用戶點(diǎn)擊“開始”按鈕,Applet 讀取并傳輸數(shù)據(jù)至VRML 場(chǎng)景,進(jìn)行動(dòng)態(tài)交互;同時(shí)把相關(guān)的數(shù)據(jù)信息顯示在用戶界面。點(diǎn)擊“停止”按鈕,中止此次仿真。
EAI 接口定義了一套針對(duì)VRML 瀏覽器的Java類,其中類vrml external Browser 至關(guān)重要,是實(shí)現(xiàn)EAI訪問的基礎(chǔ)[9]。瀏覽器類(Browser)實(shí)際上是VRML 場(chǎng)景的一個(gè)Java 封裝,包括全部的腳本語言接口,重要的是包含有g(shù)etNode()方法。通過該方法可獲得一個(gè)Node 類的實(shí)例,即為VRML 場(chǎng)景中造型節(jié)點(diǎn)在Java Applet 中的對(duì)應(yīng)節(jié)點(diǎn)。因此通信之初要先創(chuàng)建一個(gè)瀏覽器類的實(shí)例,方法如下所示:
Browser browser=Browser.getBrowser();
Browser 類實(shí)例化后,EAI 即可訪問VRML 場(chǎng)景的節(jié)點(diǎn)、往eventIn 域發(fā)送事件、eventOut 域發(fā)出事件及監(jiān)聽eventOut 域,下面分別闡述。
(1)訪問節(jié)點(diǎn)
VRML 場(chǎng)景中的節(jié)點(diǎn)通過瀏覽器類的getNode()方法實(shí)例化,其eventIn 和eventOut 則通過Node 類的getEventIn()和getEventOut()方法實(shí)例化為Applet 中的對(duì)應(yīng)體,將域名以字符串參數(shù)傳入,實(shí)例化為EventIn 或者是EventOut。ExposedField 域也允許訪問,事件入口需在域名前加set_作為前綴,事件出口需在域名后加_changed 作為后綴。三維場(chǎng)景中已經(jīng)定義moxing 節(jié)點(diǎn),其實(shí)例的獲得方法如下所示:
Node moxing=browser.getNode(“moxing”);
(2)往eventIn 域發(fā)送事件
將被訪問節(jié)點(diǎn)的eventIn 類實(shí)例化,即可向場(chǎng)景中該節(jié)點(diǎn)發(fā)送事件,由于eventIn 是抽象類,必須先強(qiáng)制轉(zhuǎn)換成合適的如EventInSFVec3f 等eventIn 類的子類,才可以提供發(fā)送事件的方法。例設(shè)置moxing 節(jié)點(diǎn)的EventInSFVec3f 類的scale 輸入值,如下所示:
EventInSFVec3f scale=(EventInSFVec3f)moxing.getEventIn(“set_scale”);
(3)eventOut 域發(fā)出事件
將被訪問節(jié)點(diǎn)的EventOut 類實(shí)例化,即可獲取場(chǎng)景中目標(biāo)節(jié)點(diǎn)eventOut 域的當(dāng)前值,也可在eventOut域發(fā)出事件時(shí)設(shè)置callback()方法。eventOut 類同eventIn 一樣也是抽象類,必須先強(qiáng)制轉(zhuǎn)換成合適的eventOut 類的子類,才可獲取eventOut 當(dāng)前值的方法。例取得moxing 節(jié)點(diǎn)的EventInSFVec3f 類的scale輸出值,如下所示:
scale=((EventOutSFVec3f)moxing.getEventOut(“scale_changed”))).getValue();
(4)監(jiān)聽eventOut 域
當(dāng)場(chǎng)景目標(biāo)節(jié)點(diǎn)的eventOut 域有新值產(chǎn)生時(shí),EAI提供的監(jiān)聽機(jī)制可使Applet 實(shí)時(shí)反應(yīng)并進(jìn)行相應(yīng)的后續(xù)處理。具體實(shí)現(xiàn)是先將接口類EventOutObserver 類的子類實(shí)例化,調(diào)用其advise()方法監(jiān)聽場(chǎng)景節(jié)點(diǎn)的eventOut,發(fā)現(xiàn)eventOut 有輸出,EventOutObserver 子類的callback()方法會(huì)自動(dòng)執(zhí)行。例監(jiān)聽moxing 節(jié)點(diǎn)的scale 域發(fā)生變化,如下所示:
moxing.getEventOut(“set_scale”).advise(observer,null);
Java Applet 與數(shù)據(jù)庫通過JDBC(Java Database Connectivity)連接,JDBC 是Java 語言編寫的類和接口,允許Applet 對(duì)遠(yuǎn)程數(shù)據(jù)庫進(jìn)行訪問、獲取及更新數(shù)據(jù)等操作。利用JDBC 接口將Java Applet 與數(shù)據(jù)庫連接的一般步驟有:建立數(shù)據(jù)源;加載由數(shù)據(jù)庫類型決定的驅(qū)動(dòng)程序;建立與某個(gè)數(shù)據(jù)源的連接;發(fā)送SQL 語句;處理返回的ResultSet 類的對(duì)象,將查詢結(jié)果最后顯示給用戶;關(guān)閉連接;捕獲異常,尤其是當(dāng)新建連接、驅(qū)動(dòng)程序加載、語句執(zhí)行、類型轉(zhuǎn)換等操作發(fā)生時(shí)的異常。
圖3 為貼裝機(jī)貼裝場(chǎng)景實(shí)例。用EAI 實(shí)現(xiàn)在同一HTML 頁面中三維虛擬世界的瀏覽(用VRML 創(chuàng)建)和場(chǎng)景的交互(Java Applet 實(shí)現(xiàn)),用戶界面包括三個(gè)按鈕(“連接數(shù)據(jù)庫”、“開始”、“停止”)和幾個(gè)文本顯示框,其中按鈕用來控制程序的執(zhí)行,文本框用于動(dòng)態(tài)顯示貼裝過程參數(shù)。

圖3 貼裝機(jī)貼裝場(chǎng)景實(shí)例
VRML 作為虛擬現(xiàn)實(shí)標(biāo)準(zhǔn)建模語言,側(cè)重對(duì)三維空間場(chǎng)景模型的搭建,復(fù)雜交互功能的實(shí)現(xiàn)必須借助于Java 等功能強(qiáng)大的高級(jí)語言,這樣才能讓用戶真正成為場(chǎng)景的直接參與者與控制者。本文詳細(xì)論述以Java Applet 作為控制的核心、VRML 場(chǎng)景為三維展示的平臺(tái),借助EAI 構(gòu)建一個(gè)三維交互式虛擬場(chǎng)景的方法,以期為VRML 的研究與應(yīng)用做進(jìn)一步探索。