Advertisement Jump to content
Sign in to follow this  

box falling thru a triangle mesh in ODE (solved)

This topic is 4988 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Maybe someone can take a look and see if I forgot something. For the life of me I can't figure out why I'm having such problems with the tri mesh. The box vs. box works fine, it's just that box vs. tri mesh that I have problems with figuring out. This code shows a box falling down onto a triangle and thru it. I use opengl default coordinate basis ie. +y is up, +z is out of screen. The triangle has 3 verts, 3 indices, normal points up and has CCW winding order. Right now I'm using ODE space but I tried w/o it and same problem. My collision callback isn't called for weird reason. Had it at non-quick step, same thing. Running simulation at 60hz. Frames are like 500fps. Ask me questions if something is not clear. I cut off lots of code that is not relevant I think, it's tied to my libs as well. Thanks all. (triangle doesn't have a body and it had one but still problems even if not influenced by gravity)
struct UserData
	dWorldID world;
	dJointGroupID jointGroup;
	dBodyID boxBody;
int WinMain(...)
	vector<Mesh*> meshes;

	meshes.push_back(new Mesh(object_level.meshes[0], 0.02f, 0.02f, 0.02f, "Textures\\checkers.tga"));
	meshes[0]->Offset(0, 1.5f, 0);
	float boxWidth=0.2f, boxHeight=0.2f, boxDepth=0.2f;
	meshes.push_back(new Mesh(boxWidth, boxHeight, boxDepth, Color(0, 200, 0), false));// box
	meshes[1]->Offset(0, 2, 0);

	// create physics for our world
	dWorldID world = dWorldCreate();
	dWorldSetGravity(world, 0, -0.2, 0);
	dWorldSetAutoDisableFlag(world, 1);// auto disable bodies after some time or steps to speed up simulation
	// space
	dSpaceID space = dSimpleSpaceCreate(0);

	// bodies
	dBodyID boxBody = dBodyCreate(world);
	dBodySetPosition(boxBody, meshes[1]->GetPosition().x, meshes[1]->GetPosition().y, meshes[1]->GetPosition().z); 
	dMass boxMass;
	dMassSetBoxTotal(&boxMass, 1, boxWidth, boxHeight, boxDepth);
	dBodySetMass(boxBody, &boxMass);
	// geoms
	dGeomID boxGeom = dCreateBox(space, boxWidth, boxHeight, boxDepth);
	dGeomSetBody(boxGeom, boxBody);

	dTriMeshDataID levelData = dGeomTriMeshDataCreate();
		3 * sizeof(dReal),// vert stride
		3 * sizeof(int),// tri stride


	dGeomID levelGeom = dCreateTriMesh(space, levelData, 0, 0, 0);// last three params are callbacks
	dGeomSetBody(levelGeom, 0);// level becomes static object

	// must reset position of geom because dGeomSetBody(geom, 0) moves it back to the center
	dGeomSetPosition(levelGeom, meshes[0]->GetPosition().x, meshes[0]->GetPosition().y, meshes[0]->GetPosition().z); 

	// joint group
	dJointGroupID jointGroup = dJointGroupCreate(0);
	UserData userData; = world;
	userData.jointGroup = jointGroup;
	userData.boxBody = boxBody;

	struct CB
		static void dNearCallback(void *userData, dGeomID geom1, dGeomID geom2)
			const int nMaxContacts = 4;// number of contact points to generate
			dContactGeom contacts[nMaxContacts];
			int nContacts = 0;
			nContacts = dCollide(geom1, geom2, nContacts, contacts, sizeof(dContactGeom));
			// create contact joint for every collision point and put it into joint group
			for(int i = 0; i < nContacts; ++i)
				static dSurfaceParameters surface;
				surface.mode = dContactBounce | dContactSoftCFM; = dInfinity;
				surface.mu2 = 0;
				surface.bounce = 0.1f;
				surface.bounce_vel = 0.1f;
				surface.soft_cfm = 0.01f;
				dContact contact;
				contact.surface = surface;
				contact.geom = contacts;
				contact.fdir1[0] =  0;
				contact.fdir1[1] = -1;
				contact.fdir1[2] =  0;
				contact.fdir1[3] =  0;

				dJointID joint = dJointCreateContact(((UserData*)userData)->world,
					((UserData*)userData)->jointGroup, &contact);
				// attach a joint only to non-static body					
				dJointAttach(joint, ((UserData*)userData)->boxBody, 0);			
	CTimer t;	
	float deltaTime = 0;	
	float accumFrameTime = 0;
	// denominator is how many times per second you want physics to update
	const float stepTime = 1.0f/60.0f;
	// Main message loop:
	while(msg.message != WM_QUIT)
		if(!DrawWorld(meshes, deltaTime))			

		deltaTime = t.GetTimeNum();			
		accumFrameTime += deltaTime;
		while(accumFrameTime >= stepTime)
			accumFrameTime -= stepTime;

			// PHYSICS				
			// call collision detection
			dSpaceCollide(space, &userData, CB::dNearCallback);

			// take a simulation step
			dWorldQuickStep(world, stepTime);				

			// remove all joints in the contact joint group	
			// move box's mesh in world
			rad::Vec3 pos(*(rad::Vec3*)dGeomGetPosition(boxGeom));						

[Edited by - JD on May 25, 2005 3:07:06 AM]

Share this post

Link to post
Share on other sites
Original post by JD
The triangle has 3 verts, 3 indices, normal points up and has CCW winding order.

*Disclaimer* I'm still learning ODE though another wrapper.

In the wrapper for Ode I am using, OgreOde, it has this comment:

TriangleMeshGeometry* EntityInformer::createStaticTriangleMesh(Space* space)
assert(_vertex_count && (_index_count >= 6) && "Mesh must have some vertices and at least 6 indices (2 triangles)");

Perhaps you should try that - having at least 6 indices instead? Sorry, I don't know much else. Good luck!

Share this post

Link to post
Share on other sites
That's probably ogre's requirement. I had a box, a largish mesh and a tri and they all failed. When I used ODE plane, collision with the box sort of worked in that the box went thru the tri but was stopped on the other side. Sort of hanging off the bottom like that. The body and mesh are in synch. Very strange. I took a look at the ODE's tri mesh example and other than they having z-up I haven't noticed anything else. I should mention that the box is a box geom, not another triangle based mesh. Thanks for your help.

Share this post

Link to post
Share on other sites
Problem solved :) Just a bug in the following:

int nContacts = 0;
nContacts = dCollide(geom1, geom2, nContacts, contacts, sizeof(dContactGeom));

nContacts param in dCollide() should have been MaxContacts possible not zero as I have set it to. Thus I wasn't getting any actual contacts made.

Now, things work fine. I have a box bouncing inside a room and it's quite fun. Seems to be pretty stable so far but only time will tell how it handles game levels.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!