scriptThis()); "> Fix for Vehicle vs. Static Shape collision crash problem | Torque Game Engine | Forums | Community | GarageGames.com

Game Development Community

Fix for Vehicle vs. Static Shape collision crash problem

by Ken Finney · in Torque Game Engine · 04/12/2002 (10:50 pm) · 12 replies

It's Quick, it's dirty, but it works.

In ShapeBase.cc, around line 2846 is this function:

void ShapeBase::onCollision(ShapeBase* object)
{
   if (!isGhost())
      Con::executef(mDataBlock,3,"onCollision",scriptThis(),object->scriptThis());

}

The game crashes in the getID() call inside the object->scriptThis() method.

When we arrive here, object is NULL, hence the crash in getID().

My quick fix that gets me going again is to simply check for NULL and exiting if it visits us.

void ShapeBase::onCollision(ShapeBase* object)
{
  [b]if ( object == NULL ) return;[/b]

   if (!isGhost())
      Con::executef(mDataBlock,3,"onCollision",scriptThis(),object->scriptThis());
   
}

I don't know why we are being visited by NULL, obviously the proper fix is somewhere upstream of here. Something was queued that shouldn't have been, or wasn't properly queued.

However the Quick n' Dirty fix above will get you romping through the corn fields in your monster truck again ...

#1
04/13/2002 (3:38 am)
I think I located where the bug comes from a few weeks back, but I Forget who I was working on with it. Might have been Ed Gardener, I can't remember!

But yeah, this should fix that annoying as heck bug... of course, you won't collide with the object now.

Hmm, I'll have to look at it. All I can remember was that the function being called called a function that needed the object that was hit, and it wasn't being provided that object (I didn't bother trying to figure out what object was hit by messing with the collision matrix)

I'll try to take a look at the code tomarrow, of course I'm sure someone else can do better than that :p
#2
04/13/2002 (10:48 am)
It's in another thread a thread called "collision bug" in the "SDK Bugs" forum.
#3
04/13/2002 (11:16 am)
The solutions in that thread appear to be exclusively related to problems with colliding with dead players...

Ken, it would be very interesting to see what the call stack is when object is NULL in that function.
#4
04/13/2002 (12:52 pm)
Here it is:


ShapeBase::onCollision(ShapeBase * 0x00000000) line 2856
Vehicle::damageQueuedObjects(const float 4.80498) line 1187 + 26 bytes
Vehicle::advanceToCollision(float 0.0320000) line 987
Vehicle::updatePos(float 0.0320000) line 832 + 12 bytes
Vehicle::processTick(const Move * 0x00edf710) line 630
WheeledVehicle::processTick(const Move * 0x00edf710) line 610
Player::processTick(const Move * 0x01fa65cc) line 1068 + 85 bytes
ProcessList::advanceObjects() line 249 + 67 bytes
ProcessList::advanceServerTime(unsigned int 76) line 87 + 8 bytes
serverProcess(unsigned int 76) line 603
DemoGame::processTimeEvent(TimeEvent * 0x00edfcd4) line 675 + 9 bytes
GameInterface::processEvent(Event * 0x00edfcd4) line 72 + 17 bytes
GameInterface::postEvent(Event & {...}) line 153 + 17 bytes
TimeManager::process() line 1179 + 22 bytes
DemoGame::main(int 1, const char * * 0x01720e80) line 503
#5
04/13/2002 (3:33 pm)
Yeah, but RIGHT above that line (or right below) is the damage queue related to items ;)

Commenting that out makes the item crash go away ;)

I dunno which is better.
#6
04/13/2002 (3:40 pm)
well, I need the item related damage...
#7
04/13/2002 (5:10 pm)
The odd thing here is that the object field of a CollisionTimeout is not one of those "safe pointers" that goes to NULL when its pointed-at object has been deleted; it must be explicitly set to NULL. So, the object pointer must have been NULL when it was originally placed on the list, or else this CollisionTimeout entry has already been used.

Right now I'd guess that the latter case is what's happening. If you look in ShapeBase::notifyCollision for another example of going through the CollisionTimeout list, you can see that the code carefully only checks for collisions that have the appropriate timestamp. Both ShapeBase::notifyCollision and Vehicle::damageQueuedObjects set the object field to 0 when the CollisionTimeout object is used, but the object remains on the list; it is not "garbage collected" until more collisions are added later.

Anyway, it might be good to insert into this Vehicle::damageQueuedObjects loop the same "if (ptr->expireTime == expireTime && ptr->object)" check as used by ShapeBase::notifyCollision, and see if the problem goes away... undoubtedly it will, since part of that check is looking to see if object is non-NULL, which is the same thing you were doing before in ShapeBase::onCollision, but perhaps it's more elegant to do the check up in this loop. :-)

I don't think you'll actually be "missing" any collisions, since my theory here is that those are old collision entries. But if you have a quick test case where you can replicate this problem, it would be good to journal it, then run it through the debugger a few times stepping through the relevant code to verify that theory.
#8
04/13/2002 (7:42 pm)
Very good, Joel. I've made that change you suggest, it's the sensible place to do it.

However, in testing I've discovered a rather unusual behaviour (it exists whether the collision is fixed my original way above, or using the timestamp check):

When I run a vehicle over an item, it can be a weapon, ammo or any other static shape, the vehicle motion bogs down, way down, the vehicle barely crawls. If I dismount from the vehicle, the vehicle vanishes and reappears back at the location of the item I collided with earlier...

Kinda spooky :-)
#9
04/13/2002 (8:03 pm)
Yikes.
#10
04/13/2002 (8:14 pm)
I'm beginning to think the above effect is a server synchronization issue, where the client thinks all is cool, but the server thinks the vehicle is still at the collision site.
#11
04/14/2002 (9:49 am)
Bah. After hours and hours of testing, I've figured it out. The collision mesh for the vehicle model (a land rover) extends below the plane of the model origin (0,0,0). I moved the bottom up to about one unit above the plane, and set the hub joints about 4 units above the plane, and everything is fine now. The specific details about why it behaves as described above when the mesh & joints are poorly situtated I leave to the more focused among us.

Anyway:

No more server crashes when hitting shapes (due to the bug fix above), and no more abuse of the space-time continuum ... :-)
#12
04/14/2002 (7:36 pm)
So THAT'S what causes that? Mesh below origin...

Crap, I KNEW it was mesh related...

That might explain some other stupid server crashes I am seeing.