SubMeshes [Solved] Topic is solved

Problems building or running the engine, queries about how to use features etc.
Post Reply
WWJD
Gnoblar
Posts: 14
Joined: Tue Aug 04, 2015 2:17 am
x 1

SubMeshes [Solved]

Post by WWJD » Tue Feb 19, 2019 12:30 am

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
Last edited by WWJD on Thu Mar 28, 2019 5:43 am, edited 1 time in total.
0 x

WWJD
Gnoblar
Posts: 14
Joined: Tue Aug 04, 2015 2:17 am
x 1

Re: SubMeshes

Post by WWJD » Tue Feb 19, 2019 2:15 am

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
1 x

sercero
Bronze Sponsor
Bronze Sponsor
Posts: 22
Joined: Sun Jan 18, 2015 4:20 pm
x 5

Re: SubMeshes

Post by sercero » Thu Feb 21, 2019 4:33 pm

Thanks for posting the solution and congrats for solving the problem yourself.

Can you edit the subject and add [Solved]?

Thanks.
0 x

Post Reply