OGRE中mesh文件信息解析及提取之一

来源:互联网 发布:mysql数据库文件扩展名 编辑:程序博客网 时间:2024/06/02 16:16

      用过OGRE的朋友应该知道mesh文件,它是OGRE中保存模型数据的,文件结构如下:

enum MeshChunkID {        M_HEADER                = 0x1000,            // char*          version           : Version number check        M_MESH                = 0x3000,            // bool skeletallyAnimated   // important flag which affects h/w buffer policies            // Optional M_GEOMETRY chunk            M_SUBMESH             = 0x4000,                 // char* materialName                // bool useSharedVertices                // unsigned int indexCount                // bool indexes32Bit                // unsigned int* faceVertexIndices (indexCount)                // OR                // unsigned short* faceVertexIndices (indexCount)                // M_GEOMETRY chunk (Optional: present only if useSharedVertices = false)                M_SUBMESH_OPERATION = 0x4010, // optional, trilist assumed if missing                    // unsigned short operationType                M_SUBMESH_BONE_ASSIGNMENT = 0x4100,                    // Optional bone weights (repeating section)                    // unsigned int vertexIndex;                    // unsigned short boneIndex;                    // float weight;                // Optional chunk that matches a texture name to an alias                // a texture alias is sent to the submesh material to use this texture name                // instead of the one in the texture unit with a matching alias name                M_SUBMESH_TEXTURE_ALIAS = 0x4200, // Repeating section                    // char* aliasName;                    // char* textureName;            M_GEOMETRY          = 0x5000, // NB this chunk is embedded within M_MESH and M_SUBMESH                // unsigned int vertexCount                M_GEOMETRY_VERTEX_DECLARATION = 0x5100,                    M_GEOMETRY_VERTEX_ELEMENT = 0x5110, // Repeating section                        // unsigned short source;      // buffer bind source                        // unsigned short type;        // VertexElementType                        // unsigned short semantic; // VertexElementSemantic                        // unsigned short offset;    // start offset in buffer in bytes                        // unsigned short index;    // index of the semantic (for colours and texture coords)                M_GEOMETRY_VERTEX_BUFFER = 0x5200, // Repeating section                    // unsigned short bindIndex;    // Index to bind this buffer to                    // unsigned short vertexSize;    // Per-vertex size, must agree with declaration at this index                    M_GEOMETRY_VERTEX_BUFFER_DATA = 0x5210,                        // raw buffer data            M_MESH_SKELETON_LINK = 0x6000,                // Optional link to skeleton                // char* skeletonName           : name of .skeleton to use            M_MESH_BONE_ASSIGNMENT = 0x7000,                // Optional bone weights (repeating section)                // unsigned int vertexIndex;                // unsigned short boneIndex;                // float weight;            M_MESH_LOD = 0x8000,                // Optional LOD information                // string strategyName;                // unsigned short numLevels;                // bool manual;  (true for manual alternate meshes, false for generated)                M_MESH_LOD_USAGE = 0x8100,                // Repeating section, ordered in increasing depth                // NB LOD 0 (full detail from 0 depth) is omitted                // LOD value - this is a distance, a pixel count etc, based on strategy                // float lodValue;                    M_MESH_LOD_MANUAL = 0x8110,                    // Required if M_MESH_LOD section manual = true                    // String manualMeshName;                    M_MESH_LOD_GENERATED = 0x8120,                    // Required if M_MESH_LOD section manual = false                    // Repeating section (1 per submesh)                    // unsigned int indexCount;                    // bool indexes32Bit                    // unsigned short* faceIndexes;  (indexCount)                    // OR                    // unsigned int* faceIndexes;  (indexCount)            M_MESH_BOUNDS = 0x9000,                // float minx, miny, minz                // float maxx, maxy, maxz                // float radius                                // Added By DrEvil            // optional chunk that contains a table of submesh indexes and the names of            // the sub-meshes.            M_SUBMESH_NAME_TABLE = 0xA000,                // Subchunks of the name table. Each chunk contains an index & string                M_SUBMESH_NAME_TABLE_ELEMENT = 0xA100,                    // short index                    // char* name                        // Optional chunk which stores precomputed edge data                                 M_EDGE_LISTS = 0xB000,                // Each LOD has a separate edge list                M_EDGE_LIST_LOD = 0xB100,                    // unsigned short lodIndex                    // bool isManual            // If manual, no edge data here, loaded from manual mesh                        // bool isClosed                        // unsigned long numTriangles                        // unsigned long numEdgeGroups                        // Triangle* triangleList                            // unsigned long indexSet                            // unsigned long vertexSet                            // unsigned long vertIndex[3]                            // unsigned long sharedVertIndex[3]                             // float normal[4]                         M_EDGE_GROUP = 0xB110,                            // unsigned long vertexSet                            // unsigned long triStart                            // unsigned long triCount                            // unsigned long numEdges                            // Edge* edgeList                                // unsigned long  triIndex[2]                                // unsigned long  vertIndex[2]                                // unsigned long  sharedVertIndex[2]                                // bool degenerate            // Optional poses section, referred to by pose keyframes            M_POSES = 0xC000,                M_POSE = 0xC100,                    // char* name (may be blank)                    // unsigned short target    // 0 for shared geometry,                                                 // 1+ for submesh index + 1                    // bool includesNormals [1.8+]                    M_POSE_VERTEX = 0xC111,                        // unsigned long vertexIndex                        // float xoffset, yoffset, zoffset                        // float xnormal, ynormal, znormal (optional, 1.8+)            // Optional vertex animation chunk            M_ANIMATIONS = 0xD000,                 M_ANIMATION = 0xD100,                // char* name                // float length                M_ANIMATION_BASEINFO = 0xD105,                // [Optional] base keyframe information (pose animation only)                // char* baseAnimationName (blank for self)                // float baseKeyFrameTime                        M_ANIMATION_TRACK = 0xD110,                    // unsigned short type            // 1 == morph, 2 == pose                    // unsigned short target        // 0 for shared geometry,                                                     // 1+ for submesh index + 1                    M_ANIMATION_MORPH_KEYFRAME = 0xD111,                        // float time                        // bool includesNormals [1.8+]                        // float x,y,z            // repeat by number of vertices in original geometry                    M_ANIMATION_POSE_KEYFRAME = 0xD112,                        // float time                        M_ANIMATION_POSE_REF = 0xD113, // repeat for number of referenced poses                            // unsigned short poseIndex                             // float influence            // Optional submesh extreme vertex list chink            M_TABLE_EXTREMES = 0xE000,            // unsigned short submesh_index;            // float extremes [n_extremes][3];    /* Version 1.2 of the .mesh format (deprecated)    enum MeshChunkID {        M_HEADER                = 0x1000,            // char*          version           : Version number check        M_MESH                = 0x3000,            // bool skeletallyAnimated   // important flag which affects h/w buffer policies            // Optional M_GEOMETRY chunk            M_SUBMESH             = 0x4000,                 // char* materialName                // bool useSharedVertices                // unsigned int indexCount                // bool indexes32Bit                // unsigned int* faceVertexIndices (indexCount)                // OR                // unsigned short* faceVertexIndices (indexCount)                // M_GEOMETRY chunk (Optional: present only if useSharedVertices = false)                M_SUBMESH_OPERATION = 0x4010, // optional, trilist assumed if missing                    // unsigned short operationType                M_SUBMESH_BONE_ASSIGNMENT = 0x4100,                    // Optional bone weights (repeating section)                    // unsigned int vertexIndex;                    // unsigned short boneIndex;                    // float weight;            M_GEOMETRY          = 0x5000, // NB this chunk is embedded within M_MESH and M_SUBMESH            */                // unsigned int vertexCount                // float* pVertices (x, y, z order x numVertices)                M_GEOMETRY_NORMALS = 0x5100,    //(Optional)                    // float* pNormals (x, y, z order x numVertices)                M_GEOMETRY_COLOURS = 0x5200,    //(Optional)                    // unsigned long* pColours (RGBA 8888 format x numVertices)                M_GEOMETRY_TEXCOORDS = 0x5300    //(Optional, REPEATABLE, each one adds an extra set)                    // unsigned short dimensions    (1 for 1D, 2 for 2D, 3 for 3D)                    // float* pTexCoords  (u [v] [w] order, dimensions x numVertices)            /*            M_MESH_SKELETON_LINK = 0x6000,                // Optional link to skeleton                // char* skeletonName           : name of .skeleton to use            M_MESH_BONE_ASSIGNMENT = 0x7000,                // Optional bone weights (repeating section)                // unsigned int vertexIndex;                // unsigned short boneIndex;                // float weight;            M_MESH_LOD = 0x8000,                // Optional LOD information                // unsigned short numLevels;                // bool manual;  (true for manual alternate meshes, false for generated)                M_MESH_LOD_USAGE = 0x8100,                // Repeating section, ordered in increasing depth                // NB LOD 0 (full detail from 0 depth) is omitted                // float fromSquaredDepth;                    M_MESH_LOD_MANUAL = 0x8110,                    // Required if M_MESH_LOD section manual = true                    // String manualMeshName;                    M_MESH_LOD_GENERATED = 0x8120,                    // Required if M_MESH_LOD section manual = false                    // Repeating section (1 per submesh)                    // unsigned int indexCount;                    // bool indexes32Bit                    // unsigned short* faceIndexes;  (indexCount)                    // OR                    // unsigned int* faceIndexes;  (indexCount)            M_MESH_BOUNDS = 0x9000                // float minx, miny, minz                // float maxx, maxy, maxz                // float radius            // Added By DrEvil            // optional chunk that contains a table of submesh indexes and the names of            // the sub-meshes.            M_SUBMESH_NAME_TABLE,                // Subchunks of the name table. Each chunk contains an index & string                M_SUBMESH_NAME_TABLE_ELEMENT,                    // short index                    // char* name    */    };

        mesh的文件结构如树形,构成mesh的基本数据单位为chunk块,每个chunk块又由下面三部分组成:

    unsigned short CHUNK_ID        : one of the following chunk ids identifying the chunk    unsigned long  LENGTH          : length of the chunk in bytes, including this header    void*          DATA            : the data, which may contain other sub-chunks (various data types)
        由于内容很多,只解释mesh文件中主要的节点,如Mesh,SubMesh,Geometry,MeshSkeletonLink,MeshLOD等,有些节点中很多部分都是和动画有关,在这里,我们先分析简单的Mesh,也就是不包含动画里的。这些主节点采用如0xX000,而在各个主节点下如SubMesh(0x4000)下的分支SubMeshOperation(0x4010),SubMeshBoneAssignment(0x4100),可以看到每个主Chunk之间可以有0x1000(4096)个分Chunk。主分支的值是0x1000的整数倍,分支Chunk也可以由他的值判断是那个主分支下的节点。

     ******** M_HEADER
     Mesh文件首先是他的头文件,分别是short类型,用于检查是否是Mesh的节点0x1000,如果不是,说明此文件有误,然后是Mesh的版本信息。
     ******** M_MESH
     第一个确实是否是动画,第二个M_GEOMETRY chunk仅在mesh与submesh有共享数据时有效,在后面会详细解释。
     ******** M_SUBMESH
     下一Chunk块是SubMesh,这块里首先读取对应的材质文件,材质信息会在后面重点讲解并提取。然后有个变量useSharedVertices,如果这个为true的话,证明Mesh和本身的SubMesh共享数据。此时,只有Mesh数据有顶点信息,而所有的SubMesh只持有对应Mesh数据的顶点索引信息。useSharedVertices为false时,即是不共享数据,Mesh本身没有顶点数据信息,而各个SubMesh保存自己的顶点信息与对应的顶点索引信息。一般来说共享数据时,Mesh本身才有Geometry(保存顶点信息)节点信息的。
   每个submesh钟包含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,正确。在此块后面还有两个块,一个指定数据的组织形式(operationType),如是三角形还是四边形或是点等,后面一块指定这个Mesh的包围盒和半径。
     ******** M_MESH_LOD
     接着我们看MeshLOD Chunk,这个Chunk里,首先读取什么方式启用Lod,然后是Lod级别,然后指出是否手动生成Lod。如果是manual Lod,如果是那么就每lodlevel加载对应的manmal name,如果不是,就需要在每个lodlevel里就每个SubMesh读取MeshLODGenerated Chunk块,然后在此块读取第一个颜色块里的对应的IndexData,VertexData的数据。
  本文主要介绍了下mesh文件的结构及大致内容,其中主要内容也是参考他人博客居多,后续会重点介绍如何用程序提取这些信息。

[References]:
http://www.cnblogs.com/yzwalkman/archive/2013/02/20/2916953.html
http://www.cnblogs.com/zhouxin/p/3599680.html



0 0