Hi, i`m glad to introduce to you a manual mesh merging into one entity.
Given: std::vector< MeshPtr > m_Meshes
Target: One entity, where each of subentity is mesh from a given vector.
Let`s begin. First of all, we need to create a base mesh and add a submeshes to him:
std::string m_ModelId = "MergedMesh"; Ogre::MeshPtr m_BaseMesh = MeshManager::getSingleton().createManual( m_ModelId, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME ); //Lets add some submeshes std::vector< MeshPtr >::iterator itr = m_Meshes.begin(); std::vector< MeshPtr >::iterator itr_e = m_Meshes.end(); for( ; itr !=itr_e; ++itr ) { Mesh::SubMeshIterator mesh_itr = source->getSubMeshIterator(); SubMesh *in = 0, *out = 0; VertexBoneAssignment vbass; while( mesh_itr.hasMoreElements()) { in = mesh_itr.getNext(); out = m_BaseMesh->createSubMesh(); out->indexData = in->indexData->clone(); out->mLodFaceList = in->mLodFaceList; out->operationType = in->operationType; out->parent = m_BaseMesh.get(); out->useSharedVertices = false; out->vertexData = in->vertexData->clone(); out->clearBoneAssignments(); for( size_t i = 0; i < in->vertexData->vertexCount; ++i ) { vbass.vertexIndex = i; vbass.weight = 1.0f; out->addBoneAssignment(vbass); } } }
SubMeshes was added, but for correct raytracing and picking entity now we need to set a bounding box for it :
//define a extreme boundary values Real max_x = -1e+8; Real min_x = 1e+8; Real max_y = -1e+8; Real min_y = 1e+8; Real max_z = -1e+8; Real min_z = +1e+8; // Setting bounding box Mesh::SubMeshIterator mesh_itr = m_BaseMesh->getSubMeshIterator(); while( itr.hasMoreElements()) { in = mesh_itr.getNext(); VertexData *vertex_data = in->vertexData; const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); HardwareVertexBufferSharedPtr hwvb = in->vertexData->vertexBufferBinding->getBuffer( posElem->getSource() ); unsigned char *hbuff = static_cast<unsigned char*>( hwvb->lock( HardwareBuffer::HBL_READ_ONLY )); Real *pValue; Real value; for( size_t idx = 0; idx < vertex_data->vertexCount; ++idx, hbuff += hwvb->getVertexSize() ) { posElem->baseVertexPointerToElement( hbuff, &pValue ); value = (*pValue++); if( value > max_x ) max_x = value; if( value < min_x ) min_x = value; value = (*pValue++); if( value > max_y ) max_y = value; if( value < min_y ) min_y = value; value = (*pValue++); if( value > max_z ) max_z = value; if( value < min_z ) min_z = value; } hwvb->unlock(); } m_BaseMesh->_setBounds( AxisAlignedBox( min_x, min_y, min_z, max_x, max_y, max_z ));
And last step is a retrieving an entitiy from a mesh:
Entity* ent = m_pSceneManager->createEntity( "entName", m_BaseMesh->getName() );
Cleaning up:
MeshManager::getSingleton().remove( m_BaseMesh->getHandle());
Now we have a one mesh which contains all of our submeshes.