本章為實作(system implementation)的細節部份,說明各子系統的實作過程以及整合各 個子系統的系統運作機制。VPS 為架構在 CAVE 環境下的純軟體系統,所有實作皆以 C/C++
程式語言完成,編譯器為Microsoft Visual C++以及 Borland C++ Builder,實作涵蓋的相關 技術及背景知識有:
多重執行緒 (multi-threading)
動態聯結函式庫 (dynamic linking library, DLL)
序列埠通訊 (serial port communication)
網路程式 (windows socket programming)
動態型別轉換 (dynamic casting)
視窗訊息處理 (windows message handler)
物件聯結與嵌入 (object linking and embedding, OLE)
通訊協定 (communication protocol)
AT 指令集 (AT command set)
系統規劃的結果,VPS 被分為六個模組,分別實作為六個子系統,這些子系統各自有各 自的任務,可獨立擴充,但是要透過一個方式將這些子系統串聯整合,才能確保各個子系統 在擴充後仍能夠與其他子系統溝通。例如:將來裝置系統擴充支援了新的裝置,但是新裝置 的訊號並無法被其他的系統理解,所以在任何子系統實作之前,必須先制定一個共通的協定 (protocol)作為子系統間溝通之用。
這個共通的協定在VPS 裡被稱為”動作指令”(action command),動作指令是一種文字系 統,任何輸入的訊號都會被轉成相對應的動作指令再傳遞至各個子系統,動作指令穿梭在整 個VPS 系統裡,進行傳遞信息的任務。這個協定在情境管理子系統裡設定,同樣也是可以加 以擴充的,有關動作指令的細節會在情境管理一節有詳細的說明。
4.1 ྅ཉგந̄ր
滑鼠:左鍵、右鍵、螢幕座標、單按事件(click)、雙按事件(double click)
PDA:按鍵值(上下左右)、模擬滑鼠的事件
如果連線的裝置是屬於藍芽的裝置,則裝置管理系統會透過藍芽的SPP 模式與裝置進行 連結,再將連線後的資源轉交給訊號處理執行緒進行訊號的接收與後續處理,訊號處理執行 緒並不負責連結的工作,這樣的工作分配是為了讓裝置管理系統能夠完整地掌握各裝置的連 線情形。
而目前具備藍芽連線功能的手機,在啟動的時候必須要傳入一系列的AT 指令,讓之後 所有的輸入都會被直接傳入連線的電腦,所以必須有額外的初始化動作。以下為將藍芽手機 初始化的虛擬碼(pseudo code):
訊號處理執行緒在面對不同的裝置時就依據裝置管理系統傳入的性質描述而能用正確 的方式取得訊號,再加以處理。實作上是用物件的方式記錄裝置的名稱、類別以及描述,啟 動後便是將物件傳入訊號處理執行緒,以下為物件的範例:
//開啟 Serial Port
hComm = CreateSerialPort(bluetooth_virtual_serial_port);
if(hComm != INVALID_HANDLE_VALUE) {
//設定該裝置多久沒回應即視為離線
SetCommTimeouts(hComm, commTimeout);
//設定序列埠的狀態
BuildCommDCB("115200,N,8,1", dcbCommPort);
SetCommState(hComm, dcbCommPort);
//傳入 AT 指令設定手機狀態
hcmd = "at+cmer=3,2,0,0,0\r";
WriteFile(hComm, hcmd);
FlushFileBuffers(hComm);Sleep(250);
//傳入 AT 指令將手機鎖定,所有按鍵輸入都直接傳進電腦,手機不會反應 hcmd = "at+clck=\"CS\",1\r";
WritePort(hComm, hcmd);
FlushFileBuffers(hComm);Sleep(250);
//傳入 AT 指令設定字串編碼方式 hcmd = "at+cscs=\"8859-1\"\r";
WriteFile(hComm, hcmd);
FlushFileBuffers(hComm);Sleep(250);
//啟動執行緒
ReadMobileThread = new TReadMobile(true);
//傳入開啟完成的裝置資源
ReadMobileThread->SethComm(hComm, &DeviceDesc);
//訊號處理執行緒開始運作
ReadMobileThread->Resume();
}
由於對裝置的描述是採用物件的方式來定義,目前在系統裡已經建立了一些基礎的輸入
Class DeviceDesc {
String DeviceName;
int DeviceType;
}
Class MouseDesc extends DeviceDesc {
Class PDADesc extends Mouse {
button Navi;
}
訊號處理的執行緒在實作上是透過兩種方式,一種是標準的輸出輸入裝置,如:鍵盤、
滑鼠,直接利用windows 的事件訊息(event message)就可以取得輸入;另一個方式則是要 透過序列埠取得訊號。取得訊號後將訊號內容傳進情境管理系統,而為了避免多個訊號處理
switch (uMsg) {
//如果是鍵盤
case WM_KEYDOWN:
InBuffer = wParam;
break;
case WM_KEYUP:
….
case WM_CHAR:
….
//如果是滑鼠,各有左、中、右鍵 case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK;
case WM_MBUTTONDOWN:
….
case WM_RBUTTONDOWN:
….
ReadPortMsg(threadhComm, InBuff, 80, &dwBytesRead, NULL);
FlushFileBuffers(threadhComm);
//有輸入訊號
if(dwBytesRead) {
InBuff[dwBytesRead] = 0;
//將訊號送進情境管理系統
Synchronize(ScenarioControl);
} }
4.3 ଐဩგந̄ր
情境管理系統的實作本體是在控制伺服器上的一個執行檔VPS_Master.exe,在控制伺服 器負責了最重要的工作 – 管理整個發表的流程,此系統也同時肩負發送同步化訊號,而在 訊號處理執行緒接受到訊號後也必須依照情境的設定將這些裝置的訊號轉換成動作指令。
VPS 啟動時,情境管理系統必須讀取及分析發表者的設定檔(present profile)以了解情境 之間的關係與切換的機制(圖 4.1 右),發表者設定檔是一個純文字檔案,目的就是要將整個 發表的過程做完整的設定,在發表時就能照著這些設定切換各種情境提供多樣的互動方式或 是媒材訊息。分析完成接著開始嘗試跟顯示客戶端連線,這透過一個紀錄所有要連線的顯示 客戶端的位址IP 清單的 iplist.txt 來完成,系統並沒有限制顯示客戶端的數量,所以是可以 有彈性的設定,例如只要修改iplist.txt 為單一部個人電腦,就可以在該電腦上進行多人互 動,此時的模式就會跟標準的SDG 一樣,當然如果未來 CAVE 的環境擴充為六面(十二部顯 示客戶端)或甚至更多,VPS 系統也只要修改這部份就可以繼續供應多人互動的功能。由於控 制伺服器的部份是在後端處理的,並不會提供給使用者操作用,所以只有一個簡單的介面(圖 4.1 左)作為偵測錯誤跟紀錄訊息之用。
#sample present profile [scenario 1]
Z8[1]=11openfMyPresent.ppt Z8[*]=10prevs
Z8[#]=10nexts Z8[2]=01scena2 Z8[3]=01scena3 [scenario 2]
Z8[1]=01openfOpengl.exe [scenario 3]
Z8[1]=01openfTest.mpg Z8[[]=00playm
Z8[]]=00stopm
圖4.1 VPS 控制伺服器啟動 (左)畫面; (右)發表者設定檔範例
動作指令為一種文字規範,由兩個數字、五個字母以及後面若干文字參數組成,用以傳
1 openf MyPresent.ppt
執行結果為第一群組的顯示客戶 端電腦開啟MyPresent.ppt 檔 1
執行結果為移動至整個畫面的 (300,200)位置
02movet300,200
圖4.2 動作指令
Powerpoint 檔案 Powerpoint 外掛
4.4.1 ಫՄγଭనࢍ
動態聯結函式庫的目的是為了讓執行檔不會佔用系統太多的資源,而且要擴充的時候也 不需要修改很大的部份,只要讓執行檔去呼叫擴充過後或是新增加的DLL 即可。在 VPS 裡,
執行檔的角色就是資料運算系統,資料運算系統的工作是負責接受透過網路傳來的動作指令 資料並將指令傳進各種媒材以完成互動,工作內容並不會有什麼變動,所以資料運算系統只 要製作完成後就不需要再更動,往後的擴充就藉著資源管理系統來完成。
要不更動執行檔(資料運算系統)的架構,首先就是要設計一個共通的函式介面(common function interface),只要執行檔都是透過相同的函式介面進行呼叫(function call),就不需 要擔心修改後不相容的問題,因為新的DLL 也會提供相同的函式介面供執行檔呼叫,只是功 能換成新的。依照資料運算系統的工作項目,共通函式介面需要以下幾項:
DllInitial():初始化函式庫,包括一些資源的配置
DllSendCommand(char*, char*):讓資料運算系統將命令送進媒材外掛
DllShow(char*):載入媒材及顯示畫面
DllUninitial();:卸載函式庫時的清理工作
實作便是透過DLL 的 export 方式將這些函式介面提供出去,實作如下:
資料運算系統
QuicktimeVR 外掛 QuicktimeVR 檔案
未來的媒材….
資源管理系統
圖4.3 採用外掛設計的資源管理系統
//Powerpoint 外掛的內容
extern "C" __declspec(dllexport)int _stdcall DllInitial();
extern "C" __declspec(dllexport)int _stdcall DllSendCommand(char*, char*);
extern "C" __declspec(dllexport)int _stdcall DllShow(char*);
extern "C" __declspec(dllexport)int _stdcall DllUninitial();
int _stdcall DllSendCommand(char* dll_cmd, char* dll_param) {
switch (dll_cmd) {
case “fopen”:
Powerpnt->filename = AnsiString(dll_param);
Powerpnt()->Open();
int (*DllSendCommand)(char*, char*);
int (*DllShow)(char*);
int (*DllUninitial)();
//DLL_NAME 可以是任何外掛 hInst = LoadLibrary(DLL_NAME);
(FARPROC &)DllInitial = GetProcAddress(hInst,"DllInitial");
(FARPROC &)DllSendCommand = GetProcAddress(hInst,"DllSendCommand");
(FARPROC &)DllShow = GetProcAddress(hInst,"DllShow");
//將訊息處理系統送來的動作指令送至媒材外掛 DllSendCommand(action_command, parameter);
4.4.2 ͚೯ЧಫՄ۞γଭ
Flash:可以載入 Macromedia 的 Flash 檔案(.swf),虛擬版面的實作是透過 Flash 來完 成的
各種媒材的載入方式都有很大的差異,每種媒材外掛除了提供共同介面外,還必須透過 各種不同的方式與技術實作才能在VPS 這樣的共同空間下同時呈現,因此也透過外掛的設計 方式實作出以下多個DLL。
Powerpoint 簡報檔(VPS_Powerpoint.DLL):控制 Powerpoint 檔案必須透過 OLE(Object Linking and Embedding)的機制呼叫 Powerpoint 的物件以執行使用者的命令。”OLE 是一種 機制,可允許使用者建立和編輯包含由多個應用程式所建立的項目或「物件」的文件。OLE 文 件,傳統上被稱為複合文件,可完全整合不同型別的資料或是元件,音效短片、試算表和點 陣圖都是OLE文件中可見的一般元件範例。透過OLE的支援可以允許使用者在使用OLE文 件時不必費心在不同應用程式之間切換,OLE會負責切換….您可以使用容器應用程式 (container application)建立複合文件和伺服應用程式,或是使用元件應用程式建立容器文 件內的項目….OLE 所加入的許多不同概念,都是為了達成應用程式間無縫隙互動的目的” [MSDN, 2003]。OLE 的操作可以讓系統不需要重新實作讀取載入 Powerpoint 簡報檔的程式,
而可以直接呼叫Powerpoint 並嵌入作為容器應用程式的 VPS 系統內負責相關的工作。
2D 影像檔(VPS_Image.DLL):顯示影像(.bmp, .jpg),切換其他影像檔,也可以對影像 進行放大/縮小(zoom in/out)。這部份由於 Borland C++ Builder 直接支援載入這兩類型的圖 檔,透過以下函式的呼叫就完成了:
Image->Picture->LoadFromFile(ImageFile);
3D 模型檔(VPS_OpenGL.DLL):要呈現即時的 3D 立體模型,VPS 必須能夠載入模型檔案 並以即時運算(realtime rendering)的方式呈現。模型檔案格式相當多,3ds 及 obj 檔案格式 則是最常用的兩種,因此VPS 以實作這兩種為主。在載入模型檔後,由顯示輸出系統計算視 差,並自動依照所在的位置分成左右眼的畫面輸出,提供立體視覺,設計者只要將模型建置 好即可,不需要考慮鏡頭視差的計算。然而在設計發表的過程中,不同的評審(或其他設計 者)經常會專注在模型的不同角度的畫面細節上,因此系統提供螢幕擷取(screen capture)的 功能,讓每個使用者都可以將想要深入探究的畫面擷取後放置到虛擬版面的區塊以與發表者 或是其他使用者討論。擷取下來的畫面會上傳到控制伺服器端的特定資料夾以供其他外掛 (例:虛擬版面)存取。
動畫影片檔(VPS_Medaiplayer.DLL):影片的部份是呼叫 Microsoft Mediaplayer 進行播 放影片的功能,但是考量畫面的同步處理,因此無法支援串流型態(stream-based)的影片 檔,而僅能支援以影格為基礎(frame-based)的影片,如:AVI、MPEG 等
環景影片檔(VPS_QTVR.DLL):QuicktimeVR 是一種常用的以影像為基礎的環場虛擬實境 (image-based panorama virtual reality),製作方式是先拍攝 360 度的環景照片,透過製作 軟體將兩端連接並製作成qtvr 的格式,就可以提供使用者 360 度觀看現場環境的體驗,由
環景影片檔(VPS_QTVR.DLL):QuicktimeVR 是一種常用的以影像為基礎的環場虛擬實境 (image-based panorama virtual reality),製作方式是先拍攝 360 度的環景照片,透過製作 軟體將兩端連接並製作成qtvr 的格式,就可以提供使用者 360 度觀看現場環境的體驗,由