Back to index

supertuxkart  0.5+dfsg1
Classes | Public Member Functions | Private Attributes
btSimulationIslandManager Class Reference

SimulationIslandManager creates and handles simulation islands, using btUnionFind. More...

#include <btSimulationIslandManager.h>

Collaboration diagram for btSimulationIslandManager:
Collaboration graph
[legend]

List of all members.

Classes

struct  IslandCallback

Public Member Functions

 btSimulationIslandManager ()
virtual ~btSimulationIslandManager ()
void initUnionFind (int n)
btUnionFindgetUnionFind ()
virtual void updateActivationState (btCollisionWorld *colWorld, btDispatcher *dispatcher)
virtual void storeIslandActivationState (btCollisionWorld *world)
void findUnions (btDispatcher *dispatcher, btCollisionWorld *colWorld)
void buildAndProcessIslands (btDispatcher *dispatcher, btCollisionObjectArray &collisionObjects, IslandCallback *callback)

Private Attributes

btUnionFind m_unionFind
btAlignedObjectArray
< btPersistentManifold * > 
m_islandmanifold
btAlignedObjectArray
< btCollisionObject * > 
m_islandBodies

Detailed Description

SimulationIslandManager creates and handles simulation islands, using btUnionFind.

Definition at line 31 of file btSimulationIslandManager.h.


Constructor & Destructor Documentation

Definition at line 13 of file btSimulationIslandManager.cpp.

{
}

Definition at line 17 of file btSimulationIslandManager.cpp.

{
}

Here is the caller graph for this function:


Member Function Documentation

void btSimulationIslandManager::buildAndProcessIslands ( btDispatcher dispatcher,
btCollisionObjectArray collisionObjects,
IslandCallback callback 
)

Process the actual simulation, only if not sleeping/deactivated

Definition at line 138 of file btSimulationIslandManager.cpp.

{

       BT_PROFILE("islandUnionFindAndQuickSort");
       
       //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();

       int endIslandIndex=1;
       int startIslandIndex;


       //update the sleeping state for bodies, if all are sleeping
       for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
       {
              int islandId = getUnionFind().getElement(startIslandIndex).m_id;
              for (endIslandIndex = startIslandIndex+1;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
              {
              }

              //int numSleeping = 0;

              bool allSleeping = true;

              int idx;
              for (idx=startIslandIndex;idx<endIslandIndex;idx++)
              {
                     int i = getUnionFind().getElement(idx).m_sz;

                     btCollisionObject* colObj0 = collisionObjects[i];
                     if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
                     {
//                          printf("error in island management\n");
                     }

                     assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
                     if (colObj0->getIslandTag() == islandId)
                     {
                            if (colObj0->getActivationState()== ACTIVE_TAG)
                            {
                                   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;
                            btCollisionObject* colObj0 = collisionObjects[i];
                            if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
                            {
//                                 printf("error in island management\n");
                            }

                            assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));

                            if (colObj0->getIslandTag() == islandId)
                            {
                                   colObj0->setActivationState( ISLAND_SLEEPING );
                            }
                     }
              } else
              {

                     int idx;
                     for (idx=startIslandIndex;idx<endIslandIndex;idx++)
                     {
                            int i = getUnionFind().getElement(idx).m_sz;

                            btCollisionObject* colObj0 = collisionObjects[i];
                            if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
                            {
//                                 printf("error in island management\n");
                            }

                            assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));

                            if (colObj0->getIslandTag() == islandId)
                            {
                                   if ( colObj0->getActivationState() == ISLAND_SLEEPING)
                                   {
                                          colObj0->setActivationState( WANTS_DEACTIVATION);
                                   }
                            }
                     }
              }
       }

       
       int i;
       int maxNumManifolds = dispatcher->getNumManifolds();

#define SPLIT_ISLANDS 1
#ifdef SPLIT_ISLANDS

       
#endif //SPLIT_ISLANDS

       
       for (i=0;i<maxNumManifolds ;i++)
       {
               btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
               
               btCollisionObject* colObj0 = static_cast<btCollisionObject*>(manifold->getBody0());
               btCollisionObject* colObj1 = static_cast<btCollisionObject*>(manifold->getBody1());
              
               //todo: check sleeping conditions!
               if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) ||
                     ((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING))
              {
              
                     //kinematic objects don't merge islands, but wake up all connected objects
                     if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
                     {
                            colObj1->activate();
                     }
                     if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
                     {
                            colObj0->activate();
                     }
#ifdef SPLIT_ISLANDS
       //            //filtering for response
                     if (dispatcher->needsResponse(colObj0,colObj1))
                            m_islandmanifold.push_back(manifold);
#endif //SPLIT_ISLANDS
              }
       }

#ifndef SPLIT_ISLANDS
       btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer();
       
       callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1);
#else
       // Sort manifolds, based on islands
       // Sort the vector using predicate and std::sort
       //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);

       int numManifolds = int (m_islandmanifold.size());

       //we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
       m_islandmanifold.quickSort(btPersistentManifoldSortPredicate());

       //now process all active islands (sets of manifolds for now)

       int startManifoldIndex = 0;
       int endManifoldIndex = 1;

       //int islandId;

       

//     printf("Start Islands\n");

       //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
       for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
       {
              int islandId = getUnionFind().getElement(startIslandIndex).m_id;


              bool islandSleeping = false;
                
                for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
                {
                        int i = getUnionFind().getElement(endIslandIndex).m_sz;
                        btCollisionObject* colObj0 = collisionObjects[i];
                                          m_islandBodies.push_back(colObj0);
                        if (!colObj0->isActive())
                                islandSleeping = true;
                }
                

              //find the accompanying contact manifold for this islandId
              int numIslandManifolds = 0;
              btPersistentManifold** startManifold = 0;

              if (startManifoldIndex<numManifolds)
              {
                     int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]);
                     if (curIslandId == islandId)
                     {
                            startManifold = &m_islandmanifold[startManifoldIndex];
                     
                            for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++)
                            {

                            }
                            numIslandManifolds = endManifoldIndex-startManifoldIndex;
                     }

              }

              if (!islandSleeping)
              {
                     callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId);
//                   printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
              }
              
              if (numIslandManifolds)
              {
                     startManifoldIndex = endManifoldIndex;
              }

              m_islandBodies.resize(0);
       }
#endif //SPLIT_ISLANDS

       m_islandmanifold.resize(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void btSimulationIslandManager::findUnions ( btDispatcher dispatcher,
btCollisionWorld colWorld 
)

Definition at line 28 of file btSimulationIslandManager.cpp.

{
       
       {
              btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();

              for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++)
              {
                     const btBroadphasePair& collisionPair = pairPtr[i];
                     btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
                     btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;

                     if (((colObj0) && ((colObj0)->mergesSimulationIslands())) &&
                            ((colObj1) && ((colObj1)->mergesSimulationIslands())))
                     {

                            m_unionFind.unite((colObj0)->getIslandTag(),
                                   (colObj1)->getIslandTag());
                     }
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 47 of file btSimulationIslandManager.h.

{ return m_unionFind;}

Here is the caller graph for this function:

Definition at line 22 of file btSimulationIslandManager.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 83 of file btSimulationIslandManager.cpp.

{
       // put the islandId ('find' value) into m_tag    
       {
              
              
              int index = 0;
              int i;
              for (i=0;i<colWorld->getCollisionObjectArray().size();i++)
              {
                     btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i];
                     if (collisionObject->mergesSimulationIslands())
                     {
                            collisionObject->setIslandTag( m_unionFind.find(index) );
                            collisionObject->setCompanionId(-1);
                     } else
                     {
                            collisionObject->setIslandTag(-1);
                            collisionObject->setCompanionId(-2);
                     }
                     index++;
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void btSimulationIslandManager::updateActivationState ( btCollisionWorld colWorld,
btDispatcher dispatcher 
) [virtual]

Definition at line 52 of file btSimulationIslandManager.cpp.

{
       
       initUnionFind( int (colWorld->getCollisionObjectArray().size()));
       
       // put the index into m_controllers into m_tag   
       {
              
              int index = 0;
              int i;
              for (i=0;i<colWorld->getCollisionObjectArray().size(); i++)
              {
                     btCollisionObject*   collisionObject= colWorld->getCollisionObjectArray()[i];
                     collisionObject->setIslandTag(index);
                     collisionObject->setCompanionId(-1);
                     collisionObject->setHitFraction(btScalar(1.));
                     index++;
                     
              }
       }
       // do the union find
       
       findUnions(dispatcher,colWorld);
       

       
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 36 of file btSimulationIslandManager.h.

Definition at line 35 of file btSimulationIslandManager.h.

Definition at line 33 of file btSimulationIslandManager.h.


The documentation for this class was generated from the following files: