Game Development Community

Vehicle Collision and Impulse

by Kevin Ostrowski · in Torque Game Engine · 03/06/2002 (1:27 am) · 13 replies

I'm trying to get my vehicle's to have some kickback and be bumped and moved around if you hit them hard enough. I did the Impulses and Explosions tutorial and it seemed easy enough to do something similar with vehicle's... but, I can't figure out how to get the id of whatever I'm colliding with, I tried it like this:

function TestCar::onImpact(%this, %obj, %collidedObject, %vec, %vecLen)
{
       %targetObject = %collidedObject;
       %position = %targetObject.getPosition();
       %impulse = %this.areaImpulse;
       %impulseVec = VectorSub(%targetObject.getWorldBoxCenter(), %position);
       %impulseVec = VectorNormalize(%impulseVec);
       %impulseVec = VectorScale(%impulseVec, %impulse );
       %impulseVec = VectorScale(%impulseVec, (640 / %targetObject.getDataBlock().mass));
       %targetObject.applyImpulse(%position, %impulseVec);
}

For some reason %collidedObject is always 0...
I found onImpact in shapeBase.cc but there are 2 almost identical bits of code:

void ShapeBase::onImpact(SceneObject* obj, VectorF vec)
{
   if (!isGhost()) {
      char buff1[256];
      char buff2[32];
      
      dSprintf(buff1,sizeof(buff1),"%f %f %f",vec.x, vec.y, vec.z);
      dSprintf(buff2,sizeof(buff2),"%f",vec.len());
      Con::executef(mDataBlock,5,"onImpact",scriptThis(), obj->getIdString(), buff1, buff2);
   }
}

void ShapeBase::onImpact(VectorF vec)
{
   if (!isGhost()) {
      char buff1[256];
      char buff2[32];
      
      dSprintf(buff1,sizeof(buff1),"%f %f %f",vec.x, vec.y, vec.z);
      dSprintf(buff2,sizeof(buff2),"%f",vec.len());
      Con::executef(mDataBlock,5,"onImpact",scriptThis(), "0", buff1, buff2);
   }
}

the second onImpact has a hardcoded 0 after scriptThis() and this is what is being sent back as %collidedObject. If I echo %collidedObject in the Armor::onImpact() in player.cs, it returns the object id that the player is colliding with. Why is the player using the first chunk and the vehicle's using the second? Or better yet, is there an easier way to figure out what I'm colliding with?

#1
03/06/2002 (3:20 pm)
anyone...??
#2
03/06/2002 (3:41 pm)
I'll take a look at this once im out of the office. Right now im typing between doing bits of work hehe.

Maybe 1hour until I get back to you.
#3
03/06/2002 (3:43 pm)
Thanks... Maybe you can save the few hairs I haven't pulled out :)
#4
03/21/2002 (11:09 am)
Anyone looked at this?
#5
03/21/2002 (11:24 am)
I gave up on it for the moment... It's a little out of my programming skill-set and I was hung up on it for about a week. So to save me from destroying my computer out of frustration I have moved on to other things, but I hope that someone will get to it eventually. To me it seems like a common feature for anybody using vehicles.
#6
01/24/2003 (6:03 am)
Anyone ever figured this one out, the collided object is always zero - no matter what. I would love to move other vehicles around if I ran into them with a vehicle.
#7
01/24/2003 (7:18 am)
I just had a quick look into the source code of the engine and this is what I found:

- the player (and thus the armor) class uses the first onImpact-method that sends the id of the impacted object to the script

- the vehicle class only uses the method that doesn't know about the id of the impacted object and thus sends 0 to the script

- in addition to "onImpact" there is another callback "onCollision" which seems to provide the information you need, however, there is only one variation of that method, so the id of the collision object should always be sent. I'm not quite sure what the exact difference in the function between "onImpact" and "onCollision" is.

Have you ever tried that onCollision-callback? I haven't tried it yet, since I'm quite busy with the so called "real life" right now, but I hope this helps anyway.

Stefan.
#8
01/25/2003 (9:43 am)
onCollision is called everytime you collide with something, I believe it's called on all shape base objects. onImpact is particular to the vehicles and is only called when you collide with an object and the change in velocity exceeds the min impact velocity datatblock value. Can't remember exactly why that was added.
#9
01/31/2003 (8:00 pm)
Thanks for giving this thread new life... I hadn't even attempted to look at this in a long time, but after seeing this I figured I'd give it another try.

So after about 5 min of digging up the old code I had and trying it in the onCollision it work the first try! I know at some point I was trying it on collision before because I pulled it out of an old commented onCollision function, but I must have messed something up back then...

If it doesn't quite seem to work like it should whereas things like to get stuck for a second before they fly back. Then make sure you have the latest head from a few days ago with the new vehicle collisions.

Here's the function I'm using:

function WheeledVehicleData::onCollision(%this,%obj,%col,%vec,%speed)
{
        %position = %col.getPosition();
        %impulse = %this.areaImpulse;
        %fwVec = %obj.getForwardVector();
        %impulseVec = VectorSub(%col.getWorldBoxCenter(), %position);
        %impulseVec = VectorNormalize(%impulseVec);
        %impulseVec = VectorScale(%impulseVec, %impulse *10); //* %fwVec
        %impulseVec = VectorScale(%impulseVec, (640 / %col.getDataBlock().mass));
        %col.applyImpulse(%position, %impulseVec);

}

And make sure and set areaImpulse somewhere in your vehicle's datablock
areaImpulse = 50;

That should do it.
#10
02/23/2003 (11:27 pm)
The normal Impluses and this, both crash my computer when it has to Impluses something sometimes (most of the time)

Anyone else getting this problem?
#11
04/30/2006 (1:22 pm)
I know this is an old thread, but I think the issue that Ed had was the vehicle colliding with itself somehow. Put this is the oncollision method to fix it:
function WheeledVehicleData::onCollision(%this,%obj,%col,%vec,%speed)
{
   if(%obj == %col)
      return;

The function definition is not new, but the 'if' statement is.
#12
04/23/2008 (5:25 am)
I found a way to make onImpact work where the collided object isn't returning "0"...

In the file vehicle.cc, inside of the function "void Vehicle::updatePos(F32 dt)", you will see a block of code like this:

// Server side impact script callback
      if (collided) {
         VectorF collVec = mRigid.linVelocity - origVelocity;
         F32 collSpeed = collVec.len();
         if (collSpeed > mDataBlock->minImpactSpeed)
			 onImpact(collVec);
      }

To make the collided object's ID come back (instead of "0"), simply change this:

onImpact(collVec);

into this:
onImpact(mCollisionList.collision[0].object, collVec);

This is working beautifully for me! :-) Hope this helps, even though this is a rather old post.
#13
04/23/2008 (7:53 am)
Thanks Jason!

Just what I needed.