+ improved split impulse constraint solver option
+ improved friction warm starting + made constraint solver configuration more consistent (moved m_solverMode into btContactSolverInfo) + reset timing in CDTestFramework after initialization (SAP init destorts timings) + make it easier to change default sizes for stack allocator in btDefaultCollisionConfiguration
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
@@ -26,6 +25,7 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
|
||||
|
||||
|
||||
@@ -35,17 +35,24 @@ subject to the following restrictions:
|
||||
|
||||
|
||||
|
||||
#define DEFAULT_MAX_OVERLAPPING_PAIRS 65535
|
||||
#define DEFAULT_STACK_ALLOCATOR_SIZE (5*1024*1024)
|
||||
|
||||
|
||||
btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool)
|
||||
btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
|
||||
//btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool)
|
||||
{
|
||||
|
||||
void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16);
|
||||
m_simplexSolver = new (mem)btVoronoiSimplexSolver();
|
||||
|
||||
#define USE_EPA 1
|
||||
#ifdef USE_EPA
|
||||
mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16);
|
||||
m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver;
|
||||
#else
|
||||
mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver),16);
|
||||
m_pdSolver = new (mem)btMinkowskiPenetrationDepthSolver;
|
||||
#endif//USE_EPA
|
||||
|
||||
|
||||
//default CreationFunctions, filling the m_doubleDispatch table
|
||||
mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16);
|
||||
@@ -94,37 +101,37 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* s
|
||||
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
|
||||
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4);
|
||||
|
||||
if (stackAlloc)
|
||||
if (constructionInfo.m_stackAlloc)
|
||||
{
|
||||
m_ownsStackAllocator = false;
|
||||
this->m_stackAlloc = stackAlloc;
|
||||
this->m_stackAlloc = constructionInfo.m_stackAlloc;
|
||||
} else
|
||||
{
|
||||
m_ownsStackAllocator = true;
|
||||
void* mem = btAlignedAlloc(sizeof(btStackAlloc),16);
|
||||
m_stackAlloc = new(mem)btStackAlloc(DEFAULT_STACK_ALLOCATOR_SIZE);
|
||||
m_stackAlloc = new(mem)btStackAlloc(constructionInfo.m_defaultStackAllocatorSize);
|
||||
}
|
||||
|
||||
if (persistentManifoldPool)
|
||||
if (constructionInfo.m_persistentManifoldPool)
|
||||
{
|
||||
m_ownsPersistentManifoldPool = false;
|
||||
m_persistentManifoldPool = persistentManifoldPool;
|
||||
m_persistentManifoldPool = constructionInfo.m_persistentManifoldPool;
|
||||
} else
|
||||
{
|
||||
m_ownsPersistentManifoldPool = true;
|
||||
void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
|
||||
m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),DEFAULT_MAX_OVERLAPPING_PAIRS);
|
||||
m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),constructionInfo.m_defaultMaxPersistentManifoldPoolSize);
|
||||
}
|
||||
|
||||
if (collisionAlgorithmPool)
|
||||
if (constructionInfo.m_collisionAlgorithmPool)
|
||||
{
|
||||
m_ownsCollisionAlgorithmPool = false;
|
||||
m_collisionAlgorithmPool = collisionAlgorithmPool;
|
||||
m_collisionAlgorithmPool = constructionInfo.m_collisionAlgorithmPool;
|
||||
} else
|
||||
{
|
||||
m_ownsCollisionAlgorithmPool = true;
|
||||
void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
|
||||
m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,DEFAULT_MAX_OVERLAPPING_PAIRS);
|
||||
m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +194,9 @@ btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
|
||||
|
||||
m_simplexSolver->~btVoronoiSimplexSolver();
|
||||
btAlignedFree(m_simplexSolver);
|
||||
m_pdSolver->~btGjkEpaPenetrationDepthSolver();
|
||||
|
||||
m_pdSolver->~btConvexPenetrationDepthSolver();
|
||||
|
||||
btAlignedFree(m_pdSolver);
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,28 @@ subject to the following restrictions:
|
||||
|
||||
#include "btCollisionConfiguration.h"
|
||||
class btVoronoiSimplexSolver;
|
||||
class btGjkEpaPenetrationDepthSolver;
|
||||
class btConvexPenetrationDepthSolver;
|
||||
|
||||
struct btDefaultCollisionConstructionInfo
|
||||
{
|
||||
btStackAlloc* m_stackAlloc;
|
||||
btPoolAllocator* m_persistentManifoldPool;
|
||||
btPoolAllocator* m_collisionAlgorithmPool;
|
||||
int m_defaultMaxPersistentManifoldPoolSize;
|
||||
int m_defaultMaxCollisionAlgorithmPoolSize;
|
||||
int m_defaultStackAllocatorSize;
|
||||
|
||||
btDefaultCollisionConstructionInfo()
|
||||
:m_stackAlloc(0),
|
||||
m_persistentManifoldPool(0),
|
||||
m_collisionAlgorithmPool(0),
|
||||
m_defaultMaxPersistentManifoldPoolSize(65535),
|
||||
m_defaultMaxCollisionAlgorithmPoolSize(65535),
|
||||
m_defaultStackAllocatorSize(5*1024*1024)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
///btCollisionConfiguration allows to configure Bullet collision detection
|
||||
@@ -40,7 +61,7 @@ class btDefaultCollisionConfiguration : public btCollisionConfiguration
|
||||
|
||||
//default simplex/penetration depth solvers
|
||||
btVoronoiSimplexSolver* m_simplexSolver;
|
||||
btGjkEpaPenetrationDepthSolver* m_pdSolver;
|
||||
btConvexPenetrationDepthSolver* m_pdSolver;
|
||||
|
||||
//default CreationFunctions, filling the m_doubleDispatch table
|
||||
btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc;
|
||||
@@ -60,7 +81,8 @@ class btDefaultCollisionConfiguration : public btCollisionConfiguration
|
||||
|
||||
public:
|
||||
|
||||
btDefaultCollisionConfiguration(btStackAlloc* stackAlloc=0,btPoolAllocator* persistentManifoldPool=0,btPoolAllocator* collisionAlgorithmPool=0);
|
||||
|
||||
btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo());
|
||||
|
||||
virtual ~btDefaultCollisionConfiguration();
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ class btManifoldPoint
|
||||
btManifoldPoint()
|
||||
:m_userPersistentData(0),
|
||||
m_appliedImpulse(0.f),
|
||||
m_lateralFrictionInitialized(false),
|
||||
m_lifeTime(0)
|
||||
{
|
||||
}
|
||||
@@ -46,6 +47,9 @@ class btManifoldPoint
|
||||
m_combinedRestitution(btScalar(0.)),
|
||||
m_userPersistentData(0),
|
||||
m_appliedImpulse(0.f),
|
||||
m_lateralFrictionInitialized(false),
|
||||
m_appliedImpulseLateral1(0.f),
|
||||
m_appliedImpulseLateral2(0.f),
|
||||
m_lifeTime(0)
|
||||
{
|
||||
|
||||
@@ -74,8 +78,14 @@ class btManifoldPoint
|
||||
mutable void* m_userPersistentData;
|
||||
btScalar m_appliedImpulse;
|
||||
|
||||
int m_lifeTime;//lifetime of the contactpoint in frames
|
||||
bool m_lateralFrictionInitialized;
|
||||
btScalar m_appliedImpulseLateral1;
|
||||
btScalar m_appliedImpulseLateral2;
|
||||
int m_lifeTime;//lifetime of the contactpoint in frames
|
||||
|
||||
btVector3 m_lateralFrictionDir1;
|
||||
btVector3 m_lateralFrictionDir2;
|
||||
|
||||
btScalar getDistance() const
|
||||
{
|
||||
return m_distance1;
|
||||
|
||||
@@ -125,6 +125,9 @@ public:
|
||||
//get rid of duplicated userPersistentData pointer
|
||||
m_pointCache[lastUsedIndex].m_userPersistentData = 0;
|
||||
m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
|
||||
m_pointCache[lastUsedIndex].m_lateralFrictionInitialized = false;
|
||||
m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
|
||||
m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
|
||||
m_pointCache[lastUsedIndex].m_lifeTime = 0;
|
||||
}
|
||||
|
||||
@@ -139,6 +142,9 @@ public:
|
||||
#ifdef MAINTAIN_PERSISTENCY
|
||||
int lifeTime = m_pointCache[insertIndex].getLifeTime();
|
||||
btScalar appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
|
||||
btScalar appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
|
||||
btScalar appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
|
||||
|
||||
btAssert(lifeTime>=0);
|
||||
void* cache = m_pointCache[insertIndex].m_userPersistentData;
|
||||
|
||||
@@ -146,6 +152,9 @@ public:
|
||||
|
||||
m_pointCache[insertIndex].m_userPersistentData = cache;
|
||||
m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
|
||||
m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
|
||||
m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
|
||||
|
||||
m_pointCache[insertIndex].m_lifeTime = lifeTime;
|
||||
#else
|
||||
clearUserCache(m_pointCache[insertIndex]);
|
||||
|
||||
@@ -16,8 +16,18 @@ subject to the following restrictions:
|
||||
#ifndef CONTACT_SOLVER_INFO
|
||||
#define CONTACT_SOLVER_INFO
|
||||
|
||||
enum btSolverMode
|
||||
{
|
||||
SOLVER_RANDMIZE_ORDER = 1,
|
||||
SOLVER_FRICTION_SEPARATE = 2,
|
||||
SOLVER_USE_WARMSTARTING = 4,
|
||||
SOLVER_CACHE_FRIENDLY = 8
|
||||
};
|
||||
|
||||
struct btContactSolverInfoData
|
||||
{
|
||||
|
||||
|
||||
btScalar m_tau;
|
||||
btScalar m_damping;
|
||||
btScalar m_friction;
|
||||
@@ -27,10 +37,13 @@ struct btContactSolverInfoData
|
||||
btScalar m_maxErrorReduction;
|
||||
btScalar m_sor;
|
||||
btScalar m_erp;//used as Baumgarte factor
|
||||
bool m_splitImpulse;
|
||||
btScalar m_erp2;//used in Split Impulse
|
||||
int m_splitImpulse;
|
||||
btScalar m_splitImpulsePenetrationThreshold;
|
||||
btScalar m_linearSlop;
|
||||
btScalar m_warmstartingFactor;
|
||||
|
||||
int m_solverMode;
|
||||
|
||||
|
||||
};
|
||||
@@ -38,6 +51,8 @@ struct btContactSolverInfoData
|
||||
struct btContactSolverInfo : public btContactSolverInfoData
|
||||
{
|
||||
|
||||
|
||||
|
||||
inline btContactSolverInfo()
|
||||
{
|
||||
m_tau = btScalar(0.6);
|
||||
@@ -47,10 +62,13 @@ struct btContactSolverInfo : public btContactSolverInfoData
|
||||
m_maxErrorReduction = btScalar(20.);
|
||||
m_numIterations = 10;
|
||||
m_erp = btScalar(0.2);
|
||||
m_erp2 = btScalar(0.1);
|
||||
m_sor = btScalar(1.3);
|
||||
m_splitImpulse = true;
|
||||
m_splitImpulsePenetrationThreshold = 1.f;
|
||||
m_linearSlop = 0.0002f;
|
||||
m_splitImpulse = false;
|
||||
m_splitImpulsePenetrationThreshold = -0.02f;
|
||||
m_linearSlop = btScalar(0.0);
|
||||
m_warmstartingFactor=btScalar(0.85);
|
||||
m_solverMode = SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY | SOLVER_USE_WARMSTARTING;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -297,18 +297,6 @@ void btOdeQuickstepConstraintSolver::ConvertConstraint(btPersistentManifold* man
|
||||
for (i=0;i<numContacts;i++)
|
||||
{
|
||||
|
||||
if (debugDrawer)
|
||||
{
|
||||
const btManifoldPoint& cp = manifold->getContactPoint(i);
|
||||
|
||||
debugDrawer->drawContactPoint(
|
||||
cp.m_positionWorldOnB,
|
||||
cp.m_normalWorldOnB,
|
||||
cp.getDistance(),
|
||||
cp.getLifeTime(),
|
||||
color);
|
||||
|
||||
}
|
||||
//assert (m_CurJoint < ODE_MAX_SOLVER_JOINTS);
|
||||
|
||||
// if (manifold->getContactPoint(i).getDistance() < 0.0f)
|
||||
|
||||
@@ -106,8 +106,7 @@ bool MyContactDestroyedCallback(void* userPersistentData)
|
||||
|
||||
|
||||
btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
|
||||
:m_solverMode(SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY | SOLVER_USE_WARMSTARTING ),
|
||||
m_btSeed2(0)
|
||||
:m_btSeed2(0)
|
||||
{
|
||||
gContactDestroyedCallback = &MyContactDestroyedCallback;
|
||||
|
||||
@@ -154,6 +153,8 @@ void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject
|
||||
solverBody->m_turnVelocity.setValue(0.f,0.f,0.f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int gNumSplitImpulseRecoveries = 0;
|
||||
|
||||
btScalar restitutionCurve(btScalar rel_vel, btScalar restitution);
|
||||
@@ -179,7 +180,7 @@ void resolveSplitPenetrationImpulseCacheFriendly(
|
||||
{
|
||||
(void)solverInfo;
|
||||
|
||||
if (contactConstraint.m_penetration > solverInfo.m_splitImpulsePenetrationThreshold)
|
||||
if (contactConstraint.m_penetration < solverInfo.m_splitImpulsePenetrationThreshold)
|
||||
{
|
||||
|
||||
gNumSplitImpulseRecoveries++;
|
||||
@@ -200,7 +201,7 @@ void resolveSplitPenetrationImpulseCacheFriendly(
|
||||
rel_vel = vel1Dotn-vel2Dotn;
|
||||
|
||||
|
||||
btScalar positionalError = contactConstraint.m_penetration;
|
||||
btScalar positionalError = -contactConstraint.m_penetration * solverInfo.m_erp2/solverInfo.m_timeStep;
|
||||
// btScalar positionalError = contactConstraint.m_penetration;
|
||||
|
||||
btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping;
|
||||
@@ -264,9 +265,9 @@ btScalar resolveSingleCollisionCombinedCacheFriendly(
|
||||
rel_vel = vel1Dotn-vel2Dotn;
|
||||
|
||||
btScalar positionalError = 0.f;
|
||||
if (!solverInfo.m_splitImpulse || (contactConstraint.m_penetration<solverInfo.m_splitImpulsePenetrationThreshold))
|
||||
if (!solverInfo.m_splitImpulse || (contactConstraint.m_penetration > solverInfo.m_splitImpulsePenetrationThreshold))
|
||||
{
|
||||
positionalError = contactConstraint.m_penetration;
|
||||
positionalError = -contactConstraint.m_penetration * solverInfo.m_erp/solverInfo.m_timeStep;
|
||||
}
|
||||
|
||||
btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping;
|
||||
@@ -725,8 +726,10 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
solverConstraint.m_restitution = 0.f;
|
||||
};
|
||||
|
||||
|
||||
btScalar penVel = -solverConstraint.m_penetration/infoGlobal.m_timeStep;
|
||||
solverConstraint.m_penetration *= -(infoGlobal.m_erp/infoGlobal.m_timeStep);
|
||||
|
||||
|
||||
|
||||
if (solverConstraint.m_restitution > penVel)
|
||||
{
|
||||
@@ -736,42 +739,78 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
|
||||
|
||||
///warm starting (or zero if disabled)
|
||||
if (m_solverMode & SOLVER_USE_WARMSTARTING)
|
||||
if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
|
||||
{
|
||||
solverConstraint.m_appliedImpulse = cp.m_appliedImpulse;
|
||||
solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
|
||||
if (rb0)
|
||||
m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass(),solverConstraint.m_angularComponentA,cp.m_appliedImpulse);
|
||||
m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
|
||||
if (rb1)
|
||||
m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass(),solverConstraint.m_angularComponentB,-cp.m_appliedImpulse);
|
||||
m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass(),solverConstraint.m_angularComponentB,-solverConstraint.m_appliedImpulse);
|
||||
} else
|
||||
{
|
||||
solverConstraint.m_appliedImpulse = 0.f;
|
||||
}
|
||||
|
||||
solverConstraint.m_appliedPushImpulse = 0.f;
|
||||
}
|
||||
|
||||
{
|
||||
btVector3 frictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
|
||||
btScalar lat_rel_vel = frictionDir1.length2();
|
||||
if (lat_rel_vel > SIMD_EPSILON)//0.0f)
|
||||
|
||||
solverConstraint.m_frictionIndex = m_tmpSolverFrictionConstraintPool.size();
|
||||
if (!cp.m_lateralFrictionInitialized)
|
||||
{
|
||||
frictionDir1 /= btSqrt(lat_rel_vel);
|
||||
addFrictionConstraint(frictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
btVector3 frictionDir2 = frictionDir1.cross(cp.m_normalWorldOnB);
|
||||
frictionDir2.normalize();//??
|
||||
addFrictionConstraint(frictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
|
||||
btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2();
|
||||
if (lat_rel_vel > SIMD_EPSILON)//0.0f)
|
||||
{
|
||||
cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel);
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
|
||||
cp.m_lateralFrictionDir2.normalize();//??
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
} else
|
||||
{
|
||||
//re-calculate friction direction every frame, todo: check if this is really needed
|
||||
|
||||
btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
}
|
||||
cp.m_lateralFrictionInitialized = true;
|
||||
|
||||
} else
|
||||
{
|
||||
//re-calculate friction direction every frame, todo: check if this is really needed
|
||||
btVector3 frictionDir1,frictionDir2;
|
||||
btPlaneSpace1(cp.m_normalWorldOnB,frictionDir1,frictionDir2);
|
||||
addFrictionConstraint(frictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
addFrictionConstraint(frictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
}
|
||||
|
||||
{
|
||||
btSolverConstraint& frictionConstraint1 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex];
|
||||
if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
|
||||
{
|
||||
frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
|
||||
if (rb0)
|
||||
m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
|
||||
if (rb1)
|
||||
m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass(),frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse);
|
||||
} else
|
||||
{
|
||||
frictionConstraint1.m_appliedImpulse = 0.f;
|
||||
}
|
||||
}
|
||||
{
|
||||
btSolverConstraint& frictionConstraint2 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
|
||||
if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
|
||||
{
|
||||
frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
|
||||
if (rb0)
|
||||
m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
|
||||
if (rb1)
|
||||
m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse);
|
||||
} else
|
||||
{
|
||||
frictionConstraint2.m_appliedImpulse = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -829,7 +868,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
|
||||
{
|
||||
|
||||
int j;
|
||||
if (m_solverMode & SOLVER_RANDMIZE_ORDER)
|
||||
if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
|
||||
{
|
||||
if ((iteration & 7) == 0) {
|
||||
for (j=0; j<numConstraintPool; ++j) {
|
||||
@@ -907,6 +946,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
|
||||
|
||||
if (infoGlobal.m_splitImpulse)
|
||||
{
|
||||
|
||||
for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
|
||||
{
|
||||
{
|
||||
@@ -946,6 +986,9 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio
|
||||
btManifoldPoint* pt = (btManifoldPoint*) solveManifold.m_originalContactPoint;
|
||||
btAssert(pt);
|
||||
pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
|
||||
pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
|
||||
pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
|
||||
|
||||
//do a callback here?
|
||||
|
||||
}
|
||||
@@ -989,7 +1032,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio
|
||||
btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc,btDispatcher* /*dispatcher*/)
|
||||
{
|
||||
BT_PROFILE("solveGroup");
|
||||
if (getSolverMode() & SOLVER_CACHE_FRIENDLY)
|
||||
if (infoGlobal.m_solverMode & SOLVER_CACHE_FRIENDLY)
|
||||
{
|
||||
//you need to provide at least some bodies
|
||||
//btSimpleDynamicsWorld needs to switch off SOLVER_CACHE_FRIENDLY
|
||||
@@ -1040,7 +1083,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bod
|
||||
for ( iteration = 0;iteration<numiter;iteration++)
|
||||
{
|
||||
int j;
|
||||
if (m_solverMode & SOLVER_RANDMIZE_ORDER)
|
||||
if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
|
||||
{
|
||||
if ((iteration & 7) == 0) {
|
||||
for (j=0; j<totalPoints; ++j) {
|
||||
@@ -1198,7 +1241,7 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol
|
||||
|
||||
|
||||
btScalar relaxation = info.m_damping;
|
||||
if (m_solverMode & SOLVER_USE_WARMSTARTING)
|
||||
if (info.m_solverMode & SOLVER_USE_WARMSTARTING)
|
||||
{
|
||||
cpd->m_appliedImpulse *= relaxation;
|
||||
} else
|
||||
|
||||
@@ -46,21 +46,13 @@ protected:
|
||||
ContactSolverFunc m_contactDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES];
|
||||
ContactSolverFunc m_frictionDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES];
|
||||
|
||||
//choose between several modes, different friction model etc.
|
||||
int m_solverMode;
|
||||
|
||||
///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
|
||||
unsigned long m_btSeed2;
|
||||
|
||||
public:
|
||||
|
||||
enum eSolverMode
|
||||
{
|
||||
SOLVER_RANDMIZE_ORDER = 1,
|
||||
SOLVER_FRICTION_SEPARATE = 2,
|
||||
SOLVER_USE_WARMSTARTING = 4,
|
||||
SOLVER_CACHE_FRIENDLY = 8
|
||||
};
|
||||
|
||||
|
||||
btSequentialImpulseConstraintSolver();
|
||||
|
||||
///Advanced: Override the default contact solving function for contacts, for certain types of rigidbody
|
||||
@@ -92,16 +84,7 @@ public:
|
||||
btScalar solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer);
|
||||
|
||||
|
||||
void setSolverMode(int mode)
|
||||
{
|
||||
m_solverMode = mode;
|
||||
}
|
||||
|
||||
int getSolverMode() const
|
||||
{
|
||||
return m_solverMode;
|
||||
}
|
||||
|
||||
|
||||
unsigned long btRand2();
|
||||
|
||||
int btRandInt2 (int n);
|
||||
|
||||
@@ -64,8 +64,8 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverBody
|
||||
m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void writebackVelocity()
|
||||
{
|
||||
if (m_invMass)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
@@ -23,7 +23,7 @@ class btOverlappingPairCache;
|
||||
class btConstraintSolver;
|
||||
class btSimulationIslandManager;
|
||||
class btTypedConstraint;
|
||||
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
|
||||
|
||||
|
||||
class btRaycastVehicle;
|
||||
class btIDebugDraw;
|
||||
@@ -52,9 +52,7 @@ protected:
|
||||
bool m_ownsIslandManager;
|
||||
bool m_ownsConstraintSolver;
|
||||
|
||||
btContactSolverInfo m_solverInfo;
|
||||
|
||||
|
||||
|
||||
btAlignedObjectArray<btRaycastVehicle*> m_vehicles;
|
||||
|
||||
int m_profileTimings;
|
||||
@@ -140,11 +138,7 @@ public:
|
||||
|
||||
virtual const btTypedConstraint* getConstraint(int index) const;
|
||||
|
||||
btContactSolverInfo& getSolverInfo()
|
||||
{
|
||||
return m_solverInfo;
|
||||
}
|
||||
|
||||
|
||||
virtual btDynamicsWorldType getWorldType() const
|
||||
{
|
||||
return BT_DISCRETE_DYNAMICS_WORLD;
|
||||
|
||||
@@ -17,11 +17,13 @@ subject to the following restrictions:
|
||||
#define BT_DYNAMICS_WORLD_H
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
|
||||
|
||||
class btTypedConstraint;
|
||||
class btRaycastVehicle;
|
||||
class btConstraintSolver;
|
||||
|
||||
class btDynamicsWorld;
|
||||
|
||||
/// Type for the callback for each tick
|
||||
typedef void (*btInternalTickCallback)(const btDynamicsWorld *world, btScalar timeStep);
|
||||
|
||||
@@ -35,7 +37,13 @@ enum btDynamicsWorldType
|
||||
///btDynamicsWorld is the baseclass for several dynamics implementation, basic, discrete, parallel, and continuous
|
||||
class btDynamicsWorld : public btCollisionWorld
|
||||
{
|
||||
public:
|
||||
|
||||
protected:
|
||||
btInternalTickCallback m_internalTickCallback;
|
||||
|
||||
btContactSolverInfo m_solverInfo;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration)
|
||||
@@ -89,8 +97,11 @@ class btDynamicsWorld : public btCollisionWorld
|
||||
|
||||
/// Set the callback for when an internal tick (simulation substep) happens
|
||||
void setInternalTickCallback(btInternalTickCallback cb) { m_internalTickCallback = cb; }
|
||||
|
||||
btInternalTickCallback m_internalTickCallback;
|
||||
|
||||
btContactSolverInfo& getSolverInfo()
|
||||
{
|
||||
return m_solverInfo;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -20,8 +20,8 @@ subject to the following restrictions:
|
||||
|
||||
#define ENABLE_SOFTBODY_CONCAVE_COLLISIONS 1
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool)
|
||||
:btDefaultCollisionConfiguration(stackAlloc,persistentManifoldPool,collisionAlgorithmPool)
|
||||
btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
|
||||
:btDefaultCollisionConfiguration(constructionInfo)
|
||||
{
|
||||
void* mem;
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class btSoftBodyRigidBodyCollisionConfiguration : public btDefaultCollisionConfi
|
||||
|
||||
public:
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration(btStackAlloc* stackAlloc=0,btPoolAllocator* persistentManifoldPool=0,btPoolAllocator* collisionAlgorithmPool=0);
|
||||
btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo());
|
||||
|
||||
virtual ~btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user