您的位置:首页 > 其它

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

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

蔡军生 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 {

#257 if (face[j] > mNumVertices - 1)

#258 {

#259 mNumVertices = face[j] + 1;

#260 }

#261 }

#262 }

#263 mFaces[i][0] = face[0];

#264 mFaces[i][1] = face[1];

#265 mFaces[i][2] = face[2];

#266

#267 // S32 j;

#268 // for(j = 0; j < 3; j++)

#269 // {

#270 // LLDynamicArray<S32> *face_list = mVertFaceMap.getIfThere(face[j]);

#271 // if (!face_list)

#272 // {

#273 // face_list = new LLDynamicArray<S32>;

#274 // mVertFaceMap.addData(face[j], face_list);

#275 // }

#276 // face_list->put(i);

#277 // }

#278

#279 numTris++;

#280 }

#281

#282 lldebugs << "verts: " << numVertices

#283 << ", faces: " << numFaces

#284 << ", tris: " << numTris

#285 << llendl;

上面读取每个表面的索引值。

#286

#287 //----------------------------------------------------------------

#288 // NumSkinJoints

#289 //----------------------------------------------------------------

#290 if (!isLOD())

#291 {

#292 U16 numSkinJoints = 0;

#293 if ( mHasWeights )

#294 {

#295 numRead = fread(&numSkinJoints, sizeof(U16), 1, fp);

#296 llendianswizzle(&numSkinJoints, sizeof(U16), 1);

#297 if (numRead != 1)

#298 {

#299 llerrs << "can't read NumSkinJoints from " << fileName << llendl;

#300 return FALSE;

#301 }

#302 allocateJointNames( numSkinJoints );

#303 }

读取有多少个联接名称。

#304

#305 //----------------------------------------------------------------

#306 // SkinJoints

#307 //----------------------------------------------------------------

#308 for (i=0; i < numSkinJoints; i++)

#309 {

#310 char jointName[64+1];

#311 numRead = fread(jointName, sizeof(jointName)-1, 1, fp);

#312 jointName[sizeof(jointName)-1] = '/0'; // ensure nul-termination

#313 if (numRead != 1)

#314 {

#315 llerrs << "can't read Skin[" << i << "].Name from " << fileName << llendl;

#316 return FALSE;

#317 }

#318

#319 std::string *jn = &mJointNames[i];

#320 *jn = jointName;

#321 }

#322

读取联接名称。

#323 //-------------------------------------------------------------------------

#324 // look for morph section

#325 //-------------------------------------------------------------------------

#326 char morphName[64+1];

#327 morphName[sizeof(morphName)-1] = '/0'; // ensure nul-termination

#328 while(fread(&morphName, sizeof(char), 64, fp) == 64)

#329 {

#330 if (!strcmp(morphName, "End Morphs"))

#331 {

#332 // we reached the end of the morphs

#333 break;

#334 }

#335 LLPolyMorphData* morph_data = new LLPolyMorphData(morphName);

#336

#337 BOOL result = morph_data->loadBinary(fp, this);

#338

#339 if (!result)

#340 {

#341 delete morph_data;

#342 continue;

#343 }

#344

#345 mMorphData.addData(morph_data);

#346 }

#347

#348 S32 numRemaps;

#349 if (fread(&numRemaps, sizeof(S32), 1, fp) == 1)

#350 {

#351 llendianswizzle(&numRemaps, sizeof(S32), 1);

#352 for (S32 i = 0; i < numRemaps; i++)

#353 {

#354 S32 remapSrc;

#355 S32 remapDst;

#356 if (fread(&remapSrc, sizeof(S32), 1, fp) != 1)

#357 {

#358 llerrs << "can't read source vertex in vertex remap data" << llendl;

#359 break;

#360 }

#361 if (fread(&remapDst, sizeof(S32), 1, fp) != 1)

#362 {

#363 llerrs << "can't read destination vertex in vertex remap data" << llendl;

#364 break;

#365 }

#366 llendianswizzle(&remapSrc, sizeof(S32), 1);

#367 llendianswizzle(&remapDst, sizeof(S32), 1);

#368

#369 mSharedVerts[remapSrc] = remapDst;

#370 }

#371 }

#372 }

上面读取动画方面的数据。

#373

#374 status = TRUE;

#375 }

#376 else

#377 {

#378 llerrs << "invalid mesh file header: " << fileName << llendl;

#379 status = FALSE;

#380 }

#381

#382 if (0 == mNumJointNames)

#383 {

#384 allocateJointNames(1);

#385 }

#386

#387 fclose( fp );

#388

#389 return status;

#390 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐