Bullet and ITerrainSceneNode

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
yamashi
Posts: 82
Joined: Sat Jan 03, 2009 4:53 am

Bullet and ITerrainSceneNode

Post by yamashi »

Hello !
I used to use Irrlicht for my paged terrain system but it would just crash randomly so I decided to go for bullet and I couldn't find a code to cook a Terrain to a Bullet triangle mesh, so I made one and decided to post it for people who will need it in the future !
Here it is :

Code: Select all

void createHeightField(scene::ITerrainSceneNode* node)
{
	btVector3 vertices[3];
	s32 j,k;
	btTriangleMesh *  mTriMesh = new btTriangleMesh();

	irr::scene::CDynamicMeshBuffer* buffer = 0;

	buffer = new irr::scene::CDynamicMeshBuffer(irr::video::EVT_2TCOORDS, irr::video::EIT_16BIT);
	node->getMeshBufferForLOD(*buffer, 0);

	const irr::u32 vertexCount = buffer->getVertexCount();
	const irr::u32 indexCount = buffer->getIndexCount();


	irr::video::S3DVertex2TCoords* mb_vertices = (irr::video::S3DVertex2TCoords*)buffer->getVertexBuffer().getData();
	
	u16* mb_indices = buffer->getIndices();

	for(j=0;j<indexCount;j+=3)
	{ 
		for (k=0;k<3;k++) 
		{
			s32 index = mb_indices[j+k];
			vertices[k] = btVector3(
				mb_vertices[index].Pos.X*node->getScale().X,
				mb_vertices[index].Pos.Y*node->getScale().Y,
				mb_vertices[index].Pos.Z*node->getScale().Z);	
		}
		mTriMesh->addTriangle(vertices[0], vertices[1], vertices[2]);
	}

	buffer->drop();

	btCollisionShape* mShape = new btBvhTriangleMeshShape(mTriMesh, true);

	btDefaultMotionState* state =	new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),
		btVector3(node->getPosition().X,node->getPosition().Y,node->getPosition().Z)));

	btRigidBody* mRigidBody = new btRigidBody(0, state, mShape, btVector3(0, 0, 0));
	mRigidBody->setCollisionFlags(mRigidBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
	mDynamicsWorld->addRigidBody(mRigidBody);
}
gbox
Posts: 37
Joined: Mon May 01, 2006 3:41 am
Location: jeonju, korea
Contact:

Post by gbox »

thanks~ :)
http://cafe.naver.com/jcga

professor of Jelabukdo Game Engine Academy
enif
Posts: 12
Joined: Sun Nov 15, 2009 5:31 pm
Location: Prague, Czech Republic

How to get the total number of vertices.

Post by enif »

Hi!

The code above looks promissing - I need to test it. :-) I have one question about it, resp. this line of code is not particulary perfect :-) :

Code: Select all

 buffer = new irr::scene::CDynamicMeshBuffer(irr::video::EVT_2TCOORDS, irr::video::EIT_16BIT); 
The problem is, that this works for small terrains only (256x256 max.). Reason for that is the EIT_16BIT, which creates a 16bit buffer. With a bigger terrain it causes a crash, because terrain vertices does not fit into this buffer.

So, for bigger terrains (with more than 64k vertexes) you should use this:

Code: Select all

 buffer = new irr::scene::CDynamicMeshBuffer(irr::video::EVT_2TCOORDS, irr::video::EIT_32BIT); 
If you look into the sources of the ITerrainSceneNode, you can see a code like this:

Code: Select all

const u32 numVertices = TerrainData.Size * TerrainData.Size;
if (numVertices <= 65536)
{
	//small enough for 16bit buffers
	mb=new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_16BIT);
			RenderBuffer->getIndexBuffer().setType(video::EIT_16BIT);
}
else
{
	//we need 32bit buffers
	mb=new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_32BIT);
			RenderBuffer->getIndexBuffer().setType(video::EIT_32BIT);
}
This code decides, how big mesh buffer we really need.

The "TerrainData.Size" is private, so you can not use it for getting the total number of vertices in terrain scene node.

But, how to do it?

I am using this:

Code: Select all

const u32 numVertices = node->getMesh()->getMeshBuffer(0)->getVertexCount();
But is this a correct way?

Thanks for any ideas and happy codding!
yamashi
Posts: 82
Joined: Sat Jan 03, 2009 4:53 am

Post by yamashi »

I don't need this because I use 33x33 terrains and I made a paged terrain system (see my Paged Terrain system video).
So if I can skip a few lines of code and optimize the system even by a few instructions it's always better for realtime loading.
enif
Posts: 12
Joined: Sun Nov 15, 2009 5:31 pm
Location: Prague, Czech Republic

Post by enif »

yamashi: Hi! Your code is gread, no doubt about it! :-) May bye I sound, like I am trying to fix something, thats needs no fixing. I am sorry for that! I am trying to make it better and more universal. And my English is a crap... :-)

I discovered one week point in the code - the indices.

If numVertices <= 65536, indices are 16bit. If not, indices are 32bit! You can (and should) test for the indices format by calling:

Code: Select all

video::E_INDEX_TYPE indicesType = buffer->getIndexType();
... on your CDynamicMeshBuffer.

For video::EIT_16BIT type you are OK. For video::EIT_32BIT you are getting u32* array pointer. So you should do something like this:

Code: Select all

u32* mb_indices32 = (u32*)buffer->getIndices();
... and continue with that.

For us, the big-terrain-lowers, this should help. :-)

Thanks!
yamashi
Posts: 82
Joined: Sat Jan 03, 2009 4:53 am

Post by yamashi »

You might be a big terrain lover but mine is infinite ^^ and I still use 16bits array... It's all about the way you chose to implement it.
Of course if you use the basic irrlicht system, you need a huge height-map which is not the best imo (loads of memory and slow), my system is able to load infinite terrains and in real time with little performance hit. But of course it takes time and work...
See a demo : http://www.youtube.com/watch?v=ETOOCZ0Hpxc
kamikaze942
Posts: 52
Joined: Wed Mar 03, 2010 7:11 pm

heightfield

Post by kamikaze942 »

been working on this for a little bit. i get access violations, and i'm curious as to what im doing wrong. is this code correct? the bolded part is where im getting the access violation.

Code: Select all

First-chance exception at 0x00475222 in Trials of the Gods.exe: 0xC0000005: Access violation reading location 0x35852c54.
Unhandled exception at 0x00475222 in Trials of the Gods.exe: 0xC0000005: Access violation reading location 0x35852c54.
The program '[4772] Trials of the Gods.exe: Native' has exited with code -1073741819 (0xc0000005).

Code: Select all

void createHeightField(scene::ITerrainSceneNode* node)
{
   
   btVector3 vertices[3];
   s32 j,k;
   btTriangleMesh *  mTriMesh = new btTriangleMesh();

   irr::scene::CDynamicMeshBuffer* buffer = 0;

   buffer = new irr::scene::CDynamicMeshBuffer(irr::video::EVT_2TCOORDS, irr::video::EIT_32BIT);
   node->getMeshBufferForLOD(*buffer, 0);

   const irr::u32 vertexCount = buffer->getVertexCount();
   const irr::u32 indexCount = buffer->getIndexCount();


   irr::video::S3DVertex2TCoords* mb_vertices = (irr::video::S3DVertex2TCoords*)buffer->getVertexBuffer().getData();
   
   u32* mb_indices = (u32*)buffer->getIndices();

   for(j=0;j<indexCount;j+=3)
   {
      for (k=0;k<3;k++)
      {
         s32 index = mb_indices[j+k];
         vertices[k] = btVector3(
            mb_vertices[index].Pos.X*node->getScale().X,
            mb_vertices[index].Pos.Y*node->getScale().Y,
          [b]  mb_vertices[index].Pos.Z*node->getScale().Z);   [/b]
      }
      mTriMesh->addTriangle(vertices[0], vertices[1], vertices[2]);
   }

   buffer->drop();

   btCollisionShape* mShape = new btBvhTriangleMeshShape(mTriMesh, true);
   btTransform T;
   T.setIdentity();
   T.setOrigin(btVector3(node->getPosition().X, node->getPosition().Y, node->getPosition().Z));
   btDefaultMotionState* state =   new btDefaultMotionState(T);
   btVector3 Inertia;
   mShape->calculateLocalInertia(0, Inertia);
   btRigidBody* mRigidBody = new btRigidBody(0, state, mShape,Inertia);
   mRigidBody->setCollisionFlags(mRigidBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
   World->addRigidBody(mRigidBody);
} 
Kamikaze
Post Reply