constraints between bodies merge constraint simulations (this fixes problems with deactivation/sleeping)

This commit is contained in:
ejcoumans
2006-06-17 15:22:06 +00:00
parent f73244b36a
commit 51a645bb4a
5 changed files with 90 additions and 54 deletions

View File

@@ -122,8 +122,10 @@ void CollisionDispatcher::ReleaseManifold(PersistentManifold* manifold)
// //
// todo: this is random access, it can be walked 'cache friendly'! // todo: this is random access, it can be walked 'cache friendly'!
// //
void CollisionDispatcher::BuildAndProcessIslands(int numBodies, IslandCallback* callback) void CollisionDispatcher::BuildAndProcessIslands(CollisionObjectArray& collisionObjects, IslandCallback* callback)
{ {
int numBodies = collisionObjects.size();
for (int islandId=0;islandId<numBodies;islandId++) for (int islandId=0;islandId<numBodies;islandId++)
{ {
@@ -133,7 +135,25 @@ void CollisionDispatcher::BuildAndProcessIslands(int numBodies, IslandCallback*
bool allSleeping = true; bool allSleeping = true;
for (int i=0;i<GetNumManifolds();i++) 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); PersistentManifold* manifold = this->GetManifoldByIndexInternal(i);
@@ -141,25 +161,11 @@ void CollisionDispatcher::BuildAndProcessIslands(int numBodies, IslandCallback*
CollisionObject* colObj0 = static_cast<CollisionObject*>(manifold->GetBody0()); CollisionObject* colObj0 = static_cast<CollisionObject*>(manifold->GetBody0());
CollisionObject* colObj1 = static_cast<CollisionObject*>(manifold->GetBody1()); CollisionObject* colObj1 = static_cast<CollisionObject*>(manifold->GetBody1());
{ {
if (((colObj0) && (colObj0)->m_islandTag1 == (islandId)) || if (((colObj0) && (colObj0)->m_islandTag1 == (islandId)) ||
((colObj1) && (colObj1)->m_islandTag1 == (islandId))) ((colObj1) && (colObj1)->m_islandTag1 == (islandId)))
{ {
if (((colObj0) && (colObj0)->GetActivationState()== ACTIVE_TAG) ||
((colObj1) && (colObj1)->GetActivationState() == ACTIVE_TAG))
{
allSleeping = false;
}
if (((colObj0) && (colObj0)->GetActivationState()== DISABLE_DEACTIVATION) ||
((colObj1) && (colObj1)->GetActivationState() == DISABLE_DEACTIVATION))
{
allSleeping = false;
}
if (NeedsResponse(*colObj0,*colObj1)) if (NeedsResponse(*colObj0,*colObj1))
islandmanifold.push_back(manifold); islandmanifold.push_back(manifold);
} }
@@ -167,51 +173,34 @@ void CollisionDispatcher::BuildAndProcessIslands(int numBodies, IslandCallback*
} }
if (allSleeping) if (allSleeping)
{ {
//tag all as 'ISLAND_SLEEPING' int i;
for (size_t i=0;i<islandmanifold.size();i++) for (i=0;i<numBodies;i++)
{ {
PersistentManifold* manifold = islandmanifold[i]; CollisionObject* colObj0 = collisionObjects[i];
if (colObj0->m_islandTag1 == islandId)
CollisionObject* colObj0 = static_cast<CollisionObject*>(manifold->GetBody0());
CollisionObject* colObj1 = static_cast<CollisionObject*>(manifold->GetBody1());
if ((colObj0))
{ {
(colObj0)->SetActivationState( ISLAND_SLEEPING ); colObj0->SetActivationState( ISLAND_SLEEPING );
} }
if ((colObj1))
{
(colObj1)->SetActivationState( ISLAND_SLEEPING);
} }
}
} else } else
{ {
//tag all as 'ISLAND_SLEEPING' int i;
for (size_t i=0;i<islandmanifold.size();i++) for (i=0;i<numBodies;i++)
{ {
PersistentManifold* manifold = islandmanifold[i]; CollisionObject* colObj0 = collisionObjects[i];
CollisionObject* body0 = (CollisionObject*)manifold->GetBody0(); if (colObj0->m_islandTag1 == islandId)
CollisionObject* body1 = (CollisionObject*)manifold->GetBody1();
if (body0)
{ {
if ( body0->GetActivationState() == ISLAND_SLEEPING) if ( colObj0->GetActivationState() == ISLAND_SLEEPING)
{ {
body0->SetActivationState( WANTS_DEACTIVATION); colObj0->SetActivationState( WANTS_DEACTIVATION);
} }
} }
if (body1)
{
if ( body1->GetActivationState() == ISLAND_SLEEPING)
{
body1->SetActivationState(WANTS_DEACTIVATION);
}
}
} }
/// Process the actual simulation, only if not sleeping/deactivated
if (islandmanifold.size()) if (islandmanifold.size())
{ {
callback->ProcessIsland(&islandmanifold[0],islandmanifold.size()); callback->ProcessIsland(&islandmanifold[0],islandmanifold.size());

View File

@@ -26,7 +26,7 @@ subject to the following restrictions:
class IDebugDraw; class IDebugDraw;
typedef std::vector<struct CollisionObject*> CollisionObjectArray;
struct CollisionAlgorithmCreateFunc struct CollisionAlgorithmCreateFunc
@@ -106,7 +106,7 @@ public:
virtual void ReleaseManifold(PersistentManifold* manifold); virtual void ReleaseManifold(PersistentManifold* manifold);
virtual void BuildAndProcessIslands(int numBodies, IslandCallback* callback); virtual void BuildAndProcessIslands(CollisionObjectArray& collisionObjects, IslandCallback* callback);
///allows the user to get contact point callbacks ///allows the user to get contact point callbacks
virtual ManifoldResult* GetNewManifoldResult(CollisionObject* obj0,CollisionObject* obj1,PersistentManifold* manifold); virtual ManifoldResult* GetNewManifoldResult(CollisionObject* obj0,CollisionObject* obj1,PersistentManifold* manifold);

View File

@@ -76,6 +76,14 @@ void CollisionWorld::UpdateActivationState()
m_dispatcher->FindUnions(); m_dispatcher->FindUnions();
}
void CollisionWorld::StoreIslandActivationState()
{
// put the islandId ('find' value) into m_tag // put the islandId ('find' value) into m_tag
{ {
UnionFind& unionFind = m_dispatcher->GetUnionFind(); UnionFind& unionFind = m_dispatcher->GetUnionFind();
@@ -98,7 +106,6 @@ void CollisionWorld::UpdateActivationState()
index++; index++;
} }
} }
} }

View File

@@ -13,6 +13,7 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
/** /**
* @mainpage Bullet Documentation * @mainpage Bullet Documentation
* *
@@ -57,19 +58,23 @@ subject to the following restrictions:
* *
*/ */
#ifndef COLLISION_WORLD_H #ifndef COLLISION_WORLD_H
#define COLLISION_WORLD_H #define COLLISION_WORLD_H
class CollisionShape; class CollisionShape;
class CollisionDispatcher;
class BroadphaseInterface; class BroadphaseInterface;
#include "SimdVector3.h" #include "SimdVector3.h"
#include "SimdTransform.h" #include "SimdTransform.h"
#include "CollisionObject.h" #include "CollisionObject.h"
#include "CollisionDispatcher.h" //for definition of CollisionObjectArray
#include <vector> #include <vector>
///CollisionWorld is interface and container for the collision detection ///CollisionWorld is interface and container for the collision detection
class CollisionWorld class CollisionWorld
{ {
@@ -93,6 +98,7 @@ public:
virtual ~CollisionWorld(); virtual ~CollisionWorld();
virtual void UpdateActivationState(); virtual void UpdateActivationState();
virtual void StoreIslandActivationState();
BroadphaseInterface* GetBroadphase() BroadphaseInterface* GetBroadphase()
{ {
@@ -197,6 +203,17 @@ public:
void AddCollisionObject(CollisionObject* collisionObject); void AddCollisionObject(CollisionObject* collisionObject);
CollisionObjectArray& GetCollisionObjectArray()
{
return m_collisionObjects;
}
const CollisionObjectArray& GetCollisionObjectArray() const
{
return m_collisionObjects;
}
void RemoveCollisionObject(CollisionObject* collisionObject); void RemoveCollisionObject(CollisionObject* collisionObject);
virtual void PerformDiscreteCollisionDetection(); virtual void PerformDiscreteCollisionDetection();

View File

@@ -80,8 +80,6 @@ RaycastVehicle::VehicleTuning gTuning;
#include "ConstraintSolver/Generic6DofConstraint.h" #include "ConstraintSolver/Generic6DofConstraint.h"
//#include "BroadphaseCollision/QueryDispatcher.h" //#include "BroadphaseCollision/QueryDispatcher.h"
//#include "BroadphaseCollision/QueryBox.h" //#include "BroadphaseCollision/QueryBox.h"
//todo: change this to allow dynamic registration of types! //todo: change this to allow dynamic registration of types!
@@ -506,6 +504,10 @@ void CcdPhysicsEnvironment::beginFrame()
bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep) bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
{ {
//don't simulate without timesubsteps
if (m_numTimeSubSteps<1)
return true;
//printf("proceedDeltaTime\n"); //printf("proceedDeltaTime\n");
@@ -686,6 +688,27 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
m_collisionWorld->UpdateActivationState(); m_collisionWorld->UpdateActivationState();
{
int i;
int numConstraints = m_constraints.size();
for (i=0;i< numConstraints ; i++ )
{
TypedConstraint* constraint = m_constraints[i];
const CollisionObject* colObj0 = &constraint->GetRigidBodyA();
const CollisionObject* colObj1 = &constraint->GetRigidBodyB();
if (((colObj0) && ((colObj0)->mergesSimulationIslands())) &&
((colObj1) && ((colObj1)->mergesSimulationIslands())))
{
GetDispatcher()->GetUnionFind().unite((colObj0)->m_islandTag1,
(colObj1)->m_islandTag1);
}
}
}
m_collisionWorld->StoreIslandActivationState();
//contacts //contacts
@@ -778,7 +801,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
#endif //USE_QUICKPROF #endif //USE_QUICKPROF
/// solve all the contact points and contact friction /// solve all the contact points and contact friction
GetDispatcher()->BuildAndProcessIslands(numRigidBodies,&solverCallback); GetDispatcher()->BuildAndProcessIslands(m_collisionWorld->GetCollisionObjectArray(),&solverCallback);
#ifdef USE_QUICKPROF #ifdef USE_QUICKPROF
Profiler::endBlock("BuildAndProcessIslands"); Profiler::endBlock("BuildAndProcessIslands");