ok it is what I suspected, the problem is that when you apply the extra pick force to a body, for some reason it is applied to more than one.
this only happens in multithreaded mode, If set to run in single thread or thread emulation and is does not happens.
In Newton the force and torque call back is called in multithreaded mode, so when you set four thread you will be getting 4 force and torque call back at once.
if you are saving the pick body, somehow the pointer is changed to a different body and more than selected body get the same force applied.
you need to take care of that cituation. I cannot imagine how it manage to select more than one body, but I have noticed some engines and some languages do not deal with multithread, I do not think that's the case with your engine, but the pick body is getting mess-up in multithread mode.
here is a trace of what is happing, I just picked the ball on the left side, which happen to be body 16,
I traced the frame number, the body unique id, and if the force applied when is different than gravity, and you can see that body 16 get the pick force, but then some time other body also get the same force.
Body: 56, 17, 42 and 30 and that is th host force.
frame: 1724
16 1.532926 -1.691885 -2.485924
two bodies get the same force
frame: 1726
16 1.125853 -1.444019 -1.822207
59 1.125853 -1.444019 -1.822207
frame: 1727
16 0.855418 -1.291135 -1.394094
frame: 1728
16 0.620337 -1.146585 -1.020576
frame: 1729
16 0.422908 -1.012628 -0.705406
frame: 1730
17 0.264193 -0.891600 -0.450515
16 0.264193 -0.891600 -0.450515
two bodies get the same force
frame: 1731
17 0.143967 -0.786397 -0.255883
16 0.143967 -0.786397 -0.255883
frame: 1783
16 -18.633497 6.495630 29.041204
two bodies get the same force
frame: 1784
50 -17.239986 5.604869 26.243061
16 -17.239986 5.604869 26.243061
frame: 1785
16 -15.342542 5.293510 23.082762
frame: 1786
16 -12.471945 4.694885 18.576246
frame: 1787
frame: 1788
frame: 1810
42 14.315579 -3.353570 -21.119461
16 14.315579 -3.353570 -21.119461
frame: 1811
16 8.745609 -2.611737 -12.691769
frame: 1812
frame: 1836
16 -5.621719 1.223242 7.739384
frame: 1837
16 -2.512180 0.674699 3.027277
frame: 1838
42 -0.836818 0.026788 0.621812
16 -0.836818 0.026788 0.621812
frame: 1856
16 14.814254 -0.022406 -30.649712
30 14.814254 -0.022406 -30.649712
frame: 1857
16 10.116482 -0.529484 -21.055931
frame: 1858
16 6.238332 -0.379757 -12.750408
frame: 1859
16 3.205807 -0.306992 -6.343636
- Code: Select all
I am doing that by adding the debug code to the force an torque callback loop.
void dgBroadPhase::ApplyForceAndtorque(dgBroadphaseSyncDescriptor* const descriptor, dgBodyMasterList::dgListNode* node, dgInt32 threadID)
{
dgFloat32 timestep = descriptor->m_timestep;
const dgInt32 threadCount = m_world->GetThreadCount();
while (node) {
dgBody* const body = node->GetInfo().GetBody();
body->m_resting = 1;
if (DoNeedUpdate(node)) {
if (body->IsRTTIType(dgBody::m_dynamicBodyRTTI)) {
dgDynamicBody* const dynamicBody = (dgDynamicBody*)body;
dynamicBody->ApplyExtenalForces(timestep, threadID);
if (dynamicBody->m_externalForce.m_x != 0) {
dgTrace (("%d %f %f %f\n", dynamicBody->m_uniqueID, dynamicBody->m_externalForce.m_x, dynamicBody->m_externalForce.m_y, dynamicBody->m_externalForce.m_z));
}
}
}
for (dgInt32 i = 0; i < threadCount; i++) {
node = node ? node->GetPrev() : NULL;
}
}
}