Page系統設計思想
Steve Streeting
將Page
系統作為Ogre(1.7.2)
的核心組件,其設計理念如下:
1. 勿須假定Page系統明確了解世界,世界的新的組成部分不僅具備可以被用于動態加載定義好的數據的特性,還必須有被動態"發現\探索到"的特性.
注:對原有的世界必須也有個改進,讓其具備一定被動態發現的特性.
2. 允許多策略決定頁面的生命周期---烏鴉飛行距離路線案例就是一個很好的印證[1],但我們也必須允許其他策略(尤其是在密集的、閉塞的場景中,它可能是連通或閉塞的區域狀態)的存在.
3. 將分頁策略(Paging Strategy)和分頁內容當做一個正交概念對待,亦即你可以用多種方式混合和匹配組合它們.
4. 勿須假定分頁是規則的尺寸,或者分頁占據獨特的、非重疊的空間區域。
5. 支持設置多種多樣結構的分頁。可以是網格的地形,也可以是巖洞結構的'蛇型'區域。
6. 頁面之間的過渡不能有具體類型相關的細節信息,關鍵是需要支持各種不同的場景的過渡,例如從洞穴結構到二維地形再到空曠空間。
7. 可以在一個獨立線程中完成分頁的加載,不管是在全線程或半線程下都可以用相同的形式將資源作為可用資源來使用[2]。
8. 分頁應該在物理內容變化的時候支持多重LODs。分頁中的內容可以有自己的LOD,但我們也應該允許物理內容在更高級別上也可以發生變化。
9. 現在還不支持分頁坐標系。為了配合大世界的精細處理,可以使用雙精度坐標系和與攝像機相關的渲染方法。頁面相關的坐標系需要一個較大的代碼變動,主席肯定不允許冒這么大的風險把這差事給我這大把年紀的程序猿去做滴,那就預留給以后的版本完成。
10. 總的來說,對分頁系統的支持不能過分要求場景管理器有太多改動,公主澤肯定會不高興滴,那這些就保留到2.0版的時候再搞吧。
PageManager(頁面管理器)
主要作用是提供PageStrategy、PageContentFactory這樣的擴展類的一個中心注冊入口,同是也是訪問當前加載的世界分頁(PagedWorld)的地方。我還沒有決定是將其掛在核心的Root下還是讓它作為一個獨立庫讓使用者引用。
PagedWorld(世界分頁)
這個基本上是整個結構中的數據驅動部分。一個PagedWorld是世界中內容的集合,可以從文件中加載或在代碼中定義。最重要的是,它不需要創建其中的全部東西---頂多需要創建一個分頁世界區域(PagedWorldSections),并且可以在定義了“重生點”的情況下選擇性的創建一個分頁入口點(PageEntryPoints,在出現不可能簡單獲的從一個相機的世界位置加載分頁需要的數據源的情況下,這點非常重要)。 用這種適當的方式,請求就能動態的加載余下需要的部分。
PagedWorldSection(世界分頁區域)
這是世界的一個組成區域,它符合特定的分頁策略。例如,室外2D地形區域(這里的'地形'我的意思是:它在結構上是2D的,而不是指它定義了地形的內容)可能會使用一個策略,并被限定使用一種方式;室外的天空區域可能使用另一種策略,一個復雜的室內區域可能使用再另一種策略。這里只需要掌握一個高層次的描述---世界的區域編號(section id)、通用邊界信息以及可選的入口點(僅僅包含一個坐標和一個頁面標識符 ---在策略缺失而通過上下文無法將坐標點直接轉換成一個分頁的情況下尤為重要)
注:Section這里指組成某個整體的一部分區域。Space這里指地形上的天空,不是天空盒。
PageStrategy(分頁策略)
這個類是負責決定如何加載和清除分頁,并且可以選選擇僅從世界位置獲得一個分頁(和一個PagedWorldSection)。每當攝像機移動的時候,PageStrategy負責決定如何響應一個在世界分頁區域(PagedWorldSection)中的頁面請求。它可能是一個網格系統,這個時候它可能使用頁面之間的關聯性來確定遍歷的深度。無論如何,只要給定了一個世界統一坐標、一個存在的分頁或一個分頁入口點(PageEntry point),這個策略就必須能夠決定哪些分頁必須被請求、哪些分頁必須被拋棄。分頁策略(PageStrategy)被設計成具備用戶可擴展性。
Page(頁面)
這個類聚合了一個數據頁的所有表述。它雖然定義了頁面,但實際上不包含其自身的任何數據。相反,它只是包含了一個LOD levels的列表和一個LOD策略的引用。每個分頁在世界區域里都有一個唯一的ID。
PageLOD(頁面層級)
這個是為了在需要的情況下讓頁面內容不止一次加載完。例如,您可能想要一個分多個階段加載的分頁,其中包括最基本的內容與一個距離相關的非常簡單的定義,然后是包括靠近的時候更多細節的定義。我打算重用可插拔的LodStrategy類來表現這些轉換規則(transition rules)。
現在定義我們頁面加載中所需單位化的特殊標記:“世界ID:世界區域ID:分頁ID:分頁層級索引 (WorldID:WorldSectionID:PAGEID:PageLODIndex)”。我可能會在一個適當的地方放置一個可插拔的轉換系統,這樣就可以運用這些數字,并將其轉換成一個獨特的資源來加載---這個資源可能簡單到是一個文件(“myworld_sec1_p1234_0.dat”),或者可以轉換成一個現成的已打包好的資源文件或類似東西中的一個偏移量。
PageContent(頁面內容)
雖然PageLOD是加載的單位量,但是你可能還想要包含多種不同類型的內容。例如,在一個分頁中你可能有一塊地形、一些靜態幾何體、一些自定義的用戶數據(如觸發區域,世界中的物體等)。因此使用了PageLOD你就可以有多個PageContent實例,它們都被放在一起加載,但每一個實例都會有自定義數據格式和同樣的套路用于將其在線獲取。在加載時,它們都將被工廠系統實例化,而這個工廠系統則基于名字加載器來實現的。
這些不同類型的頁面內容(PageContent)中的每一種也都可以自由地做他們自己的LOD版本的事情。例如,如果某個內容包括了創建一些實體的實例并且它們是使用了LOD的網格,那么這個情況下將仍然提出申請。對于地形,每個分頁都有它自己的細分(subdivisions)與LOD,但其前提是這是一個基于內存的LOD,適合于輕量級的動態調整,而更高級別的PageLOD則更重量級并在實際上改變頁面內容、造成內存占用(memory footprint)的變化等(也同樣被潛在的執行了)。這就是為什么存在兩種類型的LOD的原因,它們并非互相重復。頁面內容(PageContent)和頁面內容工廠(PageContentFactory)都被設計成具備用戶可擴展性。
Phew(瑪雅)
瑪雅,好吧,這是我有生以來寫出的內容最多的帖子之一。我希望一切看起來都很好---不過它仍然不夠精煉,因此沒有任何內容是一成不變的,但我已經花了相當多的時間來思考整體架構、我要支持什么樣的功能以及擴展點在哪里,所以我很高興為公主澤做了這么多。歡迎評論!
Steve Streeting
Tue Mar 03, 2009 7:39 pm
[1] 一個著名的策略分析案例,指烏鴉飛行路線有一定隨機性,可能很遠,可能很近.
[2] with the same modes as available for resources