A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by fractile » Tue Mar 01, 2011 12:44 pm
How can I determine the force that a body causes on another body while the bodies are continuously in contact (e.g. stacked on top of each other)?
What I'm eventually trying to do is to calculate the damage caused to player when it is crushed against floor by an elevator (player stuck under the elevator). Both are simple bodies with compound collision. I would like to determine the magnitude of force that the elevator applies to the player and use that to decrease player health over time.
I'm also open to suggestions if there's easier or better way to do that..
-
fractile
-
- Posts: 37
- Joined: Wed Jun 07, 2006 2:26 pm
by Julio Jerez » Tue Mar 01, 2011 3:26 pm
after the update you can call an function like this
- Code: Select all
dVector ForceBeteenBody (NewtonBody* const body0, NewtonBody* const body1)
{
dVector forceAcc (0.0f, 0.0f, 0.0f, 0.0f);
for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(body0); joint; joint = NewtonBodyGetNextContactJoint(body0, joint)) {
if ((NewtonJointGetBody0(joint) == body0) || (NewtonJointGetBody0(joint) == body1)) {
for (void* contact = NewtonContactJointGetFirstContact (joint); contact; contact = NewtonContactJointGetNextContact (joint, contact)) {
dVector point;
dVector normal;
float forceMag;
NewtonMaterial* const material = NewtonContactGetMaterial (contact);
NewtonMaterialGetContactPositionAndNormal (material, &point.m_x, &normal.m_x);
NewtonMaterialGetContactForce(material, &forceMag);
forceAcc += normal.Scale (forceMag);
}
break;
}
}
return forceAcc;
}
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by fractile » Wed Mar 02, 2011 8:27 am
Copy pasting your code as it is caused a crash, since NewtonMaterialGetContactForce() expects a pointer to vector. After fixing that it works. Exactly what I needed, thanks a lot!
-
fractile
-
- Posts: 37
- Joined: Wed Jun 07, 2006 2:26 pm
by Julio Jerez » Wed Mar 02, 2011 9:43 am
Ha ok, I did not test it I just copied in the debug.cpp in the demos, and compiled it.
Good you have what you wanted.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by fractile » Wed Mar 09, 2011 7:02 am
I simplified the code a bit since I don't really care which body is crushing the player, only the magnitude of force matters:
- Code: Select all
m_SensorArray[i] = 0.0f;
for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(m_NewtonBody); joint;
joint = NewtonBodyGetNextContactJoint(m_NewtonBody, joint))
{
for (void* contact = NewtonContactJointGetFirstContact(joint); contact;
contact = NewtonContactJointGetNextContact(joint, contact))
{
Ogre::Vector3 force;
NewtonMaterial* material = NewtonContactGetMaterial(contact);
NewtonMaterialGetContactForce(material, force.ptr());
m_SensorArray[i] += force.length();
}
}
It does work well with elevators, but I am having a problem with sliding doors (For example the door on the right side in image posted here:
http://newtondynamics.com/forum/viewtopic.php?f=9&t=6498). The door is a body with box collision that is connected to static level body with slider joint. When the player walks against the door, NewtonMaterialGetContactForce() sometimes temporarily returns very large force for contact between the door and player bodies. Most of the times when player is walking against the door, the contact force stays reasonable (in relation to force used to move the player).
My best guess is that this is somehow caused by slider joint correcting door position after player has pushed it "out of place". Is that right? Is there a way to detect and ignore this situation?
I could add a time delay so that force would have to stay above damage limit for certain amount of time before applying "crushing damage" to player, but that does not sound very elegant solution..
-
fractile
-
- Posts: 37
- Joined: Wed Jun 07, 2006 2:26 pm
by Julio Jerez » Wed Mar 09, 2011 8:34 am
when you get teh very big force is whne teh solver calculate and impulse.
basically there are tow kind of forces, teh permance restiing forces, and impulse that at for one frame.
the resting force are generated by a the prinsiple of actopn reaction, liek a body restion on another.
Impules are generated by the change of velocity of contac point on the body.
I beleive you can detect when a force calculated by teh solve is an impulse by measuring the contact velocity in a contact collback.
basically you will have to set a contact callback and track when the two bodies collide, then signal that in that frame force will be dominated by and impulsive reaction.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by fractile » Wed Mar 09, 2011 9:51 am
I understood from the wiki page for NewtonMaterialGetContactForce() that it would return zero force vector in case of impulse contacts (non-zero relative velocity), so I assumed that I could safely just sum all the contact forces. I did sound too simple to be true

I will try your suggestion.
-
fractile
-
- Posts: 37
- Joined: Wed Jun 07, 2006 2:26 pm
by Julio Jerez » Wed Mar 09, 2011 11:46 am
Not do no asume that, force are vector, and adding the will lead to wrong answer.
just read the normal speed of the contact point and if it is smaller than some small value then you can asume that contact is in resting mode.
I look complex becaus eit is no trivial contact happen before teh solver, so you do no knwo i fthe force need it to stoppit form penetration.
you can mesaure the contact speed.
when a i movong teh solve need to calculate a huge force to stopped for penetration, that is why you reall all force as just resting forces than are changing wildly
but whit the information from the material collision you can discard what forces are impulsive and what are resting forces.
notice that in the same frame a joint can have two different kind contact at the same time.
this will be the case of a Box falling on a floor edge on, and hinging of one edge untill the face hit the ground.
at the moment the contacts on teh face will be impulsive while the contacts on the edge are resting.
My guess si that you can just descar the joint altogether is at least one contact is impulse.
So basilly in the Material you set a flag that tell your force code if it should prossess the body for damage on that frame.
and the you rest it.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 0 guests