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


        MeshSerializer::importMesh()调用的MeshSerializerImpl::importMesh()(参见:http://www.cnblogs.com/yzwalkman/archive/2013/02/21/2920277.html Mesh文件结构及加载(二)第三段代码37行)展开如下:

     1     void MeshSerializerImpl::importMesh(DataStreamPtr& stream, Mesh* pMesh, MeshSerializerListener *listener)
     2     {
     3         // Determine endianness (must be the first thing we do!)
     4         determineEndianness(stream);
     5 
     6         // Check header
     7         readFileHeader(stream);
     8 
     9         unsigned short streamID;
    10         while(!stream->eof())
    11         {
    12             streamID = readChunk(stream);
    13             switch (streamID)
    14             {
    15             case M_MESH:
    16                 readMesh(stream, pMesh, listener);
    17                 break;
    18             }
    19 
    20         }
    21     }

        以上代码中的10-20行说明,一个Mesh文件可以有多个id值为M_MESH的chunk(参见:http://www.cnblogs.com/yzwalkman/archive/2013/02/20/2916953.html Mesh文件结构及加载(一))。对每个M_MESH的chunk的读取工作由readMesh函数来完成。readMesh函数展开如下:

     1  void MeshSerializerImpl::readMesh(DataStreamPtr& stream, Mesh* pMesh, MeshSerializerListener *listener)
     2     {
     3         // Never automatically build edge lists for this version
     4         // expect them in the file or not at all
     5         pMesh->mAutoBuildEdgeLists = false;
     6 
     7         // bool skeletallyAnimated
     8         bool skeletallyAnimated;
     9         readBools(stream, &skeletallyAnimated, 1);
    10 
    11         // Find all substreams
    12         if (!stream->eof())
    13         {
    14             unsigned short streamID = readChunk(stream);
    15             while(!stream->eof() &&
    16                 (streamID == M_GEOMETRY ||
    17                  streamID == M_SUBMESH ||
    18                  streamID == M_MESH_SKELETON_LINK ||
    19                  streamID == M_MESH_BONE_ASSIGNMENT ||
    20                  streamID == M_MESH_LOD ||
    21                  streamID == M_MESH_BOUNDS ||
    22                  streamID == M_SUBMESH_NAME_TABLE ||
    23                  streamID == M_EDGE_LISTS ||
    24                  streamID == M_POSES ||
    25                  streamID == M_ANIMATIONS ||
    26                  streamID == M_TABLE_EXTREMES))
    27             {
    28                 switch(streamID)
    29                 {
    30                 case M_GEOMETRY:
    31                     pMesh->sharedVertexData = OGRE_NEW VertexData();
    32                     try {
    33                         readGeometry(stream, pMesh, pMesh->sharedVertexData);
    34                     }
    35                     catch (Exception& e)
    36                     {
    37                         if (e.getNumber() == Exception::ERR_ITEM_NOT_FOUND)
    38                         {
    39                             // duff geometry data entry with 0 vertices
    40                             OGRE_DELETE pMesh->sharedVertexData;
    41                             pMesh->sharedVertexData = 0;
    42                             // Skip this stream (pointer will have been returned to just after header)
    43                             stream->skip(mCurrentstreamLen - MSTREAM_OVERHEAD_SIZE);
    44                         }
    45                         else
    46                         {
    47                             throw;
    48                         }
    49                     }
    50                     break;
    51                 case M_SUBMESH:
    52                     readSubMesh(stream, pMesh, listener);
    53                     break;
    54                 case M_MESH_SKELETON_LINK:
    55                     readSkeletonLink(stream, pMesh, listener);
    56                     break;
    57                 case M_MESH_BONE_ASSIGNMENT:
    58                     readMeshBoneAssignment(stream, pMesh);
    59                     break;
    60                 case M_MESH_LOD:
    61                     readMeshLodInfo(stream, pMesh);
    62                     break;
    63                 case M_MESH_BOUNDS:
    64                     readBoundsInfo(stream, pMesh);
    65                     break;
    66                 case M_SUBMESH_NAME_TABLE:
    67                     readSubMeshNameTable(stream, pMesh);
    68                     break;
    69                 case M_EDGE_LISTS:
    70                     readEdgeList(stream, pMesh);
    71                     break;
    72                 case M_POSES:
    73                     readPoses(stream, pMesh);
    74                     break;
    75                 case M_ANIMATIONS:
    76                     readAnimations(stream, pMesh);
    77                     break;
    78                 case M_TABLE_EXTREMES:
    79                     readExtremes(stream, pMesh);
    80                     break;
    81                 }
    82 
    83                 if (!stream->eof())
    84                 {
    85                     streamID = readChunk(stream);
    86                 }
    87 
    88             }
    89             if (!stream->eof())
    90             {
    91                 // Backpedal back to start of stream
    92                 stream->skip(-MSTREAM_OVERHEAD_SIZE);
    93             }
    94         }
    95 
    96     }

         某些自定义的3D文件,会出现递归结构——比如在submesh中还可以定义submesh。读取这种结构的文件数据,就要依靠函数的递归调用。但Ogre的Mesh文件格式没有这么复杂的嵌套定义,故只需要在一个循环的状态机中即可实现所有数据的正确导入。15-88行即是这样一种循环状态机结构,这种程序结构是与Ogre的Mesh文件结构相对应的。

    作者:yzwalkman
    转载请注明出处。
  • 相关阅读:
    自动化测试selenium教程
    Java开发.gitignore文件包含.iml,.log的看法
    基于接口设计与编程
    搭建大众点评CAT监控平台
    正确的打日志姿势
    【每天一条Linux指令-Day1】kill掉多个mysql的进程
    一道SQL面试题——表行列数据转换(表转置)
    @SuppressWarnings注解用法详解
    Spring IoC的底层技术支持——Java反射机制
    出现java.lang.NoSuchMethodError错误的原因
  • 原文地址:https://www.cnblogs.com/yzwalkman/p/2922077.html
Copyright © 2020-2023  润新知