Code-style consistency improvement:

Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files.
make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type.
This commit contains no other changes aside from adding and applying clang-format-all.sh
This commit is contained in:
erwincoumans
2018-09-23 14:17:31 -07:00
parent b73b05e9fb
commit ab8f16961e
1773 changed files with 1081087 additions and 474249 deletions

View File

@@ -26,21 +26,16 @@ class btCollisionWorld;
class btActionInterface
{
protected:
static btRigidBody& getFixedBody();
public:
public:
virtual ~btActionInterface()
{
}
virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTimeStep)=0;
virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) = 0;
virtual void debugDraw(btIDebugDraw* debugDrawer) = 0;
};
#endif //_BT_ACTION_INTERFACE_H
#endif //_BT_ACTION_INTERFACE_H

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,6 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_DISCRETE_DYNAMICS_WORLD_H
#define BT_DISCRETE_DYNAMICS_WORLD_H
@@ -32,159 +31,153 @@ struct InplaceSolverIslandCallback;
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btThreads.h"
///btDiscreteDynamicsWorld provides discrete rigid body simulation
///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController
ATTRIBUTE_ALIGNED16(class) btDiscreteDynamicsWorld : public btDynamicsWorld
ATTRIBUTE_ALIGNED16(class)
btDiscreteDynamicsWorld : public btDynamicsWorld
{
protected:
btAlignedObjectArray<btTypedConstraint*> m_sortedConstraints;
InplaceSolverIslandCallback* m_solverIslandCallback;
btAlignedObjectArray<btTypedConstraint*> m_sortedConstraints;
InplaceSolverIslandCallback* m_solverIslandCallback;
btConstraintSolver* m_constraintSolver;
btConstraintSolver* m_constraintSolver;
btSimulationIslandManager* m_islandManager;
btSimulationIslandManager* m_islandManager;
btAlignedObjectArray<btTypedConstraint*> m_constraints;
btAlignedObjectArray<btRigidBody*> m_nonStaticRigidBodies;
btVector3 m_gravity;
btVector3 m_gravity;
//for variable timesteps
btScalar m_localTime;
btScalar m_fixedTimeStep;
btScalar m_localTime;
btScalar m_fixedTimeStep;
//for variable timesteps
bool m_ownsIslandManager;
bool m_ownsConstraintSolver;
bool m_synchronizeAllMotionStates;
bool m_applySpeculativeContactRestitution;
bool m_ownsIslandManager;
bool m_ownsConstraintSolver;
bool m_synchronizeAllMotionStates;
bool m_applySpeculativeContactRestitution;
btAlignedObjectArray<btActionInterface*> m_actions;
int m_profileTimings;
btAlignedObjectArray<btActionInterface*> m_actions;
bool m_latencyMotionStateInterpolation;
int m_profileTimings;
btAlignedObjectArray<btPersistentManifold*> m_predictiveManifolds;
btSpinMutex m_predictiveManifoldsMutex; // used to synchronize threads creating predictive contacts
bool m_latencyMotionStateInterpolation;
virtual void predictUnconstraintMotion(btScalar timeStep);
void integrateTransformsInternal( btRigidBody** bodies, int numBodies, btScalar timeStep ); // can be called in parallel
virtual void integrateTransforms(btScalar timeStep);
virtual void calculateSimulationIslands();
btAlignedObjectArray<btPersistentManifold*> m_predictiveManifolds;
btSpinMutex m_predictiveManifoldsMutex; // used to synchronize threads creating predictive contacts
virtual void solveConstraints(btContactSolverInfo& solverInfo);
virtual void updateActivationState(btScalar timeStep);
virtual void predictUnconstraintMotion(btScalar timeStep);
void updateActions(btScalar timeStep);
void integrateTransformsInternal(btRigidBody * *bodies, int numBodies, btScalar timeStep); // can be called in parallel
virtual void integrateTransforms(btScalar timeStep);
void startProfiling(btScalar timeStep);
virtual void calculateSimulationIslands();
virtual void internalSingleStepSimulation( btScalar timeStep);
virtual void solveConstraints(btContactSolverInfo & solverInfo);
void releasePredictiveContacts();
void createPredictiveContactsInternal( btRigidBody** bodies, int numBodies, btScalar timeStep ); // can be called in parallel
virtual void createPredictiveContacts(btScalar timeStep);
virtual void updateActivationState(btScalar timeStep);
virtual void saveKinematicState(btScalar timeStep);
void updateActions(btScalar timeStep);
void serializeRigidBodies(btSerializer* serializer);
void startProfiling(btScalar timeStep);
void serializeDynamicsWorldInfo(btSerializer* serializer);
virtual void internalSingleStepSimulation(btScalar timeStep);
void releasePredictiveContacts();
void createPredictiveContactsInternal(btRigidBody * *bodies, int numBodies, btScalar timeStep); // can be called in parallel
virtual void createPredictiveContacts(btScalar timeStep);
virtual void saveKinematicState(btScalar timeStep);
void serializeRigidBodies(btSerializer * serializer);
void serializeDynamicsWorldInfo(btSerializer * serializer);
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those
btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
btDiscreteDynamicsWorld(btDispatcher * dispatcher, btBroadphaseInterface * pairCache, btConstraintSolver * constraintSolver, btCollisionConfiguration * collisionConfiguration);
virtual ~btDiscreteDynamicsWorld();
///if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's
virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
virtual int stepSimulation(btScalar timeStep, int maxSubSteps = 1, btScalar fixedTimeStep = btScalar(1.) / btScalar(60.));
virtual void synchronizeMotionStates();
virtual void synchronizeMotionStates();
///this can be useful to synchronize a single rigid body -> graphics object
void synchronizeSingleMotionState(btRigidBody* body);
void synchronizeSingleMotionState(btRigidBody * body);
virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false);
virtual void addConstraint(btTypedConstraint * constraint, bool disableCollisionsBetweenLinkedBodies = false);
virtual void removeConstraint(btTypedConstraint* constraint);
virtual void removeConstraint(btTypedConstraint * constraint);
virtual void addAction(btActionInterface*);
virtual void addAction(btActionInterface*);
virtual void removeAction(btActionInterface*);
btSimulationIslandManager* getSimulationIslandManager()
virtual void removeAction(btActionInterface*);
btSimulationIslandManager* getSimulationIslandManager()
{
return m_islandManager;
}
const btSimulationIslandManager* getSimulationIslandManager() const
const btSimulationIslandManager* getSimulationIslandManager() const
{
return m_islandManager;
}
btCollisionWorld* getCollisionWorld()
btCollisionWorld* getCollisionWorld()
{
return this;
}
virtual void setGravity(const btVector3& gravity);
virtual void setGravity(const btVector3& gravity);
virtual btVector3 getGravity () const;
virtual btVector3 getGravity() const;
virtual void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup=btBroadphaseProxy::StaticFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
virtual void addCollisionObject(btCollisionObject * collisionObject, int collisionFilterGroup = btBroadphaseProxy::StaticFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
virtual void addRigidBody(btRigidBody* body);
virtual void addRigidBody(btRigidBody * body);
virtual void addRigidBody(btRigidBody* body, int group, int mask);
virtual void addRigidBody(btRigidBody * body, int group, int mask);
virtual void removeRigidBody(btRigidBody* body);
virtual void removeRigidBody(btRigidBody * body);
///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btCollisionWorld::removeCollisionObject
virtual void removeCollisionObject(btCollisionObject* collisionObject);
virtual void removeCollisionObject(btCollisionObject * collisionObject);
virtual void debugDrawConstraint(btTypedConstraint * constraint);
virtual void debugDrawConstraint(btTypedConstraint* constraint);
virtual void debugDrawWorld();
virtual void debugDrawWorld();
virtual void setConstraintSolver(btConstraintSolver* solver);
virtual void setConstraintSolver(btConstraintSolver * solver);
virtual btConstraintSolver* getConstraintSolver();
virtual int getNumConstraints() const;
virtual btTypedConstraint* getConstraint(int index) ;
virtual int getNumConstraints() const;
virtual btTypedConstraint* getConstraint(int index);
virtual const btTypedConstraint* getConstraint(int index) const;
virtual btDynamicsWorldType getWorldType() const
virtual btDynamicsWorldType getWorldType() const
{
return BT_DISCRETE_DYNAMICS_WORLD;
}
///the forces on each rigidbody is accumulating together with gravity. clear this after each timestep.
virtual void clearForces();
virtual void clearForces();
///apply gravity, call this once per timestep
virtual void applyGravity();
virtual void applyGravity();
virtual void setNumTasks(int numTasks)
virtual void setNumTasks(int numTasks)
{
(void) numTasks;
(void)numTasks;
}
///obsolete, use updateActions instead
@@ -194,15 +187,15 @@ public:
}
///obsolete, use addAction instead
virtual void addVehicle(btActionInterface* vehicle);
virtual void addVehicle(btActionInterface * vehicle);
///obsolete, use removeAction instead
virtual void removeVehicle(btActionInterface* vehicle);
virtual void removeVehicle(btActionInterface * vehicle);
///obsolete, use addAction instead
virtual void addCharacter(btActionInterface* character);
virtual void addCharacter(btActionInterface * character);
///obsolete, use removeAction instead
virtual void removeCharacter(btActionInterface* character);
virtual void removeCharacter(btActionInterface * character);
void setSynchronizeAllMotionStates(bool synchronizeAll)
void setSynchronizeAllMotionStates(bool synchronizeAll)
{
m_synchronizeAllMotionStates = synchronizeAll;
}
@@ -215,18 +208,18 @@ public:
{
m_applySpeculativeContactRestitution = enable;
}
bool getApplySpeculativeContactRestitution() const
{
return m_applySpeculativeContactRestitution;
}
///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see Bullet/Demos/SerializeDemo)
virtual void serialize(btSerializer* serializer);
virtual void serialize(btSerializer * serializer);
///Interpolate motion state between previous and current transform, instead of current and next transform.
///This can relieve discontinuities in the rendering, due to penetrations
void setLatencyMotionStateInterpolation(bool latencyInterpolation )
void setLatencyMotionStateInterpolation(bool latencyInterpolation)
{
m_latencyMotionStateInterpolation = latencyInterpolation;
}
@@ -236,4 +229,4 @@ public:
}
};
#endif //BT_DISCRETE_DYNAMICS_WORLD_H
#endif //BT_DISCRETE_DYNAMICS_WORLD_H

View File

@@ -13,7 +13,6 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "btDiscreteDynamicsWorldMt.h"
//collision detection
@@ -38,148 +37,139 @@ subject to the following restrictions:
#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
#include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
#include "LinearMath/btIDebugDraw.h"
#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletDynamics/Dynamics/btActionInterface.h"
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btMotionState.h"
#include "LinearMath/btSerializer.h"
///
/// btConstraintSolverPoolMt
///
btConstraintSolverPoolMt::ThreadSolver* btConstraintSolverPoolMt::getAndLockThreadSolver()
{
int i = 0;
int i = 0;
#if BT_THREADSAFE
i = btGetCurrentThreadIndex() % m_solvers.size();
#endif // #if BT_THREADSAFE
while ( true )
{
ThreadSolver& solver = m_solvers[ i ];
if ( solver.mutex.tryLock() )
{
return &solver;
}
// failed, try the next one
i = ( i + 1 ) % m_solvers.size();
}
return NULL;
i = btGetCurrentThreadIndex() % m_solvers.size();
#endif // #if BT_THREADSAFE
while (true)
{
ThreadSolver& solver = m_solvers[i];
if (solver.mutex.tryLock())
{
return &solver;
}
// failed, try the next one
i = (i + 1) % m_solvers.size();
}
return NULL;
}
void btConstraintSolverPoolMt::init( btConstraintSolver** solvers, int numSolvers )
void btConstraintSolverPoolMt::init(btConstraintSolver** solvers, int numSolvers)
{
m_solverType = BT_SEQUENTIAL_IMPULSE_SOLVER;
m_solvers.resize( numSolvers );
for ( int i = 0; i < numSolvers; ++i )
{
m_solvers[ i ].solver = solvers[ i ];
}
if ( numSolvers > 0 )
{
m_solverType = solvers[ 0 ]->getSolverType();
}
m_solverType = BT_SEQUENTIAL_IMPULSE_SOLVER;
m_solvers.resize(numSolvers);
for (int i = 0; i < numSolvers; ++i)
{
m_solvers[i].solver = solvers[i];
}
if (numSolvers > 0)
{
m_solverType = solvers[0]->getSolverType();
}
}
// create the solvers for me
btConstraintSolverPoolMt::btConstraintSolverPoolMt( int numSolvers )
btConstraintSolverPoolMt::btConstraintSolverPoolMt(int numSolvers)
{
btAlignedObjectArray<btConstraintSolver*> solvers;
solvers.reserve( numSolvers );
for ( int i = 0; i < numSolvers; ++i )
{
btConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
solvers.push_back( solver );
}
init( &solvers[ 0 ], numSolvers );
btAlignedObjectArray<btConstraintSolver*> solvers;
solvers.reserve(numSolvers);
for (int i = 0; i < numSolvers; ++i)
{
btConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
solvers.push_back(solver);
}
init(&solvers[0], numSolvers);
}
// pass in fully constructed solvers (destructor will delete them)
btConstraintSolverPoolMt::btConstraintSolverPoolMt( btConstraintSolver** solvers, int numSolvers )
btConstraintSolverPoolMt::btConstraintSolverPoolMt(btConstraintSolver** solvers, int numSolvers)
{
init( solvers, numSolvers );
init(solvers, numSolvers);
}
btConstraintSolverPoolMt::~btConstraintSolverPoolMt()
{
// delete all solvers
for ( int i = 0; i < m_solvers.size(); ++i )
{
ThreadSolver& solver = m_solvers[ i ];
delete solver.solver;
solver.solver = NULL;
}
// delete all solvers
for (int i = 0; i < m_solvers.size(); ++i)
{
ThreadSolver& solver = m_solvers[i];
delete solver.solver;
solver.solver = NULL;
}
}
///solve a group of constraints
btScalar btConstraintSolverPoolMt::solveGroup( btCollisionObject** bodies,
int numBodies,
btPersistentManifold** manifolds,
int numManifolds,
btTypedConstraint** constraints,
int numConstraints,
const btContactSolverInfo& info,
btIDebugDraw* debugDrawer,
btDispatcher* dispatcher
)
btScalar btConstraintSolverPoolMt::solveGroup(btCollisionObject** bodies,
int numBodies,
btPersistentManifold** manifolds,
int numManifolds,
btTypedConstraint** constraints,
int numConstraints,
const btContactSolverInfo& info,
btIDebugDraw* debugDrawer,
btDispatcher* dispatcher)
{
ThreadSolver* ts = getAndLockThreadSolver();
ts->solver->solveGroup( bodies, numBodies, manifolds, numManifolds, constraints, numConstraints, info, debugDrawer, dispatcher );
ts->mutex.unlock();
return 0.0f;
ThreadSolver* ts = getAndLockThreadSolver();
ts->solver->solveGroup(bodies, numBodies, manifolds, numManifolds, constraints, numConstraints, info, debugDrawer, dispatcher);
ts->mutex.unlock();
return 0.0f;
}
void btConstraintSolverPoolMt::reset()
{
for ( int i = 0; i < m_solvers.size(); ++i )
{
ThreadSolver& solver = m_solvers[ i ];
solver.mutex.lock();
solver.solver->reset();
solver.mutex.unlock();
}
for (int i = 0; i < m_solvers.size(); ++i)
{
ThreadSolver& solver = m_solvers[i];
solver.mutex.lock();
solver.solver->reset();
solver.mutex.unlock();
}
}
///
/// btDiscreteDynamicsWorldMt
///
btDiscreteDynamicsWorldMt::btDiscreteDynamicsWorldMt(btDispatcher* dispatcher,
btBroadphaseInterface* pairCache,
btConstraintSolverPoolMt* constraintSolver,
btConstraintSolver* constraintSolverMt,
btCollisionConfiguration* collisionConfiguration
)
: btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration)
btBroadphaseInterface* pairCache,
btConstraintSolverPoolMt* constraintSolver,
btConstraintSolver* constraintSolverMt,
btCollisionConfiguration* collisionConfiguration)
: btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration)
{
if (m_ownsIslandManager)
{
m_islandManager->~btSimulationIslandManager();
btAlignedFree( m_islandManager);
btAlignedFree(m_islandManager);
}
{
void* mem = btAlignedAlloc(sizeof(btSimulationIslandManagerMt),16);
void* mem = btAlignedAlloc(sizeof(btSimulationIslandManagerMt), 16);
btSimulationIslandManagerMt* im = new (mem) btSimulationIslandManagerMt();
im->setMinimumSolverBatchSize( m_solverInfo.m_minimumSolverBatchSize );
m_islandManager = im;
im->setMinimumSolverBatchSize(m_solverInfo.m_minimumSolverBatchSize);
m_islandManager = im;
}
m_constraintSolverMt = constraintSolverMt;
m_constraintSolverMt = constraintSolverMt;
}
btDiscreteDynamicsWorldMt::~btDiscreteDynamicsWorldMt()
{
}
void btDiscreteDynamicsWorldMt::solveConstraints(btContactSolverInfo& solverInfo)
{
BT_PROFILE("solveConstraints");
@@ -187,92 +177,87 @@ void btDiscreteDynamicsWorldMt::solveConstraints(btContactSolverInfo& solverInfo
m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds());
/// solve all the constraints for this island
btSimulationIslandManagerMt* im = static_cast<btSimulationIslandManagerMt*>(m_islandManager);
btSimulationIslandManagerMt::SolverParams solverParams;
solverParams.m_solverPool = m_constraintSolver;
solverParams.m_solverMt = m_constraintSolverMt;
solverParams.m_solverInfo = &solverInfo;
solverParams.m_debugDrawer = m_debugDrawer;
solverParams.m_dispatcher = getCollisionWorld()->getDispatcher();
im->buildAndProcessIslands( getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_constraints, solverParams );
btSimulationIslandManagerMt* im = static_cast<btSimulationIslandManagerMt*>(m_islandManager);
btSimulationIslandManagerMt::SolverParams solverParams;
solverParams.m_solverPool = m_constraintSolver;
solverParams.m_solverMt = m_constraintSolverMt;
solverParams.m_solverInfo = &solverInfo;
solverParams.m_debugDrawer = m_debugDrawer;
solverParams.m_dispatcher = getCollisionWorld()->getDispatcher();
im->buildAndProcessIslands(getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_constraints, solverParams);
m_constraintSolver->allSolved(solverInfo, m_debugDrawer);
}
struct UpdaterUnconstrainedMotion : public btIParallelForBody
{
btScalar timeStep;
btRigidBody** rigidBodies;
btScalar timeStep;
btRigidBody** rigidBodies;
void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE
{
for ( int i = iBegin; i < iEnd; ++i )
{
btRigidBody* body = rigidBodies[ i ];
if ( !body->isStaticOrKinematicObject() )
{
//don't integrate/update velocities here, it happens in the constraint solver
body->applyDamping( timeStep );
body->predictIntegratedTransform( timeStep, body->getInterpolationWorldTransform() );
}
}
}
void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
{
for (int i = iBegin; i < iEnd; ++i)
{
btRigidBody* body = rigidBodies[i];
if (!body->isStaticOrKinematicObject())
{
//don't integrate/update velocities here, it happens in the constraint solver
body->applyDamping(timeStep);
body->predictIntegratedTransform(timeStep, body->getInterpolationWorldTransform());
}
}
}
};
void btDiscreteDynamicsWorldMt::predictUnconstraintMotion( btScalar timeStep )
void btDiscreteDynamicsWorldMt::predictUnconstraintMotion(btScalar timeStep)
{
BT_PROFILE( "predictUnconstraintMotion" );
if ( m_nonStaticRigidBodies.size() > 0 )
{
UpdaterUnconstrainedMotion update;
update.timeStep = timeStep;
update.rigidBodies = &m_nonStaticRigidBodies[ 0 ];
int grainSize = 50; // num of iterations per task for task scheduler
btParallelFor( 0, m_nonStaticRigidBodies.size(), grainSize, update );
}
BT_PROFILE("predictUnconstraintMotion");
if (m_nonStaticRigidBodies.size() > 0)
{
UpdaterUnconstrainedMotion update;
update.timeStep = timeStep;
update.rigidBodies = &m_nonStaticRigidBodies[0];
int grainSize = 50; // num of iterations per task for task scheduler
btParallelFor(0, m_nonStaticRigidBodies.size(), grainSize, update);
}
}
void btDiscreteDynamicsWorldMt::createPredictiveContacts( btScalar timeStep )
void btDiscreteDynamicsWorldMt::createPredictiveContacts(btScalar timeStep)
{
BT_PROFILE( "createPredictiveContacts" );
releasePredictiveContacts();
if ( m_nonStaticRigidBodies.size() > 0 )
{
UpdaterCreatePredictiveContacts update;
update.world = this;
update.timeStep = timeStep;
update.rigidBodies = &m_nonStaticRigidBodies[ 0 ];
int grainSize = 50; // num of iterations per task for task scheduler
btParallelFor( 0, m_nonStaticRigidBodies.size(), grainSize, update );
}
BT_PROFILE("createPredictiveContacts");
releasePredictiveContacts();
if (m_nonStaticRigidBodies.size() > 0)
{
UpdaterCreatePredictiveContacts update;
update.world = this;
update.timeStep = timeStep;
update.rigidBodies = &m_nonStaticRigidBodies[0];
int grainSize = 50; // num of iterations per task for task scheduler
btParallelFor(0, m_nonStaticRigidBodies.size(), grainSize, update);
}
}
void btDiscreteDynamicsWorldMt::integrateTransforms( btScalar timeStep )
void btDiscreteDynamicsWorldMt::integrateTransforms(btScalar timeStep)
{
BT_PROFILE( "integrateTransforms" );
if ( m_nonStaticRigidBodies.size() > 0 )
{
UpdaterIntegrateTransforms update;
update.world = this;
update.timeStep = timeStep;
update.rigidBodies = &m_nonStaticRigidBodies[ 0 ];
int grainSize = 50; // num of iterations per task for task scheduler
btParallelFor( 0, m_nonStaticRigidBodies.size(), grainSize, update );
}
BT_PROFILE("integrateTransforms");
if (m_nonStaticRigidBodies.size() > 0)
{
UpdaterIntegrateTransforms update;
update.world = this;
update.timeStep = timeStep;
update.rigidBodies = &m_nonStaticRigidBodies[0];
int grainSize = 50; // num of iterations per task for task scheduler
btParallelFor(0, m_nonStaticRigidBodies.size(), grainSize, update);
}
}
int btDiscreteDynamicsWorldMt::stepSimulation( btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep )
int btDiscreteDynamicsWorldMt::stepSimulation(btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep)
{
int numSubSteps = btDiscreteDynamicsWorld::stepSimulation(timeStep, maxSubSteps, fixedTimeStep);
if (btITaskScheduler* scheduler = btGetTaskScheduler())
{
// tell Bullet's threads to sleep, so other threads can run
scheduler->sleepWorkerThreadsHint();
}
return numSubSteps;
int numSubSteps = btDiscreteDynamicsWorld::stepSimulation(timeStep, maxSubSteps, fixedTimeStep);
if (btITaskScheduler* scheduler = btGetTaskScheduler())
{
// tell Bullet's threads to sleep, so other threads can run
scheduler->sleepWorkerThreadsHint();
}
return numSubSteps;
}

View File

@@ -13,7 +13,6 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_DISCRETE_DYNAMICS_WORLD_MT_H
#define BT_DISCRETE_DYNAMICS_WORLD_MT_H
@@ -21,7 +20,6 @@ subject to the following restrictions:
#include "btSimulationIslandManagerMt.h"
#include "BulletDynamics/ConstraintSolver/btConstraintSolver.h"
///
/// btConstraintSolverPoolMt - masquerades as a constraint solver, but really it is a threadsafe pool of them.
///
@@ -34,46 +32,43 @@ subject to the following restrictions:
class btConstraintSolverPoolMt : public btConstraintSolver
{
public:
// create the solvers for me
explicit btConstraintSolverPoolMt( int numSolvers );
// create the solvers for me
explicit btConstraintSolverPoolMt(int numSolvers);
// pass in fully constructed solvers (destructor will delete them)
btConstraintSolverPoolMt( btConstraintSolver** solvers, int numSolvers );
// pass in fully constructed solvers (destructor will delete them)
btConstraintSolverPoolMt(btConstraintSolver** solvers, int numSolvers);
virtual ~btConstraintSolverPoolMt();
virtual ~btConstraintSolverPoolMt();
///solve a group of constraints
virtual btScalar solveGroup( btCollisionObject** bodies,
int numBodies,
btPersistentManifold** manifolds,
int numManifolds,
btTypedConstraint** constraints,
int numConstraints,
const btContactSolverInfo& info,
btIDebugDraw* debugDrawer,
btDispatcher* dispatcher
) BT_OVERRIDE;
///solve a group of constraints
virtual btScalar solveGroup(btCollisionObject** bodies,
int numBodies,
btPersistentManifold** manifolds,
int numManifolds,
btTypedConstraint** constraints,
int numConstraints,
const btContactSolverInfo& info,
btIDebugDraw* debugDrawer,
btDispatcher* dispatcher) BT_OVERRIDE;
virtual void reset() BT_OVERRIDE;
virtual btConstraintSolverType getSolverType() const BT_OVERRIDE { return m_solverType; }
virtual void reset() BT_OVERRIDE;
virtual btConstraintSolverType getSolverType() const BT_OVERRIDE { return m_solverType; }
private:
const static size_t kCacheLineSize = 128;
struct ThreadSolver
{
btConstraintSolver* solver;
btSpinMutex mutex;
char _cachelinePadding[ kCacheLineSize - sizeof( btSpinMutex ) - sizeof( void* ) ]; // keep mutexes from sharing a cache line
};
btAlignedObjectArray<ThreadSolver> m_solvers;
btConstraintSolverType m_solverType;
const static size_t kCacheLineSize = 128;
struct ThreadSolver
{
btConstraintSolver* solver;
btSpinMutex mutex;
char _cachelinePadding[kCacheLineSize - sizeof(btSpinMutex) - sizeof(void*)]; // keep mutexes from sharing a cache line
};
btAlignedObjectArray<ThreadSolver> m_solvers;
btConstraintSolverType m_solverType;
ThreadSolver* getAndLockThreadSolver();
void init( btConstraintSolver** solvers, int numSolvers );
ThreadSolver* getAndLockThreadSolver();
void init(btConstraintSolver** solvers, int numSolvers);
};
///
/// btDiscreteDynamicsWorldMt -- a version of DiscreteDynamicsWorld with some minor changes to support
/// solving simulation islands on multiple threads.
@@ -84,53 +79,53 @@ private:
/// - integrateTransforms
/// - createPredictiveContacts
///
ATTRIBUTE_ALIGNED16(class) btDiscreteDynamicsWorldMt : public btDiscreteDynamicsWorld
ATTRIBUTE_ALIGNED16(class)
btDiscreteDynamicsWorldMt : public btDiscreteDynamicsWorld
{
protected:
btConstraintSolver* m_constraintSolverMt;
btConstraintSolver* m_constraintSolverMt;
virtual void solveConstraints(btContactSolverInfo& solverInfo) BT_OVERRIDE;
virtual void solveConstraints(btContactSolverInfo & solverInfo) BT_OVERRIDE;
virtual void predictUnconstraintMotion( btScalar timeStep ) BT_OVERRIDE;
virtual void predictUnconstraintMotion(btScalar timeStep) BT_OVERRIDE;
struct UpdaterCreatePredictiveContacts : public btIParallelForBody
{
btScalar timeStep;
btRigidBody** rigidBodies;
btDiscreteDynamicsWorldMt* world;
struct UpdaterCreatePredictiveContacts : public btIParallelForBody
{
btScalar timeStep;
btRigidBody** rigidBodies;
btDiscreteDynamicsWorldMt* world;
void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE
{
world->createPredictiveContactsInternal( &rigidBodies[ iBegin ], iEnd - iBegin, timeStep );
}
};
virtual void createPredictiveContacts( btScalar timeStep ) BT_OVERRIDE;
void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
{
world->createPredictiveContactsInternal(&rigidBodies[iBegin], iEnd - iBegin, timeStep);
}
};
virtual void createPredictiveContacts(btScalar timeStep) BT_OVERRIDE;
struct UpdaterIntegrateTransforms : public btIParallelForBody
{
btScalar timeStep;
btRigidBody** rigidBodies;
btDiscreteDynamicsWorldMt* world;
struct UpdaterIntegrateTransforms : public btIParallelForBody
{
btScalar timeStep;
btRigidBody** rigidBodies;
btDiscreteDynamicsWorldMt* world;
void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE
{
world->integrateTransformsInternal( &rigidBodies[ iBegin ], iEnd - iBegin, timeStep );
}
};
virtual void integrateTransforms( btScalar timeStep ) BT_OVERRIDE;
void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
{
world->integrateTransformsInternal(&rigidBodies[iBegin], iEnd - iBegin, timeStep);
}
};
virtual void integrateTransforms(btScalar timeStep) BT_OVERRIDE;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btDiscreteDynamicsWorldMt(btDispatcher* dispatcher,
btBroadphaseInterface* pairCache,
btConstraintSolverPoolMt* constraintSolver, // Note this should be a solver-pool for multi-threading
btConstraintSolver* constraintSolverMt, // single multi-threaded solver for large islands (or NULL)
btCollisionConfiguration* collisionConfiguration
);
btDiscreteDynamicsWorldMt(btDispatcher * dispatcher,
btBroadphaseInterface * pairCache,
btConstraintSolverPoolMt * constraintSolver, // Note this should be a solver-pool for multi-threading
btConstraintSolver * constraintSolverMt, // single multi-threaded solver for large islands (or NULL)
btCollisionConfiguration * collisionConfiguration);
virtual ~btDiscreteDynamicsWorldMt();
virtual int stepSimulation( btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep ) BT_OVERRIDE;
virtual int stepSimulation(btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep) BT_OVERRIDE;
};
#endif //BT_DISCRETE_DYNAMICS_WORLD_H
#endif //BT_DISCRETE_DYNAMICS_WORLD_H

View File

@@ -24,150 +24,150 @@ class btActionInterface;
class btConstraintSolver;
class btDynamicsWorld;
/// Type for the callback for each tick
typedef void (*btInternalTickCallback)(btDynamicsWorld *world, btScalar timeStep);
typedef void (*btInternalTickCallback)(btDynamicsWorld* world, btScalar timeStep);
enum btDynamicsWorldType
{
BT_SIMPLE_DYNAMICS_WORLD=1,
BT_DISCRETE_DYNAMICS_WORLD=2,
BT_CONTINUOUS_DYNAMICS_WORLD=3,
BT_SOFT_RIGID_DYNAMICS_WORLD=4,
BT_GPU_DYNAMICS_WORLD=5,
BT_SOFT_MULTIBODY_DYNAMICS_WORLD=6
BT_SIMPLE_DYNAMICS_WORLD = 1,
BT_DISCRETE_DYNAMICS_WORLD = 2,
BT_CONTINUOUS_DYNAMICS_WORLD = 3,
BT_SOFT_RIGID_DYNAMICS_WORLD = 4,
BT_GPU_DYNAMICS_WORLD = 5,
BT_SOFT_MULTIBODY_DYNAMICS_WORLD = 6
};
///The btDynamicsWorld is the interface class for several dynamics implementation, basic, discrete, parallel, and continuous etc.
class btDynamicsWorld : public btCollisionWorld
{
protected:
btInternalTickCallback m_internalTickCallback;
btInternalTickCallback m_internalPreTickCallback;
void* m_worldUserInfo;
btInternalTickCallback m_internalTickCallback;
btInternalTickCallback m_internalPreTickCallback;
void* m_worldUserInfo;
btContactSolverInfo m_solverInfo;
btContactSolverInfo m_solverInfo;
public:
btDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* broadphase, btCollisionConfiguration* collisionConfiguration)
: btCollisionWorld(dispatcher, broadphase, collisionConfiguration), m_internalTickCallback(0), m_internalPreTickCallback(0), m_worldUserInfo(0)
{
}
btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration)
:btCollisionWorld(dispatcher,broadphase,collisionConfiguration), m_internalTickCallback(0),m_internalPreTickCallback(0), m_worldUserInfo(0)
virtual ~btDynamicsWorld()
{
}
///stepSimulation proceeds the simulation over 'timeStep', units in preferably in seconds.
///By default, Bullet will subdivide the timestep in constant substeps of each 'fixedTimeStep'.
///in order to keep the simulation real-time, the maximum number of substeps can be clamped to 'maxSubSteps'.
///You can disable subdividing the timestep/substepping by passing maxSubSteps=0 as second argument to stepSimulation, but in that case you have to keep the timeStep constant.
virtual int stepSimulation(btScalar timeStep, int maxSubSteps = 1, btScalar fixedTimeStep = btScalar(1.) / btScalar(60.)) = 0;
virtual void debugDrawWorld() = 0;
virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies = false)
{
(void)constraint;
(void)disableCollisionsBetweenLinkedBodies;
}
virtual void removeConstraint(btTypedConstraint* constraint) { (void)constraint; }
virtual void addAction(btActionInterface* action) = 0;
virtual void removeAction(btActionInterface* action) = 0;
//once a rigidbody is added to the dynamics world, it will get this gravity assigned
//existing rigidbodies in the world get gravity assigned too, during this method
virtual void setGravity(const btVector3& gravity) = 0;
virtual btVector3 getGravity() const = 0;
virtual void synchronizeMotionStates() = 0;
virtual void addRigidBody(btRigidBody* body) = 0;
virtual void addRigidBody(btRigidBody* body, int group, int mask) = 0;
virtual void removeRigidBody(btRigidBody* body) = 0;
virtual void setConstraintSolver(btConstraintSolver* solver) = 0;
virtual btConstraintSolver* getConstraintSolver() = 0;
virtual int getNumConstraints() const { return 0; }
virtual btTypedConstraint* getConstraint(int index)
{
(void)index;
return 0;
}
virtual const btTypedConstraint* getConstraint(int index) const
{
(void)index;
return 0;
}
virtual btDynamicsWorldType getWorldType() const = 0;
virtual void clearForces() = 0;
/// Set the callback for when an internal tick (simulation substep) happens, optional user info
void setInternalTickCallback(btInternalTickCallback cb, void* worldUserInfo = 0, bool isPreTick = false)
{
if (isPreTick)
{
m_internalPreTickCallback = cb;
}
virtual ~btDynamicsWorld()
else
{
m_internalTickCallback = cb;
}
///stepSimulation proceeds the simulation over 'timeStep', units in preferably in seconds.
///By default, Bullet will subdivide the timestep in constant substeps of each 'fixedTimeStep'.
///in order to keep the simulation real-time, the maximum number of substeps can be clamped to 'maxSubSteps'.
///You can disable subdividing the timestep/substepping by passing maxSubSteps=0 as second argument to stepSimulation, but in that case you have to keep the timeStep constant.
virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))=0;
virtual void debugDrawWorld() = 0;
virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false)
{
(void)constraint; (void)disableCollisionsBetweenLinkedBodies;
}
m_worldUserInfo = worldUserInfo;
}
virtual void removeConstraint(btTypedConstraint* constraint) {(void)constraint;}
void setWorldUserInfo(void* worldUserInfo)
{
m_worldUserInfo = worldUserInfo;
}
virtual void addAction(btActionInterface* action) = 0;
void* getWorldUserInfo() const
{
return m_worldUserInfo;
}
virtual void removeAction(btActionInterface* action) = 0;
//once a rigidbody is added to the dynamics world, it will get this gravity assigned
//existing rigidbodies in the world get gravity assigned too, during this method
virtual void setGravity(const btVector3& gravity) = 0;
virtual btVector3 getGravity () const = 0;
virtual void synchronizeMotionStates() = 0;
virtual void addRigidBody(btRigidBody* body) = 0;
virtual void addRigidBody(btRigidBody* body, int group, int mask) = 0;
virtual void removeRigidBody(btRigidBody* body) = 0;
virtual void setConstraintSolver(btConstraintSolver* solver) = 0;
virtual btConstraintSolver* getConstraintSolver() = 0;
virtual int getNumConstraints() const { return 0; }
virtual btTypedConstraint* getConstraint(int index) { (void)index; return 0; }
virtual const btTypedConstraint* getConstraint(int index) const { (void)index; return 0; }
virtual btDynamicsWorldType getWorldType() const=0;
virtual void clearForces() = 0;
/// Set the callback for when an internal tick (simulation substep) happens, optional user info
void setInternalTickCallback(btInternalTickCallback cb, void* worldUserInfo=0,bool isPreTick=false)
{
if (isPreTick)
{
m_internalPreTickCallback = cb;
} else
{
m_internalTickCallback = cb;
}
m_worldUserInfo = worldUserInfo;
}
void setWorldUserInfo(void* worldUserInfo)
{
m_worldUserInfo = worldUserInfo;
}
void* getWorldUserInfo() const
{
return m_worldUserInfo;
}
btContactSolverInfo& getSolverInfo()
{
return m_solverInfo;
}
const btContactSolverInfo& getSolverInfo() const
{
return m_solverInfo;
}
///obsolete, use addAction instead.
virtual void addVehicle(btActionInterface* vehicle) {(void)vehicle;}
///obsolete, use removeAction instead
virtual void removeVehicle(btActionInterface* vehicle) {(void)vehicle;}
///obsolete, use addAction instead.
virtual void addCharacter(btActionInterface* character) {(void)character;}
///obsolete, use removeAction instead
virtual void removeCharacter(btActionInterface* character) {(void)character;}
btContactSolverInfo& getSolverInfo()
{
return m_solverInfo;
}
const btContactSolverInfo& getSolverInfo() const
{
return m_solverInfo;
}
///obsolete, use addAction instead.
virtual void addVehicle(btActionInterface* vehicle) { (void)vehicle; }
///obsolete, use removeAction instead
virtual void removeVehicle(btActionInterface* vehicle) { (void)vehicle; }
///obsolete, use addAction instead.
virtual void addCharacter(btActionInterface* character) { (void)character; }
///obsolete, use removeAction instead
virtual void removeCharacter(btActionInterface* character) { (void)character; }
};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btDynamicsWorldDoubleData
{
btContactSolverInfoDoubleData m_solverInfo;
btVector3DoubleData m_gravity;
btContactSolverInfoDoubleData m_solverInfo;
btVector3DoubleData m_gravity;
};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btDynamicsWorldFloatData
{
btContactSolverInfoFloatData m_solverInfo;
btVector3FloatData m_gravity;
btContactSolverInfoFloatData m_solverInfo;
btVector3FloatData m_gravity;
};
#endif //BT_DYNAMICS_WORLD_H
#endif //BT_DYNAMICS_WORLD_H

View File

@@ -22,36 +22,34 @@ subject to the following restrictions:
#include "LinearMath/btSerializer.h"
//'temporarily' global variables
btScalar gDeactivationTime = btScalar(2.);
bool gDisableDeactivation = false;
btScalar gDeactivationTime = btScalar(2.);
bool gDisableDeactivation = false;
static int uniqueId = 0;
btRigidBody::btRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo)
{
setupRigidBody(constructionInfo);
}
btRigidBody::btRigidBody(btScalar mass, btMotionState *motionState, btCollisionShape *collisionShape, const btVector3 &localInertia)
btRigidBody::btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia)
{
btRigidBodyConstructionInfo cinfo(mass,motionState,collisionShape,localInertia);
btRigidBodyConstructionInfo cinfo(mass, motionState, collisionShape, localInertia);
setupRigidBody(cinfo);
}
void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo)
void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo)
{
m_internalType=CO_RIGID_BODY;
m_internalType = CO_RIGID_BODY;
m_linearVelocity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
m_angularFactor.setValue(1,1,1);
m_linearFactor.setValue(1,1,1);
m_angularVelocity.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
m_angularFactor.setValue(1, 1, 1);
m_linearFactor.setValue(1, 1, 1);
m_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
m_gravity_acceleration.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping);
setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping);
m_linearSleepingThreshold = constructionInfo.m_linearSleepingThreshold;
m_angularSleepingThreshold = constructionInfo.m_angularSleepingThreshold;
@@ -67,48 +65,44 @@ void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo&
if (m_optionalMotionState)
{
m_optionalMotionState->getWorldTransform(m_worldTransform);
} else
}
else
{
m_worldTransform = constructionInfo.m_startWorldTransform;
}
m_interpolationWorldTransform = m_worldTransform;
m_interpolationLinearVelocity.setValue(0,0,0);
m_interpolationAngularVelocity.setValue(0,0,0);
m_interpolationLinearVelocity.setValue(0, 0, 0);
m_interpolationAngularVelocity.setValue(0, 0, 0);
//moved to btCollisionObject
m_friction = constructionInfo.m_friction;
m_rollingFriction = constructionInfo.m_rollingFriction;
m_spinningFriction = constructionInfo.m_spinningFriction;
m_spinningFriction = constructionInfo.m_spinningFriction;
m_restitution = constructionInfo.m_restitution;
setCollisionShape( constructionInfo.m_collisionShape );
setCollisionShape(constructionInfo.m_collisionShape);
m_debugBodyId = uniqueId++;
setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia);
updateInertiaTensor();
m_rigidbodyFlags = BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY;
m_deltaLinearVelocity.setZero();
m_deltaAngularVelocity.setZero();
m_invMass = m_inverseMass*m_linearFactor;
m_invMass = m_inverseMass * m_linearFactor;
m_pushVelocity.setZero();
m_turnVelocity.setZero();
}
void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform)
void btRigidBody::predictIntegratedTransform(btScalar timeStep, btTransform& predictedTransform)
{
btTransformUtil::integrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform);
btTransformUtil::integrateTransform(m_worldTransform, m_linearVelocity, m_angularVelocity, timeStep, predictedTransform);
}
void btRigidBody::saveKinematicState(btScalar timeStep)
void btRigidBody::saveKinematicState(btScalar timeStep)
{
//todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities
if (timeStep != btScalar(0.))
@@ -116,25 +110,22 @@ void btRigidBody::saveKinematicState(btScalar timeStep)
//if we use motionstate to synchronize world transforms, get the new kinematic/animated world transform
if (getMotionState())
getMotionState()->getWorldTransform(m_worldTransform);
btVector3 linVel,angVel;
btTransformUtil::calculateVelocity(m_interpolationWorldTransform,m_worldTransform,timeStep,m_linearVelocity,m_angularVelocity);
btVector3 linVel, angVel;
btTransformUtil::calculateVelocity(m_interpolationWorldTransform, m_worldTransform, timeStep, m_linearVelocity, m_angularVelocity);
m_interpolationLinearVelocity = m_linearVelocity;
m_interpolationAngularVelocity = m_angularVelocity;
m_interpolationWorldTransform = m_worldTransform;
//printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ());
}
}
void btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const
void btRigidBody::getAabb(btVector3& aabbMin, btVector3& aabbMax) const
{
getCollisionShape()->getAabb(m_worldTransform,aabbMin,aabbMax);
getCollisionShape()->getAabb(m_worldTransform, aabbMin, aabbMax);
}
void btRigidBody::setGravity(const btVector3& acceleration)
void btRigidBody::setGravity(const btVector3& acceleration)
{
if (m_inverseMass != btScalar(0.0))
{
@@ -143,22 +134,14 @@ void btRigidBody::setGravity(const btVector3& acceleration)
m_gravity_acceleration = acceleration;
}
void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
{
m_linearDamping = btClamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
m_angularDamping = btClamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
}
///applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
void btRigidBody::applyDamping(btScalar timeStep)
void btRigidBody::applyDamping(btScalar timeStep)
{
//On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74
//todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway
@@ -168,8 +151,8 @@ void btRigidBody::applyDamping(btScalar timeStep)
m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
#else
m_linearVelocity *= btPow(btScalar(1)-m_linearDamping, timeStep);
m_angularVelocity *= btPow(btScalar(1)-m_angularDamping, timeStep);
m_linearVelocity *= btPow(btScalar(1) - m_linearDamping, timeStep);
m_angularVelocity *= btPow(btScalar(1) - m_angularDamping, timeStep);
#endif
if (m_additionalDamping)
@@ -182,7 +165,6 @@ void btRigidBody::applyDamping(btScalar timeStep)
m_angularVelocity *= m_additionalDampingFactor;
m_linearVelocity *= m_additionalDampingFactor;
}
btScalar speed = m_linearVelocity.length();
if (speed < m_linearDamping)
@@ -191,10 +173,11 @@ void btRigidBody::applyDamping(btScalar timeStep)
if (speed > dampVel)
{
btVector3 dir = m_linearVelocity.normalized();
m_linearVelocity -= dir * dampVel;
} else
m_linearVelocity -= dir * dampVel;
}
else
{
m_linearVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
m_linearVelocity.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
}
}
@@ -205,30 +188,28 @@ void btRigidBody::applyDamping(btScalar timeStep)
if (angSpeed > angDampVel)
{
btVector3 dir = m_angularVelocity.normalized();
m_angularVelocity -= dir * angDampVel;
} else
m_angularVelocity -= dir * angDampVel;
}
else
{
m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
m_angularVelocity.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
}
}
}
}
void btRigidBody::applyGravity()
{
if (isStaticOrKinematicObject())
return;
applyCentralForce(m_gravity);
applyCentralForce(m_gravity);
}
void btRigidBody::proceedToTransform(const btTransform& newTrans)
{
setCenterOfMassTransform( newTrans );
setCenterOfMassTransform(newTrans);
}
void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia)
{
@@ -236,7 +217,8 @@ void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia)
{
m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
m_inverseMass = btScalar(0.);
} else
}
else
{
m_collisionFlags &= (~btCollisionObject::CF_STATIC_OBJECT);
m_inverseMass = btScalar(1.0) / mass;
@@ -244,50 +226,45 @@ void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia)
//Fg = m * a
m_gravity = mass * m_gravity_acceleration;
m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0),
inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y(): btScalar(0.0),
inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0));
m_invMass = m_linearFactor*m_inverseMass;
m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x() : btScalar(0.0),
inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y() : btScalar(0.0),
inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z() : btScalar(0.0));
m_invMass = m_linearFactor * m_inverseMass;
}
void btRigidBody::updateInertiaTensor()
void btRigidBody::updateInertiaTensor()
{
m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose();
}
btVector3 btRigidBody::getLocalInertia() const
{
btVector3 inertiaLocal;
const btVector3 inertia = m_invInertiaLocal;
inertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x() : btScalar(0.0),
inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y() : btScalar(0.0),
inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z() : btScalar(0.0));
inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y() : btScalar(0.0),
inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z() : btScalar(0.0));
return inertiaLocal;
}
inline btVector3 evalEulerEqn(const btVector3& w1, const btVector3& w0, const btVector3& T, const btScalar dt,
const btMatrix3x3 &I)
const btMatrix3x3& I)
{
const btVector3 w2 = I*w1 + w1.cross(I*w1)*dt - (T*dt + I*w0);
const btVector3 w2 = I * w1 + w1.cross(I * w1) * dt - (T * dt + I * w0);
return w2;
}
inline btMatrix3x3 evalEulerEqnDeriv(const btVector3& w1, const btVector3& w0, const btScalar dt,
const btMatrix3x3 &I)
const btMatrix3x3& I)
{
btMatrix3x3 w1x, Iw1x;
const btVector3 Iwi = (I*w1);
const btVector3 Iwi = (I * w1);
w1.getSkewSymmetricMatrix(&w1x[0], &w1x[1], &w1x[2]);
Iwi.getSkewSymmetricMatrix(&Iw1x[0], &Iw1x[1], &Iw1x[2]);
const btMatrix3x3 dfw1 = I + (w1x*I - Iw1x)*dt;
const btMatrix3x3 dfw1 = I + (w1x * I - Iw1x) * dt;
return dfw1;
}
@@ -295,58 +272,55 @@ btVector3 btRigidBody::computeGyroscopicForceExplicit(btScalar maxGyroscopicForc
{
btVector3 inertiaLocal = getLocalInertia();
btMatrix3x3 inertiaTensorWorld = getWorldTransform().getBasis().scaled(inertiaLocal) * getWorldTransform().getBasis().transpose();
btVector3 tmp = inertiaTensorWorld*getAngularVelocity();
btVector3 tmp = inertiaTensorWorld * getAngularVelocity();
btVector3 gf = getAngularVelocity().cross(tmp);
btScalar l2 = gf.length2();
if (l2>maxGyroscopicForce*maxGyroscopicForce)
if (l2 > maxGyroscopicForce * maxGyroscopicForce)
{
gf *= btScalar(1.)/btSqrt(l2)*maxGyroscopicForce;
gf *= btScalar(1.) / btSqrt(l2) * maxGyroscopicForce;
}
return gf;
}
btVector3 btRigidBody::computeGyroscopicImpulseImplicit_Body(btScalar step) const
{
{
btVector3 idl = getLocalInertia();
btVector3 omega1 = getAngularVelocity();
btQuaternion q = getWorldTransform().getRotation();
// Convert to body coordinates
btVector3 omegab = quatRotate(q.inverse(), omega1);
btMatrix3x3 Ib;
Ib.setValue(idl.x(),0,0,
0,idl.y(),0,
0,0,idl.z());
btVector3 ibo = Ib*omegab;
Ib.setValue(idl.x(), 0, 0,
0, idl.y(), 0,
0, 0, idl.z());
btVector3 ibo = Ib * omegab;
// Residual vector
btVector3 f = step * omegab.cross(ibo);
btMatrix3x3 skew0;
omegab.getSkewSymmetricMatrix(&skew0[0], &skew0[1], &skew0[2]);
btVector3 om = Ib*omegab;
btVector3 om = Ib * omegab;
btMatrix3x3 skew1;
om.getSkewSymmetricMatrix(&skew1[0],&skew1[1],&skew1[2]);
om.getSkewSymmetricMatrix(&skew1[0], &skew1[1], &skew1[2]);
// Jacobian
btMatrix3x3 J = Ib + (skew0*Ib - skew1)*step;
// btMatrix3x3 Jinv = J.inverse();
// btVector3 omega_div = Jinv*f;
btMatrix3x3 J = Ib + (skew0 * Ib - skew1) * step;
// btMatrix3x3 Jinv = J.inverse();
// btVector3 omega_div = Jinv*f;
btVector3 omega_div = J.solve33(f);
// Single Newton-Raphson update
omegab = omegab - omega_div;//Solve33(J, f);
omegab = omegab - omega_div; //Solve33(J, f);
// Back to world coordinates
btVector3 omega2 = quatRotate(q,omegab);
btVector3 gf = omega2-omega1;
btVector3 omega2 = quatRotate(q, omegab);
btVector3 gf = omega2 - omega1;
return gf;
}
btVector3 btRigidBody::computeGyroscopicImpulseImplicit_World(btScalar step) const
{
// use full newton-euler equations. common practice to drop the wxIw term. want it for better tumbling behavior.
@@ -361,7 +335,7 @@ btVector3 btRigidBody::computeGyroscopicImpulseImplicit_World(btScalar step) con
m_worldTransform.getBasis().transpose();
// use newtons method to find implicit solution for new angular velocity (w')
// f(w') = -(T*step + Iw) + Iw' + w' + w'xIw'*step = 0
// f(w') = -(T*step + Iw) + Iw' + w' + w'xIw'*step = 0
// df/dw' = I + 1xIw'*step + w'xI*step
btVector3 w1 = w0;
@@ -383,8 +357,7 @@ btVector3 btRigidBody::computeGyroscopicImpulseImplicit_World(btScalar step) con
return gf;
}
void btRigidBody::integrateVelocities(btScalar step)
void btRigidBody::integrateVelocities(btScalar step)
{
if (isStaticOrKinematicObject())
return;
@@ -393,30 +366,28 @@ void btRigidBody::integrateVelocities(btScalar step)
m_angularVelocity += m_invInertiaTensorWorld * m_totalTorque * step;
#define MAX_ANGVEL SIMD_HALF_PI
/// clamp angular velocity. collision calculations will fail on higher angular velocities
/// clamp angular velocity. collision calculations will fail on higher angular velocities
btScalar angvel = m_angularVelocity.length();
if (angvel*step > MAX_ANGVEL)
if (angvel * step > MAX_ANGVEL)
{
m_angularVelocity *= (MAX_ANGVEL/step) /angvel;
m_angularVelocity *= (MAX_ANGVEL / step) / angvel;
}
}
btQuaternion btRigidBody::getOrientation() const
{
btQuaternion orn;
m_worldTransform.getBasis().getRotation(orn);
return orn;
btQuaternion orn;
m_worldTransform.getBasis().getRotation(orn);
return orn;
}
void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
{
if (isKinematicObject())
{
m_interpolationWorldTransform = m_worldTransform;
} else
}
else
{
m_interpolationWorldTransform = xform;
}
@@ -426,10 +397,6 @@ void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
updateInertiaTensor();
}
void btRigidBody::addConstraintRef(btTypedConstraint* c)
{
///disable collision with the 'other' body
@@ -450,39 +417,39 @@ void btRigidBody::addConstraintRef(btTypedConstraint* c)
{
colObjB->setIgnoreCollisionCheck(colObjA, true);
}
}
}
}
void btRigidBody::removeConstraintRef(btTypedConstraint* c)
{
int index = m_constraintRefs.findLinearSearch(c);
//don't remove constraints that are not referenced
if(index < m_constraintRefs.size())
{
m_constraintRefs.remove(c);
btCollisionObject* colObjA = &c->getRigidBodyA();
btCollisionObject* colObjB = &c->getRigidBodyB();
if (colObjA == this)
{
colObjA->setIgnoreCollisionCheck(colObjB, false);
}
else
{
colObjB->setIgnoreCollisionCheck(colObjA, false);
}
}
if (index < m_constraintRefs.size())
{
m_constraintRefs.remove(c);
btCollisionObject* colObjA = &c->getRigidBodyA();
btCollisionObject* colObjB = &c->getRigidBodyB();
if (colObjA == this)
{
colObjA->setIgnoreCollisionCheck(colObjB, false);
}
else
{
colObjB->setIgnoreCollisionCheck(colObjA, false);
}
}
}
int btRigidBody::calculateSerializeBufferSize() const
int btRigidBody::calculateSerializeBufferSize() const
{
int sz = sizeof(btRigidBodyData);
return sz;
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* serializer) const
///fills the dataBuffer and returns the struct name (and 0 on failure)
const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* serializer) const
{
btRigidBodyData* rbd = (btRigidBodyData*) dataBuffer;
btRigidBodyData* rbd = (btRigidBodyData*)dataBuffer;
btCollisionObject::serialize(&rbd->m_collisionObjectData, serializer);
@@ -504,7 +471,7 @@ const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* seriali
rbd->m_additionalLinearDampingThresholdSqr = m_additionalLinearDampingThresholdSqr;
rbd->m_additionalAngularDampingThresholdSqr = m_additionalAngularDampingThresholdSqr;
rbd->m_additionalAngularDampingFactor = m_additionalAngularDampingFactor;
rbd->m_linearSleepingThreshold=m_linearSleepingThreshold;
rbd->m_linearSleepingThreshold = m_linearSleepingThreshold;
rbd->m_angularSleepingThreshold = m_angularSleepingThreshold;
// Fill padding with zeros to appease msan.
@@ -515,13 +482,9 @@ const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* seriali
return btRigidBodyDataName;
}
void btRigidBody::serializeSingleObject(class btSerializer* serializer) const
{
btChunk* chunk = serializer->allocate(calculateSerializeBufferSize(),1);
btChunk* chunk = serializer->allocate(calculateSerializeBufferSize(), 1);
const char* structType = serialize(chunk->m_oldPtr, serializer);
serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,(void*)this);
serializer->finalizeChunk(chunk, structType, BT_RIGIDBODY_CODE, (void*)this);
}

View File

@@ -25,209 +25,195 @@ class btCollisionShape;
class btMotionState;
class btTypedConstraint;
extern btScalar gDeactivationTime;
extern bool gDisableDeactivation;
#ifdef BT_USE_DOUBLE_PRECISION
#define btRigidBodyData btRigidBodyDoubleData
#define btRigidBodyDataName "btRigidBodyDoubleData"
#define btRigidBodyData btRigidBodyDoubleData
#define btRigidBodyDataName "btRigidBodyDoubleData"
#else
#define btRigidBodyData btRigidBodyFloatData
#define btRigidBodyDataName "btRigidBodyFloatData"
#endif //BT_USE_DOUBLE_PRECISION
#define btRigidBodyData btRigidBodyFloatData
#define btRigidBodyDataName "btRigidBodyFloatData"
#endif //BT_USE_DOUBLE_PRECISION
enum btRigidBodyFlags
enum btRigidBodyFlags
{
BT_DISABLE_WORLD_GRAVITY = 1,
///BT_ENABLE_GYROPSCOPIC_FORCE flags is enabled by default in Bullet 2.83 and onwards.
///and it BT_ENABLE_GYROPSCOPIC_FORCE becomes equivalent to BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY
///See Demos/GyroscopicDemo and computeGyroscopicImpulseImplicit
BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT = 2,
BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD=4,
BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY=8,
BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD = 4,
BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY = 8,
BT_ENABLE_GYROPSCOPIC_FORCE = BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY,
};
///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
///It is recommended for performance and memory use to share btCollisionShape objects whenever possible.
///There are 3 types of rigid bodies:
///There are 3 types of rigid bodies:
///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics.
///- B) Fixed objects with zero mass. They are not moving (basically collision objects)
///- C) Kinematic objects, which are objects without mass, but the user can move them. There is on-way interaction, and Bullet calculates a velocity based on the timestep and previous and current world transform.
///Bullet automatically deactivates dynamic rigid bodies, when the velocity is below a threshold for a given time.
///Deactivated (sleeping) rigid bodies don't take any processing time, except a minor broadphase collision detection impact (to allow active objects to activate/wake up sleeping objects)
class btRigidBody : public btCollisionObject
class btRigidBody : public btCollisionObject
{
btMatrix3x3 m_invInertiaTensorWorld;
btVector3 m_linearVelocity;
btVector3 m_angularVelocity;
btScalar m_inverseMass;
btVector3 m_linearFactor;
btMatrix3x3 m_invInertiaTensorWorld;
btVector3 m_linearVelocity;
btVector3 m_angularVelocity;
btScalar m_inverseMass;
btVector3 m_linearFactor;
btVector3 m_gravity;
btVector3 m_gravity_acceleration;
btVector3 m_invInertiaLocal;
btVector3 m_totalForce;
btVector3 m_totalTorque;
btVector3 m_gravity;
btVector3 m_gravity_acceleration;
btVector3 m_invInertiaLocal;
btVector3 m_totalForce;
btVector3 m_totalTorque;
btScalar m_linearDamping;
btScalar m_angularDamping;
btScalar m_linearDamping;
btScalar m_angularDamping;
bool m_additionalDamping;
btScalar m_additionalDampingFactor;
btScalar m_additionalLinearDampingThresholdSqr;
btScalar m_additionalAngularDampingThresholdSqr;
btScalar m_additionalAngularDampingFactor;
bool m_additionalDamping;
btScalar m_additionalDampingFactor;
btScalar m_additionalLinearDampingThresholdSqr;
btScalar m_additionalAngularDampingThresholdSqr;
btScalar m_additionalAngularDampingFactor;
btScalar m_linearSleepingThreshold;
btScalar m_angularSleepingThreshold;
btScalar m_linearSleepingThreshold;
btScalar m_angularSleepingThreshold;
//m_optionalMotionState allows to automatic synchronize the world transform for active objects
btMotionState* m_optionalMotionState;
btMotionState* m_optionalMotionState;
//keep track of typed constraints referencing this rigid body, to disable collision between linked bodies
btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
int m_rigidbodyFlags;
int m_debugBodyId;
int m_rigidbodyFlags;
int m_debugBodyId;
protected:
ATTRIBUTE_ALIGNED16(btVector3 m_deltaLinearVelocity);
btVector3 m_deltaAngularVelocity;
btVector3 m_angularFactor;
btVector3 m_invMass;
btVector3 m_pushVelocity;
btVector3 m_turnVelocity;
ATTRIBUTE_ALIGNED16(btVector3 m_deltaLinearVelocity);
btVector3 m_deltaAngularVelocity;
btVector3 m_angularFactor;
btVector3 m_invMass;
btVector3 m_pushVelocity;
btVector3 m_turnVelocity;
public:
///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument)
///You can use the motion state to synchronize the world transform between physics and graphics objects.
///You can use the motion state to synchronize the world transform between physics and graphics objects.
///And if the motion state is provided, the rigid body will initialize its initial world transform from the motion state,
///m_startWorldTransform is only used when you don't provide a motion state.
struct btRigidBodyConstructionInfo
struct btRigidBodyConstructionInfo
{
btScalar m_mass;
btScalar m_mass;
///When a motionState is provided, the rigid body will initialize its world transform from the motion state
///In this case, m_startWorldTransform is ignored.
btMotionState* m_motionState;
btTransform m_startWorldTransform;
btMotionState* m_motionState;
btTransform m_startWorldTransform;
btCollisionShape* m_collisionShape;
btVector3 m_localInertia;
btScalar m_linearDamping;
btScalar m_angularDamping;
btCollisionShape* m_collisionShape;
btVector3 m_localInertia;
btScalar m_linearDamping;
btScalar m_angularDamping;
///best simulation results when friction is non-zero
btScalar m_friction;
btScalar m_friction;
///the m_rollingFriction prevents rounded shapes, such as spheres, cylinders and capsules from rolling forever.
///See Bullet/Demos/RollingFrictionDemo for usage
btScalar m_rollingFriction;
btScalar m_spinningFriction;//torsional friction around contact normal
///best simulation results using zero restitution.
btScalar m_restitution;
btScalar m_rollingFriction;
btScalar m_spinningFriction; //torsional friction around contact normal
btScalar m_linearSleepingThreshold;
btScalar m_angularSleepingThreshold;
///best simulation results using zero restitution.
btScalar m_restitution;
btScalar m_linearSleepingThreshold;
btScalar m_angularSleepingThreshold;
//Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
//Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
bool m_additionalDamping;
btScalar m_additionalDampingFactor;
btScalar m_additionalLinearDampingThresholdSqr;
btScalar m_additionalAngularDampingThresholdSqr;
btScalar m_additionalAngularDampingFactor;
bool m_additionalDamping;
btScalar m_additionalDampingFactor;
btScalar m_additionalLinearDampingThresholdSqr;
btScalar m_additionalAngularDampingThresholdSqr;
btScalar m_additionalAngularDampingFactor;
btRigidBodyConstructionInfo( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)):
m_mass(mass),
m_motionState(motionState),
m_collisionShape(collisionShape),
m_localInertia(localInertia),
m_linearDamping(btScalar(0.)),
m_angularDamping(btScalar(0.)),
m_friction(btScalar(0.5)),
m_rollingFriction(btScalar(0)),
m_spinningFriction(btScalar(0)),
m_restitution(btScalar(0.)),
m_linearSleepingThreshold(btScalar(0.8)),
m_angularSleepingThreshold(btScalar(1.f)),
m_additionalDamping(false),
m_additionalDampingFactor(btScalar(0.005)),
m_additionalLinearDampingThresholdSqr(btScalar(0.01)),
m_additionalAngularDampingThresholdSqr(btScalar(0.01)),
m_additionalAngularDampingFactor(btScalar(0.01))
btRigidBodyConstructionInfo(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia = btVector3(0, 0, 0)) : m_mass(mass),
m_motionState(motionState),
m_collisionShape(collisionShape),
m_localInertia(localInertia),
m_linearDamping(btScalar(0.)),
m_angularDamping(btScalar(0.)),
m_friction(btScalar(0.5)),
m_rollingFriction(btScalar(0)),
m_spinningFriction(btScalar(0)),
m_restitution(btScalar(0.)),
m_linearSleepingThreshold(btScalar(0.8)),
m_angularSleepingThreshold(btScalar(1.f)),
m_additionalDamping(false),
m_additionalDampingFactor(btScalar(0.005)),
m_additionalLinearDampingThresholdSqr(btScalar(0.01)),
m_additionalAngularDampingThresholdSqr(btScalar(0.01)),
m_additionalAngularDampingFactor(btScalar(0.01))
{
m_startWorldTransform.setIdentity();
}
};
///btRigidBody constructor using construction info
btRigidBody( const btRigidBodyConstructionInfo& constructionInfo);
btRigidBody(const btRigidBodyConstructionInfo& constructionInfo);
///btRigidBody constructor for backwards compatibility.
///btRigidBody constructor for backwards compatibility.
///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo)
btRigidBody( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));
btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia = btVector3(0, 0, 0));
virtual ~btRigidBody()
{
//No constraints should point to this rigidbody
//Remove constraints from the dynamics world before you delete the related rigidbodies.
btAssert(m_constraintRefs.size()==0);
}
{
//No constraints should point to this rigidbody
//Remove constraints from the dynamics world before you delete the related rigidbodies.
btAssert(m_constraintRefs.size() == 0);
}
protected:
///setupRigidBody is only used internally by the constructor
void setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo);
void setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo);
public:
void proceedToTransform(const btTransform& newTrans);
void proceedToTransform(const btTransform& newTrans);
///to keep collision detection and dynamics separate we don't store a rigidbody pointer
///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast
static const btRigidBody* upcast(const btCollisionObject* colObj)
static const btRigidBody* upcast(const btCollisionObject* colObj)
{
if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY)
if (colObj->getInternalType() & btCollisionObject::CO_RIGID_BODY)
return (const btRigidBody*)colObj;
return 0;
}
static btRigidBody* upcast(btCollisionObject* colObj)
static btRigidBody* upcast(btCollisionObject* colObj)
{
if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY)
if (colObj->getInternalType() & btCollisionObject::CO_RIGID_BODY)
return (btRigidBody*)colObj;
return 0;
}
/// continuous collision detection needs prediction
void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
void saveKinematicState(btScalar step);
void applyGravity();
void setGravity(const btVector3& acceleration);
const btVector3& getGravity() const
/// continuous collision detection needs prediction
void predictIntegratedTransform(btScalar step, btTransform& predictedTransform);
void saveKinematicState(btScalar step);
void applyGravity();
void setGravity(const btVector3& acceleration);
const btVector3& getGravity() const
{
return m_gravity_acceleration;
}
void setDamping(btScalar lin_damping, btScalar ang_damping);
void setDamping(btScalar lin_damping, btScalar ang_damping);
btScalar getLinearDamping() const
{
@@ -249,18 +235,20 @@ public:
return m_angularSleepingThreshold;
}
void applyDamping(btScalar timeStep);
void applyDamping(btScalar timeStep);
SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const {
SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const
{
return m_collisionShape;
}
SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() {
return m_collisionShape;
SIMD_FORCE_INLINE btCollisionShape* getCollisionShape()
{
return m_collisionShape;
}
void setMassProps(btScalar mass, const btVector3& inertia);
void setMassProps(btScalar mass, const btVector3& inertia);
const btVector3& getLinearFactor() const
{
return m_linearFactor;
@@ -268,20 +256,21 @@ public:
void setLinearFactor(const btVector3& linearFactor)
{
m_linearFactor = linearFactor;
m_invMass = m_linearFactor*m_inverseMass;
m_invMass = m_linearFactor * m_inverseMass;
}
btScalar getInvMass() const { return m_inverseMass; }
const btMatrix3x3& getInvInertiaTensorWorld() const {
return m_invInertiaTensorWorld;
}
void integrateVelocities(btScalar step);
void setCenterOfMassTransform(const btTransform& xform);
void applyCentralForce(const btVector3& force)
btScalar getInvMass() const { return m_inverseMass; }
const btMatrix3x3& getInvInertiaTensorWorld() const
{
m_totalForce += force*m_linearFactor;
return m_invInertiaTensorWorld;
}
void integrateVelocities(btScalar step);
void setCenterOfMassTransform(const btTransform& xform);
void applyCentralForce(const btVector3& force)
{
m_totalForce += force * m_linearFactor;
}
const btVector3& getTotalForce() const
@@ -293,90 +282,93 @@ public:
{
return m_totalTorque;
};
const btVector3& getInvInertiaDiagLocal() const
{
return m_invInertiaLocal;
};
void setInvInertiaDiagLocal(const btVector3& diagInvInertia)
void setInvInertiaDiagLocal(const btVector3& diagInvInertia)
{
m_invInertiaLocal = diagInvInertia;
}
void setSleepingThresholds(btScalar linear,btScalar angular)
void setSleepingThresholds(btScalar linear, btScalar angular)
{
m_linearSleepingThreshold = linear;
m_angularSleepingThreshold = angular;
}
void applyTorque(const btVector3& torque)
void applyTorque(const btVector3& torque)
{
m_totalTorque += torque*m_angularFactor;
m_totalTorque += torque * m_angularFactor;
}
void applyForce(const btVector3& force, const btVector3& rel_pos)
void applyForce(const btVector3& force, const btVector3& rel_pos)
{
applyCentralForce(force);
applyTorque(rel_pos.cross(force*m_linearFactor));
applyTorque(rel_pos.cross(force * m_linearFactor));
}
void applyCentralImpulse(const btVector3& impulse)
{
m_linearVelocity += impulse *m_linearFactor * m_inverseMass;
m_linearVelocity += impulse * m_linearFactor * m_inverseMass;
}
void applyTorqueImpulse(const btVector3& torque)
void applyTorqueImpulse(const btVector3& torque)
{
m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
}
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
{
if (m_inverseMass != btScalar(0.))
{
applyCentralImpulse(impulse);
if (m_angularFactor)
{
applyTorqueImpulse(rel_pos.cross(impulse*m_linearFactor));
applyTorqueImpulse(rel_pos.cross(impulse * m_linearFactor));
}
}
}
void clearForces()
void clearForces()
{
m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
}
void updateInertiaTensor();
const btVector3& getCenterOfMassPosition() const {
return m_worldTransform.getOrigin();
void updateInertiaTensor();
const btVector3& getCenterOfMassPosition() const
{
return m_worldTransform.getOrigin();
}
btQuaternion getOrientation() const;
const btTransform& getCenterOfMassTransform() const {
return m_worldTransform;
const btTransform& getCenterOfMassTransform() const
{
return m_worldTransform;
}
const btVector3& getLinearVelocity() const {
return m_linearVelocity;
const btVector3& getLinearVelocity() const
{
return m_linearVelocity;
}
const btVector3& getAngularVelocity() const {
return m_angularVelocity;
const btVector3& getAngularVelocity() const
{
return m_angularVelocity;
}
inline void setLinearVelocity(const btVector3& lin_vel)
{
{
m_updateRevision++;
m_linearVelocity = lin_vel;
m_linearVelocity = lin_vel;
}
inline void setAngularVelocity(const btVector3& ang_vel)
{
inline void setAngularVelocity(const btVector3& ang_vel)
{
m_updateRevision++;
m_angularVelocity = ang_vel;
m_angularVelocity = ang_vel;
}
btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
@@ -388,18 +380,13 @@ public:
// return (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
}
void translate(const btVector3& v)
void translate(const btVector3& v)
{
m_worldTransform.getOrigin() += v;
m_worldTransform.getOrigin() += v;
}
void getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
void getAabb(btVector3& aabbMin, btVector3& aabbMax) const;
SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
{
btVector3 r0 = pos - getCenterOfMassPosition();
@@ -409,7 +396,6 @@ public:
btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0);
return m_inverseMass + normal.dot(vec);
}
SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const
@@ -418,26 +404,25 @@ public:
return axis.dot(vec);
}
SIMD_FORCE_INLINE void updateDeactivation(btScalar timeStep)
SIMD_FORCE_INLINE void updateDeactivation(btScalar timeStep)
{
if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION))
if ((getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION))
return;
if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) &&
(getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold))
if ((getLinearVelocity().length2() < m_linearSleepingThreshold * m_linearSleepingThreshold) &&
(getAngularVelocity().length2() < m_angularSleepingThreshold * m_angularSleepingThreshold))
{
m_deactivationTime += timeStep;
} else
}
else
{
m_deactivationTime=btScalar(0.);
m_deactivationTime = btScalar(0.);
setActivationState(0);
}
}
SIMD_FORCE_INLINE bool wantsSleeping()
SIMD_FORCE_INLINE bool wantsSleeping()
{
if (getActivationState() == DISABLE_DEACTIVATION)
return false;
@@ -445,41 +430,39 @@ public:
if (gDisableDeactivation || (gDeactivationTime == btScalar(0.)))
return false;
if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION))
if ((getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION))
return true;
if (m_deactivationTime> gDeactivationTime)
if (m_deactivationTime > gDeactivationTime)
{
return true;
}
return false;
}
const btBroadphaseProxy* getBroadphaseProxy() const
const btBroadphaseProxy* getBroadphaseProxy() const
{
return m_broadphaseHandle;
}
btBroadphaseProxy* getBroadphaseProxy()
btBroadphaseProxy* getBroadphaseProxy()
{
return m_broadphaseHandle;
}
void setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy)
void setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy)
{
m_broadphaseHandle = broadphaseProxy;
}
//btMotionState allows to automatic synchronize the world transform for active objects
btMotionState* getMotionState()
btMotionState* getMotionState()
{
return m_optionalMotionState;
}
const btMotionState* getMotionState() const
const btMotionState* getMotionState() const
{
return m_optionalMotionState;
}
void setMotionState(btMotionState* motionState)
void setMotionState(btMotionState* motionState)
{
m_optionalMotionState = motionState;
if (m_optionalMotionState)
@@ -487,27 +470,27 @@ public:
}
//for experimental overriding of friction/contact solver func
int m_contactSolverType;
int m_frictionSolverType;
int m_contactSolverType;
int m_frictionSolverType;
void setAngularFactor(const btVector3& angFac)
void setAngularFactor(const btVector3& angFac)
{
m_updateRevision++;
m_angularFactor = angFac;
}
void setAngularFactor(btScalar angFac)
void setAngularFactor(btScalar angFac)
{
m_updateRevision++;
m_angularFactor.setValue(angFac,angFac,angFac);
m_angularFactor.setValue(angFac, angFac, angFac);
}
const btVector3& getAngularFactor() const
const btVector3& getAngularFactor() const
{
return m_angularFactor;
}
//is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase?
bool isInWorld() const
bool isInWorld() const
{
return (getBroadphaseProxy() != 0);
}
@@ -525,7 +508,7 @@ public:
return m_constraintRefs.size();
}
void setFlags(int flags)
void setFlags(int flags)
{
m_rigidbodyFlags = flags;
}
@@ -535,12 +518,9 @@ public:
return m_rigidbodyFlags;
}
///perform implicit force computation in world space
btVector3 computeGyroscopicImpulseImplicit_World(btScalar dt) const;
///perform implicit force computation in body space (inertial frame)
btVector3 computeGyroscopicImpulseImplicit_Body(btScalar step) const;
@@ -550,70 +530,66 @@ public:
///////////////////////////////////////////////
virtual int calculateSerializeBufferSize() const;
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
virtual void serializeSingleObject(class btSerializer* serializer) const;
};
//@todo add m_optionalMotionState and m_constraintRefs to btRigidBodyData
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btRigidBodyFloatData
struct btRigidBodyFloatData
{
btCollisionObjectFloatData m_collisionObjectData;
btMatrix3x3FloatData m_invInertiaTensorWorld;
btVector3FloatData m_linearVelocity;
btVector3FloatData m_angularVelocity;
btVector3FloatData m_angularFactor;
btVector3FloatData m_linearFactor;
btVector3FloatData m_gravity;
btVector3FloatData m_gravity_acceleration;
btVector3FloatData m_invInertiaLocal;
btVector3FloatData m_totalForce;
btVector3FloatData m_totalTorque;
float m_inverseMass;
float m_linearDamping;
float m_angularDamping;
float m_additionalDampingFactor;
float m_additionalLinearDampingThresholdSqr;
float m_additionalAngularDampingThresholdSqr;
float m_additionalAngularDampingFactor;
float m_linearSleepingThreshold;
float m_angularSleepingThreshold;
int m_additionalDamping;
btCollisionObjectFloatData m_collisionObjectData;
btMatrix3x3FloatData m_invInertiaTensorWorld;
btVector3FloatData m_linearVelocity;
btVector3FloatData m_angularVelocity;
btVector3FloatData m_angularFactor;
btVector3FloatData m_linearFactor;
btVector3FloatData m_gravity;
btVector3FloatData m_gravity_acceleration;
btVector3FloatData m_invInertiaLocal;
btVector3FloatData m_totalForce;
btVector3FloatData m_totalTorque;
float m_inverseMass;
float m_linearDamping;
float m_angularDamping;
float m_additionalDampingFactor;
float m_additionalLinearDampingThresholdSqr;
float m_additionalAngularDampingThresholdSqr;
float m_additionalAngularDampingFactor;
float m_linearSleepingThreshold;
float m_angularSleepingThreshold;
int m_additionalDamping;
};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btRigidBodyDoubleData
struct btRigidBodyDoubleData
{
btCollisionObjectDoubleData m_collisionObjectData;
btMatrix3x3DoubleData m_invInertiaTensorWorld;
btVector3DoubleData m_linearVelocity;
btVector3DoubleData m_angularVelocity;
btVector3DoubleData m_angularFactor;
btVector3DoubleData m_linearFactor;
btVector3DoubleData m_gravity;
btVector3DoubleData m_gravity_acceleration;
btVector3DoubleData m_invInertiaLocal;
btVector3DoubleData m_totalForce;
btVector3DoubleData m_totalTorque;
double m_inverseMass;
double m_linearDamping;
double m_angularDamping;
double m_additionalDampingFactor;
double m_additionalLinearDampingThresholdSqr;
double m_additionalAngularDampingThresholdSqr;
double m_additionalAngularDampingFactor;
double m_linearSleepingThreshold;
double m_angularSleepingThreshold;
int m_additionalDamping;
char m_padding[4];
btCollisionObjectDoubleData m_collisionObjectData;
btMatrix3x3DoubleData m_invInertiaTensorWorld;
btVector3DoubleData m_linearVelocity;
btVector3DoubleData m_angularVelocity;
btVector3DoubleData m_angularFactor;
btVector3DoubleData m_linearFactor;
btVector3DoubleData m_gravity;
btVector3DoubleData m_gravity_acceleration;
btVector3DoubleData m_invInertiaLocal;
btVector3DoubleData m_totalForce;
btVector3DoubleData m_totalTorque;
double m_inverseMass;
double m_linearDamping;
double m_angularDamping;
double m_additionalDampingFactor;
double m_additionalLinearDampingThresholdSqr;
double m_additionalAngularDampingThresholdSqr;
double m_additionalAngularDampingFactor;
double m_linearSleepingThreshold;
double m_angularSleepingThreshold;
int m_additionalDamping;
char m_padding[4];
};
#endif //BT_RIGIDBODY_H
#endif //BT_RIGIDBODY_H

View File

@@ -21,47 +21,40 @@ subject to the following restrictions:
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
/*
Make sure this dummy function never changes so that it
can be used by probes that are checking whether the
library is actually installed.
*/
extern "C"
extern "C"
{
void btBulletDynamicsProbe ();
void btBulletDynamicsProbe () {}
void btBulletDynamicsProbe();
void btBulletDynamicsProbe() {}
}
btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
m_constraintSolver(constraintSolver),
m_ownsConstraintSolver(false),
m_gravity(0,0,-10)
btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration)
: btDynamicsWorld(dispatcher, pairCache, collisionConfiguration),
m_constraintSolver(constraintSolver),
m_ownsConstraintSolver(false),
m_gravity(0, 0, -10)
{
}
btSimpleDynamicsWorld::~btSimpleDynamicsWorld()
{
if (m_ownsConstraintSolver)
btAlignedFree( m_constraintSolver);
btAlignedFree(m_constraintSolver);
}
int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
int btSimpleDynamicsWorld::stepSimulation(btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep)
{
(void)fixedTimeStep;
(void)maxSubSteps;
///apply gravity, predict motion
predictUnconstraintMotion(timeStep);
btDispatcherInfo& dispatchInfo = getDispatchInfo();
btDispatcherInfo& dispatchInfo = getDispatchInfo();
dispatchInfo.m_timeStep = timeStep;
dispatchInfo.m_stepCount = 0;
dispatchInfo.m_debugDraw = getDebugDrawer();
@@ -74,17 +67,17 @@ int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, b
if (numManifolds)
{
btPersistentManifold** manifoldPtr = ((btCollisionDispatcher*)m_dispatcher1)->getInternalManifoldPointer();
btContactSolverInfo infoGlobal;
infoGlobal.m_timeStep = timeStep;
m_constraintSolver->prepareSolve(0,numManifolds);
m_constraintSolver->solveGroup(&getCollisionObjectArray()[0],getNumCollisionObjects(),manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_dispatcher1);
m_constraintSolver->allSolved(infoGlobal,m_debugDrawer);
m_constraintSolver->prepareSolve(0, numManifolds);
m_constraintSolver->solveGroup(&getCollisionObjectArray()[0], getNumCollisionObjects(), manifoldPtr, numManifolds, 0, 0, infoGlobal, m_debugDrawer, m_dispatcher1);
m_constraintSolver->allSolved(infoGlobal, m_debugDrawer);
}
///integrate transforms
integrateTransforms(timeStep);
updateAabbs();
synchronizeMotionStates();
@@ -92,29 +85,27 @@ int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, b
clearForces();
return 1;
}
void btSimpleDynamicsWorld::clearForces()
void btSimpleDynamicsWorld::clearForces()
{
///@todo: iterate over awake simulation islands!
for ( int i=0;i<m_collisionObjects.size();i++)
for (int i = 0; i < m_collisionObjects.size(); i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
body->clearForces();
}
}
}
}
void btSimpleDynamicsWorld::setGravity(const btVector3& gravity)
void btSimpleDynamicsWorld::setGravity(const btVector3& gravity)
{
m_gravity = gravity;
for ( int i=0;i<m_collisionObjects.size();i++)
for (int i = 0; i < m_collisionObjects.size(); i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -125,17 +116,17 @@ void btSimpleDynamicsWorld::setGravity(const btVector3& gravity)
}
}
btVector3 btSimpleDynamicsWorld::getGravity () const
btVector3 btSimpleDynamicsWorld::getGravity() const
{
return m_gravity;
}
void btSimpleDynamicsWorld::removeRigidBody(btRigidBody* body)
void btSimpleDynamicsWorld::removeRigidBody(btRigidBody* body)
{
btCollisionWorld::removeCollisionObject(body);
}
void btSimpleDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
void btSimpleDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
{
btRigidBody* body = btRigidBody::upcast(collisionObject);
if (body)
@@ -144,8 +135,7 @@ void btSimpleDynamicsWorld::removeCollisionObject(btCollisionObject* collisionOb
btCollisionWorld::removeCollisionObject(collisionObject);
}
void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body)
void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body)
{
body->setGravity(m_gravity);
@@ -155,37 +145,32 @@ void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body)
}
}
void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body, int group, int mask)
void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body, int group, int mask)
{
body->setGravity(m_gravity);
if (body->getCollisionShape())
{
addCollisionObject(body,group,mask);
addCollisionObject(body, group, mask);
}
}
void btSimpleDynamicsWorld::debugDrawWorld()
void btSimpleDynamicsWorld::debugDrawWorld()
{
}
void btSimpleDynamicsWorld::addAction(btActionInterface* action)
{
}
void btSimpleDynamicsWorld::removeAction(btActionInterface* action)
void btSimpleDynamicsWorld::addAction(btActionInterface* action)
{
}
void btSimpleDynamicsWorld::removeAction(btActionInterface* action)
{
}
void btSimpleDynamicsWorld::updateAabbs()
void btSimpleDynamicsWorld::updateAabbs()
{
btTransform predictedTrans;
for ( int i=0;i<m_collisionObjects.size();i++)
for (int i = 0; i < m_collisionObjects.size(); i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -193,19 +178,19 @@ void btSimpleDynamicsWorld::updateAabbs()
{
if (body->isActive() && (!body->isStaticObject()))
{
btVector3 minAabb,maxAabb;
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
btVector3 minAabb, maxAabb;
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb, maxAabb);
btBroadphaseInterface* bp = getBroadphase();
bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
bp->setAabb(body->getBroadphaseHandle(), minAabb, maxAabb, m_dispatcher1);
}
}
}
}
void btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep)
void btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep)
{
btTransform predictedTrans;
for ( int i=0;i<m_collisionObjects.size();i++)
for (int i = 0; i < m_collisionObjects.size(); i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -214,17 +199,15 @@ void btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep)
if (body->isActive() && (!body->isStaticObject()))
{
body->predictIntegratedTransform(timeStep, predictedTrans);
body->proceedToTransform( predictedTrans);
body->proceedToTransform(predictedTrans);
}
}
}
}
void btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
void btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
{
for ( int i=0;i<m_collisionObjects.size();i++)
for (int i = 0; i < m_collisionObjects.size(); i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -235,20 +218,19 @@ void btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
if (body->isActive())
{
body->applyGravity();
body->integrateVelocities( timeStep);
body->integrateVelocities(timeStep);
body->applyDamping(timeStep);
body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
body->predictIntegratedTransform(timeStep, body->getInterpolationWorldTransform());
}
}
}
}
}
void btSimpleDynamicsWorld::synchronizeMotionStates()
void btSimpleDynamicsWorld::synchronizeMotionStates()
{
///@todo: iterate over awake simulation islands!
for ( int i=0;i<m_collisionObjects.size();i++)
for (int i = 0; i < m_collisionObjects.size(); i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -260,11 +242,9 @@ void btSimpleDynamicsWorld::synchronizeMotionStates()
}
}
}
}
void btSimpleDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
void btSimpleDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
{
if (m_ownsConstraintSolver)
{

View File

@@ -27,63 +27,58 @@ class btConstraintSolver;
class btSimpleDynamicsWorld : public btDynamicsWorld
{
protected:
btConstraintSolver* m_constraintSolver;
btConstraintSolver* m_constraintSolver;
bool m_ownsConstraintSolver;
bool m_ownsConstraintSolver;
void predictUnconstraintMotion(btScalar timeStep);
void integrateTransforms(btScalar timeStep);
btVector3 m_gravity;
void predictUnconstraintMotion(btScalar timeStep);
void integrateTransforms(btScalar timeStep);
btVector3 m_gravity;
public:
///this btSimpleDynamicsWorld constructor creates dispatcher, broadphase pairCache and constraintSolver
btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
btSimpleDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration);
virtual ~btSimpleDynamicsWorld();
///maxSubSteps/fixedTimeStep for interpolation is currently ignored for btSimpleDynamicsWorld, use btDiscreteDynamicsWorld instead
virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
virtual int stepSimulation(btScalar timeStep, int maxSubSteps = 1, btScalar fixedTimeStep = btScalar(1.) / btScalar(60.));
virtual void setGravity(const btVector3& gravity);
virtual void setGravity(const btVector3& gravity);
virtual btVector3 getGravity () const;
virtual btVector3 getGravity() const;
virtual void addRigidBody(btRigidBody* body);
virtual void addRigidBody(btRigidBody* body);
virtual void addRigidBody(btRigidBody* body, int group, int mask);
virtual void addRigidBody(btRigidBody* body, int group, int mask);
virtual void removeRigidBody(btRigidBody* body);
virtual void removeRigidBody(btRigidBody* body);
virtual void debugDrawWorld();
virtual void addAction(btActionInterface* action);
virtual void debugDrawWorld();
virtual void removeAction(btActionInterface* action);
virtual void addAction(btActionInterface* action);
virtual void removeAction(btActionInterface* action);
///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btCollisionWorld::removeCollisionObject
virtual void removeCollisionObject(btCollisionObject* collisionObject);
virtual void updateAabbs();
virtual void removeCollisionObject(btCollisionObject* collisionObject);
virtual void synchronizeMotionStates();
virtual void updateAabbs();
virtual void setConstraintSolver(btConstraintSolver* solver);
virtual void synchronizeMotionStates();
virtual void setConstraintSolver(btConstraintSolver* solver);
virtual btConstraintSolver* getConstraintSolver();
virtual btDynamicsWorldType getWorldType() const
virtual btDynamicsWorldType getWorldType() const
{
return BT_SIMPLE_DYNAMICS_WORLD;
}
virtual void clearForces();
virtual void clearForces();
};
#endif //BT_SIMPLE_DYNAMICS_WORLD_H
#endif //BT_SIMPLE_DYNAMICS_WORLD_H

File diff suppressed because it is too large Load Diff

View File

@@ -35,80 +35,78 @@ class btIDebugDraw;
class btSimulationIslandManagerMt : public btSimulationIslandManager
{
public:
struct Island
{
// a simulation island consisting of bodies, manifolds and constraints,
// to be passed into a constraint solver.
btAlignedObjectArray<btCollisionObject*> bodyArray;
btAlignedObjectArray<btPersistentManifold*> manifoldArray;
btAlignedObjectArray<btTypedConstraint*> constraintArray;
int id; // island id
bool isSleeping;
struct Island
{
// a simulation island consisting of bodies, manifolds and constraints,
// to be passed into a constraint solver.
btAlignedObjectArray<btCollisionObject*> bodyArray;
btAlignedObjectArray<btPersistentManifold*> manifoldArray;
btAlignedObjectArray<btTypedConstraint*> constraintArray;
int id; // island id
bool isSleeping;
void append( const Island& other ); // add bodies, manifolds, constraints to my own
};
struct SolverParams
{
btConstraintSolver* m_solverPool;
btConstraintSolver* m_solverMt;
btContactSolverInfo* m_solverInfo;
btIDebugDraw* m_debugDrawer;
btDispatcher* m_dispatcher;
};
static void solveIsland(btConstraintSolver* solver, Island& island, const SolverParams& solverParams);
void append(const Island& other); // add bodies, manifolds, constraints to my own
};
struct SolverParams
{
btConstraintSolver* m_solverPool;
btConstraintSolver* m_solverMt;
btContactSolverInfo* m_solverInfo;
btIDebugDraw* m_debugDrawer;
btDispatcher* m_dispatcher;
};
static void solveIsland(btConstraintSolver* solver, Island& island, const SolverParams& solverParams);
typedef void (*IslandDispatchFunc)(btAlignedObjectArray<Island*>* islands, const SolverParams& solverParams);
static void serialIslandDispatch(btAlignedObjectArray<Island*>* islandsPtr, const SolverParams& solverParams);
static void parallelIslandDispatch(btAlignedObjectArray<Island*>* islandsPtr, const SolverParams& solverParams);
typedef void( *IslandDispatchFunc ) ( btAlignedObjectArray<Island*>* islands, const SolverParams& solverParams );
static void serialIslandDispatch( btAlignedObjectArray<Island*>* islandsPtr, const SolverParams& solverParams );
static void parallelIslandDispatch( btAlignedObjectArray<Island*>* islandsPtr, const SolverParams& solverParams );
protected:
btAlignedObjectArray<Island*> m_allocatedIslands; // owner of all Islands
btAlignedObjectArray<Island*> m_activeIslands; // islands actively in use
btAlignedObjectArray<Island*> m_freeIslands; // islands ready to be reused
btAlignedObjectArray<Island*> m_lookupIslandFromId; // big lookup table to map islandId to Island pointer
Island* m_batchIsland;
int m_minimumSolverBatchSize;
int m_batchIslandMinBodyCount;
IslandDispatchFunc m_islandDispatch;
btAlignedObjectArray<Island*> m_allocatedIslands; // owner of all Islands
btAlignedObjectArray<Island*> m_activeIslands; // islands actively in use
btAlignedObjectArray<Island*> m_freeIslands; // islands ready to be reused
btAlignedObjectArray<Island*> m_lookupIslandFromId; // big lookup table to map islandId to Island pointer
Island* m_batchIsland;
int m_minimumSolverBatchSize;
int m_batchIslandMinBodyCount;
IslandDispatchFunc m_islandDispatch;
Island* getIsland(int id);
virtual Island* allocateIsland(int id, int numBodies);
virtual void initIslandPools();
virtual void addBodiesToIslands(btCollisionWorld* collisionWorld);
virtual void addManifoldsToIslands(btDispatcher* dispatcher);
virtual void addConstraintsToIslands(btAlignedObjectArray<btTypedConstraint*>& constraints);
virtual void mergeIslands();
Island* getIsland( int id );
virtual Island* allocateIsland( int id, int numBodies );
virtual void initIslandPools();
virtual void addBodiesToIslands( btCollisionWorld* collisionWorld );
virtual void addManifoldsToIslands( btDispatcher* dispatcher );
virtual void addConstraintsToIslands( btAlignedObjectArray<btTypedConstraint*>& constraints );
virtual void mergeIslands();
public:
btSimulationIslandManagerMt();
virtual ~btSimulationIslandManagerMt();
virtual void buildAndProcessIslands( btDispatcher* dispatcher,
btCollisionWorld* collisionWorld,
btAlignedObjectArray<btTypedConstraint*>& constraints,
const SolverParams& solverParams
);
virtual void buildAndProcessIslands(btDispatcher* dispatcher,
btCollisionWorld* collisionWorld,
btAlignedObjectArray<btTypedConstraint*>& constraints,
const SolverParams& solverParams);
virtual void buildIslands(btDispatcher* dispatcher,btCollisionWorld* colWorld);
virtual void buildIslands(btDispatcher* dispatcher, btCollisionWorld* colWorld);
int getMinimumSolverBatchSize() const
{
return m_minimumSolverBatchSize;
}
void setMinimumSolverBatchSize( int sz )
{
m_minimumSolverBatchSize = sz;
}
IslandDispatchFunc getIslandDispatchFunction() const
{
return m_islandDispatch;
}
// allow users to set their own dispatch function for multithreaded dispatch
void setIslandDispatchFunction( IslandDispatchFunc func )
{
m_islandDispatch = func;
}
int getMinimumSolverBatchSize() const
{
return m_minimumSolverBatchSize;
}
void setMinimumSolverBatchSize(int sz)
{
m_minimumSolverBatchSize = sz;
}
IslandDispatchFunc getIslandDispatchFunction() const
{
return m_islandDispatch;
}
// allow users to set their own dispatch function for multithreaded dispatch
void setIslandDispatchFunction(IslandDispatchFunc func)
{
m_islandDispatch = func;
}
};
#endif //BT_SIMULATION_ISLAND_MANAGER_H
#endif //BT_SIMULATION_ISLAND_MANAGER_H