The 2 specific parts of sub-collisions are then made to never collide with each other, while the center of collision and all is same as it would be for normal vehicles (in the center of the vehicle itself)
To prevent the rear end of truck, and the front end of trailer from colliding, newton contact callback is used, in that part NewtonContactJointRemoveContact is used to remove all contacts where those 2 specific shapes are found in pairs, this enables the rears of 2 trucks to collide, but never a truck rear end and front of trailer.. this enables game mechanism to attach trailer to the truck to work.
However the last newton this worked well was from around 2017 or 2018, when i updated to new build, the behavior changed, and now cars get slammed with a lot of force.
This is how the contact callback looks like, in pascal:
- Code: Select all
function CarHitCar(const contact: PNewtonJoint; timestep: float; threadindex: integer): longint; cdecl;
procedure gotonext; inline;
begin
ThisContact := NextContact;
end;
b1 := NewtonJointGetBody0(contact);
b2 := NewtonJointGetBody1(contact);
ContactCar0 := NewtonBodyGetUserData(b1);
ContactCar1 := NewtonBodyGetUserData(b2);
Result := 1;
TotalDamage := 0;
ThisContact := NewtonContactJointGetFirstContact(contact);
veh_c := ((ContactCar0.DeltaData.has_truck_connector = true) or (ContactCar1.DeltaData.has_truck_connector = true)); // is a truck cab involved in the collision?
veh_j := ((ContactCar0.DeltaData.has_trailer_joint = true) or (ContactCar1.DeltaData.has_trailer_joint = true)); // is a trailer involved in the collision?
while ThisContact <> nil do begin
NextContact := NewtonContactJointGetNextContact(contact, ThisContact);
material := NewtonContactGetMaterial(ThisContact);
c1 := ptruint(NewtonCollisionGetUserData(NewtonMaterialGetBodyCollidingShape(material, b1)));
c2 := ptruint(NewtonCollisionGetUserData(NewtonMaterialGetBodyCollidingShape(material, b2)));
// if one of vehicles is a truck cab AND other is a trailer
if (veh_c = true) and (veh_j = true) then
if (c1 <> c2) and ((c1 <> SHAPEID_TRUCKCAB) and (c2 <> SHAPEID_TRUCKCAB)) then
begin // and one of materials is different than other, and it's not the special truck cab mat (2) then don't collide.
NewtonContactJointRemoveContact(contact, ThisContact);
gotonext();
continue;
end;
NewtonMaterialGetContactPositionAndNormal(material, nil, @pos, @nor);
ImpactForce := NewtonMaterialGetContactNormalSpeed(material);
TotalDamage := TotalDamage + fabs(ImpactForce);
if (ImpactForce > 0.3) then
TParticleInstance.pSpawnEffect(pos, damagetype_vehiclecollision); // spawn special effects
gotonext();
end; // while
Here is a video of the excess forces that happen when the truck cab touches trailer on that piece, in older version of newton this worked properly (just gentle collision responses)
I will upload a test demo of the engine if you need a demonstratable example.