Page 1 of 1

SubMeshes [Solved]

Posted: Tue Feb 19, 2019 12:30 am
by WWJD
Hello,

I have a situation where I need to load three meshes to make up a single entity. Each part has it's own texture/material so I believe I need to be using a submesh. I also need this entity to move, thus it won't be static. I found some code on the wiki:

Code: Select all

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);
			}
		}
}
I implemented it, however the entity doesn't load. I can see how it loads each individual mesh in the log, but it never displays the actual entity. I'm thinking my issue is understanding what the code means by:

Code: Select all

      Mesh::SubMeshIterator mesh_itr = source->getSubMeshIterator();
I'm replacing "source" with a call to the actual models that are supposed to be merged. What am I missing? Any advice would be appreciated!
I have already tested each mesh individually, and can get them to load just fine, it's only when I'm trying to merge them that nothing shows.

This is the modded version of the above that I'm using:

Code: Select all

//code to test and create entity based off of sub-meshes
	
	//vector of meshes
	std::vector< MeshPtr > m_Meshes;


	//define meshes
	m_Meshes.push_back(MeshManager::getSingleton().load("TestUnit.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME));
	m_Meshes.push_back(MeshManager::getSingleton().load("TestUnit2.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME));
	m_Meshes.push_back(MeshManager::getSingleton().load("TestUnit3.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME));


	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();
	int i = 0;
	for (; itr != itr_e; ++itr)
	{
		Mesh::SubMeshIterator mesh_itr = m_Meshes[i]->getSubMeshIterator();
		i++;
		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);
			}
		}
	}
	Entity* ent = mSceneMgr->createEntity("entName", m_BaseMesh->getName());

	//code here is temporary and only ment as a test for the modelers
	//Entity* testEntity = mSceneMgr->createEntity("cc", source->getName());
	//testEntity->setMaterialName("TestMat");
	SceneNode* thisSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	thisSceneNode->setPosition(100, 100, 100);
	thisSceneNode->attachObject(ent);
Thanks,
WWJD

Re: SubMeshes

Posted: Tue Feb 19, 2019 2:15 am
by WWJD
I solved the issue. I needed to add in the code to set the bounding box. My fault. For anyone interested here is the final result:

Code: Select all

	//code to test and create entity based off of sub-meshes
	
	//vector of meshes
	std::vector< MeshPtr > m_Meshes;


	//define meshes
	m_Meshes.push_back(MeshManager::getSingleton().load("TestUnit.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME));
	m_Meshes.push_back(MeshManager::getSingleton().load("TestUnit2.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME));
	m_Meshes.push_back(MeshManager::getSingleton().load("TestUnit3.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME));


	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();
	int i = 0;
	for (; itr != itr_e; ++itr)
	{
		Mesh::SubMeshIterator mesh_itr = m_Meshes[i]->getSubMeshIterator();
		i++;
		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);
			}
		}
	}

	//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 (mesh_itr.hasMoreElements())
	{
		SubMesh* 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));
	Entity* ent = mSceneMgr->createEntity("entName", m_BaseMesh->getName());
	ent->setMaterialName("TestMat");

	//code here is temporary and only ment as a test for the modelers
	//Entity* testEntity = mSceneMgr->createEntity("cc", source->getName());
	//testEntity->setMaterialName("TestMat");
	SceneNode* thisSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	thisSceneNode->setPosition(100, 100, 100);
	thisSceneNode->attachObject(ent);
Have a good one!
WWJD

Re: SubMeshes

Posted: Thu Feb 21, 2019 4:33 pm
by sercero
Thanks for posting the solution and congrats for solving the problem yourself.

Can you edit the subject and add [Solved]?

Thanks.