optimized the island management. It was unoptimized, and becomes a bottleneck for large amounts of objects.
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
#include "CollisionDispatch/CollisionObject.h"
|
||||
#include "CollisionDispatch/CollisionWorld.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
SimulationIslandManager::SimulationIslandManager()
|
||||
@@ -105,7 +107,23 @@ void SimulationIslandManager::StoreIslandActivationState(CollisionWorld* colWorl
|
||||
}
|
||||
}
|
||||
|
||||
inline int getIslandId(const PersistentManifold* lhs)
|
||||
{
|
||||
int islandId;
|
||||
const CollisionObject* rcolObj0 = static_cast<const CollisionObject*>(lhs->GetBody0());
|
||||
const CollisionObject* rcolObj1 = static_cast<const CollisionObject*>(lhs->GetBody1());
|
||||
islandId= rcolObj0->m_islandTag1>=0?rcolObj0->m_islandTag1:rcolObj1->m_islandTag1;
|
||||
return islandId;
|
||||
|
||||
}
|
||||
|
||||
bool PersistentManifoldSortPredicate(const PersistentManifold* lhs, const PersistentManifold* rhs)
|
||||
{
|
||||
int rIslandId0,lIslandId0;
|
||||
rIslandId0 = getIslandId(rhs);
|
||||
lIslandId0 = getIslandId(lhs);
|
||||
return lIslandId0 < rIslandId0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
@@ -114,101 +132,143 @@ void SimulationIslandManager::StoreIslandActivationState(CollisionWorld* colWorl
|
||||
void SimulationIslandManager::BuildAndProcessIslands(Dispatcher* dispatcher,CollisionObjectArray& collisionObjects, IslandCallback* callback)
|
||||
{
|
||||
|
||||
|
||||
int numBodies = collisionObjects.size();
|
||||
|
||||
//first calculate the number of islands, and iterate over the islands id's
|
||||
//we are going to sort the unionfind array, and store the element id in the size
|
||||
//afterwards, we clean unionfind, to make sure no-one uses it anymore
|
||||
|
||||
GetUnionFind().sortIslands();
|
||||
int numElem = GetUnionFind().getNumElements();
|
||||
|
||||
const UnionFind& uf = this->GetUnionFind();
|
||||
int startIslandIndex=0,endIslandIndex=1;
|
||||
|
||||
for (int islandId=0;islandId<uf.getNumElements();islandId++)
|
||||
//update the sleeping state for bodies, if all are sleeping
|
||||
for (int startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
|
||||
{
|
||||
if (uf.isRoot(islandId))
|
||||
int islandId = GetUnionFind().getElement(startIslandIndex).m_id;
|
||||
for (endIslandIndex = startIslandIndex+1;(endIslandIndex<numElem) && (GetUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<PersistentManifold*> islandmanifold;
|
||||
|
||||
//int numSleeping = 0;
|
||||
//int numSleeping = 0;
|
||||
|
||||
bool allSleeping = true;
|
||||
bool allSleeping = true;
|
||||
|
||||
int i;
|
||||
for (i=0;i<numBodies;i++)
|
||||
int idx;
|
||||
for (idx=startIslandIndex;idx<endIslandIndex;idx++)
|
||||
{
|
||||
int i = GetUnionFind().getElement(idx).m_sz;
|
||||
|
||||
CollisionObject* colObj0 = collisionObjects[i];
|
||||
if ((colObj0->m_islandTag1 != islandId) && (colObj0->m_islandTag1 != -1))
|
||||
{
|
||||
CollisionObject* colObj0 = collisionObjects[i];
|
||||
|
||||
if (colObj0->m_islandTag1 == islandId)
|
||||
{
|
||||
|
||||
if (colObj0->GetActivationState()== ACTIVE_TAG)
|
||||
{
|
||||
allSleeping = false;
|
||||
}
|
||||
if (colObj0->GetActivationState()== DISABLE_DEACTIVATION)
|
||||
{
|
||||
allSleeping = false;
|
||||
}
|
||||
}
|
||||
printf("error in island management\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (allSleeping)
|
||||
assert((colObj0->m_islandTag1 == islandId) || (colObj0->m_islandTag1 == -1));
|
||||
if (colObj0->m_islandTag1 == islandId)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<numBodies;i++)
|
||||
if (colObj0->GetActivationState()== ACTIVE_TAG)
|
||||
{
|
||||
CollisionObject* colObj0 = collisionObjects[i];
|
||||
if (colObj0->m_islandTag1 == islandId)
|
||||
allSleeping = false;
|
||||
}
|
||||
if (colObj0->GetActivationState()== DISABLE_DEACTIVATION)
|
||||
{
|
||||
allSleeping = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allSleeping)
|
||||
{
|
||||
int idx;
|
||||
for (idx=startIslandIndex;idx<endIslandIndex;idx++)
|
||||
{
|
||||
int i = GetUnionFind().getElement(idx).m_sz;
|
||||
CollisionObject* colObj0 = collisionObjects[i];
|
||||
if ((colObj0->m_islandTag1 != islandId) && (colObj0->m_islandTag1 != -1))
|
||||
{
|
||||
printf("error in island management\n");
|
||||
}
|
||||
|
||||
assert((colObj0->m_islandTag1 == islandId) || (colObj0->m_islandTag1 == -1));
|
||||
|
||||
if (colObj0->m_islandTag1 == islandId)
|
||||
{
|
||||
colObj0->SetActivationState( ISLAND_SLEEPING );
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
|
||||
int idx;
|
||||
for (idx=startIslandIndex;idx<endIslandIndex;idx++)
|
||||
{
|
||||
int i = GetUnionFind().getElement(idx).m_sz;
|
||||
|
||||
CollisionObject* colObj0 = collisionObjects[i];
|
||||
if ((colObj0->m_islandTag1 != islandId) && (colObj0->m_islandTag1 != -1))
|
||||
{
|
||||
printf("error in island management\n");
|
||||
}
|
||||
|
||||
assert((colObj0->m_islandTag1 == islandId) || (colObj0->m_islandTag1 == -1));
|
||||
|
||||
if (colObj0->m_islandTag1 == islandId)
|
||||
{
|
||||
if ( colObj0->GetActivationState() == ISLAND_SLEEPING)
|
||||
{
|
||||
colObj0->SetActivationState( ISLAND_SLEEPING );
|
||||
colObj0->SetActivationState( WANTS_DEACTIVATION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else
|
||||
{
|
||||
|
||||
int i;
|
||||
for (i=0;i<numBodies;i++)
|
||||
{
|
||||
CollisionObject* colObj0 = collisionObjects[i];
|
||||
if (colObj0->m_islandTag1 == islandId)
|
||||
{
|
||||
if ( colObj0->GetActivationState() == ISLAND_SLEEPING)
|
||||
{
|
||||
colObj0->SetActivationState( WANTS_DEACTIVATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0;i<dispatcher->GetNumManifolds();i++)
|
||||
{
|
||||
PersistentManifold* manifold = dispatcher->GetManifoldByIndexInternal(i);
|
||||
|
||||
//filtering for response
|
||||
|
||||
CollisionObject* colObj0 = static_cast<CollisionObject*>(manifold->GetBody0());
|
||||
CollisionObject* colObj1 = static_cast<CollisionObject*>(manifold->GetBody1());
|
||||
assert(colObj0);
|
||||
assert(colObj1);
|
||||
{
|
||||
if (((colObj0)->m_islandTag1 == (islandId)) ||
|
||||
((colObj1)->m_islandTag1 == (islandId)))
|
||||
{
|
||||
if (dispatcher->NeedsResponse(*colObj0,*colObj1))
|
||||
islandmanifold.push_back(manifold);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Process the actual simulation, only if not sleeping/deactivated
|
||||
if (islandmanifold.size())
|
||||
{
|
||||
callback->ProcessIsland(&islandmanifold[0],islandmanifold.size());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<PersistentManifold*> islandmanifold;
|
||||
int i;
|
||||
int numManifolds = dispatcher->GetNumManifolds();
|
||||
islandmanifold.reserve(numManifolds);
|
||||
|
||||
for (i=0;i<numManifolds ;i++)
|
||||
{
|
||||
PersistentManifold* manifold = dispatcher->GetManifoldByIndexInternal(i);
|
||||
|
||||
CollisionObject* colObj0 = static_cast<CollisionObject*>(manifold->GetBody0());
|
||||
CollisionObject* colObj1 = static_cast<CollisionObject*>(manifold->GetBody1());
|
||||
|
||||
//todo: check sleeping conditions!
|
||||
if (((colObj0) && colObj0->GetActivationState() != ISLAND_SLEEPING) ||
|
||||
((colObj1) && colObj1->GetActivationState() != ISLAND_SLEEPING))
|
||||
{
|
||||
//filtering for response
|
||||
if (dispatcher->NeedsResponse(*colObj0,*colObj1))
|
||||
islandmanifold.push_back(manifold);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sort manifolds, based on islands
|
||||
// Sort the vector using predicate and std::sort
|
||||
std::sort(islandmanifold.begin(), islandmanifold.end(), PersistentManifoldSortPredicate);
|
||||
|
||||
//now process all active islands (sets of manifolds for now)
|
||||
|
||||
int startManifoldIndex = 0;
|
||||
int endManifoldIndex = 1;
|
||||
|
||||
for (startManifoldIndex=0;startManifoldIndex<numManifolds;startManifoldIndex = endManifoldIndex)
|
||||
{
|
||||
int islandId = getIslandId(islandmanifold[startManifoldIndex]);
|
||||
for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(islandmanifold[endManifoldIndex]));endManifoldIndex++)
|
||||
{
|
||||
}
|
||||
/// Process the actual simulation, only if not sleeping/deactivated
|
||||
int numIslandManifolds = endManifoldIndex-startManifoldIndex;
|
||||
if (numIslandManifolds)
|
||||
{
|
||||
callback->ProcessIsland(&islandmanifold[startManifoldIndex],numIslandManifolds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user