00001
00002
00003 #include <OgreStableHeaders.h>
00004 #include <OgreMeshFileFormat.h>
00005 #include <OgreMesh.h>
00006 #include <OgreSubMesh.h>
00007 #include <OgreException.h>
00008 #include <OgreLogManager.h>
00009 #include <OgreSkeleton.h>
00010 #include <OgreHardwareBufferManager.h>
00011 #include <OgreMaterial.h>
00012 #include <OgreTechnique.h>
00013 #include <OgrePass.h>
00014 #include <OgreAnimation.h>
00015 #include <OgreAnimationTrack.h>
00016 #include <OgreKeyFrame.h>
00017 #include <OgreRoot.h>
00018
00019 #include "lugre_prefix.h"
00020 #include "lugre_meshbuffer.h"
00021 #include "lugre_meshloader.h"
00022 #undef min
00023 #undef max
00024 #include <Ogre.h>
00025 #include <map>
00026 #include <string>
00027 #include <iostream>
00028 #include <fstream>
00029 #include "lugre_meshshape.h"
00030 using namespace Ogre;
00031
00032 #define MESHLOAD_SKIP
00033
00034
00035 namespace Lugre {
00036
00037 void MeshLoader_LoadFile (const char* szFilePath,cBufferedMesh* pDest) {
00038 #ifdef ENABLE_LUGRE_MESH_LOADER
00039 std::ifstream fp;
00040 fp.open(szFilePath, std::ios::in | std::ios::binary);
00041 if (!fp) { printf("MeshLoader_LoadFile:error opening file %s\n",szFilePath); return; }
00042 Ogre::DataStreamPtr stream(new FileStreamDataStream(szFilePath, &fp, false));
00043 cMeshLoader myloader;
00044 myloader.importMesh(stream,pDest);
00045 #endif
00046 }
00047
00048
00049
00050
00051
00052 #ifdef ENABLE_LUGRE_MESH_LOADER
00054 const long STREAM_OVERHEAD_SIZE = sizeof(uint16) + sizeof(uint32);
00055
00056 cMeshLoader::cMeshLoader()
00057 {
00058
00059 mVersion = "[Lugre_cMeshLoader_v1.40]";
00060 }
00061
00062 cMeshLoader::~cMeshLoader()
00063 {
00064 }
00065
00066
00067
00068 void cMeshLoader::importMesh(DataStreamPtr& stream, Mesh* pMesh)
00069 {
00070
00071 determineEndianness(stream);
00072
00073
00074 readFileHeader(stream);
00075
00076 unsigned short streamID;
00077 while(!stream->eof())
00078 {
00079 streamID = readChunk(stream);
00080 switch (streamID)
00081 {
00082 case M_MESH:
00083 readMesh(stream, pMesh);
00084 break;
00085 }
00086
00087 }
00088 }
00089
00090
00091 void cMeshLoader::readGeometry(DataStreamPtr& stream, Mesh* pMesh,
00092 VertexData* dest)
00093 {
00094
00095 dest->vertexStart = 0;
00096
00097 unsigned int vertexCount = 0;
00098 readInts(stream, &vertexCount, 1);
00099 dest->vertexCount = vertexCount;
00100
00101
00102 if (!stream->eof())
00103 {
00104 unsigned short streamID = readChunk(stream);
00105 while(!stream->eof() &&
00106 (streamID == M_GEOMETRY_VERTEX_DECLARATION ||
00107 streamID == M_GEOMETRY_VERTEX_BUFFER ))
00108 {
00109 switch (streamID)
00110 {
00111 case M_GEOMETRY_VERTEX_DECLARATION:
00112 readGeometryVertexDeclaration(stream, pMesh, dest);
00113 break;
00114 case M_GEOMETRY_VERTEX_BUFFER:
00115 readGeometryVertexBuffer(stream, pMesh, dest);
00116 break;
00117 }
00118
00119 if (!stream->eof())
00120 {
00121 streamID = readChunk(stream);
00122 }
00123 }
00124 if (!stream->eof())
00125 {
00126
00127 stream->skip(-STREAM_OVERHEAD_SIZE);
00128 }
00129 }
00130
00131
00132 if (Root::getSingletonPtr() && Root::getSingleton().getRenderSystem())
00133 {
00134
00135
00136
00137 dest->convertPackedColour(VET_COLOUR_ARGB,
00138 VertexElement::getBestColourVertexElementType());
00139 }
00140 }
00141
00142 void cMeshLoader::readGeometryVertexDeclaration(DataStreamPtr& stream,
00143 Mesh* pMesh, VertexData* dest)
00144 {
00145
00146 if (!stream->eof())
00147 {
00148 unsigned short streamID = readChunk(stream);
00149 while(!stream->eof() &&
00150 (streamID == M_GEOMETRY_VERTEX_ELEMENT ))
00151 {
00152 switch (streamID)
00153 {
00154 case M_GEOMETRY_VERTEX_ELEMENT:
00155 readGeometryVertexElement(stream, pMesh, dest);
00156 break;
00157 }
00158
00159 if (!stream->eof())
00160 {
00161 streamID = readChunk(stream);
00162 }
00163 }
00164 if (!stream->eof())
00165 {
00166
00167 stream->skip(-STREAM_OVERHEAD_SIZE);
00168 }
00169 }
00170
00171 }
00172
00173 void cMeshLoader::readGeometryVertexElement(DataStreamPtr& stream,
00174 Mesh* pMesh, VertexData* dest)
00175 {
00176 unsigned short source, offset, index, tmp;
00177 VertexElementType vType;
00178 VertexElementSemantic vSemantic;
00179
00180 readShorts(stream, &source, 1);
00181
00182 readShorts(stream, &tmp, 1);
00183 vType = static_cast<VertexElementType>(tmp);
00184
00185 readShorts(stream, &tmp, 1);
00186 vSemantic = static_cast<VertexElementSemantic>(tmp);
00187
00188 readShorts(stream, &offset, 1);
00189
00190 readShorts(stream, &index, 1);
00191
00192 dest->vertexDeclaration->addElement(source, offset, vType, vSemantic, index);
00193
00194 if (vType == VET_COLOUR)
00195 {
00196 StringUtil::StrStreamType s;
00197 s << "Warning: VET_COLOUR element type is deprecated, you should use "
00198 << "one of the more specific types to indicate the byte order. "
00199 << "Use OgreMeshUpgrade on " << pMesh->getName() << " as soon as possible. ";
00200 LogManager::getSingleton().logMessage(s.str());
00201 }
00202
00203 }
00204
00205 void cMeshLoader::readGeometryVertexBuffer(DataStreamPtr& stream,
00206 Mesh* pMesh, VertexData* dest)
00207 {
00208 unsigned short bindIndex, vertexSize;
00209
00210 readShorts(stream, &bindIndex, 1);
00211
00212 readShorts(stream, &vertexSize, 1);
00213
00214
00215 unsigned short headerID;
00216 headerID = readChunk(stream);
00217 if (headerID != M_GEOMETRY_VERTEX_BUFFER_DATA)
00218 {
00219 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Can't find vertex buffer data area",
00220 "cMeshLoader::readGeometryVertexBuffer");
00221 }
00222
00223 if (dest->vertexDeclaration->getVertexSize(bindIndex) != vertexSize)
00224 {
00225 OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer vertex size does not agree with vertex declaration",
00226 "cMeshLoader::readGeometryVertexBuffer");
00227 }
00228
00229 #ifdef MESHLOAD_SKIP
00230 stream->skip(dest->vertexCount * vertexSize);
00231 #else
00232
00233 HardwareVertexBufferSharedPtr vbuf;
00234 vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
00235 vertexSize,
00236 dest->vertexCount,
00237 pMesh->mVertexBufferUsage,
00238 pMesh->mVertexBufferShadowBuffer);
00239 void* pBuf = vbuf->lock(HardwareBuffer::HBL_DISCARD);
00240 stream->read(pBuf, dest->vertexCount * vertexSize);
00241
00242
00243 flipFromLittleEndian(
00244 pBuf,
00245 dest->vertexCount,
00246 vertexSize,
00247 dest->vertexDeclaration->findElementsBySource(bindIndex));
00248 vbuf->unlock();
00249
00250
00251 dest->vertexBufferBinding->setBinding(bindIndex, vbuf);
00252 #endif
00253 }
00254
00255 void cMeshLoader::readSubMeshNameTable(DataStreamPtr& stream, Mesh* pMesh)
00256 {
00257
00258 std::map<unsigned short, String> subMeshNames;
00259 unsigned short streamID, subMeshIndex;
00260
00261
00262
00263
00264
00265
00266
00267
00268 if (!stream->eof())
00269 {
00270 streamID = readChunk(stream);
00271 while(!stream->eof() && (streamID == M_SUBMESH_NAME_TABLE_ELEMENT ))
00272 {
00273
00274 readShorts(stream, &subMeshIndex, 1);
00275
00276 subMeshNames[subMeshIndex] = readString(stream);
00277
00278
00279 if (!stream->eof())
00280 streamID = readChunk(stream);
00281 }
00282 if (!stream->eof())
00283 {
00284
00285 stream->skip(-STREAM_OVERHEAD_SIZE);
00286 }
00287 }
00288
00289
00290
00291
00292
00293 std::map<unsigned short, String>::const_iterator it = subMeshNames.begin();
00294
00295 while(it != subMeshNames.end())
00296 {
00297
00298 pMesh->nameSubMesh(it->second, it->first);
00299 ++it;
00300 }
00301
00302
00303
00304 }
00305
00306 void cMeshLoader::readMesh(DataStreamPtr& stream, Mesh* pMesh)
00307 {
00308 unsigned short streamID;
00309
00310
00311
00312 pMesh->mAutoBuildEdgeLists = false;
00313
00314
00315 bool skeletallyAnimated;
00316 readBools(stream, &skeletallyAnimated, 1);
00317
00318
00319 if (!stream->eof())
00320 {
00321 streamID = readChunk(stream);
00322 while(!stream->eof() &&
00323 (streamID == M_GEOMETRY ||
00324 streamID == M_SUBMESH ||
00325 streamID == M_MESH_SKELETON_LINK ||
00326 streamID == M_MESH_BONE_ASSIGNMENT ||
00327 streamID == M_MESH_LOD ||
00328 streamID == M_MESH_BOUNDS ||
00329 streamID == M_SUBMESH_NAME_TABLE ||
00330 streamID == M_EDGE_LISTS ||
00331 streamID == M_POSES ||
00332 streamID == M_ANIMATIONS ||
00333 streamID == M_TABLE_EXTREMES))
00334 {
00335 switch(streamID)
00336 {
00337 case M_GEOMETRY:
00338 pMesh->sharedVertexData = new VertexData();
00339 try {
00340 readGeometry(stream, pMesh, pMesh->sharedVertexData);
00341 }
00342 catch (Exception& e)
00343 {
00344 if (e.getNumber() == Exception::ERR_ITEM_NOT_FOUND)
00345 {
00346
00347 delete pMesh->sharedVertexData;
00348 pMesh->sharedVertexData = 0;
00349
00350 stream->skip(mCurrentstreamLen - STREAM_OVERHEAD_SIZE);
00351 }
00352 else
00353 {
00354 throw;
00355 }
00356 }
00357 break;
00358 case M_SUBMESH:
00359 readSubMesh(stream, pMesh);
00360 break;
00361 case M_MESH_SKELETON_LINK:
00362 readSkeletonLink(stream, pMesh);
00363 break;
00364 case M_MESH_BONE_ASSIGNMENT:
00365 readMeshBoneAssignment(stream, pMesh);
00366 break;
00367 case M_MESH_LOD:
00368 readMeshLodInfo(stream, pMesh);
00369 break;
00370 case M_MESH_BOUNDS:
00371 readBoundsInfo(stream, pMesh);
00372 break;
00373 case M_SUBMESH_NAME_TABLE:
00374 readSubMeshNameTable(stream, pMesh);
00375 break;
00376 case M_EDGE_LISTS:
00377 readEdgeList(stream, pMesh);
00378 break;
00379 case M_POSES:
00380 readPoses(stream, pMesh);
00381 break;
00382 case M_ANIMATIONS:
00383 readAnimations(stream, pMesh);
00384 break;
00385 case M_TABLE_EXTREMES:
00386 readExtremes(stream, pMesh);
00387 break;
00388 }
00389
00390 if (!stream->eof())
00391 {
00392 streamID = readChunk(stream);
00393 }
00394
00395 }
00396 if (!stream->eof())
00397 {
00398
00399 stream->skip(-STREAM_OVERHEAD_SIZE);
00400 }
00401 }
00402
00403 }
00404
00405 void cMeshLoader::readSubMesh(DataStreamPtr& stream, Mesh* pMesh)
00406 {
00407 unsigned short streamID;
00408
00409 SubMesh* sm = pMesh->createSubMesh();
00410
00411 String materialName = readString(stream);
00412 sm->setMaterialName(materialName);
00413
00414 readBools(stream,&sm->useSharedVertices, 1);
00415
00416 sm->indexData->indexStart = 0;
00417 unsigned int indexCount = 0;
00418 readInts(stream, &indexCount, 1);
00419 sm->indexData->indexCount = indexCount;
00420
00421 HardwareIndexBufferSharedPtr ibuf;
00422
00423 bool idx32bit;
00424 readBools(stream, &idx32bit, 1);
00425 if (idx32bit)
00426 {
00427 ibuf = HardwareBufferManager::getSingleton().
00428 createIndexBuffer(
00429 HardwareIndexBuffer::IT_32BIT,
00430 sm->indexData->indexCount,
00431 pMesh->mIndexBufferUsage,
00432 pMesh->mIndexBufferShadowBuffer);
00433
00434 unsigned int* pIdx = static_cast<unsigned int*>(
00435 ibuf->lock(HardwareBuffer::HBL_DISCARD)
00436 );
00437 readInts(stream, pIdx, sm->indexData->indexCount);
00438 ibuf->unlock();
00439
00440 }
00441 else
00442 {
00443 ibuf = HardwareBufferManager::getSingleton().
00444 createIndexBuffer(
00445 HardwareIndexBuffer::IT_16BIT,
00446 sm->indexData->indexCount,
00447 pMesh->mIndexBufferUsage,
00448 pMesh->mIndexBufferShadowBuffer);
00449
00450 unsigned short* pIdx = static_cast<unsigned short*>(
00451 ibuf->lock(HardwareBuffer::HBL_DISCARD)
00452 );
00453 readShorts(stream, pIdx, sm->indexData->indexCount);
00454 ibuf->unlock();
00455 }
00456 sm->indexData->indexBuffer = ibuf;
00457
00458
00459 if (!sm->useSharedVertices)
00460 {
00461 streamID = readChunk(stream);
00462 if (streamID != M_GEOMETRY)
00463 {
00464 OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Missing geometry data in mesh file",
00465 "cMeshLoader::readSubMesh");
00466 }
00467 sm->vertexData = new VertexData();
00468 readGeometry(stream, pMesh, sm->vertexData);
00469 }
00470
00471
00472
00473 if (!stream->eof())
00474 {
00475 streamID = readChunk(stream);
00476 while(!stream->eof() &&
00477 (streamID == M_SUBMESH_BONE_ASSIGNMENT ||
00478 streamID == M_SUBMESH_OPERATION ||
00479 streamID == M_SUBMESH_TEXTURE_ALIAS))
00480 {
00481 switch(streamID)
00482 {
00483 case M_SUBMESH_OPERATION:
00484 readSubMeshOperation(stream, pMesh, sm);
00485 break;
00486 case M_SUBMESH_BONE_ASSIGNMENT:
00487 readSubMeshBoneAssignment(stream, pMesh, sm);
00488 break;
00489 case M_SUBMESH_TEXTURE_ALIAS:
00490 readSubMeshTextureAlias(stream, pMesh, sm);
00491 break;
00492 }
00493
00494 if (!stream->eof())
00495 {
00496 streamID = readChunk(stream);
00497 }
00498
00499 }
00500 if (!stream->eof())
00501 {
00502
00503 stream->skip(-STREAM_OVERHEAD_SIZE);
00504 }
00505 }
00506
00507
00508 }
00509
00510 void cMeshLoader::readSubMeshOperation(DataStreamPtr& stream,
00511 Mesh* pMesh, SubMesh* sm)
00512 {
00513
00514 unsigned short opType;
00515 readShorts(stream, &opType, 1);
00516 sm->operationType = static_cast<RenderOperation::OperationType>(opType);
00517 }
00518
00519 void cMeshLoader::readSubMeshTextureAlias(DataStreamPtr& stream, Mesh* pMesh, SubMesh* sub)
00520 {
00521 String aliasName = readString(stream);
00522 String textureName = readString(stream);
00523 sub->addTextureAlias(aliasName, textureName);
00524 }
00525
00526
00527 void cMeshLoader::readSkeletonLink(DataStreamPtr& stream, Mesh* pMesh)
00528 {
00529 String skelName = readString(stream);
00530 pMesh->setSkeletonName(skelName);
00531 }
00532
00533 void cMeshLoader::readTextureLayer(DataStreamPtr& stream, Mesh* pMesh,
00534 MaterialPtr& pMat)
00535 {
00536
00537 }
00538
00539
00540 void cMeshLoader::readMeshBoneAssignment(DataStreamPtr& stream, Mesh* pMesh)
00541 {
00542 VertexBoneAssignment assign;
00543
00544
00545 readInts(stream, &(assign.vertexIndex),1);
00546
00547 readShorts(stream, &(assign.boneIndex),1);
00548
00549 readFloats(stream, &(assign.weight), 1);
00550
00551 pMesh->addBoneAssignment(assign);
00552
00553 }
00554
00555 void cMeshLoader::readSubMeshBoneAssignment(DataStreamPtr& stream,
00556 Mesh* pMesh, SubMesh* sub)
00557 {
00558 VertexBoneAssignment assign;
00559
00560
00561 readInts(stream, &(assign.vertexIndex),1);
00562
00563 readShorts(stream, &(assign.boneIndex),1);
00564
00565 readFloats(stream, &(assign.weight), 1);
00566
00567 sub->addBoneAssignment(assign);
00568
00569 }
00570
00571
00572
00573 void cMeshLoader::readBoundsInfo(DataStreamPtr& stream, Mesh* pMesh)
00574 {
00575 Vector3 min, max;
00576
00577 readFloats(stream, &min.x, 1);
00578 readFloats(stream, &min.y, 1);
00579 readFloats(stream, &min.z, 1);
00580
00581 readFloats(stream, &max.x, 1);
00582 readFloats(stream, &max.y, 1);
00583 readFloats(stream, &max.z, 1);
00584 AxisAlignedBox box(min, max);
00585 pMesh->_setBounds(box, true);
00586
00587 float radius;
00588 readFloats(stream, &radius, 1);
00589 pMesh->_setBoundingSphereRadius(radius);
00590
00591
00592
00593 }
00594
00595 void cMeshLoader::readMeshLodInfo(DataStreamPtr& stream, Mesh* pMesh)
00596 {
00597 unsigned short streamID, i;
00598
00599
00600 readShorts(stream, &(pMesh->mNumLods), 1);
00601
00602 readBools(stream, &(pMesh->mIsLodManual), 1);
00603
00604
00605 if (!pMesh->mIsLodManual)
00606 {
00607 unsigned short numsubs = pMesh->getNumSubMeshes();
00608 for (i = 0; i < numsubs; ++i)
00609 {
00610 SubMesh* sm = pMesh->getSubMesh(i);
00611 sm->mLodFaceList.resize(pMesh->mNumLods-1);
00612 }
00613 }
00614
00615
00616 for (i = 1; i < pMesh->getNumLodLevels(); ++i)
00617 {
00618 streamID = readChunk(stream);
00619 if (streamID != M_MESH_LOD_USAGE)
00620 {
00621 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
00622 "Missing M_MESH_LOD_USAGE stream in " + pMesh->getName(),
00623 "cMeshLoader::readMeshLodInfo");
00624 }
00625
00626 MeshLodUsage usage;
00627 readFloats(stream, &(usage.fromDepthSquared), 1);
00628
00629 if (pMesh->isLodManual())
00630 {
00631 readMeshLodUsageManual(stream, pMesh, i, usage);
00632 }
00633 else
00634 {
00635 readMeshLodUsageGenerated(stream, pMesh, i, usage);
00636 }
00637 usage.edgeData = NULL;
00638
00639
00640 #ifdef MESHLOAD_SKIP
00641 #else
00642 pMesh->mMeshLodUsageList.push_back(usage);
00643 #endif
00644 }
00645
00646
00647 }
00648
00649 void cMeshLoader::readMeshLodUsageManual(DataStreamPtr& stream,
00650 Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage)
00651 {
00652 unsigned long streamID;
00653
00654 streamID = readChunk(stream);
00655 if (streamID != M_MESH_LOD_MANUAL)
00656 {
00657 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
00658 "Missing M_MESH_LOD_MANUAL stream in " + pMesh->getName(),
00659 "cMeshLoader::readMeshLodUsageManual");
00660 }
00661
00662 usage.manualName = readString(stream);
00663 usage.manualMesh.setNull();
00664 }
00665
00666 void cMeshLoader::readMeshLodUsageGenerated(DataStreamPtr& stream,
00667 Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage)
00668 {
00669 usage.manualName = "";
00670 usage.manualMesh.setNull();
00671
00672
00673 unsigned short numSubs, i;
00674 unsigned long streamID;
00675 numSubs = pMesh->getNumSubMeshes();
00676 for (i = 0; i < numSubs; ++i)
00677 {
00678 streamID = readChunk(stream);
00679 if (streamID != M_MESH_LOD_GENERATED)
00680 {
00681 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
00682 "Missing M_MESH_LOD_GENERATED stream in " + pMesh->getName(),
00683 "cMeshLoader::readMeshLodUsageGenerated");
00684 }
00685
00686 SubMesh* sm = pMesh->getSubMesh(i);
00687
00688 sm->mLodFaceList[lodNum - 1] = new IndexData();
00689 IndexData* indexData = sm->mLodFaceList[lodNum - 1];
00690
00691 unsigned int numIndexes;
00692 readInts(stream, &numIndexes, 1);
00693 indexData->indexCount = static_cast<size_t>(numIndexes);
00694
00695 bool idx32Bit;
00696 readBools(stream, &idx32Bit, 1);
00697
00698 if (idx32Bit)
00699 {
00700 #ifdef MESHLOAD_SKIP
00701 stream->skip(indexData->indexCount * sizeof(int));
00702 #else
00703 indexData->indexBuffer = HardwareBufferManager::getSingleton().
00704 createIndexBuffer(HardwareIndexBuffer::IT_32BIT, indexData->indexCount,
00705 pMesh->mIndexBufferUsage, pMesh->mIndexBufferShadowBuffer);
00706 unsigned int* pIdx = static_cast<unsigned int*>(
00707 indexData->indexBuffer->lock(
00708 0,
00709 indexData->indexBuffer->getSizeInBytes(),
00710 HardwareBuffer::HBL_DISCARD) );
00711
00712 readInts(stream, pIdx, indexData->indexCount);
00713 indexData->indexBuffer->unlock();
00714 #endif
00715 }
00716 else
00717 {
00718 #ifdef MESHLOAD_SKIP
00719 stream->skip(indexData->indexCount * sizeof(short));
00720 #else
00721 indexData->indexBuffer = HardwareBufferManager::getSingleton().
00722 createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount,
00723 pMesh->mIndexBufferUsage, pMesh->mIndexBufferShadowBuffer);
00724 unsigned short* pIdx = static_cast<unsigned short*>(
00725 indexData->indexBuffer->lock(
00726 0,
00727 indexData->indexBuffer->getSizeInBytes(),
00728 HardwareBuffer::HBL_DISCARD) );
00729 readShorts(stream, pIdx, indexData->indexCount);
00730 indexData->indexBuffer->unlock();
00731 #endif
00732 }
00733
00734 }
00735 }
00736
00737 void cMeshLoader::flipFromLittleEndian(void* pData, size_t vertexCount,
00738 size_t vertexSize, const VertexDeclaration::VertexElementList& elems)
00739 {
00740 if (mFlipEndian)
00741 {
00742 flipEndian(pData, vertexCount, vertexSize, elems);
00743 }
00744 }
00745
00746 void cMeshLoader::flipToLittleEndian(void* pData, size_t vertexCount,
00747 size_t vertexSize, const VertexDeclaration::VertexElementList& elems)
00748 {
00749 if (mFlipEndian)
00750 {
00751 flipEndian(pData, vertexCount, vertexSize, elems);
00752 }
00753 }
00754
00755 void cMeshLoader::flipEndian(void* pData, size_t vertexCount,
00756 size_t vertexSize, const VertexDeclaration::VertexElementList& elems)
00757 {
00758 void *pBase = pData;
00759 for (size_t v = 0; v < vertexCount; ++v)
00760 {
00761 VertexDeclaration::VertexElementList::const_iterator ei, eiend;
00762 eiend = elems.end();
00763 for (ei = elems.begin(); ei != eiend; ++ei)
00764 {
00765 void *pElem;
00766
00767 (*ei).baseVertexPointerToElement(pBase, &pElem);
00768
00769 size_t typeSize = 0;
00770 switch (VertexElement::getBaseType((*ei).getType()))
00771 {
00772 case VET_FLOAT1:
00773 typeSize = sizeof(float);
00774 break;
00775 case VET_SHORT1:
00776 typeSize = sizeof(short);
00777 break;
00778 case VET_COLOUR:
00779 case VET_COLOUR_ABGR:
00780 case VET_COLOUR_ARGB:
00781 typeSize = sizeof(RGBA);
00782 break;
00783 case VET_UBYTE4:
00784 typeSize = 0;
00785 break;
00786 default:
00787 assert(false);
00788 };
00789 Serializer::flipEndian(pElem, typeSize,
00790 VertexElement::getTypeCount((*ei).getType()));
00791
00792 }
00793
00794 pBase = static_cast<void*>(
00795 static_cast<unsigned char*>(pBase) + vertexSize);
00796
00797 }
00798 }
00799
00800
00801
00802 void cMeshLoader::readEdgeList(DataStreamPtr& stream, Mesh* pMesh)
00803 {
00804 unsigned short streamID;
00805
00806 if (!stream->eof())
00807 {
00808 streamID = readChunk(stream);
00809 while(!stream->eof() &&
00810 streamID == M_EDGE_LIST_LOD)
00811 {
00812
00813
00814
00815 unsigned short lodIndex;
00816 readShorts(stream, &lodIndex, 1);
00817
00818
00819 bool isManual;
00820 readBools(stream, &isManual, 1);
00821
00822 if (!isManual)
00823 {
00824 MeshLodUsage& usage = const_cast<MeshLodUsage&>(pMesh->getLodLevel(lodIndex));
00825
00826 usage.edgeData = new EdgeData();
00827
00828
00829 readEdgeListLodInfo(stream, usage.edgeData);
00830
00831
00832 EdgeData::EdgeGroupList::iterator egi, egend;
00833 egend = usage.edgeData->edgeGroups.end();
00834 for (egi = usage.edgeData->edgeGroups.begin(); egi != egend; ++egi)
00835 {
00836 EdgeData::EdgeGroup& edgeGroup = *egi;
00837
00838
00839
00840 if (pMesh->sharedVertexData)
00841 {
00842 if (edgeGroup.vertexSet == 0)
00843 {
00844 edgeGroup.vertexData = pMesh->sharedVertexData;
00845 }
00846 else
00847 {
00848 edgeGroup.vertexData = pMesh->getSubMesh(
00849 edgeGroup.vertexSet-1)->vertexData;
00850 }
00851 }
00852 else
00853 {
00854 edgeGroup.vertexData = pMesh->getSubMesh(
00855 edgeGroup.vertexSet)->vertexData;
00856 }
00857 }
00858 }
00859
00860 if (!stream->eof())
00861 {
00862 streamID = readChunk(stream);
00863 }
00864
00865 }
00866 if (!stream->eof())
00867 {
00868
00869 stream->skip(-STREAM_OVERHEAD_SIZE);
00870 }
00871 }
00872
00873 #ifdef MESHLOAD_SKIP
00874 #else
00875 pMesh->mEdgeListsBuilt = true;
00876 #endif
00877 }
00878
00879 void cMeshLoader::readEdgeListLodInfo(DataStreamPtr& stream,
00880 EdgeData* edgeData)
00881 {
00882
00883 readBools(stream, &edgeData->isClosed, 1);
00884
00885 uint32 numTriangles;
00886 readInts(stream, &numTriangles, 1);
00887
00888 edgeData->triangles.resize(numTriangles);
00889 edgeData->triangleFaceNormals.resize(numTriangles);
00890 edgeData->triangleLightFacings.resize(numTriangles);
00891
00892 uint32 numEdgeGroups;
00893 readInts(stream, &numEdgeGroups, 1);
00894
00895 edgeData->edgeGroups.resize(numEdgeGroups);
00896
00897 uint32 tmp[3];
00898 for (size_t t = 0; t < numTriangles; ++t)
00899 {
00900 EdgeData::Triangle& tri = edgeData->triangles[t];
00901
00902 readInts(stream, tmp, 1);
00903 tri.indexSet = tmp[0];
00904
00905 readInts(stream, tmp, 1);
00906 tri.vertexSet = tmp[0];
00907
00908 readInts(stream, tmp, 3);
00909 tri.vertIndex[0] = tmp[0];
00910 tri.vertIndex[1] = tmp[1];
00911 tri.vertIndex[2] = tmp[2];
00912
00913 readInts(stream, tmp, 3);
00914 tri.sharedVertIndex[0] = tmp[0];
00915 tri.sharedVertIndex[1] = tmp[1];
00916 tri.sharedVertIndex[2] = tmp[2];
00917
00918 readFloats(stream, &(edgeData->triangleFaceNormals[t].x), 4);
00919
00920 }
00921
00922 for (uint32 eg = 0; eg < numEdgeGroups; ++eg)
00923 {
00924 unsigned short streamID = readChunk(stream);
00925 if (streamID != M_EDGE_GROUP)
00926 {
00927 OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
00928 "Missing M_EDGE_GROUP stream",
00929 "cMeshLoader::readEdgeListLodInfo");
00930 }
00931 EdgeData::EdgeGroup& edgeGroup = edgeData->edgeGroups[eg];
00932
00933
00934 readInts(stream, tmp, 1);
00935 edgeGroup.vertexSet = tmp[0];
00936
00937 readInts(stream, tmp, 1);
00938 edgeGroup.triStart = tmp[0];
00939
00940 readInts(stream, tmp, 1);
00941 edgeGroup.triCount = tmp[0];
00942
00943 uint32 numEdges;
00944 readInts(stream, &numEdges, 1);
00945 edgeGroup.edges.resize(numEdges);
00946
00947 for (uint32 e = 0; e < numEdges; ++e)
00948 {
00949 EdgeData::Edge& edge = edgeGroup.edges[e];
00950
00951 readInts(stream, tmp, 2);
00952 edge.triIndex[0] = tmp[0];
00953 edge.triIndex[1] = tmp[1];
00954
00955 readInts(stream, tmp, 2);
00956 edge.vertIndex[0] = tmp[0];
00957 edge.vertIndex[1] = tmp[1];
00958
00959 readInts(stream, tmp, 2);
00960 edge.sharedVertIndex[0] = tmp[0];
00961 edge.sharedVertIndex[1] = tmp[1];
00962
00963 readBools(stream, &(edge.degenerate), 1);
00964 }
00965 }
00966 }
00967
00968
00969 void cMeshLoader::readPoses(DataStreamPtr& stream, Mesh* pMesh)
00970 {
00971 unsigned short streamID;
00972
00973
00974 if (!stream->eof())
00975 {
00976 streamID = readChunk(stream);
00977 while(!stream->eof() &&
00978 (streamID == M_POSE))
00979 {
00980 switch(streamID)
00981 {
00982 case M_POSE:
00983 readPose(stream, pMesh);
00984 break;
00985
00986 }
00987
00988 if (!stream->eof())
00989 {
00990 streamID = readChunk(stream);
00991 }
00992
00993 }
00994 if (!stream->eof())
00995 {
00996
00997 stream->skip(-STREAM_OVERHEAD_SIZE);
00998 }
00999 }
01000 }
01001
01002 void cMeshLoader::readPose(DataStreamPtr& stream, Mesh* pMesh)
01003 {
01004
01005 String name = readString(stream);
01006
01007 unsigned short target;
01008 readShorts(stream, &target, 1);
01009
01010 Pose* pose = pMesh->createPose(target, name);
01011
01012
01013 unsigned short streamID;
01014 if (!stream->eof())
01015 {
01016 streamID = readChunk(stream);
01017 while(!stream->eof() &&
01018 (streamID == M_POSE_VERTEX))
01019 {
01020 switch(streamID)
01021 {
01022 case M_POSE_VERTEX:
01023
01024 uint32 vertIndex;
01025 Vector3 offset;
01026
01027 readInts(stream, &vertIndex, 1);
01028
01029 readFloats(stream, offset.ptr(), 3);
01030
01031 pose->addVertex(vertIndex, offset);
01032 break;
01033
01034 }
01035
01036 if (!stream->eof())
01037 {
01038 streamID = readChunk(stream);
01039 }
01040
01041 }
01042 if (!stream->eof())
01043 {
01044
01045 stream->skip(-STREAM_OVERHEAD_SIZE);
01046 }
01047 }
01048
01049 }
01050
01051 void cMeshLoader::readAnimations(DataStreamPtr& stream, Mesh* pMesh)
01052 {
01053 unsigned short streamID;
01054
01055
01056 if (!stream->eof())
01057 {
01058 streamID = readChunk(stream);
01059 while(!stream->eof() &&
01060 (streamID == M_ANIMATION))
01061 {
01062 switch(streamID)
01063 {
01064 case M_ANIMATION:
01065 readAnimation(stream, pMesh);
01066 break;
01067
01068 }
01069
01070 if (!stream->eof())
01071 {
01072 streamID = readChunk(stream);
01073 }
01074
01075 }
01076 if (!stream->eof())
01077 {
01078
01079 stream->skip(-STREAM_OVERHEAD_SIZE);
01080 }
01081 }
01082
01083
01084 }
01085
01086 void cMeshLoader::readAnimation(DataStreamPtr& stream, Mesh* pMesh)
01087 {
01088
01089
01090 String name = readString(stream);
01091
01092 float len;
01093 readFloats(stream, &len, 1);
01094
01095 Animation* anim = pMesh->createAnimation(name, len);
01096
01097
01098 unsigned short streamID;
01099
01100 if (!stream->eof())
01101 {
01102 streamID = readChunk(stream);
01103 while(!stream->eof() &&
01104 streamID == M_ANIMATION_TRACK)
01105 {
01106 switch(streamID)
01107 {
01108 case M_ANIMATION_TRACK:
01109 readAnimationTrack(stream, anim, pMesh);
01110 break;
01111 };
01112 if (!stream->eof())
01113 {
01114 streamID = readChunk(stream);
01115 }
01116
01117 }
01118 if (!stream->eof())
01119 {
01120
01121 stream->skip(-STREAM_OVERHEAD_SIZE);
01122 }
01123 }
01124 }
01125
01126 void cMeshLoader::readAnimationTrack(DataStreamPtr& stream,
01127 Animation* anim, Mesh* pMesh)
01128 {
01129
01130 uint16 inAnimType;
01131 readShorts(stream, &inAnimType, 1);
01132 VertexAnimationType animType = (VertexAnimationType)inAnimType;
01133
01134
01135 uint16 target;
01136 readShorts(stream, &target, 1);
01137
01138 VertexAnimationTrack* track = anim->createVertexTrack(target,
01139 pMesh->getVertexDataByTrackHandle(target), animType);
01140
01141
01142 unsigned short streamID;
01143
01144 if (!stream->eof())
01145 {
01146 streamID = readChunk(stream);
01147 while(!stream->eof() &&
01148 (streamID == M_ANIMATION_MORPH_KEYFRAME ||
01149 streamID == M_ANIMATION_POSE_KEYFRAME))
01150 {
01151 switch(streamID)
01152 {
01153 case M_ANIMATION_MORPH_KEYFRAME:
01154 readMorphKeyFrame(stream, track);
01155 break;
01156 case M_ANIMATION_POSE_KEYFRAME:
01157 readPoseKeyFrame(stream, track);
01158 break;
01159 };
01160 if (!stream->eof())
01161 {
01162 streamID = readChunk(stream);
01163 }
01164
01165 }
01166 if (!stream->eof())
01167 {
01168
01169 stream->skip(-STREAM_OVERHEAD_SIZE);
01170 }
01171 }
01172
01173 }
01174
01175 void cMeshLoader::readMorphKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track)
01176 {
01177
01178 float timePos;
01179 readFloats(stream, &timePos, 1);
01180
01181 VertexMorphKeyFrame* kf = track->createVertexMorphKeyFrame(timePos);
01182
01183
01184 size_t vertexCount = track->getAssociatedVertexData()->vertexCount;
01185 HardwareVertexBufferSharedPtr vbuf =
01186 HardwareBufferManager::getSingleton().createVertexBuffer(
01187 VertexElement::getTypeSize(VET_FLOAT3), vertexCount,
01188 HardwareBuffer::HBU_STATIC, true);
01189
01190 float* pDst = static_cast<float*>(
01191 vbuf->lock(HardwareBuffer::HBL_DISCARD));
01192 readFloats(stream, pDst, vertexCount * 3);
01193 vbuf->unlock();
01194 kf->setVertexBuffer(vbuf);
01195
01196 }
01197
01198 void cMeshLoader::readPoseKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track)
01199 {
01200
01201 float timePos;
01202 readFloats(stream, &timePos, 1);
01203
01204
01205 VertexPoseKeyFrame* kf = track->createVertexPoseKeyFrame(timePos);
01206
01207 unsigned short streamID;
01208
01209 if (!stream->eof())
01210 {
01211 streamID = readChunk(stream);
01212 while(!stream->eof() &&
01213 streamID == M_ANIMATION_POSE_REF)
01214 {
01215 switch(streamID)
01216 {
01217 case M_ANIMATION_POSE_REF:
01218 uint16 poseIndex;
01219 float influence;
01220
01221 readShorts(stream, &poseIndex, 1);
01222
01223 readFloats(stream, &influence, 1);
01224
01225 kf->addPoseReference(poseIndex, influence);
01226
01227 break;
01228 };
01229 if (!stream->eof())
01230 {
01231 streamID = readChunk(stream);
01232 }
01233
01234 }
01235 if (!stream->eof())
01236 {
01237
01238 stream->skip(-STREAM_OVERHEAD_SIZE);
01239 }
01240 }
01241
01242 }
01243
01244
01245 void cMeshLoader::readExtremes(DataStreamPtr& stream, Mesh *pMesh)
01246 {
01247 unsigned short idx;
01248 readShorts(stream, &idx, 1);
01249
01250 SubMesh *sm = pMesh->getSubMesh (idx);
01251
01252 int n_floats = (mCurrentstreamLen - STREAM_OVERHEAD_SIZE -
01253 sizeof (unsigned short)) / sizeof (float);
01254
01255 assert ((n_floats % 3) == 0);
01256
01257 float *vert = new float[n_floats];
01258 readFloats(stream, vert, n_floats);
01259
01260 for (int i = 0; i < n_floats; i += 3)
01261 sm->extremityPoints.push_back(Vector3(vert [i], vert [i + 1], vert [i + 2]));
01262
01263 delete [] vert;
01264 }
01265
01266
01267
01268
01269 #endif
01270
01271 }
01272