在Axiom3D,或者說是Ogre的mesh的文件格式我們可能通過代碼反推出相關格式,相關過程本來我是直接寫的,后面發現相關流程寫完后,我自己都看暈了,然后我就把一些過程用Execl整理出來,發現過程清晰多了,如下這張圖:

這圖是導入一個簡單的mesh文件(沒有包含動畫)根據代碼反推出的相關結構,這個Mesh文件的版本是1.30,不同的mesh版本格式略有不同,但是不會相差太大.
首先針對上面的圖中一些需要注意的地方說下,其中上面的類型為Chunk的表示一個用ushort表示的類型,和這個Chunk塊用int表示的長度,這個長度包含他自己,就是上面說的sizeof(ushort)+sizeof(int)=6.其中的Bool類型,就是一個字節,因為在C++里有時會把bool用int表示,這里不一樣.就是C#里的一個字節.在標識紅色的地方,就是把上面從IndexCount到Vertexbuff在讀取一遍.這里關於Axiom中的數據組織可以看Axiom 3D:數據綁定基本流程,里面對於VertexData,IndexData都有介紹,這里的流程就是填充這二個對象.
Axiom3D中的mesh文件是二進制的,直接用文本打開全是亂碼,雖然不像XML,文本等格式清晰易讀.但是他本身的組織非常有條理,不是有個工具OgreXmlConverter,在看了相關代碼后,我個人認為轉成XML的難度一點不大,他本身就是用Chunk塊組成了如樹這種結構,因此在這個里面,最重要是各個Chunk塊,如下是各塊的一些信息.

他這個節點的值很有規律,大家發現沒,主要的節點,如Mesh,SubMesh,Geometry,MeshSkeletonLink,MeshLOD這些主節點采用如0xX000,而在各個主節點下如SubMesh(0x4000)下的分支SubMeshOperation(0x4010),SubMeshBoneAssignment(0x4100),可以看到每個主Chunk之間可以有0x1000(4096)個分Chunk.主分支的值是0x1000的整數倍.分支Chunk也可以由他的值判斷是那個主分支下的節點.
這個節點中很多部分都是和動畫有關,在這里,我們先分析簡單的Mesh,也就是不包含動畫里的,第一張是一個典型意義上的無動畫的Mesh結構.讓我們根據第一張圖來分析下.
Mesh文件首先是他的頭文件,分別是short類型,用於檢查是否是Mesh的節點0x1000,如果不是,說明此文件有誤,然后是Mesh的版本信息.
然后就是Mesh塊本身的信息,前面說過塊包含了類型Mesh(0x3000),長度二個信息.然后是否是動畫,在這里,是false.
如果Mesh和本身的SubMesh共享數據,先看一個不共享數據的模型,在OpenGL OBJ模型的加載,在OBJ模型中,每一部分對應各自己的頂點,有各自的頂點索引.對應OBJ模型,我們可以想到Mesh的共享數據就是只有Mesh數據有頂點信息,而所有的SubMesh只持有對應Mesh數據的頂點索引信息.不共享數據就比較簡單了,和OBJ模型一樣,Mesh本身沒有(不知有沒本身有,但是子類不用的情況),而各個SubMesh保存自己的頂點信息與對應的頂點索引信息.一般來說共享數據時,Mesh本身才有Geometry(保存頂點信息)節點信息的.
接着上面,那么下一Chunk塊應該是SubMesh,這塊里首先讀取對應的材質文件,然后加載材質到對應的Submesh中,然后讀取是否和Mesh共享數據,如果是False的話,接着讀取頂點索引信息和頂點信息,就是上圖中第一個標顏色框的部分.如果是True的話,就只讀取頂點索引信息.而相應頂點數據在Mesh中的Geometry節點中,這個節點讀取數據就是上圖中第一個標顏色框去掉前三行的部分.
針對前面標顏色框的那一部分,簡單講解下,對比Axiom 3D:數據綁定基本流程,前三行就是反序列化IndexData(頂點索引信息),另外的部分就是頂點信息VertexData,在這里面又分成VertexDeclaration的反序列化,里面包含VertexDeclaration中的VertexElement的各個屬性的反序列化,五個short類型,可以看到VertexElement Chunk長度是16,也就是5*2+(2+4)的長度,2+4就是前面提到的這個Chunk塊用int表示的長度,這個長度包含他自己,就是上面說的sizeof(ushort)+sizeof(int)=6.VertexDeclaration Chunk塊的長度就等於VertexElement的個數3*16+6=54.接着VertexDeclaration的序列化后就是VertexData本身的數據反序列化,對應的是vertexbuffer chunk,這塊里首先是綁定索引,然后是每個頂點包含數據總字節長度,對比上圖這里是32位(在頂點信息里存的都是單精度浮點數據),意思有八個浮點數據(其實就是V3N3T2),.反序列化數據總長就是58*32=1856.然后就是VertexBufferData chunk塊,在此塊里存儲着所有頂點讓我們來檢查一下.得到VertexBufferData chunk塊總長度為1862.然后驗證1862=6+1856,正確.在此塊后面還有二個塊,一個指定數據的組織形式,如是三角形還是四邊形或是一點等,后面一塊指定這個Mesh的包圍盒和半徑.
接着我們看MeshLOD Chunk,這個Chunk里,首先讀取什么方式啟用Lod,然后是Lod級別,然后指出是否手動生成Lod.如果是manual Lod,如果是那么就每lodlevel加載對應的manmal name,如果不是,就需要在每個lodlevel里就每個SubMesh讀取MeshLODGenerated Chunk塊,然后在此塊讀取第一個顏色塊里的對應的IndexData,VertexData的數據.
針對Mesh的反序列化,有助於我們理解Mesh的結構,或者以后我們要自定義一些Mesh與別的格式文件的互轉,熟悉Mesh文件結構還是有必要的.
PS:每次看到別人的開源代碼,里面都是非常清晰,沒啥冗余代碼.不知到這種水平需要多久.