Game Development Community

Vehicle collision issues

by John Vanderbeck · in Torque Game Engine · 04/03/2004 (10:13 am) · 99 replies

Reference this thread. Moving this into the private forums for code.

@Brad
bool Rigid::resolveCollision(const Point3F& p, Point3F normal)
{
   atRest = false;
   Point3F v,r;
   getOriginVector(p,&r);
   getVelocity(r,&v);
   F32 n = -mDot(v,normal);
   if (n >= 0) {

      // Collision impulse, straight forward force stuff.
      F32 d = getZeroImpulse(r,normal);
      F32 j = n * (1 + restitution) * d;
      Point3F impulse = normal * j;

[b]      // Friction impulse, calculated as a function of the
      // amount of force it would take to stop the motion
      // perpendicular to the normal.
      Point3F uv = v + (normal * n);
      F32 ul = uv.len();
      if (ul) {
         uv /= -ul;
         F32 u = ul * getZeroImpulse(r,uv);
         j *= friction;
         if (u > j)
            u = j;
         impulse += uv * u;
      }
[/b]
      //
      applyImpulse(r,impulse);
   }
   return true;
}

Is this the correct section that should be pulled out? Should the applyImpulse call immediatly after it be pulled as well?

Would it be possible to see how you handled this?
Page «Previous 1 2 3 4 5 Last »
#1
04/03/2004 (8:39 pm)
I decided to play around with this to see what I came up with. I moved the code in bold (from JV's post) into Vehicle::resolveCollision() just above where it calls the resolveCollision for the rigid. (wasn't hard for a quick and dirty move, but I did have to ensure all the variables went along with it).

Then I made a few datablock changes...

collisionTol = 0.6;
contactTol = 0.6;
bodyFriction = 0.6;
bodyRestitution = 0.1;

This is for a hover, btw.

At first I had not changed the bodyRestitution, but those changes got rid of the nasty crashes I was having between hovers and interiors. (It still tended to get stuck and/or go through terrain)
Then it dawned on me (I can be slow sometimes) that resitution could be lower. Once I dropped it down I stopped having problems with passing through terrain at the higher speeds of my particular hovers, and the tendancy to get stuck in a hillside or upside down. I spent 15 minutes gleefully zooming over the terrain, the hover simply skipping off the way I thought it should, and never once going through the terrain or getting stuck. Of course more thurough testing might find more problems(including whether or not my code changes are any where near proper), but right now it's a tremendous improvement over what I had.

So an early thanks to Brad Shapcott and Matthew Fairfax for their helpfullness!
#2
04/04/2004 (9:37 am)
Awesome!

What are the effects when the vehicle is going slow? :)

Can you send me your vehicle.cc file? I'd like to see if this can go in HEAD.
#3
04/04/2004 (11:08 am)
@Martin:

There's another improvement I haven't mentioned yet. In Vehicle::updatePos, the updateCollision call is being made before the call to Rigid::integrate, meaning that updateCollision has calculated a solution to the collision, the force and torque are integrated into the Rigid body, which potentially 'breaks' the collision solution. This I believe is causing effects such as falling through terrain even at negligible speeds, because the collision solution is being defeated by gravity.

This doesn't show up in WheeledVehicle because that class integrates the force and torque into the Rigid body in its updateForces method, which is invoked before the updateCollision in the parent class' (i.e. Vehicle) updatePos.

I checked out the latest HEAD and am going to hand patch in my changes (they were made to a version of 1.1.2, and are interleaved with out unrelated changes), test them against the Warsparrow, and then see if the patch can be made into a resource.

As a bonus, I also had the Rigid v. Rigid stuff in, although it was causing chugging, but I think that was because I forgot to integrate the force and torque into the second Rigid. A bug fix is required in the overloaded version of Rigid::resolveCollision that takes a Rigid as the last parameter -- there is a cut and paste error (at least in my version of the code) that applies the impulse and inverse impulse to the same Rigid body.

Another bonus is that the code contains some examples of using asserts to check for instability in the physics.

I don't know how long this will take but I'm promoting the task to the top of my list because there seems to be so much interest in the subject. I'm hand patching from my code base over 1.1.2 to a fresh HEAD today, and will test early next week.

In my experience, with the code changes I've made, the parameters in the datablock are far less sensitive -- it takes far less tweaking to obtain decent behaviour, and I've been able to use higher velocites in vehicles without getting stuck or passing through terrain or interiors.

Not that this code is perfect, and one reason for sending it out will be to get even more pairs of eyes looking at it.

One thing I mentioned that I would like is an analytical solver for the Baraff algorithm (Baraff references another one of his papers somewhat elliptically as containing a fairly decent and fast solver v. a quadratic solver). That paper unfortunately is even heavier slogging than the one describing the iterative algorithm, and doesn't contain any ready-to-cut-and-paste code. In the interim I'd like to see if sorting the collision points will provide better behaviour in the iterative solver, which currently handles the collision points in arbitrary order. I'd like to handle points that will apply a large impulse close along the center of gravity first, which should produce large changes in linear velocity away from the collision surface. Handling the nodes arbitrarily may be applying impulses at collision points that produce large changes in angular momentum, which depending on the collision shape, may be accelerating the collision velocity at other collision points. Even without an analytical technique, this should produce improvements in the iterative solvers performance under common conditions.
#4
04/04/2004 (12:34 pm)
I applaud your stamina in this. It has been a huge problem with the engine for quite some time, and if you fix it I'll send you TONS of warm thoughts and virtual beers.

Any improvements to the code (even if they dont fix the problem completely) should go straight into HEAD imho.
#5
04/04/2004 (3:51 pm)
It occurred to me that when I moved the friction code that I didn't have it actually doing anything. (I had forgotten to add an applyImpulse with the friction loop). Which caused some rather nasty consequences, which were the results of using the wronge normal and not applying the impulse to the rigid. After changing that, it once again was working very nice.

My team doesn't have a programmer, so bear that in mind when you look at this. :) I commented where the friction stuff begins/ends...

bool Vehicle::resolveCollision(Rigid&  ns,CollisionList& cList)
{
   // Apply impulses to resolve collision
   bool colliding, collided = false;

   do {
      colliding = false;
      for (S32 i = 0; i < cList.count; i++) {
         Collision& c = cList.collision[i];
         if (c.distance < mDataBlock->collisionTol) {
            // Velocity into surface
            Point3F v,r;
            ns.getOriginVector(c.point,&r);
            ns.getVelocity(r,&v);
            F32 vn = mDot(v,c.normal);

            // Only interested in velocities greater than sContactTol,
            // velocities less than that will be dealt with as contacts
            // "constraints".
            if (vn < -mDataBlock->contactTol)
            {
               //Founder -moving the friction calcs here from the rigid method
               //in hopes that it will kill a few errors
               
               // Friction impulse, calculated as a function of the

               // amount of force it would take to stop the motion
               // perpendicular to the normal.
               Point3F uv = v + (cList.collision[i].normal * -vn);
               F32 ul = uv.len();
               F32 d = ns.getZeroImpulse(r,cList.collision[i].normal);
               F32 j = -vn * (1 + ns.restitution) * d;
               Point3F impulse = cList.collision[i].normal * j;
               if (ul) {
                  uv /= -ul;
                  F32 u = ul * ns.getZeroImpulse(r,uv);
                  j *= ns.friction;
                  if (u > j)
                     u = j;
                  impulse += uv * u;
               }
               ns.applyImpulse(r,impulse);

               // END FRICTION LOOP

               // Apply impulses to the rigid body to keep it from
               // penetrating the surface.
               ns.resolveCollision(cList.collision[i].point,
                  cList.collision[i].normal);
               colliding = collided  = true;

               // Keep track of objects we collide with
               if (!isGhost() && c.object->getTypeMask() & ShapeBaseObjectType) {
                  ShapeBase* col = static_cast<ShapeBase*>(c.object);
                  queueCollision(col,v - col->getVelocity());
               }
            }
         }
      }
   } while (colliding);

   return collided;
}
#6
04/04/2004 (3:51 pm)
@Ben I spent about 10 minutes nudging my hover into interiors at a slow speed. If the speed is slow enough it will stop the hover, and it will sort of stuck to the interior/terrain. (almost like it was a magnate. This doesn't generally last very long, maybe 2-3 seconds before the hover forces are able to lift it away from the collision point. That being said, I was not using the controls to move the hover away, but rather letting the code do the moving by itself. Giving just a slight nudge when it was "stuck" would immediately resolve the collision and let the hover go free. The only other affects of this I saw was when I turned the hover away from the collision, it would sometimes jump up as if it had bounced from a faster landing, even though it had not touched the terrain I kind of suspect this might be the hover code itself catching up to the normals/hover height of the vehicle.

I also spent some time nudging the hover into a nice tight bottleneck between terrain and an interior. To me it appeared to resolve those collisions in a reasonable manner. It did not make the hover into a pinball bouncing between springy bumpers, and eventually shooting it into outer space as it had in the past.

All in all this has been a huge improvement for me. And the one "iffy" slow-speed collsion issue is not something that bothers me near as much as the problems I had before. (though I can almost grasp why it's doing this, though I am doubtfull I could help it any. At slow speeds when the hover bumps into the colliding object at a close to perpendicular angle, I don't think friction would play a very larger role.)

In any case I have to say;

W00T!
#7
04/04/2004 (4:24 pm)
I played around some more and found a way to reproduce the small issue that I mentioned earlier. In my hover, I would drop off a fairly steep hill ending up with a moderate speed (around 40-50 on my hud). The hover wouldn't actually touch the ground, but would come close, then begin resuming normal operations, then bounce up, as if it was a delayed reaction to hitting the terrain.

I ran the debug version so I could watch the collision boxes, and I suspect that this is a case where the collision detection is over-shooting where the hover will actually go. This doesn't occur at high speeds, and at low speeds I have only seen it when pulling away from a collision, when the hover is already close to the ground. The only thing that doesn't make sense about it is the delayed reaction. Possibly the hover-specific physics has moved the hover away before the collision code has finished calculating a resolving impulse? Dunno, just a thought.
#8
04/04/2004 (8:44 pm)
@Martin:

I actually moved the friction calculations into a separate loop outside the do loop that implements the Baraff algorithm. I don't really see a reason the friction needs to be calculated more than once, and although it would be more 'accurate' to do friction and collision simultaneously, I can't find any reference for adding friction to the Baraff algorithm (but perhaps if the analytic solution were incorporated it would be more reasonable).

I have my code hand patched into 1.2 HEAD and am testing already, so give me a day or two to complete testing to the point where other people can grab the patch and help test/debug/refine.

I doubt what you are observing is a delayed reaction. Collision is resolved in the tick loop and 'micro' effects happen too quickly to be eyeballed. If the vehicle is hitting the terrain, it is probably a combination of its movement dynamics and collision shape, and more of a 'macro' issue.

@Thomas:

Quote:
Any improvements to the code (even if they dont fix the problem completely) should go straight into HEAD imho.

It would be nice for the community to kick around the code for a bit first. I've only tested the code under a narrow set of conditions that match my usage.

I also figure since I'm doing all the work to package this up, that I'm going to implement the collision point sorting as well and leverage some testing of that by distributing the package. The collision point sorting should improve the performance of the Baraff algorithm.
#9
04/05/2004 (3:43 pm)
Heh, I'm not trying to rush anyone, I've just been ever so thrilled the last couple of days since I can now bounce my hovers off of interiors without an engine crash. 'Course it's pretty obvious I don't know much at all about the collision code, nor do I claim to. And boy do I appreciate the help you are providing!!
#10
04/05/2004 (3:51 pm)
Wow i'm offline for a few days and all this! :)

I'm going to be going through all this tonight on our game once I get VC re-installed.
#11
04/22/2004 (7:46 pm)
Any more info on this? Sounds great..
#12
04/23/2004 (5:11 am)
Well after making the move that Martin showed above, the problem is diminished but not gone completely. I Also seem to have a new problem where if I approach a DTS object vry slowly, i'll often get "stuck" to it unable to move the vehicle away.
#13
04/23/2004 (7:23 am)
What is your Friction and Restitution settings for the body?
If they are high you can get sharp edges of the Col-1 shape stuck in things.
you might want to try a little

//collisionTol = 0.1; // Collision distance tolerance, more makes vehicle Col box bigger
//contactTol = 200; // Contact velocity tolerance, velocity above this number and you go through the earth?

I don't use either of them and only the first one is any use I think. It makes it less prone to getting stuck (I think).But dont go too high with the value because then your vehicle digs into the ground (ghost bumps at high speeds). And if your Hub nodes are not inside your Col-1 shape area they will pop the wheels underground when the nodes go underground - and we all know how hard it is to keep the Col-1 mesh away from the ground AND keep the hubs inside the Col-1 at the same time.... impossible? pretty much unless your vehicle has strong springs 2 units (meters) tall and a really wide wheel base.

avoiding ghost bumps.... gives me nightmares.
#14
04/24/2004 (9:48 am)
I did the change.. but my hover board startes fliping and flying off when i add it.. and i get this error when running in on the debug build..

Fatal: (c:\documents and settings\redcore\desktop\torque\engine\scenegraph\scenegraph.cc @ 927) Error, no zones found? Should always find root at least.
#15
04/28/2004 (9:30 pm)
Just stumbled upon this thread and it has helped immensly, but it would appear I have a problem. After a few good collisions my hovercraft starts floating upwards. So now instead of being a couple feet off the ground it's like 20. I've been tweaking my datablock and I have no idea why this is occurring. Everytime I go into the game it's fine, but after a few bumps into a wall it starts floating away.

The update did solve my collision issues though as far as going through walls and extreme bounces. :)
#16
05/14/2004 (12:34 am)
Fixed my problem. For some reason the gravity wasn't being added to my vehicle all of a sudden. I noticed in the code that the gravity also uses boyency. The default boyency is set to zero which cause the whole thing to zero out. As a quick hack I ripped out the boyency addition to that variable as I won't be having water in my game and that fixed the problem.

I'm still having a bit of trouble on slow collisions however. My hovercraft will sink into a wall. Works great on fast collisions, but if I sit next to a wall it will sink ito it and I lose control until I manually move my craft in the editor away from the wall. Any suggestions?
#17
12/29/2004 (6:28 pm)
Hate to revive a dead thread (if it really is dead... I'm not necessarily sure), but I'm wondering if any of the suggested changes therein will affect what I'm trying to do.

What I'm trying to do is to use RigidShape for some simple physics solutions (stacking boxes, rolling balls, etc). Should I make some of the changes suggested in this thread to accomplish that goal, or are the fixes irrelevant to what I'm doing? Since I'm not using vehicles of any sort, I'm just wondering.

Thanks guys!
#18
12/29/2004 (7:50 pm)
I'd say they won't help you much. The issue are FYI still there, these fixes are just attempts to make it less aggresive.
#19
12/29/2004 (11:08 pm)
Back in April Ben asked for the sources, to see, if he can add this to HEAD.

Does anyone know, if GG staff has looked into the problem so far?
#20
12/30/2004 (10:54 am)
The above clamp values are arbitrary and were set based on my needs for the game. Those could be changed to whatever you like.
Page «Previous 1 2 3 4 5 Last »