用户操作
[即时聊天] [发私信] [加为好友]
蔡军生ID:caimouse
1336028次访问,排名17,好友335人,关注者532人。
C++,3D,VC++软件开发,写技术文章,操作系统开发
caimouse的文章
原创 615 篇
翻译 0 篇
转载 41 篇
评论 999 篇
蔡军生的公告

点击这里给我发消息

MSN: caimouse1976 at sina.com

最近评论
jeesy:#webkitvsfirefox 就是个SB。博主别理他。我顶你啊!真是个大牛!
derelictangel:[img=http://medal.csdn.net/ui/styles/images/yellow_3.gif][/img]

^_^
fengjl026:在一个进程分配,在另外一个进程使用的时候,地址是不是不一样?怎么转换?
liseo1:


网络营销策划 网络公关 品牌管理 搜索引擎公关 搜索引擎排名 网站优化 软文发布 QQ:441843869
工业门

各种佬虎机型干扰器|上分器|加分器13959931612|定位器|假期干扰器|飓风1-3上分器|彩金狮王定位器|闪电飓风遥控器|黑客帝国回分器|QQ87176993赛车风云破解|动物乐园||狮王传奇破解器|QQ87176993百家乐破解仪器|大小豹上分器|雪豹定位器|空军一号震荡器|QQ87176993宝藏奇兵破解|疯狂斗地主破解| 13959931612|超级斗地主包赢|大满冠……
文章分类
收藏
相册
3D引擎
第二人生
谷歌浏览器
开发板
历史回忆
常用连接
人生历程
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky

原创 第二人生的源码分析(十五)Mesh文件的读取收藏

新一篇: 第二人生的源码分析(十六)保存人物角色的XML文件 | 旧一篇: 第二人生的源码分析(十四)人物角色的实现

 

从前面可以看到人物角色显示是比较重要的,也是比较复杂的。现在就来仔细地分析一下第二人生里的Mesh文件是怎么样读取的呢?可以显示出来如此逼真优秀的画面。如下图所示:

蔡军生  2008/01/15 QQ:9073204 深圳

Mesh文件保存的格式里,最常用的有两种格式:文本格式和二进制格式。文本格式就是占用空间比较大,并且读取文件的数据也比较慢,但它便于查看。二进制格式是刚好相反的,在第二人生里使用的是二进制的文件格式。它的读取代码如下:

 

#001  BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )

#002  {

#003       //-------------------------------------------------------------------------

#004       // Open the file

#005       //-------------------------------------------------------------------------

#006       if(!fileName)

#007       {

#008              llerrs << "Filename is Empty!" << llendl;

#009              return FALSE;

#010       }

上面判断文件名称是否有效。

 

#011       FILE* fp = LLFile::fopen(fileName, "rb");               /*Flawfinder: ignore*/

#012       if (!fp)

#013       {

#014              llerrs << "can't open: " << fileName << llendl;

#015              return FALSE;

#016       }

以只读的方式打开文件。

 

#017 

#018       //-------------------------------------------------------------------------

#019       // Read a chunk

#020       //-------------------------------------------------------------------------

#021       char header[128];              /*Flawfinder: ignore*/

#022       if (fread(header, sizeof(char), 128, fp) != 128)

#023       {

#024              llwarns << "Short read" << llendl;

#025       }

读取第一块数据,大小为128个字节。这里也就是读取文件头。

 

#026 

#027       //-------------------------------------------------------------------------

#028       // Check for proper binary header

#029       //-------------------------------------------------------------------------

#030       BOOL status = FALSE;

#031       if ( strncmp(header, HEADER_BINARY, strlen(HEADER_BINARY)) == 0 )      /*Flawfinder: ignore*/

#032       {

上面是判断文件的版本。

 

#033              lldebugs << "Loading " << fileName << llendl;

#034 

#035              //----------------------------------------------------------------

#036              // File Header (seek past it)

#037              //----------------------------------------------------------------

#038              fseek(fp, 24, SEEK_SET);

移动文件指针到合适的位置。

 

#039 

#040              //----------------------------------------------------------------

#041              // HasWeights

#042              //----------------------------------------------------------------

#043              U8 hasWeights;

#044              size_t numRead = fread(&hasWeights, sizeof(U8), 1, fp);

#045              if (numRead != 1)

#046              {

#047                     llerrs << "can't read HasWeights flag from " << fileName << llendl;

#048                     return FALSE;

#049              }

#050              if (!isLOD())

#051              {

#052                     mHasWeights = (hasWeights==0) ? FALSE : TRUE;

#053              }

读取重量标志。

 

#054 

#055              //----------------------------------------------------------------

#056              // HasDetailTexCoords

#057              //----------------------------------------------------------------

#058              U8 hasDetailTexCoords;

#059              numRead = fread(&hasDetailTexCoords, sizeof(U8), 1, fp);

#060              if (numRead != 1)

#061              {

#062                     llerrs << "can't read HasDetailTexCoords flag from " << fileName << llendl;

#063                     return FALSE;

#064              }

读取是否有详细纹理坐标。

 

#065 

#066              //----------------------------------------------------------------

#067              // Position

#068              //----------------------------------------------------------------

#069              LLVector3 position;

#070              numRead = fread(position.mV, sizeof(float), 3, fp);

#071              llendianswizzle(position.mV, sizeof(float), 3);

#072              if (numRead != 3)

#073              {

#074                     llerrs << "can't read Position from " << fileName << llendl;

#075                     return FALSE;

#076              }

#077              setPosition( position );

读取网格所在的位置。

 

#078 

#079              //----------------------------------------------------------------

#080              // Rotation

#081              //----------------------------------------------------------------

#082              LLVector3 rotationAngles;

#083              numRead = fread(rotationAngles.mV, sizeof(float), 3, fp);

#084              llendianswizzle(rotationAngles.mV, sizeof(float), 3);

#085              if (numRead != 3)

#086              {

#087                     llerrs << "can't read RotationAngles from " << fileName << llendl;

#088                     return FALSE;

#089              }

读取网格旋转的角度。

 

 

#090 

#091              U8 rotationOrder;

#092              numRead = fread(&rotationOrder, sizeof(U8), 1, fp);

#093 

#094              if (numRead != 1)

#095              {

#096                     llerrs << "can't read RotationOrder from " << fileName << llendl;

#097                     return FALSE;

#098              }

#099 

#100              rotationOrder = 0;

#101 

#102              setRotation( mayaQ(  rotationAngles.mV[0],

#103                                                 rotationAngles.mV[1],

#104                                                 rotationAngles.mV[2],

#105                                                 (LLQuaternion::Order)rotationOrder ) );

读取网格旋转顺序。

 

 

#106 

#107              //----------------------------------------------------------------

#108              // Scale

#109              //----------------------------------------------------------------

#110              LLVector3 scale;

#111              numRead = fread(scale.mV, sizeof(float), 3, fp);

#112              llendianswizzle(scale.mV, sizeof(float), 3);

#113              if (numRead != 3)

#114              {

#115                     llerrs << "can't read Scale from " << fileName << llendl;

#116                     return FALSE;

#117              }

#118              setScale( scale );

读取网格缩放的大小。

 

#119 

#120              //-------------------------------------------------------------------------

#121              // Release any existing mesh geometry

#122              //-------------------------------------------------------------------------

#123              freeMeshData();

#124 

#125              U16 numVertices = 0;

#126 

#127              //----------------------------------------------------------------

#128              // NumVertices

#129              //----------------------------------------------------------------

#130              if (!isLOD())

#131              {

#132                     numRead = fread(&numVertices, sizeof(U16), 1, fp);

#133                     llendianswizzle(&numVertices, sizeof(U16), 1);

#134                     if (numRead != 1)

#135                     {

#136                            llerrs << "can't read NumVertices from " << fileName << llendl;

#137                            return FALSE;

#138                     }

#139 

#140                     allocateVertexData( numVertices );

读取网格的顶点数量,并分配顶点保存数据的内存。

 

#141 

#142                     //----------------------------------------------------------------

#143                     // Coords

#144                     //----------------------------------------------------------------

#145                     numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp);

#146                     llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices);

#147                     if (numRead != numVertices)

#148                     {

#149                            llerrs << "can't read Coordinates from " << fileName << llendl;

#150                            return FALSE;

#151                     }

#152 

上面读取网格所有顶点的坐标值。每个坐标有三个浮点数组成。

 

#153                     //----------------------------------------------------------------

#154                     // Normals

#155                     //----------------------------------------------------------------

#156                     numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp);

#157                     llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices);

#158                     if (numRead != numVertices)

#159                     {

#160                            llerrs << " can't read Normals from " << fileName << llendl;

#161                            return FALSE;

#162                     }

读取网格的顶点法向量。

 

#163 

#164                     //----------------------------------------------------------------

#165                     // Binormals

#166                     //----------------------------------------------------------------

#167                     numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp);

#168                     llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices);

#169                     if (numRead != numVertices)

#170                     {

#171                            llerrs << " can't read Binormals from " << fileName << llendl;

#172                            return FALSE;

#173                     }

读取网格的副法线向量。

 

#174 

#175 

#176                     //----------------------------------------------------------------

#177                     // TexCoords

#178                     //----------------------------------------------------------------

#179                     numRead = fread(mTexCoords, 2*sizeof(float), numVertices, fp);

#180                     llendianswizzle(mTexCoords, sizeof(float), 2*numVertices);

#181                     if (numRead != numVertices)

#182                     {

#183                            llerrs << "can't read TexCoords from " << fileName << llendl;

#184                            return FALSE;

#185                     }

读取每个顶点的纹理坐标值。

 

#186 

#187                     //----------------------------------------------------------------

#188                     // DetailTexCoords

#189                     //----------------------------------------------------------------

#190                     if (mHasDetailTexCoords)

#191                     {

#192                            numRead = fread(mDetailTexCoords, 2*sizeof(float), numVertices, fp);

#193                            llendianswizzle(mDetailTexCoords, sizeof(float), 2*numVertices);

#194                            if (numRead != numVertices)

#195                            {

#196                                   llerrs << "can't read DetailTexCoords from " << fileName << llendl;

#197                                   return FALSE;

#198                            }

#199                     }

读取详细纹理坐标值。

 

#200 

#201                     //----------------------------------------------------------------

#202                     // Weights

#203                     //----------------------------------------------------------------

#204                     if (mHasWeights)

#205                     {

#206                            numRead = fread(mWeights, sizeof(float), numVertices, fp);

#207                            llendianswizzle(mWeights, sizeof(float), numVertices);

#208                            if (numRead != numVertices)

#209                            {

#210                                   llerrs << "can't read Weights from " << fileName << llendl;

#211                                   return FALSE;

#212                            }

#213                     }

#214              }

读取每个顶点重量。

 

 

 

#215 

#216              //----------------------------------------------------------------

#217              // NumFaces

#218              //----------------------------------------------------------------

#219              U16 numFaces;

#220              numRead = fread(&numFaces, sizeof(U16), 1, fp);

#221              llendianswizzle(&numFaces, sizeof(U16), 1);

#222              if (numRead != 1)

#223              {

#224                     llerrs << "can't read NumFaces from " << fileName << llendl;

#225                     return FALSE;

#226              }

#227              allocateFaceData( numFaces );

读取网格的表面个数,并分配所有表面内存。

 

#228 

#229 

#230              //----------------------------------------------------------------

#231              // Faces

#232              //----------------------------------------------------------------

#233              U32 i;

#234              U32 numTris = 0;

#235              for (i = 0; i < numFaces; i++)

#236              {

#237                     S16 face[3];

#238                     numRead = fread(face, sizeof(U16), 3, fp);

#239                     llendianswizzle(face, sizeof(U16), 3);

#240                     if (numRead != 3)

#241                     {

#242                            llerrs << "can't read Face[" << i << "] from " << fileName << llendl;

#243                            return FALSE;

#244                     }

#245                     if (mReferenceData)

#246                     {

#247                            llassert(face[0] < mReferenceData->mNumVertices);

#248                            llassert(face[1] < mReferenceData->mNumVertices);

#249                            llassert(face[2] < mReferenceData->mNumVertices);

#250                     }

#251                    

#252                     if (isLOD())

#253                     {

#254                            // store largest index in case of LODs

#255                            for (S32 j = 0; j < 3; j++)

#256                            {