Ogitor代碼分析

引擎狀態監聽(觀察者)

 

底層變化時需要高層UI做出反應這個有一個原則就是下層邏輯不能依賴上層邏輯所以通過一個接口進行消息的派發如果是.net的話可以用delegate/event實現. C++的話可以自己用模板寫個delegate效率比用接口高

實體抽象(工廠方法)

擴展性是很強但是類太多了-_-. 這裏有種基於DLL的插件模型可以學習工廠方法需要知道具體的工廠對象這裏要求初始化工廠的對象(OgitorRoot)要知道具體的工廠定義(C++#include做得太失敗了導致編譯效率低下…). 但是做成DLL插件的話就可以利用DLL的導出函數反向調用OgitorRoot進行註冊不過對於內部使用進行二進制分離有意義嗎?

Undo/Redo(命令模式)

這機制實現的前提是所有CBaseEditor對象都可以用一系列的屬性來進行初始化/設置所以每一個Command都是針對屬性的修改對於Create/Destory來說可以看成對所有屬性的修改外加對象的創建/刪除屬性的變量類型並沒有進行抽象而是轉換成了字符串需要時再轉換回來如果是.net的話就方便許多直接可以獲得PropertyInfo[], 而且能跟PropertyGrid控件進行屬性的自動綁定不過這屬於語言的反射應用標準C++不具備這個特性(@_@).

 

 

 

鼠標編輯

就是移動旋轉縮放對象的操作響應還有可視化表示操作時的選中軸是所有編輯對象統一使用一套, 自定義的表示如下圖中的spot light, 是通過派生CVisualHelper來進行定製繪製的.

 

多選處理

這裏到是沒用什麼有用的模式不過對於OgitorsRoot::VolumeSelect()的算法到是很感興趣.

viewport上的矩形選框可以對應3D空間一個5個平面組成的包圍體(遠面不包含), 以這個包圍體到場景樹去遍歷查詢所有實體就能得到選中的實體列表所有選中對象組合成一個CMultiSelEditor進行移動/旋轉/縮放.

屬性編輯

SetXXX全部定義到一個函數指針數組根據類型(ID)進行索引避免了一堆if-else. 無論是UI到引擎還是引擎到UI的通知都是以這個ID來進行查找的. PropertyGridItem綁定的數據也是這個ID, 而不是實際的對象但是這樣也帶來另一個問題每擴充一個屬性就會去改動這個類型定義的頭文件DLL中定義的特殊屬性怎麼辦?

 

 

 

序列化

這裏有能體現出屬性進行抽象的好處了所有對象直接寫進XML格式的工程文件XML的好處就是增刪屬性不用改文件序列化的代碼缺點是解析速度慢佔用空間大.而二進制就比較鬱悶格式一改動就要進行代碼變更通常還要兼容幾個版本的文件地形方面由於是插件的原因文件是獨立的不過不管什麼場景地形獨立出來其實沒什麼不好的因爲地形的格式比較穩定不會經常變動獨立出來更方便做版本管理.

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章