Game Development Community

Flying Vehical crashing revisited

by Gonzo T. Clown · in Torque Game Engine · 08/12/2004 (12:44 am) · 17 replies

Ok, for the last two nights I have been having the same problems others have had for the last two years with the vehicals crashing (or more to the point, getting caught in the infinite loop lockup). After trying every possible setting I could find in every "Flying Vehical" thread and examining every resource I could find I finally started trying to debug this problem....


First off, no matter what settings I try for the flying vehical datablock I get the same crash every time, over and over. So this has got to be an engine flaw.

The first problem VC++ points out is in convex.h at line 183

"ConvexType getType() { return mType; }"

returns the error of...

CXX0069: Error: variable needs stack frame


This function is being called from terrCollision.cc in function "void TerrainBlock::buildConvex(const Box3F& box,Convex* convex)" at line 390 and it hangs up and starts it's inifnate loop in this section of code....

for(CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext)
          
  if(itr->mConvex->getType() == TerrainConvexType && static_cast<TerrainConvex*>(itr->mConvex)->squareId == sid)
  {
        cc = itr->mConvex;
        break;
   }
   if(cc)
       continue;


As best I can tell squareId and sid are never going to equal each other so it just loops forever and "if(cc) continue;" returns a 'cannot be evaluated' error because it's set at zero and stays there. Should that statement even be there, or should CC be set at 1 just so it can be evaluated? Regardless, if squareId and sid are never equal, then the engine will never escape that for loop.

I'm not a C++ expert so I'm not sure what the fix for this would be. Any help on this would be greatly appreciated.

#1
08/12/2004 (3:47 am)
Just a thought. You using a valid .dts shape with proper collision meshs? I haven't seen this issue playing with flying vehicles. I used
Badguy's model from one of his thread. My modeling attempts misdirected me for days.
#2
08/12/2004 (6:21 am)
Ok, I finally figured it out. None of the datablock settings really make a that much of a difference here except for one, "integration". The amount of integration you need is directly related to how fast you are going. The real trick here is that speed and integration have nothing to do with each other in the code but they will trip each other up while each does their job. Here's how to manage this age old problem.


By default, in 'vehicle.cc' you find on line 75....

integration = 1;

This will not do. I highly recommend that GG sets the default to 5 to prevent others from going through this in the future. Also in 'vehicle.cc' on line 637 you find...

S32 count = mDataBlock->integration;

I also recommend that GG insert a check of...

if(count < 5) { count = 5; }

to prevent anyone from setting it below 5. And here's why...


During my research most of the datablocks I reviewed had integrations of 1 or 2 and in the documentation it shows a default value of 1 for this variable.

www.garagegames.com/docs/torque/general/apcs07.php

1 and 2 are fine if you are not moving very fast or not moving at all. But once you start moving, you are asking for a crash. During my tests I found that by going from 1 to 2, I could fly a little longer before I crashed. Going from 2 to 3, I could fly even longer before the crash, going from 3 to 4 same thing, when I got to 5, the crashing stopped. So I flew the hell out of it at max speed for a good 15 minutes straight, then I banged the flyer off the terrain and trees and other shapes at full speed for a while and still no crash. After doing a few more experiments I found that my speed was directly affected with the integration factor, the faster I go, the more time I need. Ultimately I set my integration at 6 even though 5 seemed to do just fine. I figure that way I'll never have this problem again, and I can't tell any difference in 5 and 6 while playing.

Integration of 5 is sufficient to handle my maxSpeed of 500 and maxForwardSpeed of 250 in case anyone is interested in a "speed to integration" comparison. This equates to 50 to 1 on your maxForwardSpeed and 100 to 1 on your maxSpeed.
#3
08/12/2004 (8:34 am)
Excellent research, Gonzo. This is on my "to patch" list.
#4
08/12/2004 (4:18 pm)
Thanks Ben. I have been doing a lot more experimentation and research of the settings involved with vehicles and flying vehicles and it pretty much all boils down to the "integration" factor. The weird part is that the debugging in VC++ was returning funky data and getting caught in previously stated infinite loop. I'm still not qualified to say exactly what is causing the conflict but my best guess is that the engine is not finished processing the first set of physics data before it tries to do it again and it gets conflicted and stuck. As soon as the integration is high enough to allow the physics processing to finish before repeating it works perfectly as best I can tell. Since I posted my above fix I have not yet experienced a single crash. But I can faithfully reproduce the crash whenever I choose just by dropping the 'integration to anything below 5 at my current settings. If I slow my vehicle down (maxSpeed's settings) proportionately to the drop in my 'integration' then the crash is still prevented....

Example...

Dropping my integration from 5 to 4 requires at least a 20% drop in max speeds from (in my case) 250 to 200 or less to prevent the crash. Also, other than the crashing problem I really cannot tell any difference in flying or handling the vehicle based on integration settings. I guess I could do some experiements in setting the integration realy high to see what effect it might have on the vehicle and report back on what I find just for curiosity sake.
#5
08/13/2004 (3:05 am)
With these observations in place maybe one could code an optimization for the integration rate based on the datablocks speed setting(s). This might avoid such issues in the future.
#6
08/13/2004 (8:54 am)
I believe there was a forum thread or resource describing how to do that.
#7
09/23/2004 (8:48 pm)
Another note... I don't know if this is related at all to Gonzo's problems, but in my space game, my modified FlyingVehicles had a nasty habit of causing infinite loops when they rammed DIF objects. All of my objects have very low integration levels. (Because I need lots of vehicles moving around. I don't care too much about how realistic their physics look, as this is mostly a free-flying space game.)

Anyway, from what I can tell, when an object strikes a DIF object with suffient velocity, it will get stuck in an endless loop inside of Vehicle::resolveCollision(). I haven't checked this out in detail, but my guess is the resolveCollisions isn't properly "ejecting" the collided object from what it hit, so therefore thge bool colliding never goes false.

Well, a super-quick dirty fix is to just add a timeout value. For example, change the while loop to read:

coltimeout++;
} while (colliding && coltimeout < COLTIMEOUT);
My COLTIMEOUT is set to 50 iterations.

It's not pretty, but at least it stops the lockups. Unfortunately, because you are overriding Torque's rigid/collision behavior, objects will sometimes "squeeze" through other objects. But it works good enough for now.

I haven't tested this with flying vehicles ramming terrain, but I presume it will help there, too.

I presume Gonzo is seeing an actual crash, which I haven't seen so far. Just the lockups, where Torque stops responding and I have to three-finger salute it...
#8
09/24/2004 (7:40 pm)
Quote:I presume Gonzo is seeing an actual crash, which I haven't seen so far. Just the lockups, where Torque stops responding and I have to three-finger salute it...



I presume you didn't read what I said which was...

Quote:
getting caught in the infinite loop lockup).
#9
10/05/2004 (1:26 pm)
I've had problems with this as well recently. Setting the integration to 5 doesn't solve anything.
It doesn't behave this way in Tribes II though, which makes me very curious to what they did to not make it happen.
#10
10/05/2004 (1:43 pm)
collisionTol = 0.2;        // Collision distance tolerance
    contactTol = 0.1;

These two do not even exist in Tribes..
#11
10/05/2004 (1:59 pm)
Stefan, integration of 5 is a minimum in my book. And what setting you need is directly related to your speed. If you are traveling really fast, try setting to 7 or 8 and see what happens.
#12
10/05/2004 (2:02 pm)
I even tried with speed of 400, and Integration of 10.
It crashes less, but I just have to bump into one of the interiors and there we go again. :(

I'll try with 50 integration ticks per second.

Edit: Crashed. 400 speed. 50 integration.
#13
10/05/2004 (2:18 pm)
Can you post your datablock? You may have another setting out of spec.

EDIT: You can e-mail me if you want confidential.
#14
10/05/2004 (2:20 pm)
I have tried to email you before but I think it went the wrong address. I'll try again, thanks.

Tried changing:
integration = 50;
collisionTol = 0.6;
contactTol = 0.1;
bodyFriction =0;
bodyRestitution = 0.1;

Now it doesn't crash in the interior anymore. But the game moves down from 96 fps to 4 when colliding.
#15
10/14/2004 (3:37 am)
Quote:Now it doesn't crash in the interior anymore. But the game moves down from 96 fps to 4 when colliding.

I'm getting this exact behaviour when my flying vehicles collide with objects.

Has anyone made any progress on this issue?
#16
10/14/2004 (4:03 am)
Nah. It's a problem with the vehicle code, if you do try and collide as much as you can with a object, you will suffer frame rate loss because of the high integration.

Hopefully sometime someone or GG will rework the Collision code, but don't bet on it.
The odd thing is that it works in Tribes II which is the same engine, basically.
#17
01/12/2006 (1:45 pm)
Yeah I know its an old thread, I'm just trying to make sense of something odd here. I'm trying to make my code more efficient and decided to take a look at this integration issue. Note, I'm not saying it does not work as described above, I'm saying there is a better way.

updateforces() in wheeledvehicle is quite calculation intensive so I figured the less I can call it, the better, but if your vehicle is going at 200km/h then you are moving at 55m/s and you would penetrate an object by a few meters before the collision is noticed. Hence Gonzo's observations above.

But is it necessary to update the physics several times per frame ?

In vehicle.cc in method processTick()
S32 count = mDataBlock->integration;
      updateWorkingCollisionSet(getCollisionMask());
	       for (U32 i = 0; i < count; i++)
	          updatePos(TickSec / count);
That means that if you have integration set to 5 then updatePos will get called 5 times in a loop without any of those interim calculation results ever being drawn on the screen. It's extemely inefficient.

It should only be done once per frame because you can't see whats not drawn on the screen...

Surely its possible to check on a frame by frame basis whether or not a collision would have occured in-between frames and apply forces from the point of impact/time of impact to calculate where the objects would be at the current frame time and then render them as such.

I believe the integration approach was a hack, a rather expensive hack as well, which attempts to look for collisions on a moment by moment basis, rather than a frame by frame basis.

Games like joint-ops achieve 64 players and about 20 vehicles on similar hardware where TGE only manages to handle 8 vehicles. Fixing the above will make us more competitive.