Sign in to follow this  
jujumbura

Character collision responses

Recommended Posts

Hello all. I've finally had some success in getting my BB's and my world polygons to collide, as well as getting BB's to collide with BB's( after trying lots of stupid algorithms and redoing SAT a bunch of times ) . I am pleased with the 3D collision detection, but now comes the question: what do I do with it? From what I can see in most games where you have the usual 'WASD' + jump controls, running into a wall/entity doesn't always entirely stop your motion. If you are running directly into the normal of the wall, you don't move at all. But, if you are coming at an angle to it, you still move along the wall, though at a slower speed. My guess is that they take the dotProd of the wall normal and the motion vector, then add them together( should be negative ) to cancel out the "normal component" of the motion vector. If you're running right into the wall, that would be everything. If you're barely angled into it, that would be almost nothing. This would result in that "sliding along the wall" effect that seems to be pretty standard. Also, it would have the nice side effect of allowing me to move up ramps with the same old motion vector I've been using. Does this sound about right? Or dead wrong? Are there other 'basic collision responses' that you guys know about? I'm all ears. Thanks, jujumbura

Share this post


Link to post
Share on other sites
Alrighty, so I plugged in my little "collision rerouter" function that I mentioned earlier, where a portion of the motion vector is redirected to be parallel to the normal of a collision surface. The sliding along walls looks and feels good.

However, I now have an additional problem. What if this rerouted motion vector collides with ANOTHER surface? I could just redirect the rerouted vector for the new surface just like I did with the first one, but this seems like it could result in some weird movements.


For example. Your character is facing NW. You move forward, and you hit a wall that runs east-to-west. Your motion vector portion parallel to the wall is going west. So the rerouted vector would be heading west, with only a portion of the magnitude you would normally move.

But you do a collision test for this vector against ANOTHER wall next to the east-to-west wall. This second wall runs northeast-to-southwest. The corner looks something like this;

***_________
**/ <-rerouted motion
*/
/

So it turns out that this rerouted vector is going to collide with the northeast-to-southwest wall. If you took the rerouted vector and redirected that against the second wall, you would now be moving southwest with an even SMALLER magnitude.

But hang on here. Your character is facing NW, and this double-redirect on a motion attempt results in a vector going SW? That's a little freaking weird if you ask me. Depending on how steep the walls are angled to one another, you have the potential to get double-rerouted almost 180 degrees! ( although the magnitude would be TINY at that point )

So I'm wondering: is it just a better idea to flat-out cancel any motion vector that has a collision AFTER being rerouted from the first collision? I am trying to think of how these collisions are handled in most games; it seems like usually if you move into a corner you stop moving, until you turn into a better angle.

Does this sound right? Any suggestions?
jujumbura

Share this post


Link to post
Share on other sites
Only time for a short answer now, but I thought I'd mention that the problems you're describing can be dealt with. There are probably other ways to do it, but in my own implementation of this method I kept track of which surfaces had been collided with and handled certain cases separately (I got the idea from studying the Quake 2 source code, which uses a similar collision detection and response method). In particular, when the object gets in a 'crease', you restrict the velocity vector to the direction of the crease, which is the cross product of the face normals. This may actually be what you described in your last post - I'm not sure. I was very happy with the results of this method; no shaking, sticking, or getting stuck in corners.

I think I did a 'black box' implementation of the whole swept-test-and-sliding-response thing at some point, but it might be kind of hard to dig up at the moment. However, if you think it might be useful to you I could look around for it.

Share this post


Link to post
Share on other sites
Cross products of the face normals? Whoa.

So then, when running around on a flat floor and you run into a corner formed by vertical walls, the cross product of their normals will be either straight up, or straight down right? Neither of which you probably want to move in from a simple corner collision. A down vector could be blocked by a collision with the floor, but what if it turns out to be straight up?

I suppose I could just flat out ignore any positive y component to the crease-directed motion vector, but that's not always what I want, either. If the slope of the wall is gentle, then I'd like to move up. And if, for example, I ran into the railings for a ramp, then the cross product of the railing wall and the ramp( straight up the ramp ) would be exactly what I want to move in.

So then, is the solution to cap off any redirected motion vector if the y component is under/over an appopriate value? This would handily solve the corner problem, and also restrict characters from climbing slopes that are too steep.

How's it sound?

Share this post


Link to post
Share on other sites
Is this any help? I tried implementing it myself, but had a little trouble. In the end I just decided to give my character inertia and have it bounce back off of objects as it fitted in well with my design (which has since changed again!), so simply upon detecting a collision, had it move back in the direction it came at a reduced velocity proportionate to the initial velocity, performing another collision test each time it bounced back. In this way the character never ended up being so close to a wall that precision issues caused collision checks to fail, so there was never any worry of the character being pushed through a wall by dodgy collision.

Anyhoo, I appreciate that characters bouncing from walls doesn't really fit into all game designs, so I hope the link is of some use!

Cheers,

Steve

Share this post


Link to post
Share on other sites
Quote:
So then, when running around on a flat floor and you run into a corner formed by vertical walls, the cross product of their normals will be either straight up, or straight down right? Neither of which you probably want to move in from a simple corner collision.
Right, and you won't :) The idea is to only keep the part of the velocity vector that is parallel to the corner edge. I can't remember exactly how it's implemented, but something like:
Vector3 edge = normalize(cross(face1.normal, face2.normal));
velocity = dot(velocity, edge) * edge;
This way, in your perpendicular example above you just end up killing the velocity vector, and viola, you stop dead. But if the corner is slanted with respect to the ground plane, you'll 'climb' up it, gravity permitting.

Share this post


Link to post
Share on other sites
Oh, interesting.

So unclimbable walls are that way due to gravity negating the redirected motion vector? I had never thought of it that way. Although, if I'd REALLY thought about it, that's what's actually happening in the real world.

But won't this mean gravity will make me constantly slide down any ramp I'm on, even when it's a really low slope? That doesn't seem consistent with most games, although I have seen games where on very steep slopes you have to keep running up to prevent yourself from sliding down. How do they determine when to allow gravity to tug you down the surface, and when to let you sit there?

Please don't tell me they use a coeficient of friction >_<

Share this post


Link to post
Share on other sites
Quote:
But won't this mean gravity will make me constantly slide down any ramp I'm on, even when it's a really low slope?
Yup, unless you do something about it :)
Quote:
That doesn't seem consistent with most games, although I have seen games where on very steep slopes you have to keep running up to prevent yourself from sliding down. How do they determine when to allow gravity to tug you down the surface, and when to let you sit there?

Please don't tell me they use a coeficient of friction >_<
Nah, usually it's just a simple hack (at least for traditional FPS-type games). For example, you might decide that (assuming z is up) any surface whose normal has a z component > some threshold is 'flat enough' that you shouldn't slide.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this