Damage calculation

Topics: User Forum
Developer
Jan 25, 2008 at 10:10 AM
Hi !

When two geoms collide an event is fired and ends up in a function like this: bool OnCollide(Geom geom1, Geom geom2, ContactList contactList).

Now I want to calculate the amount of force that was produced in this collision and spread it to the vehicles as damage.

Ok. Let's see :) ...

        private bool OnCollide(Geom geom1, Geom geom2, ContactList contactList)
        {
            Vector2 impactOnThisFrame = Vector2.Zero;
            Vector2 interpolatedContactPosition = Vector2.Zero;
            Vector2 velocity1 = Vector2.Zero;
            Vector2 velocity2 = Vector2.Zero;
 
            //Get interpolated contact position
            for (int i = 0; i < contactList.Count; i++)
            {
                interpolatedContactPosition += contactList[i].Position;
            }
 
            interpolatedContactPosition /= contactList.Count;
 
            //Calculate impact
            geom1.Body.GetVelocityAtWorldPoint(ref interpolatedContactPosition, out velocity1);
            geom2.Body.GetVelocityAtWorldPoint(ref interpolatedContactPosition, out velocity2);
 
            if (geom1.Tag == this)
            {
                impactOnThisFrame = (velocity1 - velocity2) * geom2.Body.Mass;
            }
            else
            {
                impactOnThisFrame = (velocity1 - velocity2) * geom1.Body.Mass;
            }
 
            //Lose energy
            Energy -= impactOnThisFrame.Length();
            
            //Debug
            Console.WriteLine("Energy: " + Energy.ToString());
            Console.WriteLine("Impact: " + impactOnThisFrame.Length().ToString());
 
            return true;
        }

Is this correct?

I add the velocities (by subtracting them ;D) and multiply this with the mass of the other body, get the length and this is my force.

Well, I think it is :). ... and that's why I'm posting this here.
Doesn't the other mass matter? I'm not sure ...
Jan 26, 2008 at 5:36 AM
OnCollide is called before any collision response takes place (which is why it returns a bool). So by my way of thinking, the fact that you are subtracting the velocity of one object from the other looks supicious. If the two bodies, for example, were traveling toward each other, then that value could be zero... which isn't right. I think your f=ma needs to be stict with a single object...

So this might not be correct and a little hackish, but why not let collision response take place, but when it does, have your OnCollision function flag your game that a collision has taken place between the two objects. Then, on the update, (before you apply any forces due to user input or whatever) you can look at the sudden change in velocity as an indicator of the magnitude of damage you should apply. If an object suddenly changed direction and speed greatly... probably deserves a lot of damage. If it didn't change at all or very little... probably not taking much damage.

Coordinator
Jan 26, 2008 at 11:57 AM
You can also look at the actual contacts in the contact list and use the "Seperation" property as a measure of collison. The more negative it is the more the two objects are penetrating eachother which implies they collided harder.

-Jeff
Developer
Jan 26, 2008 at 6:01 PM
Edited Jan 26, 2008 at 6:04 PM
sonofdaedalus wrote:
the fact that you are subtracting the velocity of one object from the other looks supicious. If the two bodies, for example, were traveling toward each other, then that value could be zero... which isn't right.

I knew someone would say that ;). Look ...

Velocity1 = { x = -3, y = 3}
Velocity2 = { x = 1, y = -1} 

They have velocities going toward each other. Let's try subtracting ...

-3 - 1 = -4
3 - -1 = 4

Ok, now we'll let them move in the same direction ...

Velocity1 = { x = 3, y = -3}
Velocity2 = { x = 1, y = -1}
 
3 - 1 = 2
-3 - - 1 = 2

In the end I need only the length, so I don't care about positive or negative numbers... And as you can see, going toward each other adds velocities :).

sonofdaedalus wrote:
I think your f=ma needs to be stict with a single object...


Why? Doesn't it matter if I crash into a standing bus or a driving bus?


So this might not be correct and a little hackish, but why not let collision response take place, but when it does, have your OnCollision function flag your game that a collision has taken place between the two objects. Then, on the update, (before you apply any forces due to user input or whatever) you can look at the sudden change in velocity as an indicator of the magnitude of damage you should apply. If an object suddenly changed direction and speed greatly... probably deserves a lot of damage. If it didn't change at all or very little... probably not taking much damage.


Yes. But am I not calculating the impact on the current vehicle with my function? I have the effective velocity and the mass of the object that hits me.

Uhm, but the CollisionHandler doesn't fire on collision, it does before? Oh ... ... ... that's why energy goes down even if they barely touch each other moving at the same speed =D ...
Developer
Jan 26, 2008 at 6:01 PM
Edited Jan 26, 2008 at 7:31 PM

crashlander wrote:
You can also look at the actual contacts in the contact list and use the "Seperation" property as a measure of collison. The more negative it is the more the two objects are penetrating eachother which implies they collided harder.

-Jeff


Ok that tells me how heavy the collision is, but what tells me the amount of damage they take each? Split the damage by mass ratio? ... And to which of the two geometries does the contactList belong? It belongs to both I guess ... ?

So generating an average "Separation" and multiplying it with the mass of the other object ... ... uhm ... ?

sonofdaedalus wrote:
OnCollide is called before any collision response takes place (which is why it returns a bool).

Alright. I will calculate the average "Separation" and if this has a negative value I'll run my old code to generate the amount of force. So I know they actually are colliding.

edit:
I'll just search for a negative separation :). Don't need the average one ...