forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			679 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			679 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								Bullet Continuous Collision Detection and Physics Library
							 | 
						||
| 
								 | 
							
								Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This software is provided 'as-is', without any express or implied warranty.
							 | 
						||
| 
								 | 
							
								In no event will the authors be held liable for any damages arising from the use of this software.
							 | 
						||
| 
								 | 
							
								Permission is granted to anyone to use this software for any purpose, 
							 | 
						||
| 
								 | 
							
								including commercial applications, and to alter it and redistribute it freely, 
							 | 
						||
| 
								 | 
							
								subject to the following restrictions:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
							 | 
						||
| 
								 | 
							
								2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
							 | 
						||
| 
								 | 
							
								3. This notice may not be removed or altered from any source distribution.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btScalar.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btThreads.h"
							 | 
						||
| 
								 | 
							
								#include "btSimulationIslandManagerMt.h"
							 | 
						||
| 
								 | 
							
								#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
							 | 
						||
| 
								 | 
							
								#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
							 | 
						||
| 
								 | 
							
								#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
							 | 
						||
| 
								 | 
							
								#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
							 | 
						||
| 
								 | 
							
								#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btQuickprof.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SIMD_FORCE_INLINE int calcBatchCost( int bodies, int manifolds, int constraints )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // rough estimate of the cost of a batch, used for merging
							 | 
						||
| 
								 | 
							
								    int batchCost = bodies + 8 * manifolds + 4 * constraints;
							 | 
						||
| 
								 | 
							
								    return batchCost;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SIMD_FORCE_INLINE int calcBatchCost( const btSimulationIslandManagerMt::Island* island )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return calcBatchCost( island->bodyArray.size(), island->manifoldArray.size(), island->constraintArray.size() );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btSimulationIslandManagerMt::btSimulationIslandManagerMt()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    m_minimumSolverBatchSize = calcBatchCost(0, 128, 0);
							 | 
						||
| 
								 | 
							
								    m_batchIslandMinBodyCount = 32;
							 | 
						||
| 
								 | 
							
								    m_islandDispatch = parallelIslandDispatch;
							 | 
						||
| 
								 | 
							
								    m_batchIsland = NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btSimulationIslandManagerMt::~btSimulationIslandManagerMt()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < m_allocatedIslands.size(); ++i )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        delete m_allocatedIslands[ i ];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    m_allocatedIslands.resize( 0 );
							 | 
						||
| 
								 | 
							
								    m_activeIslands.resize( 0 );
							 | 
						||
| 
								 | 
							
								    m_freeIslands.resize( 0 );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline	int	getIslandId(const btPersistentManifold* lhs)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									const btCollisionObject* rcolObj0 = static_cast<const btCollisionObject*>(lhs->getBody0());
							 | 
						||
| 
								 | 
							
									const btCollisionObject* rcolObj1 = static_cast<const btCollisionObject*>(lhs->getBody1());
							 | 
						||
| 
								 | 
							
								    int islandId = rcolObj0->getIslandTag() >= 0 ? rcolObj0->getIslandTag() : rcolObj1->getIslandTag();
							 | 
						||
| 
								 | 
							
									return islandId;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SIMD_FORCE_INLINE	int	btGetConstraintIslandId( const btTypedConstraint* lhs )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
							 | 
						||
| 
								 | 
							
								    const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
							 | 
						||
| 
								 | 
							
								    int islandId = rcolObj0.getIslandTag() >= 0 ? rcolObj0.getIslandTag() : rcolObj1.getIslandTag();
							 | 
						||
| 
								 | 
							
								    return islandId;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// function object that routes calls to operator<
							 | 
						||
| 
								 | 
							
								class IslandBatchSizeSortPredicate
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    bool operator() ( const btSimulationIslandManagerMt::Island* lhs, const btSimulationIslandManagerMt::Island* rhs ) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        int lCost = calcBatchCost( lhs );
							 | 
						||
| 
								 | 
							
								        int rCost = calcBatchCost( rhs );
							 | 
						||
| 
								 | 
							
								        return lCost > rCost;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class IslandBodyCapacitySortPredicate
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    bool operator() ( const btSimulationIslandManagerMt::Island* lhs, const btSimulationIslandManagerMt::Island* rhs ) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return lhs->bodyArray.capacity() > rhs->bodyArray.capacity();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btSimulationIslandManagerMt::Island::append( const Island& other )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // append bodies
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < other.bodyArray.size(); ++i )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        bodyArray.push_back( other.bodyArray[ i ] );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // append manifolds
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < other.manifoldArray.size(); ++i )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        manifoldArray.push_back( other.manifoldArray[ i ] );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // append constraints
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < other.constraintArray.size(); ++i )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        constraintArray.push_back( other.constraintArray[ i ] );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool btIsBodyInIsland( const btSimulationIslandManagerMt::Island& island, const btCollisionObject* obj )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < island.bodyArray.size(); ++i )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ( island.bodyArray[ i ] == obj )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return false;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btSimulationIslandManagerMt::initIslandPools()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // reset island pools
							 | 
						||
| 
								 | 
							
								    int numElem = getUnionFind().getNumElements();
							 | 
						||
| 
								 | 
							
								    m_lookupIslandFromId.resize( numElem );
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < m_lookupIslandFromId.size(); ++i )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        m_lookupIslandFromId[ i ] = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    m_activeIslands.resize( 0 );
							 | 
						||
| 
								 | 
							
								    m_freeIslands.resize( 0 );
							 | 
						||
| 
								 | 
							
								    // check whether allocated islands are sorted by body capacity (largest to smallest)
							 | 
						||
| 
								 | 
							
								    int lastCapacity = 0;
							 | 
						||
| 
								 | 
							
								    bool isSorted = true;
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < m_allocatedIslands.size(); ++i )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        Island* island = m_allocatedIslands[ i ];
							 | 
						||
| 
								 | 
							
								        int cap = island->bodyArray.capacity();
							 | 
						||
| 
								 | 
							
								        if ( cap > lastCapacity )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            isSorted = false;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        lastCapacity = cap;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if ( !isSorted )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        m_allocatedIslands.quickSort( IslandBodyCapacitySortPredicate() );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    m_batchIsland = NULL;
							 | 
						||
| 
								 | 
							
								    // mark all islands free (but avoid deallocation)
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < m_allocatedIslands.size(); ++i )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        Island* island = m_allocatedIslands[ i ];
							 | 
						||
| 
								 | 
							
								        island->bodyArray.resize( 0 );
							 | 
						||
| 
								 | 
							
								        island->manifoldArray.resize( 0 );
							 | 
						||
| 
								 | 
							
								        island->constraintArray.resize( 0 );
							 | 
						||
| 
								 | 
							
								        island->id = -1;
							 | 
						||
| 
								 | 
							
								        island->isSleeping = true;
							 | 
						||
| 
								 | 
							
								        m_freeIslands.push_back( island );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btSimulationIslandManagerMt::Island* btSimulationIslandManagerMt::getIsland( int id )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    Island* island = m_lookupIslandFromId[ id ];
							 | 
						||
| 
								 | 
							
								    if ( island == NULL )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // search for existing island
							 | 
						||
| 
								 | 
							
								        for ( int i = 0; i < m_activeIslands.size(); ++i )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if ( m_activeIslands[ i ]->id == id )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                island = m_activeIslands[ i ];
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        m_lookupIslandFromId[ id ] = island;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return island;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btSimulationIslandManagerMt::Island* btSimulationIslandManagerMt::allocateIsland( int id, int numBodies )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    Island* island = NULL;
							 | 
						||
| 
								 | 
							
								    int allocSize = numBodies;
							 | 
						||
| 
								 | 
							
								    if ( numBodies < m_batchIslandMinBodyCount )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ( m_batchIsland )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            island = m_batchIsland;
							 | 
						||
| 
								 | 
							
								            m_lookupIslandFromId[ id ] = island;
							 | 
						||
| 
								 | 
							
								            // if we've made a large enough batch,
							 | 
						||
| 
								 | 
							
								            if ( island->bodyArray.size() + numBodies >= m_batchIslandMinBodyCount )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                // next time start a new batch
							 | 
						||
| 
								 | 
							
								                m_batchIsland = NULL;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return island;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            // need to allocate a batch island
							 | 
						||
| 
								 | 
							
								            allocSize = m_batchIslandMinBodyCount * 2;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    btAlignedObjectArray<Island*>& freeIslands = m_freeIslands;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // search for free island
							 | 
						||
| 
								 | 
							
								    if ( freeIslands.size() > 0 )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // try to reuse a previously allocated island
							 | 
						||
| 
								 | 
							
								        int iFound = freeIslands.size();
							 | 
						||
| 
								 | 
							
								        // linear search for smallest island that can hold our bodies
							 | 
						||
| 
								 | 
							
								        for ( int i = freeIslands.size() - 1; i >= 0; --i )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if ( freeIslands[ i ]->bodyArray.capacity() >= allocSize )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                iFound = i;
							 | 
						||
| 
								 | 
							
								                island = freeIslands[ i ];
							 | 
						||
| 
								 | 
							
								                island->id = id;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // if found, shrink array while maintaining ordering
							 | 
						||
| 
								 | 
							
								        if ( island )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            int iDest = iFound;
							 | 
						||
| 
								 | 
							
								            int iSrc = iDest + 1;
							 | 
						||
| 
								 | 
							
								            while ( iSrc < freeIslands.size() )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                freeIslands[ iDest++ ] = freeIslands[ iSrc++ ];
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            freeIslands.pop_back();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if ( island == NULL )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // no free island found, allocate
							 | 
						||
| 
								 | 
							
								        island = new Island();  // TODO: change this to use the pool allocator
							 | 
						||
| 
								 | 
							
								        island->id = id;
							 | 
						||
| 
								 | 
							
								        island->bodyArray.reserve( allocSize );
							 | 
						||
| 
								 | 
							
								        m_allocatedIslands.push_back( island );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    m_lookupIslandFromId[ id ] = island;
							 | 
						||
| 
								 | 
							
								    if ( numBodies < m_batchIslandMinBodyCount )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        m_batchIsland = island;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    m_activeIslands.push_back( island );
							 | 
						||
| 
								 | 
							
								    return island;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btSimulationIslandManagerMt::buildIslands( btDispatcher* dispatcher, btCollisionWorld* collisionWorld )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									BT_PROFILE("islandUnionFindAndQuickSort");
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//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");
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											btAssert((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");
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												btAssert((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");
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if (colObj0->getIslandTag() == islandId)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( colObj0->getActivationState() == ISLAND_SLEEPING)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														colObj0->setActivationState( WANTS_DEACTIVATION);
							 | 
						||
| 
								 | 
							
														colObj0->setDeactivationTime(0.f);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btSimulationIslandManagerMt::addBodiesToIslands( btCollisionWorld* collisionWorld )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
							 | 
						||
| 
								 | 
							
								    int endIslandIndex = 1;
							 | 
						||
| 
								 | 
							
								    int startIslandIndex;
							 | 
						||
| 
								 | 
							
								    int numElem = getUnionFind().getNumElements();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // create explicit islands and add bodies to each
							 | 
						||
| 
								 | 
							
								    for ( startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        int islandId = getUnionFind().getElement( startIslandIndex ).m_id;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // find end index
							 | 
						||
| 
								 | 
							
								        for ( endIslandIndex = startIslandIndex; ( endIslandIndex < numElem ) && ( getUnionFind().getElement( endIslandIndex ).m_id == islandId ); endIslandIndex++ )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // check if island is sleeping
							 | 
						||
| 
								 | 
							
								        bool islandSleeping = true;
							 | 
						||
| 
								 | 
							
								        for ( int iElem = startIslandIndex; iElem < endIslandIndex; iElem++ )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            int i = getUnionFind().getElement( iElem ).m_sz;
							 | 
						||
| 
								 | 
							
								            btCollisionObject* colObj = collisionObjects[ i ];
							 | 
						||
| 
								 | 
							
								            if ( colObj->isActive() )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                islandSleeping = false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if ( !islandSleeping )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            // want to count the number of bodies before allocating the island to optimize memory usage of the Island structures
							 | 
						||
| 
								 | 
							
								            int numBodies = endIslandIndex - startIslandIndex;
							 | 
						||
| 
								 | 
							
								            Island* island = allocateIsland( islandId, numBodies );
							 | 
						||
| 
								 | 
							
								            island->isSleeping = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // add bodies to island
							 | 
						||
| 
								 | 
							
								            for ( int iElem = startIslandIndex; iElem < endIslandIndex; iElem++ )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                int i = getUnionFind().getElement( iElem ).m_sz;
							 | 
						||
| 
								 | 
							
								                btCollisionObject* colObj = collisionObjects[ i ];
							 | 
						||
| 
								 | 
							
								                island->bodyArray.push_back( colObj );
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btSimulationIslandManagerMt::addManifoldsToIslands( btDispatcher* dispatcher )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // walk all the manifolds, activating bodies touched by kinematic objects, and add each manifold to its Island
							 | 
						||
| 
								 | 
							
								    int maxNumManifolds = dispatcher->getNumManifolds();
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < maxNumManifolds; i++ )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal( i );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>( manifold->getBody0() );
							 | 
						||
| 
								 | 
							
								        const btCollisionObject* colObj1 = static_cast<const 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 )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if ( colObj0->hasContactResponse() )
							 | 
						||
| 
								 | 
							
								                    colObj1->activate();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if ( colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if ( colObj1->hasContactResponse() )
							 | 
						||
| 
								 | 
							
								                    colObj0->activate();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            //filtering for response
							 | 
						||
| 
								 | 
							
								            if ( dispatcher->needsResponse( colObj0, colObj1 ) )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                // scatter manifolds into various islands
							 | 
						||
| 
								 | 
							
								                int islandId = getIslandId( manifold );
							 | 
						||
| 
								 | 
							
								                // if island not sleeping,
							 | 
						||
| 
								 | 
							
								                if ( Island* island = getIsland( islandId ) )
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    island->manifoldArray.push_back( manifold );
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btSimulationIslandManagerMt::addConstraintsToIslands( btAlignedObjectArray<btTypedConstraint*>& constraints )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // walk constraints
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < constraints.size(); i++ )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // scatter constraints into various islands
							 | 
						||
| 
								 | 
							
								        btTypedConstraint* constraint = constraints[ i ];
							 | 
						||
| 
								 | 
							
								        if ( constraint->isEnabled() )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            int islandId = btGetConstraintIslandId( constraint );
							 | 
						||
| 
								 | 
							
								            // if island is not sleeping,
							 | 
						||
| 
								 | 
							
								            if ( Island* island = getIsland( islandId ) )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                island->constraintArray.push_back( constraint );
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btSimulationIslandManagerMt::mergeIslands()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // sort islands in order of decreasing batch size
							 | 
						||
| 
								 | 
							
								    m_activeIslands.quickSort( IslandBatchSizeSortPredicate() );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // merge small islands to satisfy minimum batch size
							 | 
						||
| 
								 | 
							
								    // find first small batch island
							 | 
						||
| 
								 | 
							
								    int destIslandIndex = m_activeIslands.size();
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < m_activeIslands.size(); ++i )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        Island* island = m_activeIslands[ i ];
							 | 
						||
| 
								 | 
							
								        int batchSize = calcBatchCost( island );
							 | 
						||
| 
								 | 
							
								        if ( batchSize < m_minimumSolverBatchSize )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            destIslandIndex = i;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    int lastIndex = m_activeIslands.size() - 1;
							 | 
						||
| 
								 | 
							
								    while ( destIslandIndex < lastIndex )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // merge islands from the back of the list
							 | 
						||
| 
								 | 
							
								        Island* island = m_activeIslands[ destIslandIndex ];
							 | 
						||
| 
								 | 
							
								        int numBodies = island->bodyArray.size();
							 | 
						||
| 
								 | 
							
								        int numManifolds = island->manifoldArray.size();
							 | 
						||
| 
								 | 
							
								        int numConstraints = island->constraintArray.size();
							 | 
						||
| 
								 | 
							
								        int firstIndex = lastIndex;
							 | 
						||
| 
								 | 
							
								        // figure out how many islands we want to merge and find out how many bodies, manifolds and constraints we will have
							 | 
						||
| 
								 | 
							
								        while ( true )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            Island* src = m_activeIslands[ firstIndex ];
							 | 
						||
| 
								 | 
							
								            numBodies += src->bodyArray.size();
							 | 
						||
| 
								 | 
							
								            numManifolds += src->manifoldArray.size();
							 | 
						||
| 
								 | 
							
								            numConstraints += src->constraintArray.size();
							 | 
						||
| 
								 | 
							
								            int batchCost = calcBatchCost( numBodies, numManifolds, numConstraints );
							 | 
						||
| 
								 | 
							
								            if ( batchCost >= m_minimumSolverBatchSize )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if ( firstIndex - 1 == destIslandIndex )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            firstIndex--;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // reserve space for these pointers to minimize reallocation
							 | 
						||
| 
								 | 
							
								        island->bodyArray.reserve( numBodies );
							 | 
						||
| 
								 | 
							
								        island->manifoldArray.reserve( numManifolds );
							 | 
						||
| 
								 | 
							
								        island->constraintArray.reserve( numConstraints );
							 | 
						||
| 
								 | 
							
								        // merge islands
							 | 
						||
| 
								 | 
							
								        for ( int i = firstIndex; i <= lastIndex; ++i )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            island->append( *m_activeIslands[ i ] );
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // shrink array to exclude the islands that were merged from
							 | 
						||
| 
								 | 
							
								        m_activeIslands.resize( firstIndex );
							 | 
						||
| 
								 | 
							
								        lastIndex = firstIndex - 1;
							 | 
						||
| 
								 | 
							
								        destIslandIndex++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btSimulationIslandManagerMt::serialIslandDispatch( btAlignedObjectArray<Island*>* islandsPtr, IslandCallback* callback )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    BT_PROFILE( "serialIslandDispatch" );
							 | 
						||
| 
								 | 
							
								    // serial dispatch
							 | 
						||
| 
								 | 
							
								    btAlignedObjectArray<Island*>& islands = *islandsPtr;
							 | 
						||
| 
								 | 
							
								    for ( int i = 0; i < islands.size(); ++i )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        Island* island = islands[ i ];
							 | 
						||
| 
								 | 
							
								        btPersistentManifold** manifolds = island->manifoldArray.size() ? &island->manifoldArray[ 0 ] : NULL;
							 | 
						||
| 
								 | 
							
								        btTypedConstraint** constraintsPtr = island->constraintArray.size() ? &island->constraintArray[ 0 ] : NULL;
							 | 
						||
| 
								 | 
							
								        callback->processIsland( &island->bodyArray[ 0 ],
							 | 
						||
| 
								 | 
							
								                                 island->bodyArray.size(),
							 | 
						||
| 
								 | 
							
								                                 manifolds,
							 | 
						||
| 
								 | 
							
								                                 island->manifoldArray.size(),
							 | 
						||
| 
								 | 
							
								                                 constraintsPtr,
							 | 
						||
| 
								 | 
							
								                                 island->constraintArray.size(),
							 | 
						||
| 
								 | 
							
								                                 island->id
							 | 
						||
| 
								 | 
							
								                                 );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct UpdateIslandDispatcher : public btIParallelForBody
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    btAlignedObjectArray<btSimulationIslandManagerMt::Island*>* islandsPtr;
							 | 
						||
| 
								 | 
							
								    btSimulationIslandManagerMt::IslandCallback* callback;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        for ( int i = iBegin; i < iEnd; ++i )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            btSimulationIslandManagerMt::Island* island = ( *islandsPtr )[ i ];
							 | 
						||
| 
								 | 
							
								            btPersistentManifold** manifolds = island->manifoldArray.size() ? &island->manifoldArray[ 0 ] : NULL;
							 | 
						||
| 
								 | 
							
								            btTypedConstraint** constraintsPtr = island->constraintArray.size() ? &island->constraintArray[ 0 ] : NULL;
							 | 
						||
| 
								 | 
							
								            callback->processIsland( &island->bodyArray[ 0 ],
							 | 
						||
| 
								 | 
							
								                island->bodyArray.size(),
							 | 
						||
| 
								 | 
							
								                manifolds,
							 | 
						||
| 
								 | 
							
								                island->manifoldArray.size(),
							 | 
						||
| 
								 | 
							
								                constraintsPtr,
							 | 
						||
| 
								 | 
							
								                island->constraintArray.size(),
							 | 
						||
| 
								 | 
							
								                island->id
							 | 
						||
| 
								 | 
							
								            );
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btSimulationIslandManagerMt::parallelIslandDispatch( btAlignedObjectArray<Island*>* islandsPtr, IslandCallback* callback )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    BT_PROFILE( "parallelIslandDispatch" );
							 | 
						||
| 
								 | 
							
								    int grainSize = 1;  // iterations per task
							 | 
						||
| 
								 | 
							
								    UpdateIslandDispatcher dispatcher;
							 | 
						||
| 
								 | 
							
								    dispatcher.islandsPtr = islandsPtr;
							 | 
						||
| 
								 | 
							
								    dispatcher.callback = callback;
							 | 
						||
| 
								 | 
							
								    btParallelFor( 0, islandsPtr->size(), grainSize, dispatcher );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///@todo: this is random access, it can be walked 'cache friendly'!
							 | 
						||
| 
								 | 
							
								void btSimulationIslandManagerMt::buildAndProcessIslands( btDispatcher* dispatcher,
							 | 
						||
| 
								 | 
							
								                                                        btCollisionWorld* collisionWorld,
							 | 
						||
| 
								 | 
							
								                                                        btAlignedObjectArray<btTypedConstraint*>& constraints,
							 | 
						||
| 
								 | 
							
								                                                        IslandCallback* callback
							 | 
						||
| 
								 | 
							
								                                                        )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									buildIslands(dispatcher,collisionWorld);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									BT_PROFILE("processIslands");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(!getSplitIslands())
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								        btPersistentManifold** manifolds = dispatcher->getInternalManifoldPointer();
							 | 
						||
| 
								 | 
							
								        int maxNumManifolds = dispatcher->getNumManifolds();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for ( int i = 0; i < maxNumManifolds; i++ )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            btPersistentManifold* manifold = manifolds[ i ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>( manifold->getBody0() );
							 | 
						||
| 
								 | 
							
								            const btCollisionObject* colObj1 = static_cast<const 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 )
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    if ( colObj0->hasContactResponse() )
							 | 
						||
| 
								 | 
							
								                        colObj1->activate();
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                if ( colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING )
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    if ( colObj1->hasContactResponse() )
							 | 
						||
| 
								 | 
							
								                        colObj0->activate();
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        btTypedConstraint** constraintsPtr = constraints.size() ? &constraints[ 0 ] : NULL;
							 | 
						||
| 
								 | 
							
										callback->processIsland(&collisionObjects[0],
							 | 
						||
| 
								 | 
							
								                                 collisionObjects.size(),
							 | 
						||
| 
								 | 
							
								                                 manifolds,
							 | 
						||
| 
								 | 
							
								                                 maxNumManifolds,
							 | 
						||
| 
								 | 
							
								                                 constraintsPtr,
							 | 
						||
| 
								 | 
							
								                                 constraints.size(),
							 | 
						||
| 
								 | 
							
								                                 -1
							 | 
						||
| 
								 | 
							
								                                 );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								        initIslandPools();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
							 | 
						||
| 
								 | 
							
								        addBodiesToIslands( collisionWorld );
							 | 
						||
| 
								 | 
							
								        addManifoldsToIslands( dispatcher );
							 | 
						||
| 
								 | 
							
								        addConstraintsToIslands( constraints );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // m_activeIslands array should now contain all non-sleeping Islands, and each Island should
							 | 
						||
| 
								 | 
							
								        // have all the necessary bodies, manifolds and constraints.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // if we want to merge islands with small batch counts,
							 | 
						||
| 
								 | 
							
								        if ( m_minimumSolverBatchSize > 1 )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            mergeIslands();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // dispatch islands to solver
							 | 
						||
| 
								 | 
							
								        m_islandDispatch( &m_activeIslands, callback );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |