Terrain Mesh

aboeing
Posts: 33
Joined: Tue Jul 26, 2005 2:28 pm

Terrain Mesh

Post by aboeing »

Hi, I'm just trying to build a terrain mesh, and I'm not sure how to do it. When I run my program it crashes in "processAllTriangles" here:

Code: Select all

m_triangle[j] = btVector3(
					graphicsbase[0]*meshScaling.getX(),
					graphicsbase[1]*meshScaling.getY(),
					graphicsbase[2]*meshScaling.getZ());
This is my code:

Code: Select all

btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(
		nIndices/3,
		const_cast<int *>(pIndices),
		sizeof(int)*3,
		nVertices,
		const_cast<float *>(pVertices),
		sizeof(Float)*3);
	m_pbtTriMeshShape = new btBvhTriangleMeshShape(indexVertexArrays);

	btTransform tr;
	tr.setIdentity();
	tr.setOrigin(btVector3(x,y,z));

	btVector3 localInertia(0,0,0);
//	m_pbtTriMeshShape->calculateLocalInertia(0,localInertia);

	m_pbtMotionState = new btDefaultMotionState(tr);
	m_pbtBody = new btRigidBody(0,m_pbtMotionState,m_pbtTriMeshShape,localInertia);

	g_DynamicsWorld->addRigidBody(m_pbtBody);
My indicies and vertices are set up for rendering (opengl) and render correctly.

Any help as to what I'm doing wrong would be appreciated. Thanks!
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Terrain Mesh

Post by Erwin Coumans »

Before we debug/fix this problem: there is an easier hassle-free way of passing meshes to Bullet: using btTriangleMesh.
btTriangleMesh allows to add a single triangle at a time, and keeps them stored. Also note you can re-use all shapes among multiple rigidbodies, instancing is better then creating new shapes (this even holds for simple cubes, cylinders etc.

For btBvhTriangleMeshShape , there is not really a debug option right now except for putting breakpoints inside 'processAllTriangles'. I can put a debug method that outputs all all indices and all vertices, so you can see where things go wrong.

More important is: how is your data exactly layed out? Do you have some info about the datastructures used for vertex arrays and index arrays?
This is necessary to get the right values you pass into btTriangleIndexVertexArray.
Can you give us more details/code snippet of the memory layout of your mesh?

Thanks,
Erwin
aboeing
Posts: 33
Joined: Tue Jul 26, 2005 2:28 pm

Post by aboeing »

Hi Erwin,

Thanks for the reply, I'll have to think of some kind of intelligent instancing sheme for the shapes, but for the moment I'll just be recreating them for all objects. Is there an example for using btTriangleMesh? (I used btBvhTriangleMeshShape since that would be 'easier' for me, and its what is used in your vehicle example).

My data is layed out as:
-an array of floats, 3 floats per vertex
-an array of int's, 3 ints per tri.
eg:

Code: Select all

ver[0]=0;						ver[1]=0;				ver[2]=0;		// 1st coordinate
ver[3]=length_down;			ver[4]=0;				ver[5]=0;		// 2nd coordinate 
ver[6]=0;						ver[7]=0;				ver[8]=width_down;	// 3rd coordinate

	ind1[0]=0;				ind1[1]=3;				ind1[2]=1;				// 1st triangle
	ind1[3]=0;				ind1[4]=2;				ind1[5]=3;				// 2nd triangle
	ind1[6]=0;				ind1[7]=1;				ind1[8]=5;				// 3rd triangle
example of call:

Code: Select all

float ver[3*16];
	int ind1[3*18];	
pool->Init(0,0,0,ver,16,ind1,3*18);

void palBulletTerrainMesh::Init(Float x, Float y, Float z, const Float *pVertices, int nVertices, const int *pIndices, int nIndices) {
and code follows as above..
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Post by Erwin Coumans »

btTriangleMesh is easiest to store your triangle data. You pass it into the constructor of btBvhTriangleMeshShape, the same as you do with btTriangleIndexVertexArray. Main difference is that with btTriangleIndexVertexArray you re-use the graphics mesh, but it is very complicated to get the index/striding right. btTriangleMesh just stores the triangles, when you add them using addTriangle. Sorry, no time to debug your data, I will add some debugging option to the other

Just check Demos/UserCollisionAlgorithm for an example of btTriangleMesh-> btBvhTriangleMeshShape

Erwin



aboeing wrote:Hi Erwin,

Thanks for the reply, I'll have to think of some kind of intelligent instancing sheme for the shapes, but for the moment I'll just be recreating them for all objects. Is there an example for using btTriangleMesh? (I used btBvhTriangleMeshShape since that would be 'easier' for me, and its what is used in your vehicle example).

My data is layed out as:
-an array of floats, 3 floats per vertex
-an array of int's, 3 ints per tri.
eg:

Code: Select all

ver[0]=0;						ver[1]=0;				ver[2]=0;		// 1st coordinate
ver[3]=length_down;			ver[4]=0;				ver[5]=0;		// 2nd coordinate 
ver[6]=0;						ver[7]=0;				ver[8]=width_down;	// 3rd coordinate

	ind1[0]=0;				ind1[1]=3;				ind1[2]=1;				// 1st triangle
	ind1[3]=0;				ind1[4]=2;				ind1[5]=3;				// 2nd triangle
	ind1[6]=0;				ind1[7]=1;				ind1[8]=5;				// 3rd triangle
example of call:

Code: Select all

float ver[3*16];
	int ind1[3*18];	
pool->Init(0,0,0,ver,16,ind1,3*18);

void palBulletTerrainMesh::Init(Float x, Float y, Float z, const Float *pVertices, int nVertices, const int *pIndices, int nIndices) {
and code follows as above..
aboeing
Posts: 33
Joined: Tue Jul 26, 2005 2:28 pm

Post by aboeing »

Okay, swapped it to use btTriangleMesh as you suggested, and it works - thanks!

I notice that objects seem to be falling through the mesh though - specifically it seems to be when one object lands directly ontop of another on the mesh that they sometimes fall 'through' the object.

Any ideas on what might be causing this? Or should I just decrease the stepsize? (I'm using btDiscreteDynamicsWorld)

Attached my new code below for future reference.

Code: Select all

for (int i=0;i<nIndices/3;i++) {
		pi = pIndices[i*3+0];
		btVector3 v0(	pVertices[pi*3+0],
						pVertices[pi*3+1],
						pVertices[pi*3+2]);
		pi = pIndices[i*3+1];
		btVector3 v1(	pVertices[pi*3+0],
						pVertices[pi*3+1],
						pVertices[pi*3+2]);
		pi = pIndices[i*3+2];
		btVector3 v2(	pVertices[pi*3+0],
						pVertices[pi*3+1],
						pVertices[pi*3+2]);
		trimesh->addTriangle(v0,v1,v2);
	}
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Post by Erwin Coumans »

aboeing wrote:I notice that objects seem to be falling through the mesh though - specifically it seems to be when one object lands directly ontop of another on the mesh that they sometimes fall 'through' the object.

Any ideas on what might be causing this? Or should I just decrease the stepsize? (I'm using btDiscreteDynamicsWorld)
If objects move faster then their own radius in one timestep it can happen when using the _discrete_ dynamics world. What is the size of the moving objects, timestep and gravity? Which version of Bullet? Either decrease the 3rd argument in stepSimulation (so pass dt,1,1./180).

An upcoming btContinuousDynamicsWorld would prevent things tunneling/falling through. Until then, increase the margin of the trianglemeshshape, increase size of objects (no small objects), decrease the _fixed_ timestep (3rd argument, not the 1st of stepSimulation).

Hope this helps,
Erwin
aboeing
Posts: 33
Joined: Tue Jul 26, 2005 2:28 pm

Post by aboeing »

Problem was solved with a smaller timestep, the object size was 0.25x0.25x0.25 cube, gravity -9.8, timestep was 1/60 is now 0.01

hitting against a terrain mesh area of about 5x7.
Aphex
Posts: 1
Joined: Mon Nov 27, 2006 1:06 pm

Post by Aphex »

Is there a facility in Bullet for 'procedural' terrains at all?
I.e. something like: Bullets gives me a bounding box and I fill in the terrain poly's in the box.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Post by Erwin Coumans »

Aphex wrote:Is there a facility in Bullet for 'procedural' terrains at all?
I.e. something like: Bullets gives me a bounding box and I fill in the terrain poly's in the box.
Yes, Bullet allows user-defined procedural collision shapes (curves, landscapes etc):
You just derive your own version of a ConcaveShape, and implement the 'processAllTriangles'. This takes a bounding box as input, and you do a callback for each triangle that you produce. The triangle data is only needed during the callback, so no need to create a large persistent triangle buffer.

See btTriangleMeshShape for an example:

Code: Select all

void    btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
Some sample/demo should be added to Bullet.
Do you want to contribute?
Erwin

PS: just realized that ConcaveShape doesn't have the bt-prefix, will be fixed too.
MGB
Posts: 12
Joined: Wed Aug 24, 2005 8:54 pm
Location: uk

Post by MGB »

Aphex here (found my original account at last!)

Ah whoops - just found the heightmap stuff on the wiki.
I'm looking at moving over to using Bullet, and I'll definitely contribute if I do, but there are a few questions about supported features I'm slowly looking up at the mo :)

Is the per-triangle 'materials' stuff integrated for doing this - the wiki mentioned it was on the cards..?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Post by Erwin Coumans »

MGB wrote:Aphex here (found my original account at last!)

Ah whoops - just found the heightmap stuff on the wiki.
I'm looking at moving over to using Bullet, and I'll definitely contribute if I do, but there are a few questions about supported features I'm slowly looking up at the mo :)

Is the per-triangle 'materials' stuff integrated for doing this - the wiki mentioned it was on the cards..?
The wiki page is out-dated indeed. The per-triangle materials is in Bullet, see the Demos/ConcaveDemo: using a callback, the user can assign friction and restitution values per triangle. You can just derive a btTerrainShape from ConcaveShape, and override the processAllTriangles. Another issue mentioned in the wiki article is solved too: the boundingboxes passed into the 'processAllTrangles' is fairly small.

One useful starting point is to come up with some data to represent the heightfield: do we have some interesting data set/landscape that we are allowed to use in a TerrainDemo?

Thanks,
Erwin
Eternl Knight
Posts: 44
Joined: Sun Jan 22, 2006 4:31 am

Post by Eternl Knight »

Sorry - wrong thread. Please ignore.

--EK
MGB
Posts: 12
Joined: Wed Aug 24, 2005 8:54 pm
Location: uk

Post by MGB »

I myself don't have any terrain data sets of note; my world consists of a large number of separate islands generated at run-time by libNoise, hence the preference for procedural surface descriptions.
I'll take a look at the things suggested above.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Post by Erwin Coumans »

MGB wrote:I myself don't have any terrain data sets of note; my world consists of a large number of separate islands generated at run-time by libNoise, hence the preference for procedural surface descriptions.
I'll take a look at the things suggested above.
Bullet 2.37 has a placeholder for btHeightfieldTerrainShape, you can use that as a starting point, and just procedurally create triangles that overlap with the aabb passed in 'processAllTriangles'.

Can you provide some proof of concept using libNoise in a Bullet Demo?


Thanks,
Erwin
MGB
Posts: 12
Joined: Wed Aug 24, 2005 8:54 pm
Location: uk

Post by MGB »

I can look at this, though I'd be wary of the libnoise dependency in a demo... maybe just put in some simple midpoint code I have?