A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

I use a particularly.. maybe strange set-up in my game for towing vehicles and trailers, the vehicle shape is made up of 2 pieces into a compound shape.

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.
Help improving the Newton Game Dynamics WIKI

JernejL

Posts: 1441
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Hi JernejL,
I'm not 100% sure but I think the inline; can cause problem in multithreads callback.
The variable ThisContact is not local to the function and in this case you can get race data problem.
If the ThisContact is local in the callback function just forget what I have say.
Do you have test if the same problem happen with only one thread ?
Last edited by Dave Gravel on Mon May 27, 2019 12:48 pm, edited 1 time in total.
You search a nice physics solution, if you can read this message you're at the good place
OrionX3D Projects & Demos:

Dave Gravel

Posts: 690
Joined: Sat Apr 01, 2006 9:31 pm

basically this is a contact filter you are talking about.
do not panic, I am sure this can be resolved. all the changes in the engine are to make it better.
is the truck cab and the trailer connected by a Joints?
I will upload a test demo of the engine if you need a demonstratable example.

yes please if you can provide a test.
Julio Jerez
Moderator

Posts: 10954
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Oh I see,
You are attaching the cab to the trailer, the at some point to destroy the joint, and at that moment the two bodies are in deep penetration and they get pushed away from each other.
And this was working in the pass, but not is falling.
Do I get it right?

If so, please make the reproduce test, it should be easy to fix.
Julio Jerez
Moderator

Posts: 10954
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Dave Gravel: all functions in freepascal have their own thread variables by default, only global variables have to be explicitedly specified as per-thread by using threadvar section, so the variables and inlined function are not problematic here, the inlined function also uses parent function's variables so it is thread-safe.

The trailer is only attached with joint once the trailer has enough "attachment threshhold" once you position the car properly, it doesn't have much effect in regards to this, because it happens regardless of what i do with the joint.

I made another video how this worked with older newton 3.14 - notice it works quite well, bodies respond properly regardless of the ignored collisions:

I made you a demo that will have everything ready to reproduce this easily.

Player spawns on the truck, so you can just hit enter and go reverse to collide with trailer:

Controls: W,A,S,D, ENTER = enter truck as driver
I also disabled trailer attachment joint as it is not totally relevant for this test, it's easier to see what isgoing on without it, debug rendering is also enabled.

https://we.tl/t-F04md3GC0s

The archive has older newton by default that works properly.

there are also specific dlls for you to test:
newton OLD.dll (backup of old dll)
newton NEW.dll (latest newton 32 bit release build that you can rename and see the difference).

You can just replace the dll with your own for testing.
Help improving the Newton Game Dynamics WIKI

JernejL

Posts: 1441
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

ye I see the problem this is do to the new contact filter I added to remove as many contact as possible.
but some how it failing with compound.

here is a hack you can add temporality until I figure out the solution.
go in file D:\newton-dynamics_debug_users\sdk\dgPhysics\dgWorld.h line 43 and uncomment that line
this will use the old contact where all contacts are passes to the callback.

I am debugging. but I need to do some setting to capture the pair that case the problem, I knwo si body 202 and 203 but is not enough, I will continue tonight.
meantime try the hack I think is solve that problem, but that is no a solution becaus the new contact filter is far better I just need to find out how to make work better with compounds
Julio Jerez
Moderator

Posts: 10954
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Code: Select all
`Dave Gravel: all functions in freepascal have their own thread variables by default`

Yes it is why I have say if the var is local to the function forget what I say, The code that you posted don't show the vars.
Here I try to avoid threadvar the most possible, In many tests I have seen it is 3 or 4 times slower and more with loop situation.

Have a good day.
Last edited by Dave Gravel on Tue May 28, 2019 11:25 am, edited 1 time in total.
You search a nice physics solution, if you can read this message you're at the good place
OrionX3D Projects & Demos:

Dave Gravel

Posts: 690
Joined: Sat Apr 01, 2006 9:31 pm

ok If you sync it should be working now.
It termed out I have a bug on teh 3d contact pruner, but that's fine we can call the old method there until I find the bug.
Julio Jerez
Moderator

Posts: 10954
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Julio Jerez wrote:ye I see the problem this is do to the new contact filter I added to remove as many contact as possible.
but some how it failing with compound.

here is a hack you can add temporality until I figure out the solution.
go in file D:\newton-dynamics_debug_users\sdk\dgPhysics\dgWorld.h line 43 and uncomment that line
this will use the old contact where all contacts are passes to the callback.

I am debugging. but I need to do some setting to capture the pair that case the problem, I knwo si body 202 and 203 but is not enough, I will continue tonight.
meantime try the hack I think is solve that problem, but that is no a solution becaus the new contact filter is far better I just need to find out how to make work better with compounds

This is excellent, i uncommented out the define and engine behaves properly with compounds now, i hope the example i made gives you a good testing platform for testing the bug and getting the new contact filter to work!

Dave Gravel wrote:
Code: Select all
`Dave Gravel: all functions in freepascal have their own thread variables by default`

Yes it is why I have say if the var is local to the function forget what I say, The code that you posted don't show the vars.
Here I try to avoid threadvar the most possible, In many tests I have seen it is 3 or 4 times slower and more with loop situation.

Have a good day.

Threadvar is only needed for globals, i avoid that too, but each function with local variables has them thread-safe as iirc the parameters are in registers and stack anyways, and each thread has its own stack, so it is safe to use local variables there, multithreading does not make a problem for callbacks.
Help improving the Newton Game Dynamics WIKI

JernejL

Posts: 1441
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

JernejL can you sync again, I narrow the boy to one function, you can always set the define if it does no work, but the new filter is far better than the old method I just need to fox the bug.

also after we get this bug fix I think you are doin this game play functionality in no the most efferent way, I will tell you how to do it better without having to generate all the unnecessary contact and them delete them.

But for now I will use this test to implement function dgInt32 dgWorld::Prune3dContacts(....) const
properly. because this is where the bug really is.
Julio Jerez
Moderator

Posts: 10954
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

I can just wait for the bugfix, i can use the workaround in the meantime, no problem for me.

I use the compounds and discard contacts so that the bodies of trailer and truck can collide fully with anything else, but not the "attachment" part between bodies. I used this, because materials are assigned to bodies and not collisions i cannot use NewtonMaterialSetDefaultCollidable.

Maybe if i could set specific FaceID pair to not collide, i could use that, i was not sure if there was a better way, but i admit my game is kinda uniquely weird, and i use the physics engine in a rather special way

Btw, faceid on trimeshes in newest build works excellently even with optimizations!!
I'm starting to rely on it more and more, and it's looking really well, however i found another bug, when NewtonCollisionForEachPolygonDo is used on a trimesh, faceId is not correctly passed to the callback, making rendering of FaceID impossible - the rest works great!
Help improving the Newton Game Dynamics WIKI

JernejL

Posts: 1441
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

A few posts were lost because forum was transferred to another hosting.

Maybe the crash is only in release mode? i don't use debug mode (because of asserts) but release mode.

Maybe i did change something that causes new crash, here is a new reproduceable demo: https://we.tl/t-vYMkoBCQNe

I just run the exe, attach visual studio 2013 debugger and then click start in game to load it. it crashes within a few seconds.
Help improving the Newton Game Dynamics WIKI

JernejL

Posts: 1441
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

ok I am doing the exact same process, to see if I catch first.

there is a bottom on the right left corner "start server" do I need to click that?
Julio Jerez
Moderator

Posts: 10954
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

I has been running for about a hour and I do no see the bug happening.

I will add a logging code that when the bug happen it print the polygon that cased the bad result.
the when it happen on your side, you just list that file here so that I can debug it.
Julio Jerez
Moderator

Posts: 10954
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

I made a video, i'm not sure what is happening why you don't get a crash.

I use visual studio 2013, could that make a difference?

Help improving the Newton Game Dynamics WIKI

JernejL

Posts: 1441
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Next