[SOLVED] Manual mesh only showing up on root scene node

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
LiMuBei
Goblin
Posts: 297
Joined: Mon Jun 09, 2008 3:56 pm
Location: Karlsruhe, Germany
x 9

[SOLVED] Manual mesh only showing up on root scene node

Post by LiMuBei »

Hello everyone! I wouldn't consider myself a pro Ogre user, but I'm not a noob either. Recently I encountered a behaviour I can't get my head around. Situation is as follows:
I've written a class that represents a pointcloud to display in Ogre. The class is fed with an array of floats representing the 3D points (x1,y1,z1,x2,y2,z2,...,xn,yn,zn) and an optional second array defining the vertex colour for each vertex. The Ogre mesh is then created like in the code below (got most of that from the wiki).

Code: Select all

Pointcloud::Pointcloud(const std::string& name, const std::string& resourcegroup, const int numpoints, float *parray, float *carray)
{
	/// Create the mesh via the MeshManager
	Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton().createManual(name, resourcegroup);

	/// Create one submesh
	Ogre::SubMesh* sub = msh->createSubMesh();
	
	/// Create vertex data structure for vertices shared between submeshes
	msh->sharedVertexData = new Ogre::VertexData();
	msh->sharedVertexData->vertexCount = numpoints;

	/// Create declaration (memory format) of vertex data
	Ogre::VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
	decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	
	vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		decl->getVertexSize(0), msh->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
	/// Upload the vertex data to the card
	vbuf->writeData(0, vbuf->getSizeInBytes(), parray, true);

	if(carray != NULL)
	{
		// Create 2nd buffer for colors
		decl->addElement(1, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
		cbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR),
			msh->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

		Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
		Ogre::RGBA *colours = new Ogre::RGBA[numpoints];
		for(int i=0, k=0; i<numpoints*3 && k<numpoints; i+=3, k++)
		{
			// Use render system to convert colour value since colour packing varies
			rs->convertColourValue(Ogre::ColourValue(carray[i],carray[i+1],carray[i+2]), &colours[k]);
		}
		// Upload colour data
		cbuf->writeData(0, cbuf->getSizeInBytes(), colours, true);
		delete[] colours;
	}

	/// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
	Ogre::VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; 
	bind->setBinding(0, vbuf);

	if(carray != NULL)
	{
		// Set colour binding so buffer 1 is bound to colour buffer
		bind->setBinding(1, cbuf);
	}

	sub->useSharedVertices = true;
	sub->operationType = Ogre::RenderOperation::OT_POINT_LIST;
	

	msh->load();
}
The actual instantiation and insertion into the Ogre scene looks like this:

Code: Select all

mPointCloud.reset( new Pointcloud(std::string(PointcloudName.mb_str()),"General",
		Points.size()/3, ptr(Points), Colors.size()?ptr(Colors):0) );

// Insert the model into the scene
const std::string EntityName = "Entity:" + boost::lexical_cast<std::string>( GetDataEntity() );
mOgreEntity = GetSceneManager()->createEntity(EntityName.c_str(), Ogre::String(PointcloudName.mb_str()));
mOgreEntity->setMaterialName( "Pointcloud" );

// works
GetSceneManager()->getRootSceneNode()->attachObject(mOgreEntity);
// doesn't show anything
// mNode = GetSceneManager()->getRootSceneNode()->createChildSceneNode();
// mNode->attachObject(mOgreEntity);
As you can see in the end of this snippet, the pointcloud only shows up when attached to the root scene node, not when attached to a childnode of the root scene node. This is what I don't get, maybe I'm missing something fundamental, but I can't explain this behaviour.
Following is the material I use to render the pointcloud:

Code: Select all

material Pointcloud
{
	technique
	{
		pass
		{
			diffuse vertexcolour
			specular vertexcolour
			ambient vertexcolour
			point_size 0.05
			point_sprites on
			point_size_attenuation on
		}
	}
}
Attached is also a screenshot of the working pointcloud when attached to the root scene node. When attached to a child node there's just nothing showing up, no errors or other failure. So if anyone has any ideas I'd really appreciate it!
Attachments
PointcloudWorking.jpg
Last edited by LiMuBei on Tue Sep 07, 2010 3:26 pm, edited 1 time in total.

User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7153
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 520

Re: Mesh from vertex buffer only showing up on root scene no

Post by Kojack »

When you create a mesh manually, the bounding box isn't set. Ogre doesn't try to read back all the positions from your vertex buffer because it might be read only. So you need to call msh->_setBounds(), giving it an axis aligned bounding box which is as big as the mesh.

Since the root is always visible, any mesh attached to it would show up regardless, but without a valid bounding box child scene nodes would be culled.

User avatar
LiMuBei
Goblin
Posts: 297
Joined: Mon Jun 09, 2008 3:56 pm
Location: Karlsruhe, Germany
x 9

Re: Mesh from vertex buffer only showing up on root scene no

Post by LiMuBei »

Ah, that totally makes sense! Gonna try that asap. Thanks for your reply!

User avatar
LiMuBei
Goblin
Posts: 297
Joined: Mon Jun 09, 2008 3:56 pm
Location: Karlsruhe, Germany
x 9

Re: Mesh from vertex buffer only showing up on root scene no

Post by LiMuBei »

Just put this fix in my code and it was indeed the cause. So thanks again!

Post Reply