physics question: Trimesh collisions

Post your questions, suggestions and experiences regarding game design, integration of external libraries here. For irrEdit, irrXML and irrKlang, see the
ambiera forums
Post Reply
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

physics question: Trimesh collisions

Post by cheesehound »

I've been grasping for solutions with a problem for a while now. I've been using ODE for physics in my game, and am using a trimesh for my world and a box for my actor.

My box keeps getting stuck in the trimesh. The problem is aggravated by high speeds, but it happens often enough at low speeds that it's an unavoidable problem for me.

Currently, I update my physics simulation with a tick time/step size of 30ms, which seemed reasonable at the time, given what I've read of other games' implementations. Is that the case?

I'm currently thinking of switching to Bullet. I was tempted to use PAL, but I'd like to be able to restrict movement to 2D, and am not confident in PAL's ability to pull that off given its level of abstraction. Those of you that have used Bullet: Does trimesh collision work without things penetrating and getting stuck in trimeshes quite so easily, and/or does setting a penetration depth work correctly? What I've seen looks pretty encouraging, but I'd rather not get burned twice on this.
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Re: physics question: Trimesh collisions

Post by sio2 »

cheesehound wrote:My box keeps getting stuck in the trimesh.
Unless I've misread your post then this is exactly what I'd expect. A box is going to get stuck; use something like a capsule instead.
twilight17
Posts: 362
Joined: Sun Dec 16, 2007 9:25 pm

Post by twilight17 »

Capsules are usually used for player collision.
Post this userbar I made on other websites to show your support for Irrlicht!
Image
http://img147.imageshack.us/img147/1261 ... wernq4.png
intworld
Posts: 3
Joined: Thu Dec 25, 2008 5:56 pm

Post by intworld »

hello,

do you have example code for the callback that are you using to resolve the collisions? what happens with the collisions when you reduce the time step from 30ms to 20ms, and do you use dWorldQuickStep or dWorldFastStep1?
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Post by cheesehound »

I'm pretty surprised that boxes don't work in trimeshes. I didn't see that in the documentation for ODE, and you guys say it like it's a given for any physics engine, but hey, capsules do seem to work much better. I can still get them stuck in some more complex geometry, but I don't aim to have unnecessarily complex terrain.

Thanks, guys.
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Post by cheesehound »

intworld:

I tried bumping my time step to 20ms and still was able to get stuck and saw boxes penetrating my mesh if friction < dInfinity.

I'm not doing anything checking on the penetration depth of a given collision. Is that off? I was under the impression that if they'd already penetrated each other in ODE that trimeshes made it awful difficult to determine the correct direction to eject in. I'm sure I could tinker with making a dumb guess, though.

I'm including my callback code below, but you probably don't have to bother if penetration code is what you were looking for.

Code: Select all

void
//-----------------------------------------------------------------------------
jazz::NearCollisionCallback
//-----------------------------------------------------------------------------
		(
		void* aNode,
		dGeomID aGeom1,
		dGeomID aGeom2
		)
{
	dBodyID theBody1 = dGeomGetBody( aGeom1 );
	dBodyID theBody2 = dGeomGetBody( aGeom2 );

	const int cMaxContacts = 4;

	if( theBody1 && theBody2 &&
		dAreConnectedExcluding( theBody1, theBody2, dJointTypeContact ) )
	{
		//just return if there's some other joint interacting between these
		//bodies besides a collision.
		return;
	}

	dContact theContact[cMaxContacts];
	for( int i = 0; i < cMaxContacts; ++i )
	{
		theContact[i].surface.mode = dContactBounce;
		theContact[i].surface.mu = dInfinity;
		theContact[i].surface.bounce = 0.1f;
		theContact[i].surface.bounce_vel = 0.1f;
	}

	//contact count for just this collision.
	int theContactCount =
		dCollide(aGeom1, aGeom2, cMaxContacts, &theContact[0].geom, sizeof( dContact ) );

	if( theContactCount > 0 )
	{
		PhysicsManager_t& thePhysicsManager = GlobalManagers().PhysicsManager();

		const WorldPhysicsInfo_t& theWorldPhysicsInfo = thePhysicsManager.WorldPhysicsInfo();

		for( int i = 0; i < theContactCount; ++i )
		{
			dJointID theContactJoint = dJointCreateContact( theWorldPhysicsInfo.worldId,
															theWorldPhysicsInfo.contactGroupId,
															&theContact[i]);

			dJointAttach( theContactJoint, theBody1, theBody2 );
		}

		PhysicsObjectMap_t::iterator theFirstIter = thePhysicsManager.ObjectFind( aGeom1 );
		PhysicsObjectMap_t::iterator theSecondIter = thePhysicsManager.ObjectFind( aGeom2 );

		//call onCollision for both PhysicsObjects.
		if( theFirstIter != thePhysicsManager.ObjectEnd() &&
			theSecondIter != thePhysicsManager.ObjectEnd() )
		{
			PhysicsObject_t* theFirstObject = theFirstIter->second;
			PhysicsObject_t* theSecondObject = theSecondIter->second;

			theFirstObject->OnCollision( *theSecondObject );
			theSecondObject->OnCollision( *theFirstObject );
		}
		else
		{
			throw 1; //FIXME: actually throw a damn exception.
		}
}
intworld
Posts: 3
Joined: Thu Dec 25, 2008 5:56 pm

Post by intworld »

hello,

the callback code appears normal, but if you are restricting motion to 2 dimensions, i think it is better with a physics library specifically designed for 2d.

Box2D
http://sourceforge.net/projects/box2d/

http://www.box2d.org/wiki/index.php?title=Sample_code

there is also Flatland, but it is less developed than Box2D. it is built on ODE, but uses many hacks to convert 3d physics into 2d physics.
http://sourceforge.net/projects/flatland/
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Post by cheesehound »

I don't want to limit my engine to 2D; I just want to be able to make it run in only two dimensions if desired.

So there's no magic to do with detecting and correcting penetrations in the collision callback? I'll tinker with it a bit, but if that's not a normal solution for this kind of thing I'll concentrate on making my collision trimeshes less complicated.
intworld67
Posts: 1
Joined: Wed Dec 31, 2008 1:53 pm

Post by intworld67 »

if you're limiting motion to a 2d plane in 2d space, you will need a 2d physics engine, but if it's a 2d plane inside a 3d space (i.e. a labyrinth or racing game with no terrain), either 2d or 3d physics can be used

i have code that tests ode collisions with boxes and trimeshes, and the boxes do not become stuck. are you using ode only or an ode wrapper? the callback code looks like the latter.
Post Reply