Refactoring for parallel processing of islands, collision detection and constraint solving.
This commit is contained in:
@@ -322,7 +322,7 @@ static void DrawAabb(IDebugDraw* debugDrawer,const SimdVector3& from,const SimdV
|
||||
|
||||
|
||||
|
||||
CcdPhysicsEnvironment::CcdPhysicsEnvironment(CollisionDispatcher* dispatcher,BroadphaseInterface* broadphase)
|
||||
CcdPhysicsEnvironment::CcdPhysicsEnvironment(CollisionDispatcher* dispatcher,OverlappingPairCache* pairCache)
|
||||
:m_scalingPropagated(false),
|
||||
m_numIterations(4),
|
||||
m_numTimeSubSteps(1),
|
||||
@@ -336,18 +336,18 @@ m_enableSatCollisionDetection(false)
|
||||
{
|
||||
m_triggerCallbacks[i] = 0;
|
||||
}
|
||||
if (!dispatcher)
|
||||
dispatcher = new CollisionDispatcher();
|
||||
//if (!dispatcher)
|
||||
// dispatcher = new CollisionDispatcher();
|
||||
|
||||
|
||||
if(!broadphase)
|
||||
if(!pairCache)
|
||||
{
|
||||
|
||||
//todo: calculate/let user specify this world sizes
|
||||
SimdVector3 worldMin(-10000,-10000,-10000);
|
||||
SimdVector3 worldMax(10000,10000,10000);
|
||||
|
||||
broadphase = new AxisSweep3(worldMin,worldMax);
|
||||
pairCache = new AxisSweep3(worldMin,worldMax);
|
||||
|
||||
//broadphase = new SimpleBroadphase();
|
||||
}
|
||||
@@ -355,7 +355,7 @@ m_enableSatCollisionDetection(false)
|
||||
|
||||
setSolverType(1);//issues with quickstep and memory allocations
|
||||
|
||||
m_collisionWorld = new CollisionWorld(dispatcher,broadphase);
|
||||
m_collisionWorld = new CollisionWorld(dispatcher,pairCache);
|
||||
|
||||
m_debugDrawer = 0;
|
||||
m_gravity = SimdVector3(0.f,-10.f,0.f);
|
||||
@@ -654,7 +654,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
|
||||
Profiler::endBlock("predictIntegratedTransform");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
BroadphaseInterface* scene = GetBroadphase();
|
||||
OverlappingPairCache* scene = m_collisionWorld->GetPairCache();
|
||||
|
||||
|
||||
//
|
||||
@@ -675,7 +675,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
|
||||
dispatchInfo.m_stepCount = 0;
|
||||
dispatchInfo.m_enableSatConvex = m_enableSatCollisionDetection;
|
||||
|
||||
scene->DispatchAllCollisionPairs(*GetDispatcher(),dispatchInfo);///numsubstep,g);
|
||||
GetDispatcher()->DispatchAllCollisionPairs(scene,dispatchInfo);
|
||||
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
@@ -842,7 +842,8 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
|
||||
dispatchInfo.m_stepCount = 0;
|
||||
dispatchInfo.m_dispatchFunc = DispatcherInfo::DISPATCH_CONTINUOUS;
|
||||
|
||||
scene->DispatchAllCollisionPairs( *GetDispatcher(),dispatchInfo);///numsubstep,g);
|
||||
GetDispatcher()->DispatchAllCollisionPairs(scene,dispatchInfo);
|
||||
|
||||
toi = dispatchInfo.m_timeOfImpact;
|
||||
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ class Dispatcher;
|
||||
class WrapperVehicle;
|
||||
class PersistentManifold;
|
||||
class BroadphaseInterface;
|
||||
class OverlappingPairCache;
|
||||
class IDebugDraw;
|
||||
|
||||
/// CcdPhysicsEnvironment is experimental mainloop for physics simulation using optional continuous collision detection.
|
||||
@@ -62,7 +63,7 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
|
||||
|
||||
|
||||
public:
|
||||
CcdPhysicsEnvironment(CollisionDispatcher* dispatcher=0, BroadphaseInterface* broadphase=0);
|
||||
CcdPhysicsEnvironment(CollisionDispatcher* dispatcher=0, OverlappingPairCache* pairCache=0);
|
||||
|
||||
virtual ~CcdPhysicsEnvironment();
|
||||
|
||||
|
||||
295
Extras/PhysicsInterface/CcdPhysics/ParallelIslandDispatcher.cpp
Normal file
295
Extras/PhysicsInterface/CcdPhysics/ParallelIslandDispatcher.cpp
Normal file
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
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 "ParallelIslandDispatcher.h"
|
||||
|
||||
|
||||
#include "BroadphaseCollision/CollisionAlgorithm.h"
|
||||
#include "CollisionDispatch/ConvexConvexAlgorithm.h"
|
||||
#include "CollisionDispatch/EmptyCollisionAlgorithm.h"
|
||||
#include "CollisionDispatch/ConvexConcaveCollisionAlgorithm.h"
|
||||
#include "CollisionShapes/CollisionShape.h"
|
||||
#include "CollisionDispatch/CollisionObject.h"
|
||||
#include <algorithm>
|
||||
|
||||
static int gNumManifold2 = 0;
|
||||
|
||||
void ParallelIslandDispatcher::FindUnions()
|
||||
{
|
||||
if (m_useIslands)
|
||||
{
|
||||
for (int i=0;i<GetNumManifolds();i++)
|
||||
{
|
||||
const PersistentManifold* manifold = this->GetManifoldByIndexInternal(i);
|
||||
//static objects (invmass 0.f) don't merge !
|
||||
|
||||
const CollisionObject* colObj0 = static_cast<const CollisionObject*>(manifold->GetBody0());
|
||||
const CollisionObject* colObj1 = static_cast<const CollisionObject*>(manifold->GetBody1());
|
||||
|
||||
if (colObj0 && colObj1 && NeedsResponse(*colObj0,*colObj1))
|
||||
{
|
||||
if (((colObj0) && ((colObj0)->mergesSimulationIslands())) &&
|
||||
((colObj1) && ((colObj1)->mergesSimulationIslands())))
|
||||
{
|
||||
|
||||
m_unionFind.unite((colObj0)->m_islandTag1,
|
||||
(colObj1)->m_islandTag1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
ParallelIslandDispatcher::ParallelIslandDispatcher ():
|
||||
m_useIslands(true),
|
||||
m_defaultManifoldResult(0,0,0),
|
||||
m_count(0)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
|
||||
{
|
||||
for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
|
||||
{
|
||||
m_doubleDispatch[i][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
PersistentManifold* ParallelIslandDispatcher::GetNewManifold(void* b0,void* b1)
|
||||
{
|
||||
gNumManifold2++;
|
||||
|
||||
//ASSERT(gNumManifold < 65535);
|
||||
|
||||
|
||||
CollisionObject* body0 = (CollisionObject*)b0;
|
||||
CollisionObject* body1 = (CollisionObject*)b1;
|
||||
|
||||
PersistentManifold* manifold = new PersistentManifold (body0,body1);
|
||||
m_manifoldsPtr.push_back(manifold);
|
||||
|
||||
return manifold;
|
||||
}
|
||||
|
||||
void ParallelIslandDispatcher::ClearManifold(PersistentManifold* manifold)
|
||||
{
|
||||
manifold->ClearManifold();
|
||||
}
|
||||
|
||||
|
||||
void ParallelIslandDispatcher::ReleaseManifold(PersistentManifold* manifold)
|
||||
{
|
||||
|
||||
gNumManifold2--;
|
||||
|
||||
//printf("ReleaseManifold: gNumManifold2 %d\n",gNumManifold2);
|
||||
|
||||
ClearManifold(manifold);
|
||||
|
||||
std::vector<PersistentManifold*>::iterator i =
|
||||
std::find(m_manifoldsPtr.begin(), m_manifoldsPtr.end(), manifold);
|
||||
if (!(i == m_manifoldsPtr.end()))
|
||||
{
|
||||
std::swap(*i, m_manifoldsPtr.back());
|
||||
m_manifoldsPtr.pop_back();
|
||||
delete manifold;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// todo: this is random access, it can be walked 'cache friendly'!
|
||||
//
|
||||
void ParallelIslandDispatcher::BuildAndProcessIslands(CollisionObjectArray& collisionObjects, IslandCallback* callback)
|
||||
{
|
||||
int numBodies = collisionObjects.size();
|
||||
|
||||
for (int islandId=0;islandId<numBodies;islandId++)
|
||||
{
|
||||
|
||||
std::vector<PersistentManifold*> islandmanifold;
|
||||
|
||||
//int numSleeping = 0;
|
||||
|
||||
bool allSleeping = true;
|
||||
|
||||
int i;
|
||||
for (i=0;i<numBodies;i++)
|
||||
{
|
||||
CollisionObject* colObj0 = collisionObjects[i];
|
||||
if (colObj0->m_islandTag1 == islandId)
|
||||
{
|
||||
if (colObj0->GetActivationState()== ACTIVE_TAG)
|
||||
{
|
||||
allSleeping = false;
|
||||
}
|
||||
if (colObj0->GetActivationState()== DISABLE_DEACTIVATION)
|
||||
{
|
||||
allSleeping = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i=0;i<GetNumManifolds();i++)
|
||||
{
|
||||
PersistentManifold* manifold = this->GetManifoldByIndexInternal(i);
|
||||
|
||||
//filtering for response
|
||||
|
||||
CollisionObject* colObj0 = static_cast<CollisionObject*>(manifold->GetBody0());
|
||||
CollisionObject* colObj1 = static_cast<CollisionObject*>(manifold->GetBody1());
|
||||
{
|
||||
if (((colObj0) && (colObj0)->m_islandTag1 == (islandId)) ||
|
||||
((colObj1) && (colObj1)->m_islandTag1 == (islandId)))
|
||||
{
|
||||
|
||||
if (NeedsResponse(*colObj0,*colObj1))
|
||||
islandmanifold.push_back(manifold);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (allSleeping)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<numBodies;i++)
|
||||
{
|
||||
CollisionObject* colObj0 = collisionObjects[i];
|
||||
if (colObj0->m_islandTag1 == islandId)
|
||||
{
|
||||
colObj0->SetActivationState( ISLAND_SLEEPING );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Process the actual simulation, only if not sleeping/deactivated
|
||||
if (islandmanifold.size())
|
||||
{
|
||||
callback->ProcessIsland(&islandmanifold[0],islandmanifold.size());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
CollisionAlgorithm* ParallelIslandDispatcher::InternalFindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
|
||||
{
|
||||
m_count++;
|
||||
CollisionObject* body0 = (CollisionObject*)proxy0.m_clientObject;
|
||||
CollisionObject* body1 = (CollisionObject*)proxy1.m_clientObject;
|
||||
|
||||
CollisionAlgorithmConstructionInfo ci;
|
||||
ci.m_dispatcher = this;
|
||||
|
||||
if (body0->m_collisionShape->IsConvex() && body1->m_collisionShape->IsConvex() )
|
||||
{
|
||||
return new ConvexConvexAlgorithm(0,ci,&proxy0,&proxy1);
|
||||
}
|
||||
|
||||
if (body0->m_collisionShape->IsConvex() && body1->m_collisionShape->IsConcave())
|
||||
{
|
||||
return new ConvexConcaveCollisionAlgorithm(ci,&proxy0,&proxy1);
|
||||
}
|
||||
|
||||
if (body1->m_collisionShape->IsConvex() && body0->m_collisionShape->IsConcave())
|
||||
{
|
||||
return new ConvexConcaveCollisionAlgorithm(ci,&proxy1,&proxy0);
|
||||
}
|
||||
|
||||
//failed to find an algorithm
|
||||
return new EmptyAlgorithm(ci);
|
||||
|
||||
}
|
||||
|
||||
bool ParallelIslandDispatcher::NeedsResponse(const CollisionObject& colObj0,const CollisionObject& colObj1)
|
||||
{
|
||||
|
||||
|
||||
//here you can do filtering
|
||||
bool hasResponse =
|
||||
(!(colObj0.m_collisionFlags & CollisionObject::noContactResponse)) &&
|
||||
(!(colObj1.m_collisionFlags & CollisionObject::noContactResponse));
|
||||
hasResponse = hasResponse &&
|
||||
(colObj0.IsActive() || colObj1.IsActive());
|
||||
return hasResponse;
|
||||
}
|
||||
|
||||
bool ParallelIslandDispatcher::NeedsCollision(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
|
||||
{
|
||||
|
||||
CollisionObject* body0 = (CollisionObject*)proxy0.m_clientObject;
|
||||
CollisionObject* body1 = (CollisionObject*)proxy1.m_clientObject;
|
||||
|
||||
assert(body0);
|
||||
assert(body1);
|
||||
|
||||
bool needsCollision = true;
|
||||
|
||||
if ((body0->m_collisionFlags & CollisionObject::isStatic) &&
|
||||
(body1->m_collisionFlags & CollisionObject::isStatic))
|
||||
needsCollision = false;
|
||||
|
||||
if ((!body0->IsActive()) && (!body1->IsActive()))
|
||||
needsCollision = false;
|
||||
|
||||
return needsCollision ;
|
||||
|
||||
}
|
||||
|
||||
///allows the user to get contact point callbacks
|
||||
ManifoldResult* ParallelIslandDispatcher::GetNewManifoldResult(CollisionObject* obj0,CollisionObject* obj1,PersistentManifold* manifold)
|
||||
{
|
||||
|
||||
|
||||
//in-place, this prevents parallel dispatching, but just adding a list would fix that.
|
||||
ManifoldResult* manifoldResult = new (&m_defaultManifoldResult) ManifoldResult(obj0,obj1,manifold);
|
||||
return manifoldResult;
|
||||
}
|
||||
|
||||
///allows the user to get contact point callbacks
|
||||
void ParallelIslandDispatcher::ReleaseManifoldResult(ManifoldResult*)
|
||||
{
|
||||
|
||||
}
|
||||
126
Extras/PhysicsInterface/CcdPhysics/ParallelIslandDispatcher.h
Normal file
126
Extras/PhysicsInterface/CcdPhysics/ParallelIslandDispatcher.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef PARALLEL_ISLAND_DISPATCHER_H
|
||||
#define PARALLEL_ISLAND_DISPATCHER_H
|
||||
|
||||
#include "BroadphaseCollision/Dispatcher.h"
|
||||
#include "NarrowPhaseCollision/PersistentManifold.h"
|
||||
#include "CollisionDispatch/UnionFind.h"
|
||||
#include "CollisionDispatch/ManifoldResult.h"
|
||||
|
||||
#include "BroadphaseCollision/BroadphaseProxy.h"
|
||||
#include <vector>
|
||||
|
||||
class IDebugDraw;
|
||||
|
||||
|
||||
#include "CollisionDispatch/CollisionCreateFunc.h"
|
||||
|
||||
|
||||
|
||||
|
||||
///ParallelIslandDispatcher dispatches entire simulation islands in parallel.
|
||||
///For both collision detection and constraint solving.
|
||||
///This development heads toward multi-core, CELL SPU and GPU approach
|
||||
class ParallelIslandDispatcher : public Dispatcher
|
||||
{
|
||||
|
||||
std::vector<PersistentManifold*> m_manifoldsPtr;
|
||||
|
||||
UnionFind m_unionFind;
|
||||
|
||||
bool m_useIslands;
|
||||
|
||||
ManifoldResult m_defaultManifoldResult;
|
||||
|
||||
CollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
|
||||
|
||||
public:
|
||||
|
||||
UnionFind& GetUnionFind() { return m_unionFind;}
|
||||
|
||||
struct IslandCallback
|
||||
{
|
||||
virtual ~IslandCallback() {};
|
||||
|
||||
virtual void ProcessIsland(PersistentManifold** manifolds,int numManifolds) = 0;
|
||||
};
|
||||
|
||||
|
||||
int GetNumManifolds() const
|
||||
{
|
||||
return m_manifoldsPtr.size();
|
||||
}
|
||||
|
||||
PersistentManifold* GetManifoldByIndexInternal(int index)
|
||||
{
|
||||
return m_manifoldsPtr[index];
|
||||
}
|
||||
|
||||
const PersistentManifold* GetManifoldByIndexInternal(int index) const
|
||||
{
|
||||
return m_manifoldsPtr[index];
|
||||
}
|
||||
|
||||
void InitUnionFind(int n)
|
||||
{
|
||||
if (m_useIslands)
|
||||
m_unionFind.reset(n);
|
||||
}
|
||||
|
||||
void FindUnions();
|
||||
|
||||
int m_count;
|
||||
|
||||
ParallelIslandDispatcher ();
|
||||
virtual ~ParallelIslandDispatcher() {};
|
||||
|
||||
virtual PersistentManifold* GetNewManifold(void* b0,void* b1);
|
||||
|
||||
virtual void ReleaseManifold(PersistentManifold* manifold);
|
||||
|
||||
|
||||
virtual void BuildAndProcessIslands(CollisionObjectArray& collisionObjects, IslandCallback* callback);
|
||||
|
||||
///allows the user to get contact point callbacks
|
||||
virtual ManifoldResult* GetNewManifoldResult(CollisionObject* obj0,CollisionObject* obj1,PersistentManifold* manifold);
|
||||
|
||||
///allows the user to get contact point callbacks
|
||||
virtual void ReleaseManifoldResult(ManifoldResult*);
|
||||
|
||||
virtual void ClearManifold(PersistentManifold* manifold);
|
||||
|
||||
|
||||
CollisionAlgorithm* FindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
|
||||
{
|
||||
CollisionAlgorithm* algo = InternalFindAlgorithm(proxy0,proxy1);
|
||||
return algo;
|
||||
}
|
||||
|
||||
CollisionAlgorithm* InternalFindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1);
|
||||
|
||||
virtual bool NeedsCollision(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1);
|
||||
|
||||
virtual bool NeedsResponse(const CollisionObject& colObj0,const CollisionObject& colObj1);
|
||||
|
||||
virtual int GetUniqueId() { return RIGIDBODY_DISPATCHER;}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //PARALLEL_ISLAND_DISPATCHER_H
|
||||
|
||||
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
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 "ParallelPhysicsEnvironment.h"
|
||||
#include "CcdPhysicsController.h"
|
||||
#include "ParallelIslandDispatcher.h"
|
||||
|
||||
|
||||
ParallelPhysicsEnvironment::ParallelPhysicsEnvironment(ParallelIslandDispatcher* dispatcher, OverlappingPairCache* pairCache):
|
||||
CcdPhysicsEnvironment(0,pairCache)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ParallelPhysicsEnvironment::~ParallelPhysicsEnvironment()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Perform an integration step of duration 'timeStep'.
|
||||
bool ParallelPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
|
||||
{
|
||||
|
||||
/*
|
||||
//printf("CcdPhysicsEnvironment::proceedDeltaTime\n");
|
||||
|
||||
if (SimdFuzzyZero(timeStep))
|
||||
return true;
|
||||
|
||||
if (m_debugDrawer)
|
||||
{
|
||||
gDisableDeactivation = (m_debugDrawer->GetDebugMode() & IDebugDraw::DBG_NoDeactivation);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::beginBlock("SyncMotionStates");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
|
||||
//this is needed because scaling is not known in advance, and scaling has to propagate to the shape
|
||||
if (!m_scalingPropagated)
|
||||
{
|
||||
SyncMotionStates(timeStep);
|
||||
m_scalingPropagated = true;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::endBlock("SyncMotionStates");
|
||||
|
||||
Profiler::beginBlock("predictIntegratedTransform");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
{
|
||||
// std::vector<CcdPhysicsController*>::iterator i;
|
||||
|
||||
|
||||
|
||||
int k;
|
||||
for (k=0;k<GetNumControllers();k++)
|
||||
{
|
||||
CcdPhysicsController* ctrl = m_controllers[k];
|
||||
// SimdTransform predictedTrans;
|
||||
RigidBody* body = ctrl->GetRigidBody();
|
||||
if (body->IsActive())
|
||||
{
|
||||
if (!body->IsStatic())
|
||||
{
|
||||
body->applyForces( timeStep);
|
||||
body->integrateVelocities( timeStep);
|
||||
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::endBlock("predictIntegratedTransform");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
BroadphaseInterface* scene = GetBroadphase();
|
||||
|
||||
|
||||
//
|
||||
// collision detection (?)
|
||||
//
|
||||
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::beginBlock("DispatchAllCollisionPairs");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
|
||||
int numsubstep = m_numIterations;
|
||||
|
||||
|
||||
DispatcherInfo dispatchInfo;
|
||||
dispatchInfo.m_timeStep = timeStep;
|
||||
dispatchInfo.m_stepCount = 0;
|
||||
dispatchInfo.m_enableSatConvex = m_enableSatCollisionDetection;
|
||||
|
||||
scene->DispatchAllCollisionPairs(*GetDispatcher(),dispatchInfo);///numsubstep,g);
|
||||
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::endBlock("DispatchAllCollisionPairs");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
|
||||
int numRigidBodies = m_controllers.size();
|
||||
|
||||
m_collisionWorld->UpdateActivationState();
|
||||
|
||||
{
|
||||
int i;
|
||||
int numConstraints = m_constraints.size();
|
||||
for (i=0;i< numConstraints ; i++ )
|
||||
{
|
||||
TypedConstraint* constraint = m_constraints[i];
|
||||
|
||||
const RigidBody* colObj0 = &constraint->GetRigidBodyA();
|
||||
const RigidBody* colObj1 = &constraint->GetRigidBodyB();
|
||||
|
||||
if (((colObj0) && ((colObj0)->mergesSimulationIslands())) &&
|
||||
((colObj1) && ((colObj1)->mergesSimulationIslands())))
|
||||
{
|
||||
if (colObj0->IsActive() || colObj1->IsActive())
|
||||
{
|
||||
GetDispatcher()->GetUnionFind().unite((colObj0)->m_islandTag1,
|
||||
(colObj1)->m_islandTag1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_collisionWorld->StoreIslandActivationState();
|
||||
|
||||
|
||||
|
||||
//contacts
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::beginBlock("SolveConstraint");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
|
||||
//solve the regular constraints (point 2 point, hinge, etc)
|
||||
|
||||
for (int g=0;g<numsubstep;g++)
|
||||
{
|
||||
//
|
||||
// constraint solving
|
||||
//
|
||||
|
||||
|
||||
int i;
|
||||
int numConstraints = m_constraints.size();
|
||||
|
||||
//point to point constraints
|
||||
for (i=0;i< numConstraints ; i++ )
|
||||
{
|
||||
TypedConstraint* constraint = m_constraints[i];
|
||||
|
||||
constraint->BuildJacobian();
|
||||
constraint->SolveConstraint( timeStep );
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::endBlock("SolveConstraint");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
//solve the vehicles
|
||||
|
||||
#ifdef NEW_BULLET_VEHICLE_SUPPORT
|
||||
//vehicles
|
||||
int numVehicles = m_wrapperVehicles.size();
|
||||
for (int i=0;i<numVehicles;i++)
|
||||
{
|
||||
WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i];
|
||||
RaycastVehicle* vehicle = wrapperVehicle->GetVehicle();
|
||||
vehicle->UpdateVehicle( timeStep);
|
||||
}
|
||||
#endif //NEW_BULLET_VEHICLE_SUPPORT
|
||||
|
||||
|
||||
struct InplaceSolverIslandCallback : public ParallelIslandDispatcher::IslandCallback
|
||||
{
|
||||
|
||||
ContactSolverInfo& m_solverInfo;
|
||||
ConstraintSolver* m_solver;
|
||||
IDebugDraw* m_debugDrawer;
|
||||
|
||||
InplaceSolverIslandCallback(
|
||||
ContactSolverInfo& solverInfo,
|
||||
ConstraintSolver* solver,
|
||||
IDebugDraw* debugDrawer)
|
||||
:m_solverInfo(solverInfo),
|
||||
m_solver(solver),
|
||||
m_debugDrawer(debugDrawer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void ProcessIsland(PersistentManifold** manifolds,int numManifolds)
|
||||
{
|
||||
m_solver->SolveGroup( manifolds, numManifolds,m_solverInfo,m_debugDrawer);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
m_solverInfo.m_friction = 0.9f;
|
||||
m_solverInfo.m_numIterations = m_numIterations;
|
||||
m_solverInfo.m_timeStep = timeStep;
|
||||
m_solverInfo.m_restitution = 0.f;//m_restitution;
|
||||
|
||||
InplaceSolverIslandCallback solverCallback(
|
||||
m_solverInfo,
|
||||
m_solver,
|
||||
m_debugDrawer);
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::beginBlock("BuildAndProcessIslands");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
/// solve all the contact points and contact friction
|
||||
GetDispatcher()->BuildAndProcessIslands(m_collisionWorld->GetCollisionObjectArray(),&solverCallback);
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::endBlock("BuildAndProcessIslands");
|
||||
|
||||
Profiler::beginBlock("CallbackTriggers");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
CallbackTriggers();
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::endBlock("CallbackTriggers");
|
||||
|
||||
|
||||
Profiler::beginBlock("proceedToTransform");
|
||||
|
||||
#endif //USE_QUICKPROF
|
||||
{
|
||||
|
||||
|
||||
|
||||
{
|
||||
|
||||
|
||||
|
||||
UpdateAabbs(timeStep);
|
||||
|
||||
|
||||
float toi = 1.f;
|
||||
|
||||
|
||||
|
||||
if (m_ccdMode == 3)
|
||||
{
|
||||
DispatcherInfo dispatchInfo;
|
||||
dispatchInfo.m_timeStep = timeStep;
|
||||
dispatchInfo.m_stepCount = 0;
|
||||
dispatchInfo.m_dispatchFunc = DispatcherInfo::DISPATCH_CONTINUOUS;
|
||||
|
||||
scene->DispatchAllCollisionPairs( *GetDispatcher(),dispatchInfo);///numsubstep,g);
|
||||
toi = dispatchInfo.m_timeOfImpact;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// integrating solution
|
||||
//
|
||||
|
||||
{
|
||||
|
||||
std::vector<CcdPhysicsController*>::iterator i;
|
||||
|
||||
for (i=m_controllers.begin();
|
||||
!(i==m_controllers.end()); i++)
|
||||
{
|
||||
|
||||
CcdPhysicsController* ctrl = *i;
|
||||
|
||||
SimdTransform predictedTrans;
|
||||
RigidBody* body = ctrl->GetRigidBody();
|
||||
|
||||
if (body->IsActive())
|
||||
{
|
||||
|
||||
if (!body->IsStatic())
|
||||
{
|
||||
body->predictIntegratedTransform(timeStep* toi, predictedTrans);
|
||||
body->proceedToTransform( predictedTrans);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// disable sleeping physics objects
|
||||
//
|
||||
|
||||
std::vector<CcdPhysicsController*> m_sleepingControllers;
|
||||
|
||||
std::vector<CcdPhysicsController*>::iterator i;
|
||||
|
||||
for (i=m_controllers.begin();
|
||||
!(i==m_controllers.end()); i++)
|
||||
{
|
||||
CcdPhysicsController* ctrl = (*i);
|
||||
RigidBody* body = ctrl->GetRigidBody();
|
||||
|
||||
ctrl->UpdateDeactivation(timeStep);
|
||||
|
||||
|
||||
if (ctrl->wantsSleeping())
|
||||
{
|
||||
if (body->GetActivationState() == ACTIVE_TAG)
|
||||
body->SetActivationState( WANTS_DEACTIVATION );
|
||||
} else
|
||||
{
|
||||
if (body->GetActivationState() != DISABLE_DEACTIVATION)
|
||||
body->SetActivationState( ACTIVE_TAG );
|
||||
}
|
||||
|
||||
if (useIslands)
|
||||
{
|
||||
if (body->GetActivationState() == ISLAND_SLEEPING)
|
||||
{
|
||||
m_sleepingControllers.push_back(ctrl);
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (ctrl->wantsSleeping())
|
||||
{
|
||||
m_sleepingControllers.push_back(ctrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::endBlock("proceedToTransform");
|
||||
|
||||
Profiler::beginBlock("SyncMotionStates");
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
SyncMotionStates(timeStep);
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
Profiler::endBlock("SyncMotionStates");
|
||||
|
||||
Profiler::endProfilingCycle();
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
|
||||
#ifdef NEW_BULLET_VEHICLE_SUPPORT
|
||||
//sync wheels for vehicles
|
||||
int numVehicles = m_wrapperVehicles.size();
|
||||
for (int i=0;i<numVehicles;i++)
|
||||
{
|
||||
WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i];
|
||||
|
||||
wrapperVehicle->SyncWheels();
|
||||
}
|
||||
#endif //NEW_BULLET_VEHICLE_SUPPORT
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef PARALLELPHYSICSENVIRONMENT
|
||||
#define PARALLELPHYSICSENVIRONMENT
|
||||
|
||||
#include "CcdPhysicsEnvironment.h"
|
||||
class ParallelIslandDispatcher;
|
||||
|
||||
|
||||
/// ParallelPhysicsEnvironment is experimental parallel mainloop for physics simulation
|
||||
/// Physics Environment takes care of stepping the simulation and is a container for physics entities.
|
||||
/// It stores rigidbodies,constraints, materials etc.
|
||||
/// A derived class may be able to 'construct' entities by loading and/or converting
|
||||
class ParallelPhysicsEnvironment : public CcdPhysicsEnvironment
|
||||
{
|
||||
|
||||
|
||||
public:
|
||||
ParallelPhysicsEnvironment(ParallelIslandDispatcher* dispatcher=0, OverlappingPairCache* pairCache=0);
|
||||
|
||||
virtual ~ParallelPhysicsEnvironment();
|
||||
|
||||
|
||||
/// Perform an integration step of duration 'timeStep'.
|
||||
bool proceedDeltaTimeOneStep(float timeStep);
|
||||
|
||||
};
|
||||
|
||||
#endif //PARALLELPHYSICSENVIRONMENT
|
||||
Reference in New Issue
Block a user