Woohoo, found the bug, very subtle but
You remember when you could no reproced determinism, I found one of the reason was that the
Aligment of the scene in the Multigrid Broadphase needed to be flushed as well, so I added this code.
- Code: Select all
void dgBroadPhaseCollision::InvalidateCache ()
{
dgBodyMasterList& masterList (*m_me);
for (dgBodyMasterList::dgListNode* node = masterList.GetFirst(); node; node = node->GetNext()) {
dgBody* body;
body = node->GetInfo().GetBody();
Remove(body);
}
for (dgBodyMasterList::dgListNode* node = masterList.GetFirst(); node; node = node->GetNext()) {
dgBody* body;
body = node->GetInfo().GetBody();
Add(body);
body->SetMatrix(body->GetMatrix());
}
That flushes all cashes, but it have one big problem,
When a body is added to the world for teh first time, the body does not have a valid AABB for the world,
However when I remove the body from the world the AABB is still Valid because teh body is no destroyed,
The second loop adds the body to the work again, but is adds the body to the root level of the Mutigrid,
then it calls SetMatrix, but now SetMatrix when is recalculates the new AABB, it finds that it is the same as the old AABB,
Therefore it says ohh this body has not changed position and it does not need to update its position in the Mutigrid world, as a result the body state in the top layer.
The usually is not a big problem for any normal scene, but your game is like a perfect storm, because you have 909 static bodies in your scene and they old state in the root level
Since static bodies do not get any update so they then never get promoted to their correct Cell on the Mutigrid world,
So the game run almost as naive SAP, so the slow down you see is when you add a new body you call Invalidate, so after that the world is sorted with a naive insertion sort.
The Solution is to invalidate the current AABB of the body when the body removed from the world.
- Code: Select all
void dgBroadPhaseCollision::InvalidateCache ()
{
dgBodyMasterList& masterList (*m_me);
for (dgBodyMasterList::dgListNode* node = masterList.GetFirst(); node; node = node->GetNext()) {
dgBody* body;
body = node->GetInfo().GetBody();
Remove(body);
// invalidate AABB so next add can promote the body to the correct CELL.
body->m_minAABB = dgVector ( 1.0e10f, 1.0e10f, 1.0e10f, 0.0f);
body->m_maxAABB = dgVector (-1.0e10f, -1.0e10f, -1.0e10f, 0.0f);
}
for (dgBodyMasterList::dgListNode* node = masterList.GetFirst(); node; node = node->GetNext()) {
dgBody* body;
body = node->GetInfo().GetBody();
Add(body);
body->SetMatrix(body->GetMatrix());
}
That solves that bug, but there is more,
I noticed that your world has a vertical direction alone the z axis, The world BradPhase is designed to work best when the axis is along y,
I made that changed when I optimize the BroadPhase, I notice the a 3d Multigrid uses a lot of memory, and that the gain in speed is maginally,
so I made the the Y axis is always zero.
that put all bodies at the center layer but since teh Grid is a hash map, there ares no cell on top and bottom of the center layer.
I will add a function to indidate what axis should be Masked and that will maximize the ditribution of bodies in the mutigrid world.
I will do tha and test this afternonn.
but wait there is more still, I believe your game can run about 2 to 3 time faster since it has some many static bodies,
If you use a Scene Collision shape and you put all the stastic bodies in that shape, then it will run a lot faster because now the world will see 1 body instead of 900 static ones,
The Scene collision is liek a compound collision bu for static bodies and it is optimized for queries of dynamics bodies agains static shape,
It never worries about checking static shape against static shapes.
I think we can try that after I post 2.08 with the fix.