63 std::string meshName = std::string(mOrigin->mName.C_Str());
66 if (meshName.find(
"Ifc") != std::string::npos)
67 meshName = meshName.substr(0, meshName.length() - 22);
77 mOgreMesh = Ogre::MeshManager::getSingleton().createManual(meshName.c_str(), mScene->
getRessourceGroup());
79 catch(Ogre::Exception &)
86 unsigned int nbSubMeshes = mOrigin->mNumMeshes;
87 for(
unsigned int n=0; n < mOrigin->mNumMeshes; ++n)
89 aiMesh* subMesh = mScene->
getAiScene()->mMeshes[mOrigin->mMeshes[n]];
91 if (subMesh->HasBones())
100 std::string skeletonName = mOgreMesh->getName() +
".skeleton";
101 mSkeleton = Ogre::SkeletonManager::getSingleton().create(skeletonName, mScene->
getRessourceGroup(),
true);
102 ALSkeleton sklAnim(mScene, mSkeleton, mOrigin);
103 mSkeletonAnim = sklAnim;
115 aiMatrix4x4 meshInverseTrans = (mOrigin->mParent != NULL) ? mOrigin->mParent->mTransformation * mOrigin->mTransformation : mOrigin->mTransformation;
116 meshInverseTrans.Inverse();
121 mOgreMesh->setSkeletonName(mOgreMesh->getName() +
".skeleton");
123 catch(Ogre::Exception &)
130 Ogre::AxisAlignedBox bbox = mOgreMesh->getBounds();
131 Ogre::Vector3 min1 = mBounding.getMinimum();
132 Ogre::Vector3 max1 = mBounding.getMaximum();
135 Ogre::Vector3 min2(min1.x, min1.y, min1.z);
136 Ogre::Vector3 max2(max1.x, max1.y, max1.z);
137 Ogre::AxisAlignedBox newbbox;
138 newbbox.setExtents(min2, max2);
143 unsigned short srcTex, destTex;
144 Ogre::VertexElementSemantic targetSemantic = Ogre::VES_TANGENT;
147 canBuild = !mOgreMesh->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, srcTex, destTex);
150 mOgreMesh->buildTangentVectors(targetSemantic, srcTex, destTex,
false,
false,
false);
152 catch (Ogre::Exception &)
161 mOgreMesh->_setBounds(bbox,
false);
162 mOgreMesh->_setBoundingSphereRadius(mSphereRadius);
165 if (mOgreMesh->sharedVertexData)
167 Ogre::VertexData* vdata = mOgreMesh->getVertexDataByTrackHandle(0);
168 Ogre::VertexDeclaration* newadcl = vdata->vertexDeclaration->getAutoOrganisedDeclaration(mOgreMesh->hasSkeleton(), mOgreMesh->hasVertexAnimation(), mOgreMesh->getSharedVertexDataAnimationIncludesNormals());
169 vdata->reorganiseBuffers(newadcl);
170 vdata->removeUnusedBuffers();
173 Ogre::VertexDeclaration* newDcl = mOgreMesh->sharedVertexData->vertexDeclaration->getAutoOrganisedDeclaration(
174 mOgreMesh->hasSkeleton(), mOgreMesh->hasVertexAnimation(), mOgreMesh->getSharedVertexDataAnimationIncludesNormals());
176 vdata->reorganiseBuffers(newDcl);
178 mOgreMesh->sharedVertexData->removeUnusedBuffers();
181 const Ogre::Mesh::SubMeshList submeshes = mOgreMesh->getSubMeshes();
183 for (
unsigned int i = 0; i < submeshes.size(); i++)
185 Ogre::SubMesh* sm = submeshes[i];
186 if (!sm->useSharedVertices)
188 const bool hasVertexAnim = sm->getVertexAnimationType() != Ogre::VAT_NONE;
190 Ogre::VertexData* vdata = mOgreMesh->getVertexDataByTrackHandle(subIdx + 1);
191 Ogre::VertexDeclaration* newadcl = vdata->vertexDeclaration->getAutoOrganisedDeclaration(mOgreMesh->hasSkeleton(), hasVertexAnim, sm->getVertexAnimationIncludesNormals());
192 vdata->reorganiseBuffers(newadcl);
193 vdata->removeUnusedBuffers();
196 Ogre::VertexDeclaration* newDcl = sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(
197 mOgreMesh->hasSkeleton(), hasVertexAnim, sm->getVertexAnimationIncludesNormals());
199 if (*newDcl != *(sm->vertexData->vertexDeclaration))
200 sm->vertexData->reorganiseBuffers(newDcl);
202 sm->vertexData->removeUnusedBuffers();
214 unsigned int nbSubMeshes = mOrigin->mNumMeshes;
215 Ogre::MaterialManager* materialManager = Ogre::MaterialManager::getSingletonPtr();
218 for(
unsigned int n=0; n<nbSubMeshes; ++n)
220 aiMesh* currentSubMesh = mScene->
getAiScene()->mMeshes[mOrigin->mMeshes[n]];
221 std::string smName = currentSubMesh->mName.C_Str();
224 Ogre::SubMesh* submesh = ogMesh->createSubMesh(smName);
225 submesh->operationType = (currentSubMesh->HasFaces()) ? Ogre::RenderOperation::OT_TRIANGLE_LIST : Ogre::RenderOperation::OT_POINT_LIST;
228 submesh->useSharedVertices =
false;
230 matName = materialNames[currentSubMesh->mMaterialIndex];
232 if (!matName.empty())
236 submesh->setMaterialName(matName);
241 if (currentSubMesh->mNumBones > 0)
244 meshInverseTrans.Inverse();
245 std::vector<aiVector3D> vertices(currentSubMesh->mNumVertices);
246 std::vector<aiVector3D> normals(currentSubMesh->mNumVertices);
249 for (
unsigned int i=0; i<currentSubMesh->mNumVertices; ++i)
251 vertices[i] = currentSubMesh->mVertices[i];
252 normals[i] = currentSubMesh->mNormals[i];
253 currentSubMesh->mVertices[i] = aiVector3D(0, 0, 0);
254 currentSubMesh->mNormals[i] = aiVector3D(0, 0, 0);
257 for(
unsigned int j=0; j<currentSubMesh->mNumBones; ++j)
259 aiBone* bone = currentSubMesh->mBones[j];
260 aiNode* bnode = mScene->
getAiScene()->mRootNode->FindNode(bone->mName);
264 for(
unsigned int w=0;
w<bone->mNumWeights; ++
w)
266 aiVertexWeight aiWeight = bone->mWeights[
w];
267 aiMatrix4x4 boneMat = meshInverseTrans * mScene->
getFullTransform(bnode) * bone->mOffsetMatrix;
268 aiMatrix3x3 normMat = aiMatrix3x3(boneMat);
269 aiVector3D vertPos = vertices[aiWeight.mVertexId];
270 aiVector3D normal = normals[aiWeight.mVertexId];
271 currentSubMesh->mVertices[aiWeight.mVertexId] += boneMat * vertPos * aiWeight.mWeight;
272 currentSubMesh->mNormals[aiWeight.mVertexId] += normMat * normal * aiWeight.mWeight;
284 if (currentSubMesh->mNumBones > 0)
286 for(
unsigned int n=0; n<currentSubMesh->mNumBones; ++n)
288 aiNode* bnode = mScene->
getAiScene()->mRootNode->FindNode(currentSubMesh->mBones[n]->mName);
290 aiNode* curBone = bnode;
291 while(curBone && (curBone->mNumMeshes == 0) && (curBone != mScene->
getAiScene()->mRootNode))
294 curBone = curBone->mParent;
300 mSkeletonAnim.
addBone(newBone, 0, submesh);
303 std::queue<aiNode*> nodes;
305 while(!nodes.empty())
307 newBone = nodes.front();
311 unsigned int nbSons = newBone->mNumChildren;
317 aiNode** sons = newBone->mChildren;
319 for(
unsigned int n=0; n<nbSons; ++n)
322 aiNode* son = sons[n];
323 if (son && mScene->
isBone(son) && (son->mNumMeshes == 0) && (son != mScene->
getAiScene()->mRootNode))
325 mSkeletonAnim.
addBone(son, 0, submesh);
335 mSkeletonAnim.
addBone(bnode, currentSubMesh->mBones[n], submesh);
338 ogMesh->_updateCompiledBoneAssignments();
341 if ( (mScene->
getAiScene()->mNumMeshes == 1) && (mScene->
getAiScene()->mRootNode->mNumChildren == 0))
343 aiScene* curScene =
const_cast<aiScene*
>(mScene->
getAiScene());
344 delete currentSubMesh;
345 curScene->mMeshes[mOrigin->mMeshes[n]] = 0;
346 curScene->mNumMeshes -= 1;
353 ogSubMesh->vertexData =
new Ogre::VertexData();
354 ogSubMesh->vertexData->vertexStart = 0;
355 ogSubMesh->vertexData->vertexCount = asSubMesh->mNumVertices;
357 if (asSubMesh->mNumFaces > 0)
359 bool bUse32BitIndexes = (asSubMesh->mNumVertices > 65535) ?
true :
false;
362 ogSubMesh->indexData->indexStart = 0;
363 ogSubMesh->indexData->indexCount = asSubMesh->mNumFaces * 3;
365 ogSubMesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
366 bUse32BitIndexes ? Ogre::HardwareIndexBuffer::IT_32BIT : Ogre::HardwareIndexBuffer::IT_16BIT,
367 ogSubMesh->indexData->indexCount,
368 Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
370 std::vector<std::vector<int>> facesIndex;
371 facesIndex.resize(asSubMesh->mNumFaces);
374 for (
unsigned int i = 0; i < asSubMesh->mNumFaces; i++)
376 facesIndex[i].resize(3);
377 for (
size_t j = 0; j < 3; j++)
379 if (asSubMesh->mFaces[i].mIndices[j] >= asSubMesh->mNumVertices)
380 facesIndex[i][j] = 0;
382 facesIndex[i][j] = asSubMesh->mFaces[i].mIndices[j];
390 if (bUse32BitIndexes)
392 Ogre::uint32* pIdx =
static_cast<Ogre::uint32*
>(ogSubMesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
393 for (
unsigned int i = 0; i < facesIndex.size(); i++)
395 *pIdx++ =
static_cast<Ogre::uint32
>(facesIndex[i][0]);
396 *pIdx++ =
static_cast<Ogre::uint32
>(facesIndex[i][1]);
397 *pIdx++ =
static_cast<Ogre::uint32
>(facesIndex[i][2]);
399 ogSubMesh->indexData->indexBuffer->unlock();
403 Ogre::uint16* pIdx =
static_cast<Ogre::uint16*
>(ogSubMesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
404 for (
unsigned int i = 0; i < facesIndex.size(); i++)
406 *pIdx++ =
static_cast<Ogre::uint16
>(facesIndex[i][0]);
407 *pIdx++ =
static_cast<Ogre::uint16
>(facesIndex[i][1]);
408 *pIdx++ =
static_cast<Ogre::uint16
>(facesIndex[i][2]);
410 ogSubMesh->indexData->indexBuffer->unlock();
419 aiVector3D* vertices = asSubMesh->mVertices;
420 aiVector3D* normals = asSubMesh->mNormals;
421 aiVector3D* tangents = asSubMesh->mTangents;
422 aiVector3D* bitangent = asSubMesh->mBitangents;
425 std::vector<aiVector3D*> uv;
426 unsigned int nbUV = asSubMesh->GetNumUVChannels();
427 for(
unsigned int n=0; n<nbUV; ++n)
429 uv.push_back(asSubMesh->mTextureCoords[n]);
432 std::vector<aiColor4D*> color;
433 unsigned int nbCol = asSubMesh->GetNumColorChannels();
434 for(
unsigned int n=0; n<nbCol; ++n)
436 color.push_back(asSubMesh->mColors[n]);
440 Ogre::VertexDeclaration* declaration = ogSubMesh->vertexData->vertexDeclaration;
441 Ogre::VertexBufferBinding* bind = ogSubMesh->vertexData->vertexBufferBinding;
443 size_t vBufSegmentSize = 0;
444 size_t texSegmentSize = 0;
446 declaration->addElement(0, vBufSegmentSize, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
447 vBufSegmentSize += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
452 declaration->addElement(0, vBufSegmentSize, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
453 vBufSegmentSize += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
458 declaration->addElement(0, vBufSegmentSize, Ogre::VET_FLOAT3, Ogre::VES_TANGENT);
459 vBufSegmentSize += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
464 declaration->addElement(0, vBufSegmentSize, Ogre::VET_FLOAT3, Ogre::VES_BINORMAL);
465 vBufSegmentSize += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
468 for(
unsigned int n=0; n<color.size(); ++n)
470 declaration->addElement(0, vBufSegmentSize, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
471 vBufSegmentSize += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);
477 declaration->addElement(1, texSegmentSize, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, countTex);
478 texSegmentSize += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
483 for (
unsigned int n = 0; n < uv.size(); ++n)
485 declaration->addElement(1, texSegmentSize, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, countTex);
486 texSegmentSize += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
492 Ogre::HardwareVertexBufferSharedPtr vbuffer = Ogre::HardwareBufferManager::getSingletonPtr()
493 ->createVertexBuffer(vBufSegmentSize, ogSubMesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY,
false);
496 Ogre::HardwareVertexBufferSharedPtr texBuf = Ogre::HardwareBufferManager::getSingletonPtr()
497 ->createVertexBuffer(texSegmentSize, ogSubMesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY,
false);
500 bind->setBinding(0, vbuffer);
501 bind->setBinding(1, texBuf);
504 unsigned char* pVert =
static_cast<unsigned char*
>(vbuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
505 unsigned char* pTexVert =
static_cast<unsigned char*
>(texBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
511 Ogre::VertexDeclaration::VertexElementList elems = declaration->findElementsBySource(0);
512 Ogre::VertexDeclaration::VertexElementList texElems = declaration->findElementsBySource(1);
516 for (
unsigned int i = 0; i < asSubMesh->mNumVertices; ++i)
518 Ogre::VertexDeclaration::VertexElementList::const_iterator elemItr, elemEnd;
519 elemEnd = elems.end();
520 for (elemItr = elems.begin(); elemItr != elemEnd; ++elemItr)
523 const Ogre::VertexElement& elem = *elemItr;
524 switch (elem.getSemantic())
526 case Ogre::VES_POSITION:
528 elem.baseVertexPointerToElement(pVert, &pFloat);
530 if (mBounding.isNull())
531 mBounding = Ogre::AxisAlignedBox(Ogre::Vector3(vertices[i].x, vertices[i].y, vertices[i].z), Ogre::Vector3(vertices[i].x, vertices[i].y, vertices[i].z));
533 updateBounds(Ogre::Vector3(vertices[i].x, vertices[i].y, vertices[i].z));
534 *pFloat++ = vertices[i].x;
535 *pFloat++ = vertices[i].y;
536 *pFloat++ = vertices[i].z;
539 case Ogre::VES_NORMAL:
541 elem.baseVertexPointerToElement(pVert, &pFloat);
542 *pFloat++ = normals[i].x;
543 *pFloat++ = normals[i].y;
544 *pFloat++ = normals[i].z;
547 case Ogre::VES_TANGENT:
549 elem.baseVertexPointerToElement(pVert, &pFloat);
550 *pFloat++ = tangents[i].x;
551 *pFloat++ = tangents[i].y;
552 *pFloat++ = tangents[i].z;
555 case Ogre::VES_BINORMAL:
557 elem.baseVertexPointerToElement(pVert, &pFloat);
558 *pFloat++ = bitangent[i].x;
559 *pFloat++ = bitangent[i].y;
560 *pFloat++ = bitangent[i].z;
563 case Ogre::VES_DIFFUSE:
565 elem.baseVertexPointerToElement(pVert, &pCol);
566 Ogre::ColourValue cv(color[0][i].r, color[0][i].g, color[0][i].b, color[0][i].a);
567 *pCol = Ogre::VertexElement::convertColourValue(cv, Ogre::VertexElement::getBestColourVertexElementType());
576 elemEnd = texElems.end();
577 for (elemItr = texElems.begin(); elemItr != elemEnd; ++elemItr)
580 const Ogre::VertexElement& elem = *elemItr;
581 switch (elem.getSemantic())
583 case Ogre::VES_TEXTURE_COORDINATES:
585 elem.baseVertexPointerToElement(pTexVert, &pFloat);
593 *pFloat++ = uv[iTexCoord][i].x;
594 *pFloat++ = 1 - uv[iTexCoord][i].y;
605 pVert += vbuffer->getVertexSize();
606 pTexVert += texBuf->getVertexSize();
643 Ogre::SkeletonSerializer sklSer;
644 boost::filesystem::path sklPath(path);
645 sklPath /=
"meshes/";
646 std::string sklFile(sklPath.generic_string()+ogMesh->getName()+
".skeleton");
647 sklSer.exportSkeleton(mSkeleton.get(), sklFile);
650 size_t nbsubmesh = ogMesh->getNumSubMeshes();
651 size_t numVertices = 0;
652 for (
unsigned int n = 0; n<nbsubmesh; ++n)
654 Ogre::SubMesh* submesh = ogMesh->getSubMesh(n);
655 if (submesh->vertexData)
656 numVertices += submesh->vertexData->vertexCount;
661 xmlMesh->
SetAttribute(
"name", ogMesh->getName().c_str());
663 std::string file =
"meshes/" + ogMesh->getName()+
".mesh";
668 for(
unsigned int n=0; n<nbsubmesh; ++n)
672 xmlsubmesh->
SetAttribute(
"materialName", ogMesh->getSubMesh(n)->getMaterialName().c_str());
687 Ogre::LodConfig lodConfig;
688 lodConfig.levels.clear();
689 lodConfig.mesh = ogMesh;
690 lodConfig.strategy = Ogre::ScreenRatioPixelCountLodStrategy::getSingletonPtr();
691 lodConfig.advanced.useCompression =
true;
692 lodConfig.advanced.useVertexNormals =
true;
696 int nbl = nbLevels + 2;
697 Ogre::Real reduction = 0.7f / nbLevels;
698 for (
int i = 2; i < nbl; i++)
700 Ogre::Real i4 = (Ogre::Real)(i * i * i * i);
701 lodConfig.createGeneratedLodLevel(Ogre::Real(2.0) / i4, reduction * i, Ogre::LodLevel::VRM_PROPORTIONAL);
704 Ogre::MeshLodGenerator::getSingleton().generateLodLevels(lodConfig);
706 catch (Ogre::Exception &)
708 ogMesh->removeLodLevels();
709 MMechostr(MSKRUNTIME,
"SO3Engine : failed to generate LOD levels on %s", ogMesh->getName().c_str());
712 catch (std::exception &)
715 ogMesh->removeLodLevels();
716 MMechostr(MSKRUNTIME,
"SO3Engine : failed to generate LOD levels, out of memory on %s", ogMesh->getName().c_str());
720 Ogre::MeshSerializer meshSer;
721 boost::filesystem::path meshPath(path);
722 meshPath /=
"meshes/";
723 std::string meshFile(meshPath.generic_string() + ogMesh->getName() +
".mesh");
724 meshSer.exportMesh(ogMesh.get(), meshFile);
727 Ogre::MeshManager::getSingleton().remove(ogMesh->getHandle());
735 Ogre::SkeletonManager::getSingleton().remove(mSkeleton->getHandle());