Ogre源代码浅析——Mesh文件结构及加载(一)

    Ogre的模型数据(模型顶点数,每个顶点的3D坐标值等等)保存在.mesh文件中,mesh文件的结构如下(版本号:MeshSerializer_v1.8):

  1     enum MeshChunkID {
  2         M_HEADER                = 0x1000,
  3             // char*          version           : Version number check
  4         M_MESH                = 0x3000,
  5             // bool skeletallyAnimated   // important flag which affects h/w buffer policies
  6             // Optional M_GEOMETRY chunk
  7             M_SUBMESH             = 0x4000, 
  8                 // char* materialName
  9                 // bool useSharedVertices
 10                 // unsigned int indexCount
 11                 // bool indexes32Bit
 12                 // unsigned int* faceVertexIndices (indexCount)
 13                 // OR
 14                 // unsigned short* faceVertexIndices (indexCount)
 15                 // M_GEOMETRY chunk (Optional: present only if useSharedVertices = false)
 16                 M_SUBMESH_OPERATION = 0x4010, // optional, trilist assumed if missing
 17                     // unsigned short operationType
 18                 M_SUBMESH_BONE_ASSIGNMENT = 0x4100,
 19                     // Optional bone weights (repeating section)
 20                     // unsigned int vertexIndex;
 21                     // unsigned short boneIndex;
 22                     // float weight;
 23                 // Optional chunk that matches a texture name to an alias
 24                 // a texture alias is sent to the submesh material to use this texture name
 25                 // instead of the one in the texture unit with a matching alias name
 26                 M_SUBMESH_TEXTURE_ALIAS = 0x4200, // Repeating section
 27                     // char* aliasName;
 28                     // char* textureName;
 29 
 30             M_GEOMETRY          = 0x5000, // NB this chunk is embedded within M_MESH and M_SUBMESH
 31                 // unsigned int vertexCount
 32                 M_GEOMETRY_VERTEX_DECLARATION = 0x5100,
 33                     M_GEOMETRY_VERTEX_ELEMENT = 0x5110, // Repeating section
 34                         // unsigned short source;      // buffer bind source
 35                         // unsigned short type;        // VertexElementType
 36                         // unsigned short semantic; // VertexElementSemantic
 37                         // unsigned short offset;    // start offset in buffer in bytes
 38                         // unsigned short index;    // index of the semantic (for colours and texture coords)
 39                 M_GEOMETRY_VERTEX_BUFFER = 0x5200, // Repeating section
 40                     // unsigned short bindIndex;    // Index to bind this buffer to
 41                     // unsigned short vertexSize;    // Per-vertex size, must agree with declaration at this index
 42                     M_GEOMETRY_VERTEX_BUFFER_DATA = 0x5210,
 43                         // raw buffer data
 44             M_MESH_SKELETON_LINK = 0x6000,
 45                 // Optional link to skeleton
 46                 // char* skeletonName           : name of .skeleton to use
 47             M_MESH_BONE_ASSIGNMENT = 0x7000,
 48                 // Optional bone weights (repeating section)
 49                 // unsigned int vertexIndex;
 50                 // unsigned short boneIndex;
 51                 // float weight;
 52             M_MESH_LOD = 0x8000,
 53                 // Optional LOD information
 54                 // string strategyName;
 55                 // unsigned short numLevels;
 56                 // bool manual;  (true for manual alternate meshes, false for generated)
 57                 M_MESH_LOD_USAGE = 0x8100,
 58                 // Repeating section, ordered in increasing depth
 59                 // NB LOD 0 (full detail from 0 depth) is omitted
 60                 // LOD value - this is a distance, a pixel count etc, based on strategy
 61                 // float lodValue;
 62                     M_MESH_LOD_MANUAL = 0x8110,
 63                     // Required if M_MESH_LOD section manual = true
 64                     // String manualMeshName;
 65                     M_MESH_LOD_GENERATED = 0x8120,
 66                     // Required if M_MESH_LOD section manual = false
 67                     // Repeating section (1 per submesh)
 68                     // unsigned int indexCount;
 69                     // bool indexes32Bit
 70                     // unsigned short* faceIndexes;  (indexCount)
 71                     // OR
 72                     // unsigned int* faceIndexes;  (indexCount)
 73             M_MESH_BOUNDS = 0x9000,
 74                 // float minx, miny, minz
 75                 // float maxx, maxy, maxz
 76                 // float radius
 77                     
 78             // Added By DrEvil
 79             // optional chunk that contains a table of submesh indexes and the names of
 80             // the sub-meshes.
 81             M_SUBMESH_NAME_TABLE = 0xA000,
 82                 // Subchunks of the name table. Each chunk contains an index & string
 83                 M_SUBMESH_NAME_TABLE_ELEMENT = 0xA100,
 84                     // short index
 85                     // char* name
 86             
 87             // Optional chunk which stores precomputed edge data                     
 88             M_EDGE_LISTS = 0xB000,
 89                 // Each LOD has a separate edge list
 90                 M_EDGE_LIST_LOD = 0xB100,
 91                     // unsigned short lodIndex
 92                     // bool isManual            // If manual, no edge data here, loaded from manual mesh
 93                         // bool isClosed
 94                         // unsigned long numTriangles
 95                         // unsigned long numEdgeGroups
 96                         // Triangle* triangleList
 97                             // unsigned long indexSet
 98                             // unsigned long vertexSet
 99                             // unsigned long vertIndex[3]
100                             // unsigned long sharedVertIndex[3] 
101                             // float normal[4] 
102 
103                         M_EDGE_GROUP = 0xB110,
104                             // unsigned long vertexSet
105                             // unsigned long triStart
106                             // unsigned long triCount
107                             // unsigned long numEdges
108                             // Edge* edgeList
109                                 // unsigned long  triIndex[2]
110                                 // unsigned long  vertIndex[2]
111                                 // unsigned long  sharedVertIndex[2]
112                                 // bool degenerate
113 
114             // Optional poses section, referred to by pose keyframes
115             M_POSES = 0xC000,
116                 M_POSE = 0xC100,
117                     // char* name (may be blank)
118                     // unsigned short target    // 0 for shared geometry, 
119                                                 // 1+ for submesh index + 1
120                     // bool includesNormals [1.8+]
121                     M_POSE_VERTEX = 0xC111,
122                         // unsigned long vertexIndex
123                         // float xoffset, yoffset, zoffset
124                         // float xnormal, ynormal, znormal (optional, 1.8+)
125             // Optional vertex animation chunk
126             M_ANIMATIONS = 0xD000, 
127                 M_ANIMATION = 0xD100,
128                 // char* name
129                 // float length
130                 M_ANIMATION_BASEINFO = 0xD105,
131                 // [Optional] base keyframe information (pose animation only)
132                 // char* baseAnimationName (blank for self)
133                 // float baseKeyFrameTime
134         
135                 M_ANIMATION_TRACK = 0xD110,
136                     // unsigned short type            // 1 == morph, 2 == pose
137                     // unsigned short target        // 0 for shared geometry, 
138                                                     // 1+ for submesh index + 1
139                     M_ANIMATION_MORPH_KEYFRAME = 0xD111,
140                         // float time
141                         // bool includesNormals [1.8+]
142                         // float x,y,z            // repeat by number of vertices in original geometry
143                     M_ANIMATION_POSE_KEYFRAME = 0xD112,
144                         // float time
145                         M_ANIMATION_POSE_REF = 0xD113, // repeat for number of referenced poses
146                             // unsigned short poseIndex 
147                             // float influence
148 
149             // Optional submesh extreme vertex list chink
150             M_TABLE_EXTREMES = 0xE000,
151             // unsigned short submesh_index;
152             // float extremes [n_extremes][3];
153 
154     /* Version 1.2 of the .mesh format (deprecated)
155     enum MeshChunkID {
156         M_HEADER                = 0x1000,
157             // char*          version           : Version number check
158         M_MESH                = 0x3000,
159             // bool skeletallyAnimated   // important flag which affects h/w buffer policies
160             // Optional M_GEOMETRY chunk
161             M_SUBMESH             = 0x4000, 
162                 // char* materialName
163                 // bool useSharedVertices
164                 // unsigned int indexCount
165                 // bool indexes32Bit
166                 // unsigned int* faceVertexIndices (indexCount)
167                 // OR
168                 // unsigned short* faceVertexIndices (indexCount)
169                 // M_GEOMETRY chunk (Optional: present only if useSharedVertices = false)
170                 M_SUBMESH_OPERATION = 0x4010, // optional, trilist assumed if missing
171                     // unsigned short operationType
172                 M_SUBMESH_BONE_ASSIGNMENT = 0x4100,
173                     // Optional bone weights (repeating section)
174                     // unsigned int vertexIndex;
175                     // unsigned short boneIndex;
176                     // float weight;
177             M_GEOMETRY          = 0x5000, // NB this chunk is embedded within M_MESH and M_SUBMESH
178             */
179                 // unsigned int vertexCount
180                 // float* pVertices (x, y, z order x numVertices)
181                 M_GEOMETRY_NORMALS = 0x5100,    //(Optional)
182                     // float* pNormals (x, y, z order x numVertices)
183                 M_GEOMETRY_COLOURS = 0x5200,    //(Optional)
184                     // unsigned long* pColours (RGBA 8888 format x numVertices)
185                 M_GEOMETRY_TEXCOORDS = 0x5300    //(Optional, REPEATABLE, each one adds an extra set)
186                     // unsigned short dimensions    (1 for 1D, 2 for 2D, 3 for 3D)
187                     // float* pTexCoords  (u [v] [w] order, dimensions x numVertices)
188             /*
189             M_MESH_SKELETON_LINK = 0x6000,
190                 // Optional link to skeleton
191                 // char* skeletonName           : name of .skeleton to use
192             M_MESH_BONE_ASSIGNMENT = 0x7000,
193                 // Optional bone weights (repeating section)
194                 // unsigned int vertexIndex;
195                 // unsigned short boneIndex;
196                 // float weight;
197             M_MESH_LOD = 0x8000,
198                 // Optional LOD information
199                 // unsigned short numLevels;
200                 // bool manual;  (true for manual alternate meshes, false for generated)
201                 M_MESH_LOD_USAGE = 0x8100,
202                 // Repeating section, ordered in increasing depth
203                 // NB LOD 0 (full detail from 0 depth) is omitted
204                 // float fromSquaredDepth;
205                     M_MESH_LOD_MANUAL = 0x8110,
206                     // Required if M_MESH_LOD section manual = true
207                     // String manualMeshName;
208                     M_MESH_LOD_GENERATED = 0x8120,
209                     // Required if M_MESH_LOD section manual = false
210                     // Repeating section (1 per submesh)
211                     // unsigned int indexCount;
212                     // bool indexes32Bit
213                     // unsigned short* faceIndexes;  (indexCount)
214                     // OR
215                     // unsigned int* faceIndexes;  (indexCount)
216             M_MESH_BOUNDS = 0x9000
217                 // float minx, miny, minz
218                 // float maxx, maxy, maxz
219                 // float radius
220 
221             // Added By DrEvil
222             // optional chunk that contains a table of submesh indexes and the names of
223             // the sub-meshes.
224             M_SUBMESH_NAME_TABLE,
225                 // Subchunks of the name table. Each chunk contains an index & string
226                 M_SUBMESH_NAME_TABLE_ELEMENT,
227                     // short index
228                     // char* name
229 
230     */
231     };

      与一般的3D文件格式类似,Ogre的mesh文件数据结构为树。构成mesh文件的基本数据单位是chunk,每个chunk由三部分组成:

1         unsigned short CHUNK_ID        : one of the following chunk ids identifying the chunk
2         unsigned long  LENGTH          : length of the chunk in bytes, including this header
3         void*          DATA            : the data, which may contain other sub-chunks (various data types)

     CHUNK_ID用来标示各个chunk,而各chunk的实际数据则保存在相应的DATA域中。各chunk在id和数据域之外还有一个长度域(长度域也可以看作是数据域中的一项),用来描述本chunk的数据字节数。如果自定义的mesh文件结构比较复杂,嵌套层比较深,有了长度域就可以在文件读取过程中,帮助程序快速定位到指定的数据段;chunk的长度域还有一个作用,就是可以在文件读取过程中进行数据校验。

     另外,随着Ogre引擎的不断改进,mesh文件衍生出多个版本,不同版本的文件结构是有所变化的,这一点从上面第一段代码(154-178行与2-30行的对比)中可以反应出来。mesh文件数据用二进制格式保存,所有版本的mesh文件开头两个字节都以0x1000作为文件标识,接下来的21-22个字节是一个字符串,用来表示mesh文件的版本号。在对文件数据进行读取时,Ogre会根据版本号的不同选择相应的文件串行器(MeshSerializer),对mesh文件数据进行读取。 

作者:yzwalkman
转载请注明出处。
原文地址:https://www.cnblogs.com/yzwalkman/p/2916953.html