Collision issues

sengoku

18-05-2006 08:38:11

Hi,
I'm trying to set up a 3rd person game with a fairly generic collision detection/handling setup (I don't need true physics).

'UP' walks forward, 'LEFT' and 'RIGHT' rotate the character.
I want instant start/stop upon key press/release, and 'correct' game behaviour for when walking into walls (ie walking at angle x, hit a wall, continue 'sliding' along wall while still facing angle x until the wall ends). I don't want my character bouncing off the walls and controlling like the game asteroids :).

Firstly, the closest I've gotten so far is to use setVelocity()/setOmega() on the character body.
This controls the character just fine, I get collisions with other objects, but theres a few problems with it. When the character (currently an ellipsoid collision) collides with a static box (house, wall, etc), it rotates towards the normal of the collision and ends up getting stuck facing that direction, and no amount of setOmega() can make it rotate out of it.
Here is a picture. A shows what happens now, B shows what I'm after.



To solve the 'sticking' problem, I've tried a bunch of things, none could fix the problem reliably.

1). I tried saving the orientation of the player before the collision, and restoring it after. This solves the player rotating towards the normal problem, but gave me a 'sinking' into the wall effect. This sinking into the wall appears unrelated to material softness/elasticity, and the amount you sink into the wall is proportional to the angle you approach it.
Additionally, I'm not able to figure out how to make the character rotate from pressing LEFT/RIGHT while it is colliding with a wall (I could use setOrientation and work out the angle to rotate manually, but it doesn't seem like the right approach).

2). I also tried setting the velocity during the collision to the current velocity (if 'UP' is pressed), but modified it so that it looks at the collision normal and removes all motion in that direction - also returning zero from userProcess() so that I can do the manual collision. This kinda works, but you can still wiggle your way through walls, and its a bit unstable near the wall corners.

Both of these approaches make my character slide alone the wall, and it looks correct, aside from their respective problems.

I initially tried using real physics forces, but I couldn't get the movement I wanted, no friction, instant stop, not bouncing off walls, and so on. The setVelocity() method also lets me use the Ogre terrain scene manager more easily than using forces, because I can just apply the correct velocity to keep the character at the right height (we can talk about PLSM2 and not using it in another thread please :)).

Here is some code for the manual collision handling method (2) that I tried. I can post code for the other parts too, but I'll try and keep this (long) post as short as I can for now.


void Cscene::forceCallback(OgreNewt::Body *body) {

Vector3 pos;
Quaternion orient;
body->getPositionOrientation(pos, orient);

Vector3 force = Vector3(m_moveCharForward * 20, 0.0, 0.0);
force = orient * force;

force.y = pos.y < 0 ? 0 : -7; // Cheap gravity...

body->setVelocity(force);
body->setOmega(Vector3(0.0, 3.0 * m_moveCharRotate, 0.0));

}


int Cscene::userProcess() {

Vector3 pos;
Vector3 norm;

getContactPositionAndNormal(pos, norm);

Vector3 vel = m_body0->getVelocity();

// this could be more advanced, not sure where to go from here though
// also note that walls are guaranteed to be boxes aligned with x/z axes
if(fabs(norm.x) > 0.0001) {
vel.x = 0;
}
if(fabs(norm.z) > 0.001) {
vel.z = 0;
}

m_body0->setVelocity(vel);

return 0;

}



So am I on the right track, or are there suggestions for a completely different approach?
Thank you!

wooohoh

29-12-2006 10:26:26

I know this thread is old, but i wanted to leave a message since this thread is TOTALY AWESOME.
i had a nightmare problem because of sticking bodies..
but no more :)

thanks, i solved it using ur method.
I can't think of any better solution than urs.

walaber

29-12-2006 17:34:16

have you tried removing all friction between the player body and the surrounding world? that will keep your body from getting "stuck", or "turning into" walls that it collides with...

wooohoh

30-12-2006 04:51:48

Jesus! walaber.... what a simple solution. Thanks.

jintal

19-01-2007 07:05:00

but if you take off the friction. then the character would just slide and wouldn't stop. now the problem is, how can u set it so that there will be friction on the floor (or some normal) but not on the walls?

nathanwilliams6

19-01-2007 10:21:27

give the walls and floor different collision materials, then create two material pairs, one between the player and the floor (which will include friction) and one between the player and the walls (which will not)

walaber

19-01-2007 20:43:43

or have 0 friction, and when the player is not moving (no movement buttons are being pressed), apply a small force in the opposite direction of the current velocity, to slow the player down.