Calculating damage from physics collision

Hi all,

im trying to calculate damage done to object when physics collision occurs


    /**
     * Physics collision occurs.
     * @param event
     */
    public void collision(PhysicsCollisionEvent event) {
        if(isEnabled() && event.getObjectA() instanceof PhysicsRigidBody && event.getObjectB() instanceof PhysicsRigidBody) {
            //System.out.println("collision started");
            if(null != event.getNodeA() && null != event.getNodeA().getControl(DamageControl.class)) {
                doDamage(event.getNodeA(), calculateKineticEnergy((PhysicsRigidBody)event.getObjectA(), (PhysicsRigidBody)event.getObjectB()));
            }
            if(null != event.getNodeB() && null != event.getNodeB().getControl(DamageControl.class)) {
                doDamage(event.getNodeB(), calculateKineticEnergy((PhysicsRigidBody)event.getObjectB(), (PhysicsRigidBody)event.getObjectA()));
            }
            //System.out.println("collision ended");
        }
    }

    private void doDamage(Spatial node, final float kineticEnergy) {
        if(kineticEnergy > 20.1f) {
            final DamageControl damageControl = node.getControl(DamageControl.class);
            //System.out.println("damaging " + node.getUserData("entityName") + " for " + kineticEnergy + " damage");
            app.enqueue(new Callable<Void>() {
                public Void call() throws Exception {
                    damageControl.doDamage(kineticEnergy);
                    return null;
                }
            });
        }
    }

    private float calculateKineticEnergy(PhysicsRigidBody rigidBodyA, PhysicsRigidBody rigidBodyB) {

        //the kinetic energy of a non-rotating object
        //of mass m traveling at a speed v is 1/2mv^2

        Vector3f relativeVelocity = rigidBodyA.getLinearVelocity().subtract(rigidBodyB.getLinearVelocity());
        float relativeVelocityLength = relativeVelocity.length();

        float impulse = FasterMath.fixedTpf * 0.5f * rigidBodyA.getMass() * (relativeVelocityLength * relativeVelocityLength);

        return impulse * FasterMath.nextRandomFloat(0.95f, 1.05f);
    }

computed damage is good enough

but what driving me mad is continuous collision. how can i say:

  1. hey this is first hit, give some damage to object
  2. hey this is continuous collision, lets do nothing
  3. where is tpf
    ?

PhysicsCollisionListener is very unintuitive, now when collision occurs, it regularily gives damage per tick until objects are touching, even no tpf, and this is bad :frowning:

while trying to find something, i found this http://stackoverflow.com/questions/20185293/collision-with-enemy-to-inflict-damage
it is from unity, and they have OnCollisionEnter

or should i do something like bombcontrol? while collision occurs, create ghost object that bump objects away and then give them damage? isnt it weird?

check the time between collisions

i dont know if next collision is between two same bodies so i cannot check time between collisions and even dont want to, because first hit should be also last in “continuous collision”

How do you not know? you get both bodys on the collision listener.
Just cache them for a small time somewhere and ignore multiple collisions that way.

What empire says… If you stop getting a collision in a physics tick thats when the collision stops… Don’t know whats so problematic about that? Just track when the collision occurs first, then each physics tick check if it still exists, if theres a frame without that collision you can reset and wait for the next.

@Empire Phoenix said: How do you not know? you get both bodys on the collision listener. Just cache them for a small time somewhere and ignore multiple collisions that way.

i thought if there is another way than cache it :slight_smile: oki then, i can create class to handle it this way :slight_smile:

edit:
from PhysicsSpace source:


        //step simulation
        getDynamicsWorld().stepSimulation(time, maxSteps, accuracy);

        //distribute events
        distributeEvents();

i think, order of things in one step is this:

  1. prePhysicsTick
  2. physicsTick
  3. collisions queue

@EmpirePhoenix another problem… :confused:

in perpendicular collision:

  1. physics update stops my ship
  2. collision listener detects collision while ship is almost stopped from physics update, so i cannot compute appropriate damage from relative velocity between two bodies… so i must somehow save body’s velocity before tick occurs and also before collision occurs

i think collisions should occur after pre physics tick and before actual physics tick changes transform of rigidbody

is there any chance to calculate the angle of incidence between two rigid bodies on collision?