History: Manual mesh merging
Source of version: 2 (current)
Copy to clipboard
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:
{CODE(wrap="1", colors="c++")}
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);
}
}
}
{CODE}
SubMeshes was added, but for correct raytracing and picking entity now we need to set a bounding box for it :
{CODE(wrap="1", colors="c++")}
//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 ));
{CODE}
And last step is a retrieving an entitiy from a mesh:
{CODE(wrap="1", colors="c++")}
Entity* ent = m_pSceneManager->createEntity( "entName", m_BaseMesh->getName() );
{CODE}
Cleaning up:
{CODE(wrap="1", colors="c++")}MeshManager::getSingleton().remove( m_BaseMesh->getHandle());{CODE}
Now we have a one mesh which contains all of our submeshes.