Difference between collision callback from newton 1.53

From Newton Wiki
Jump to: navigation, search

Description

The NewtonMaterialSetCollisionCallback callbacks have changed slightly in functionality with newer newton:

NewtonContactBegin has been renamed to NewtonOnAABBOverlap, the functionality is identical.

NewtonContactsProcess is now called only once per pair of bodies in a contact, to get actual contacts you must now use a iterator, see below for example.

NewtonContactEnd has been removed as it became redundant. if you used this, you only have to move the code to the end of NewtonContactsProcess callback routine.

Porting old code

A usual approach in newton 1.53 was, to store the two bodies that were being processed in NewtonContactBegin and then for each contact get a call to NewtonContactsProcess. But in latest newton, there are new functions such as NewtonJointGetBody0 and NewtonJointGetBody1 for this purpose, which you use inside the new NewtonContactsProcess callback, If you cached the newton body pointers from NewtonContactBegin callback you should no longer rely on that and use NewtonJointGetBody0 and NewtonJointGetBody1, as these two callbacks may now be called in a different order for many bodies!

NewtonContactsProcess

Newton library now calls NewtonContactsProcess just once for ALL contacts, in parameter it passes you a "contact joint" handle. To get the actual contacts you have to use NewtonContactJointGetFirstContact and NewtonContactJointGetNextContact, this enables you to write contact processing in a much more efficient way.

Example of a new NewtonContactsProcess callback

This is a simple callback for two "cars", which when hit spawn some spark effects and apply some damage.

function NewtonContactsProcessTest(const contact: PNewtonJoint; timestep: float; threadindex: integer): longint; cdecl;
var
  pos, nor:    vector;
  ImpactForce: single;
  TotalDamage: single;
  ContactCar0, ContactCar1: Tcar;
  material:    Pnewtonmaterial;
  ThisContact: PNewtonJoint;
begin

  ContactCar0 := NewtonBodyGetUserData(NewtonJointGetBody0(contact));
  ContactCar1 := NewtonBodyGetUserData(NewtonJointGetBody1(contact));

  Result      := 1;
  TotalDamage := 0;

  ThisContact := NewtonContactJointGetFirstContact(contact);

  while ThisContact <> nil do
  begin
    material := NewtonContactGetMaterial(ThisContact);

    NewtonMaterialGetContactPositionAndNormal(material, @pos, @nor);

    ImpactForce := NewtonMaterialGetContactNormalSpeed(material);
    TotalDamage := TotalDamage + ImpactForce;

    if (ImpactForce > 0.3) then
      spawnsomesparks(pos);

    if ImpactForce > 3 then begin
        ContactCar0.damage(ImpactForce);
        ContactCar1.damage(ImpactForce);
    end;

    ThisContact := NewtonContactJointGetNextContact(contact, ThisContact);
  end;