Help! Vehicle collision in Player class
by Daniel Buckmaster · in Torque Game Engine Advanced · 09/17/2009 (5:07 am) · 12 replies
So on a break from my work on swarms (after a more extended break when a friend came to stay with me), I'm trying to do what I've been working at for the last few months. I want to get Players using the Vehicle collision system, and especially using multiple collision hulls. I've implemented this. It doesn't work very well.
Often, the collision works nicely. I can run around the terrain and bang into trees and things perfectly well. Occasionally, randomly, I fall through the terrain entirely. In some repeatable situations (like when I spawn in the content pack demo 1), I fall through the terrain most of the way, and then get stuck jittering with my head sticking above the ground. Sometimes, collision response seems to be off - I get bumped in a silly direction when encountering a small seam in the terrain. And finally, the collision often prevents the Player from finding a ground contact, meaning he goes skating around for a while without being able to move.
I have a general question:
1. Is the vehicle collision scheme reliable enough, and fast enough, to be used this way?
Oh yes, and:
2. Anyone feel like helping out?
:P
Often, the collision works nicely. I can run around the terrain and bang into trees and things perfectly well. Occasionally, randomly, I fall through the terrain entirely. In some repeatable situations (like when I spawn in the content pack demo 1), I fall through the terrain most of the way, and then get stuck jittering with my head sticking above the ground. Sometimes, collision response seems to be off - I get bumped in a silly direction when encountering a small seam in the terrain. And finally, the collision often prevents the Player from finding a ground contact, meaning he goes skating around for a while without being able to move.
I have a general question:
1. Is the vehicle collision scheme reliable enough, and fast enough, to be used this way?
Oh yes, and:
2. Anyone feel like helping out?
:P
About the author
Studying mechatronic engineering and computer science at the University of Sydney. Game development is probably my most time-consuming hobby!
#2
It makes me feel like your avatar ;P.
I narrowed the problem down to caling Convex::findClosestState. I did some raycasts to check if we *should* be hitting the ground this tick, and in cases where we should hit the ground, findClosestState doesn't agree.
So I go and look in findClosestState, and it's completely incomprehensible to me :P.
[I'm goinng to remove my multiple-hull stuff and see if I can get it working - but multihull is crucial to my plans...]
09/17/2009 (10:26 pm)
I would, but frankly, I doubt I have the know-how to dive into collision programming at this stage.It makes me feel like your avatar ;P.
I narrowed the problem down to caling Convex::findClosestState. I did some raycasts to check if we *should* be hitting the ground this tick, and in cases where we should hit the ground, findClosestState doesn't agree.
So I go and look in findClosestState, and it's completely incomprehensible to me :P.
[I'm goinng to remove my multiple-hull stuff and see if I can get it working - but multihull is crucial to my plans...]
#3
09/18/2009 (4:04 am)
Dan, what is your collision tolerance going into findClosestState, have you tried setting it to a big number?
#4
I'll be getting straight back on swarms after this little diversion ;P
EDIT
With collision and contact tolerance at 1, and 0 restitution, the player does come to rest on the terrain, but moving collision is absolutely buggered.
EDIT
Hmm. Collision tol at 0.2, contact tol at 0.1, 0 restiution, and the collisions work perfectly - except that the character is hovering about 0.2 units off the ground. Grr.
Thanks for that tip, though! It seems I'm misunderstanding something fundamental about what collisionTol and contactTol actually do.
EDIT
Multihull isn't working anyway, so I might as well see what I can do without it for now :P.
09/18/2009 (10:28 am)
It's 0.1. I tried setting it to 0.2 and 1.0 (which is the function default), but that ended in the player sitting high above the ground, out of movement contact, and bouncing in a most ungainly fashion. I'll tweak some other bits and bobs and see whether I can get it to work with a large tolerance.I'll be getting straight back on swarms after this little diversion ;P
EDIT
With collision and contact tolerance at 1, and 0 restitution, the player does come to rest on the terrain, but moving collision is absolutely buggered.
EDIT
Hmm. Collision tol at 0.2, contact tol at 0.1, 0 restiution, and the collisions work perfectly - except that the character is hovering about 0.2 units off the ground. Grr.
Thanks for that tip, though! It seems I'm misunderstanding something fundamental about what collisionTol and contactTol actually do.
EDIT
Multihull isn't working anyway, so I might as well see what I can do without it for now :P.
#5
(The conspiracy theory side of me is waiting for his name to be mysteriously edited out...)
So now just the contactTol issue. I definitely like the fact that with it at 0.2 I can actually collide reliably. What I don't like so much is that all collisions seem to take place that distance way from the actual collision hull.
EDIT
It seems that I'd get the effect I wanted if I simply scaled contactTol dynamically according to player movement. The trouble I'm having is that contactTol is too large when the player is stationary, but too small when the player is moving quickly - why not have the best of both worlds by letting the contactTol rattle around in a given range based on movement speed?
09/19/2009 (5:57 am)
I got multihull working! It turned out to be an art issue, so thanks go to the immortal J.S. Greenawalt for his awesome Blender exporter documentation.(The conspiracy theory side of me is waiting for his name to be mysteriously edited out...)
So now just the contactTol issue. I definitely like the fact that with it at 0.2 I can actually collide reliably. What I don't like so much is that all collisions seem to take place that distance way from the actual collision hull.
EDIT
It seems that I'd get the effect I wanted if I simply scaled contactTol dynamically according to player movement. The trouble I'm having is that contactTol is too large when the player is stationary, but too small when the player is moving quickly - why not have the best of both worlds by letting the contactTol rattle around in a given range based on movement speed?
#6
with
I'm guessing, but from what you've described it sounds like different bits of code are using collision tolerance in different ways.
09/20/2009 (2:28 pm)
Instead of changing collision tolerance, have you tried overriding it in the call to GjkCollisionState::distance, i.e. leave collision tolerance at 0.1 and inside Convex::findClosestState, replace F32 dd = state->distance(axform, bxform, dontCareDist, &axforminv, &bxforminv);
with
F32 dd = state->distance(axform, bxform, 10.0f, &axforminv, &bxforminv);
I'm guessing, but from what you've described it sounds like different bits of code are using collision tolerance in different ways.
#7
Replacing the use of dontCareDist with 1.0 didn't seem to help. I'll try replacing both references in that function, with 10 this time :P.
EDIT: It does seem to be caused by the Player movement code. Removing the code that takes away acceleration into the contact surface allows the character to come to rest.
Arg. Issue not solved, just made more transparent. The character still rests above the ground by contactTol units. Unfortunately, reducing contactTol (to 0.02, I tried) breaks collision with interiors. I wasn't intending to use interiors in the game much, but that still makes no sense at all :P.
Also still some intermittent collision issues with falling through steep terrain.
EDIT: Intermittent issues solved, I *think* - I had made some assumptions in updateWorkingCOllisionSet that didn't always hold up (well, ever actually - I just usually got lucky :P).
09/20/2009 (10:23 pm)
I'm finding the behaviour seems linked in part to the usual Player movement code, specifically the distane I use in findContact. If I use the usual findContact search box, which has a height of something like 0.06 units, then the character collides nicely, but has no control and ends up spasmodically jerking down to knee-level in the terrain.Replacing the use of dontCareDist with 1.0 didn't seem to help. I'll try replacing both references in that function, with 10 this time :P.
EDIT: It does seem to be caused by the Player movement code. Removing the code that takes away acceleration into the contact surface allows the character to come to rest.
Arg. Issue not solved, just made more transparent. The character still rests above the ground by contactTol units. Unfortunately, reducing contactTol (to 0.02, I tried) breaks collision with interiors. I wasn't intending to use interiors in the game much, but that still makes no sense at all :P.
Also still some intermittent collision issues with falling through steep terrain.
EDIT: Intermittent issues solved, I *think* - I had made some assumptions in updateWorkingCOllisionSet that didn't always hold up (well, ever actually - I just usually got lucky :P).
#8
09/22/2009 (3:53 pm)
Glad to hear you are making progress:) I find debugging anything to do with collision detection really nasty because you have to catch things just at the point where they are supposed to collide, but don't, without knowing exactly where to look!
#9
So what I end up with is the character resting very nicely on the ground, but when it moves, being bumped up into the air by the expanding collision volume. And when falling from a great height, the character will be jerked to a halt quite a distance above ground height. I guess this is just a case of me implementing a sensible maximum tolerance. But I still don't see the sense in a collision system that fails to work entirely with a tolerance too small, and provides nonsense results with a tolerance too large.
There seem to be cases in the collision code, the collide point method I looked at in particular, that check to see whether the point is within collisionTol of aplane, regardless of which side it's on. Does this make sense? I wonder if I could just remove the case where the point was outside the plane...
09/24/2009 (11:24 am)
I've made some progress with my variable tolerance, but the problem seems to be my understanding of tolerance versus what it actually does. It sounds like it should be used as a penetration limit - so if a collision is deeper than collisionTol, then it's ignored. But in fact its effect seems to be 'expand the collision hull by collisionTol units' :P.So what I end up with is the character resting very nicely on the ground, but when it moves, being bumped up into the air by the expanding collision volume. And when falling from a great height, the character will be jerked to a halt quite a distance above ground height. I guess this is just a case of me implementing a sensible maximum tolerance. But I still don't see the sense in a collision system that fails to work entirely with a tolerance too small, and provides nonsense results with a tolerance too large.
There seem to be cases in the collision code, the collide point method I looked at in particular, that check to see whether the point is within collisionTol of aplane, regardless of which side it's on. Does this make sense? I wonder if I could just remove the case where the point was outside the plane...
#10
But then in Vehicle::resolveContacts it also seems to be using collisionTol to calculate a force designed to keep objects collisionTol units apart:
So maybe collisionTol should be set large, so that fast moving objects don't fall through things, but then you could try altering the force equation to
and see if that cures the hovering effect.
09/24/2009 (5:00 pm)
When I was looking through the GjkCollisionState stuff what I thought it was doing was using the collisionTol to ignore objects more than tolerance units apart before doing more detailed checks.But then in Vehicle::resolveContacts it also seems to be using collisionTol to calculate a force designed to keep objects collisionTol units apart:
F32 s = (mDataBlock->collisionTol - c.distance) * zi - ((vn / mDataBlock->contactTol) * zi);
So maybe collisionTol should be set large, so that fast moving objects don't fall through things, but then you could try altering the force equation to
F32 s = (/*mDataBlock->collisionTol*/ 0.1 - c.distance) * zi - ((vn / mDataBlock->contactTol) * zi);
and see if that cures the hovering effect.
#11
It might not help that I didn't understand what zi did in the vehicle code, so I approximated it with 2 * getMass() :P.
...And the character still seems to get bumped up to 0.2 units when moving :S.
I attempted using the momentum in the direction of the normal for zi. The Vehicle code calls rigid.getZeroImpulse, which seems like it should be the impulse to stop all velocity in a given direction. So I approximated that with getMass() * mDot(mVelocity,c.normal). It seems to work, but I'm now back to hovering above the terrain :P.
EDIT: By realising that I can simply skip collisions when the distance is greater than 0 (i.e., when the collision is outside the mesh), I fixed the floating issue. However, collision with interiors breaks completely :P.
09/24/2009 (11:13 pm)
Good catch! That seems an infinitely better solution than altering the collision detection itself :P. I think I'm going to have to do some more playing around with that equation - your suggestion does work, it seems that this code was causing the hovering (I've set it down to 0.01f). But now I still get a solid collision 0.2 units away, and a very slow sink down to 0.01 units to rest.It might not help that I didn't understand what zi did in the vehicle code, so I approximated it with 2 * getMass() :P.
...And the character still seems to get bumped up to 0.2 units when moving :S.
I attempted using the momentum in the direction of the normal for zi. The Vehicle code calls rigid.getZeroImpulse, which seems like it should be the impulse to stop all velocity in a given direction. So I approximated that with getMass() * mDot(mVelocity,c.normal). It seems to work, but I'm now back to hovering above the terrain :P.
EDIT: By realising that I can simply skip collisions when the distance is greater than 0 (i.e., when the collision is outside the mesh), I fixed the floating issue. However, collision with interiors breaks completely :P.
#12
EDIT: Or... it could be the case that Interiors are concave? I tried stacking up multiple convex interiors (the blocks from starter.racing), and the collision seemed to work much better than on the noisy surfaces of the Cottage.
Or... it could be that my collision is simply broken. For some reason, I still fall through the terrain to my knees every time I spawn in Content Pack Demo 1.
10/01/2009 (1:05 am)
Think I found a critical problem with the interior collisions. The character isn't geting pushed out of the interior's surfaces, so things are screwing up. Maybe it's to do with this:// Velocity into surface
Point3F v,r;
r = c.point - getPosition();
v = getVelocity(r);
F32 vn = -mDot(v,c.normal);
// Only interested in velocities less than mDataBlock->contactTol,
// velocities greater than that are dealt with as collisions.
if (mFabs(vn) < mDataBlock->contactTol)
{
collided = true;
// Penetration force. This is actually a spring which
// will seperate the body from the collision surface.
F32 zi = getMass() * vn;
F32 s = (0.01f - c.distance) * zi - ((vn / mDataBlock->contactTol) * zi);
Point3F f = c.normal * s;
// Accumulate forces
p += f;
}Specifically:F32 s = (0.01f - c.distance) * zi - ((vn / mDataBlock->contactTol) * zi);When the velocity is tiny (assume 0), only tiny impulses will be applied. So if you're going slow, no matter how far you've penetrated into the object, you're not going to move. I think this equation needs to be revised to be based on distance as well as velocity.
EDIT: Or... it could be the case that Interiors are concave? I tried stacking up multiple convex interiors (the blocks from starter.racing), and the collision seemed to work much better than on the noisy surfaces of the Cottage.
Or... it could be that my collision is simply broken. For some reason, I still fall through the terrain to my knees every time I spawn in Content Pack Demo 1.
Torque Owner deepscratch
DeepScratchStudios
the vehicle collision is notoriously buggy, (no pun intended)
why not look at really revamping the player collision?