moved some hardcoded constants into tweaking tresholds

exposed those tresholds to python (more 'expert' settings)
This commit is contained in:
Erwin Coumans
2005-08-03 18:22:30 +00:00
parent 8a58197cf3
commit 2cc6d565cb
16 changed files with 349 additions and 51 deletions

View File

@@ -4,6 +4,7 @@
Version="8.00"
Name="Bullet3ContinuousCollision"
ProjectGUID="{FFD3C64A-30E2-4BC7-BC8F-51818C320400}"
SignManifests="true"
>
<Platforms>
<Platform
@@ -276,6 +277,14 @@
RelativePath=".\NarrowPhaseCollision\ManifoldPoint.h"
>
</File>
<File
RelativePath=".\NarrowPhaseCollision\ManifoldPointCollector.cpp"
>
</File>
<File
RelativePath=".\NarrowPhaseCollision\ManifoldPointCollector.h"
>
</File>
<File
RelativePath=".\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.cpp"
>
@@ -428,14 +437,6 @@
RelativePath=".\CollisionShapes\TriangleCallback.h"
>
</File>
<File
RelativePath=".\CollisionShapes\TriangleMesh.cpp"
>
</File>
<File
RelativePath=".\CollisionShapes\TriangleMesh.h"
>
</File>
<File
RelativePath=".\CollisionShapes\TriangleMeshShape.cpp"
>
@@ -508,10 +509,6 @@
RelativePath="..\LinearMath\GEN_random.h"
>
</File>
<File
RelativePath="..\LinearMath\IDebugDraw.h"
>
</File>
<File
RelativePath="..\LinearMath\SimdMatrix3x3.h"
>

View File

@@ -14,6 +14,7 @@
#include "SimdTransform.h"
#include <assert.h>
float gContactBreakingTreshold = 0.02f;
PersistentManifold::PersistentManifold()
:m_body0(0),
@@ -113,7 +114,7 @@ void PersistentManifold::AddManifoldPoint(const ManifoldPoint& newPoint)
float PersistentManifold::GetManifoldMargin() const
{
return 0.02f;
return gContactBreakingTreshold;
}
void PersistentManifold::RefreshContactPoints(const SimdTransform& trA,const SimdTransform& trB)

View File

@@ -19,6 +19,9 @@
struct CollisionResult;
///contact breaking and merging treshold
extern float gContactBreakingTreshold;
#define MANIFOLD_CACHE_SIZE 4
///PersistentManifold maintains contact points, and reduces them to 4

View File

@@ -38,7 +38,10 @@ ToiContactDispatcher::ToiContactDispatcher (ConstraintSolver* solver):
m_useIslands(true),
m_unionFind(MAX_RIGIDBODIES),
m_solver(solver),
m_count(0)
m_count(0),
m_sor(1.3f),
m_tau(0.4f),
m_damping(0.9f)
{
int i;
@@ -158,13 +161,15 @@ void ToiContactDispatcher::SolveConstraints(float timeStep, int numIterations,in
///This island solving can all be scheduled in parallel
ContactSolverInfo info;
info.m_damping = 0.9f;
info.m_friction = 0.9f;
info.m_numIterations = numIterations;
info.m_timeStep = timeStep;
info.m_tau = 0.4f;
info.m_restitution = 0.0f;//m_restitution;
info.m_sor = m_sor;
info.m_tau = m_tau;
info.m_damping = m_damping;
m_solver->SolveGroup( &islandmanifold[0], islandmanifold.size(),info,debugDrawer );

View File

@@ -44,6 +44,10 @@ class ToiContactDispatcher : public Dispatcher
UnionFind m_unionFind;
ConstraintSolver* m_solver;
float m_sor;
float m_tau;
float m_damping;
CollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
public:
@@ -97,6 +101,22 @@ public:
virtual int GetUniqueId() { return RIGIDBODY_DISPATCHER;}
void SetSor(float sor)
{
m_sor = sor;
}
void SetTau(float tau)
{
m_tau = tau;
}
void SetDamping( float damping)
{
m_damping = damping;
}
};
#endif //TOI_CONTACT_DISPATCHER_H

View File

@@ -23,6 +23,7 @@ struct ContactSolverInfo
m_restitution = 0.f;
m_maxErrorReduction = 20.f;
m_numIterations = 10;
m_sor = 1.3f;
}
float m_tau;
@@ -32,7 +33,7 @@ struct ContactSolverInfo
float m_restitution;
int m_numIterations;
float m_maxErrorReduction;
float m_sor;
};

View File

@@ -43,11 +43,13 @@ class BU_Joint;
//see below
OdeConstraintSolver::OdeConstraintSolver():
m_cfm(1e-5f),
m_erp(0.2f)
{
}
int ConvertBody(RigidBody* body,RigidBody** bodies,int& numBodies);
void ConvertConstraint(PersistentManifold* manifold,BU_Joint** joints,int& numJoints,
RigidBody** bodies,int bodyId0,int bodyId1);
@@ -59,8 +61,6 @@ float OdeConstraintSolver::SolveGroup(PersistentManifold** manifoldPtr, int numM
m_CurBody = 0;
m_CurJoint = 0;
float cfm = 1e-5f;
float erp = 0.2f;
RigidBody* bodies [128];
@@ -82,7 +82,7 @@ float OdeConstraintSolver::SolveGroup(PersistentManifold** manifoldPtr, int numM
}
}
SolveInternal1(cfm,erp,bodies,numBodies,joints,numJoints,infoGlobal);
SolveInternal1(m_cfm,m_erp,bodies,numBodies,joints,numJoints,infoGlobal);
return 0.f;

View File

@@ -25,6 +25,9 @@ private:
int m_CurBody;
int m_CurJoint;
float m_cfm;
float m_erp;
int ConvertBody(RigidBody* body,RigidBody** bodies,int& numBodies);
void ConvertConstraint(PersistentManifold* manifold,BU_Joint** joints,int& numJoints,
@@ -32,10 +35,24 @@ private:
public:
OdeConstraintSolver();
virtual ~OdeConstraintSolver() {}
virtual float SolveGroup(PersistentManifold** manifold,int numManifolds,const ContactSolverInfo& info,IDebugDraw* debugDrawer = 0);
///setConstraintForceMixing, the cfm adds some positive value to the main diagonal
///This can improve convergence (make matrix positive semidefinite), but it can make the simulation look more 'springy'
void setConstraintForceMixing(float cfm) {
m_cfm = cfm;
}
///setErrorReductionParamter sets the maximum amount of error reduction
///which limits energy addition during penetration depth recovery
void setErrorReductionParamter(float erp)
{
m_erp = erp;
}
};

View File

@@ -590,8 +590,8 @@ void SolveInternal1 (float global_cfm,
const ContactSolverInfo& solverInfo)
{
int numIter = 30;
float sOr = 1.3f;
int numIter = solverInfo.m_numIterations;
float sOr = solverInfo.m_sor;
int i,j;
@@ -756,7 +756,7 @@ void SolveInternal1 (float global_cfm,
// scale CFM
for (i=0; i<m; i++)
cfm[i] =0;//*= stepsize1;
cfm[i] *= stepsize1;
// load lambda from the value saved on the previous iteration
dRealAllocaArray (lambda,m);

View File

@@ -49,10 +49,26 @@ static char PhysicsConstraints_module_documentation[] =
static char gPySetGravity__doc__[] = "setGravity(float x,float y,float z)";
static char gPySetDebugMode__doc__[] = "setDebugMode(int mode)";
static char gPySetNumIterations__doc__[] = "setNumIterations(int numiter) This sets the number of iterations for an iterative constraint solver";
static char gPySetDeactivationTime__doc__[] = "setDeactivationTime(float time) This sets the time after which a resting rigidbody gets deactived";
static char gPySetDeactivationLinearTreshold__doc__[] = "setDeactivationLinearTreshold(float linearTreshold)";
static char gPySetDeactivationAngularTreshold__doc__[] = "setDeactivationAngularTreshold(float angularTreshold)";
static char gPySetContactBreakingTreshold__doc__[] = "setContactBreakingTreshold(float breakingTreshold) Reasonable default is 0.02 (if units are meters)";
static char gPySetCcdMode__doc__[] = "setCcdMode(int ccdMode) Very experimental, not recommended";
static char gPySetSorConstant__doc__[] = "setSorConstant(float sor) Very experimental, not recommended";
static char gPySetTau__doc__[] = "setTau(float tau) Very experimental, not recommended";
static char gPySetDamping__doc__[] = "setDamping(float damping) Very experimental, not recommended";
static char gPyCreateConstraint__doc__[] = "createConstraint(ob1,ob2,float restLength,float restitution,float damping)";
static char gPyRemoveConstraint__doc__[] = "removeConstraint(constraint id)";
static PyObject* gPySetGravity(PyObject* self,
PyObject* args,
PyObject* kwds)
@@ -81,13 +97,149 @@ static PyObject* gPySetDebugMode(PyObject* self,
}
}
printf("hi\n");
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPySetNumIterations(PyObject* self,
PyObject* args,
PyObject* kwds)
{
int iter;
if (PyArg_ParseTuple(args,"i",&iter))
{
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->setNumIterations(iter);
}
}
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPySetDeactivationTime(PyObject* self,
PyObject* args,
PyObject* kwds)
{
float deactive_time;
if (PyArg_ParseTuple(args,"f",&deactive_time))
{
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->setDeactivationTime(deactive_time);
}
}
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPySetDeactivationLinearTreshold(PyObject* self,
PyObject* args,
PyObject* kwds)
{
float linearDeactivationTreshold;
if (PyArg_ParseTuple(args,"f",&linearDeactivationTreshold))
{
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->setDeactivationLinearTreshold( linearDeactivationTreshold);
}
}
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPySetDeactivationAngularTreshold(PyObject* self,
PyObject* args,
PyObject* kwds)
{
float angularDeactivationTreshold;
if (PyArg_ParseTuple(args,"f",&angularDeactivationTreshold))
{
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->setDeactivationAngularTreshold( angularDeactivationTreshold);
}
}
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPySetContactBreakingTreshold(PyObject* self,
PyObject* args,
PyObject* kwds)
{
float contactBreakingTreshold;
if (PyArg_ParseTuple(args,"f",&contactBreakingTreshold))
{
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->setContactBreakingTreshold( contactBreakingTreshold);
}
}
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPySetCcdMode(PyObject* self,
PyObject* args,
PyObject* kwds)
{
float ccdMode;
if (PyArg_ParseTuple(args,"f",&ccdMode))
{
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->setCcdMode( ccdMode);
}
}
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPySetSorConstant(PyObject* self,
PyObject* args,
PyObject* kwds)
{
float sor;
if (PyArg_ParseTuple(args,"f",&sor))
{
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->setSolverSorConstant( sor);
}
}
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPySetTau(PyObject* self,
PyObject* args,
PyObject* kwds)
{
float tau;
if (PyArg_ParseTuple(args,"f",&tau))
{
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->setTau( tau);
}
}
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPySetDamping(PyObject* self,
PyObject* args,
PyObject* kwds)
{
float damping;
if (PyArg_ParseTuple(args,"f",&damping))
{
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->setDamping( damping);
}
}
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPyCreateConstraint(PyObject* self,
@@ -167,6 +319,30 @@ static struct PyMethodDef physicsconstraints_methods[] = {
{"setDebugMode",(PyCFunction) gPySetDebugMode,
METH_VARARGS, gPySetDebugMode__doc__},
/// settings that influence quality of the rigidbody dynamics
{"setNumIterations",(PyCFunction) gPySetNumIterations,
METH_VARARGS, gPySetNumIterations__doc__},
{"setDeactivationTime",(PyCFunction) gPySetDeactivationTime,
METH_VARARGS, gPySetDeactivationTime__doc__},
{"setDeactivationLinearTreshold",(PyCFunction) gPySetDeactivationLinearTreshold,
METH_VARARGS, gPySetDeactivationLinearTreshold__doc__},
{"setDeactivationAngularTreshold",(PyCFunction) gPySetDeactivationAngularTreshold,
METH_VARARGS, gPySetDeactivationAngularTreshold__doc__},
{"setContactBreakingTreshold",(PyCFunction) gPySetContactBreakingTreshold,
METH_VARARGS, gPySetContactBreakingTreshold__doc__},
{"setCcdMode",(PyCFunction) gPySetCcdMode,
METH_VARARGS, gPySetCcdMode__doc__},
{"setSorConstant",(PyCFunction) gPySetSorConstant,
METH_VARARGS, gPySetSorConstant__doc__},
{"setTau",(PyCFunction) gPySetTau,
METH_VARARGS, gPySetTau__doc__},
{"setDamping",(PyCFunction) gPySetDamping,
METH_VARARGS, gPySetDamping__doc__},
{"createConstraint",(PyCFunction) gPyCreateConstraint,
METH_VARARGS, gPyCreateConstraint__doc__},

View File

@@ -7,7 +7,11 @@
class BP_Proxy;
bool gEnableSleeping = false;//false;//true;
//'temporarily' global variables
float gDeactivationTime = 0.f;
float gLinearSleepingTreshold = 0.8f;
float gAngularSleepingTreshold = 1.0f;
#include "Dynamics/MassProps.h"
SimdVector3 startVel(0,0,0);//-10000);
@@ -190,27 +194,19 @@ void CcdPhysicsController::setNewClientInfo(void* clientinfo)
}
#ifdef WIN32
float gSleepingTreshold = 0.8f;
float gAngularSleepingTreshold = 1.f;
#else
float gSleepingTreshold = 0.8f;
float gAngularSleepingTreshold = 1.0f;
#endif
bool CcdPhysicsController::wantsSleeping()
{
if (!gEnableSleeping)
//disable deactivation
if (gDeactivationTime == 0.f)
return false;
if ( (m_body->GetActivationState() == 3) || (m_body->GetActivationState() == 2))
return true;
if ((m_body->getLinearVelocity().length2() < gSleepingTreshold*gSleepingTreshold) &&
if ((m_body->getLinearVelocity().length2() < gLinearSleepingTreshold*gLinearSleepingTreshold) &&
(m_body->getAngularVelocity().length2() < gAngularSleepingTreshold*gAngularSleepingTreshold))
{
m_sleepingCounter++;
@@ -219,7 +215,7 @@ bool CcdPhysicsController::wantsSleeping()
m_sleepingCounter=0;
}
if (m_sleepingCounter> 150)
if (m_sleepingCounter> gDeactivationTime)
{
return true;
}

View File

@@ -10,6 +10,11 @@
#include "SimdScalar.h"
class CollisionShape;
extern float gDeactivationTime;
extern float gLinearSleepingTreshold;
extern float gAngularSleepingTreshold;
struct CcdConstructionInfo
{
CcdConstructionInfo()

View File

@@ -33,8 +33,6 @@ bool useIslands = true;
//#include "BroadphaseCollision/QueryBox.h"
//todo: change this to allow dynamic registration of types!
unsigned long gNumIterations = 10;
#ifdef WIN32
void DrawRasterizerLine(const float* from,const float* to,int color);
#endif
@@ -88,13 +86,16 @@ static void DrawAabb(IDebugDraw* debugDrawer,const SimdVector3& from,const SimdV
CcdPhysicsEnvironment::CcdPhysicsEnvironment(ToiContactDispatcher* dispatcher,BroadphaseInterface* bp)
:m_dispatcher(dispatcher),
m_broadphase(bp),
m_scalingPropagated(false)
m_scalingPropagated(false),
m_numIterations(30),
m_ccdMode(0)
{
if (!m_dispatcher)
{
OdeConstraintSolver* solver = new OdeConstraintSolver();
//SimpleConstraintSolver* solver= new SimpleConstraintSolver();
m_dispatcher = new ToiContactDispatcher(solver);
}
if (!m_broadphase)
{
@@ -290,7 +291,6 @@ void CcdPhysicsEnvironment::UpdateActivationState()
}
bool gPredictCollision = false;//true;//false;
/// Perform an integration step of duration 'timeStep'.
@@ -346,7 +346,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
int numsubstep = gNumIterations;
int numsubstep = m_numIterations;
DispatcherInfo dispatchInfo;
@@ -367,7 +367,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
//contacts
m_dispatcher->SolveConstraints(timeStep, gNumIterations ,numRigidBodies,m_debugDrawer);
m_dispatcher->SolveConstraints(timeStep, m_numIterations ,numRigidBodies,m_debugDrawer);
for (int g=0;g<numsubstep;g++)
{
@@ -454,7 +454,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
if (gPredictCollision)
if (m_ccdMode == 3)
{
DispatcherInfo dispatchInfo;
dispatchInfo.m_timeStep = timeStep;
@@ -548,7 +548,7 @@ void CcdPhysicsEnvironment::setDebugMode(int debugMode)
if (m_dispatcher)
delete m_dispatcher;
if (debugMode == 11)
if (debugMode > 100)
{
SimpleConstraintSolver* solver= new SimpleConstraintSolver();
m_dispatcher = new ToiContactDispatcher(solver);
@@ -563,6 +563,51 @@ void CcdPhysicsEnvironment::setDebugMode(int debugMode)
}
}
void CcdPhysicsEnvironment::setNumIterations(int numIter)
{
m_numIterations = numIter;
}
void CcdPhysicsEnvironment::setDeactivationTime(float dTime)
{
gDeactivationTime = dTime;
}
void CcdPhysicsEnvironment::setDeactivationLinearTreshold(float linTresh)
{
gLinearSleepingTreshold = linTresh;
}
void CcdPhysicsEnvironment::setDeactivationAngularTreshold(float angTresh)
{
gAngularSleepingTreshold = angTresh;
}
void CcdPhysicsEnvironment::setContactBreakingTreshold(float contactBreakingTreshold)
{
gContactBreakingTreshold = contactBreakingTreshold;
}
void CcdPhysicsEnvironment::setCcdMode(int ccdMode)
{
m_ccdMode = ccdMode;
}
void CcdPhysicsEnvironment::setSolverSorConstant(float sor)
{
m_dispatcher->SetSor(sor);
}
void CcdPhysicsEnvironment::setTau(float tau)
{
m_dispatcher->SetTau(tau);
}
void CcdPhysicsEnvironment::setDamping(float damping)
{
m_dispatcher->SetDamping(damping);
}
void CcdPhysicsEnvironment::SyncMotionStates(float timeStep)
{

View File

@@ -26,6 +26,8 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
SimdVector3 m_gravity;
BroadphaseInterface* m_broadphase;
IDebugDraw* m_debugDrawer;
int m_numIterations;
int m_ccdMode;
public:
CcdPhysicsEnvironment(ToiContactDispatcher* dispatcher=0, BroadphaseInterface* broadphase=0);
@@ -43,6 +45,16 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
m_debugDrawer = debugDrawer;
}
virtual void setNumIterations(int numIter);
virtual void setDeactivationTime(float dTime);
virtual void setDeactivationLinearTreshold(float linTresh) ;
virtual void setDeactivationAngularTreshold(float angTresh) ;
virtual void setContactBreakingTreshold(float contactBreakingTreshold) ;
virtual void setCcdMode(int ccdMode);
virtual void setSolverSorConstant(float sor);
virtual void setTau(float tau);
virtual void setDamping(float damping);
virtual void beginFrame() {};
virtual void endFrame() {};

View File

@@ -34,12 +34,12 @@
#include "PHY_DynamicTypes.h"
/**
PHY_IPhysicsController is the abstract simplified Interface to a physical object.
It contains the IMotionState and IDeformableMesh Interfaces.
*/
class PHY_IPhysicsController
{

View File

@@ -51,7 +51,27 @@ class PHY_IPhysicsEnvironment
//returns 0.f if no fixed timestep is used
virtual float getFixedTimeStep()=0;
///setDebugMode is used to support several ways of debug lines, contact point visualization
virtual void setDebugMode(int debugMode) {}
///setNumIterations set the number of iterations for iterative solvers
virtual void setNumIterations(int numIter) {}
///setDeactivationTime sets the minimum time that an objects has to stay within the velocity tresholds until it gets fully deactivated
virtual void setDeactivationTime(float dTime) {}
///setDeactivationLinearTreshold sets the linear velocity treshold, see setDeactivationTime
virtual void setDeactivationLinearTreshold(float linTresh) {}
///setDeactivationAngularTreshold sets the angular velocity treshold, see setDeactivationTime
virtual void setDeactivationAngularTreshold(float angTresh) {}
///setContactBreakingTreshold sets tresholds to do with contact point management
virtual void setContactBreakingTreshold(float contactBreakingTreshold) {}
///continuous collision detection mode, very experimental for Bullet
virtual void setCcdMode(int ccdMode) {}
///successive overrelaxation constant, in case PSOR is used, values in between 1 and 2 guarantee converging behaviour
virtual void setSolverSorConstant(float sor) {}
///setTau sets the spring constant of a penalty based solver
virtual void setTau(float tau) {}
///setDamping sets the damper constant of a penalty based solver
virtual void setDamping(float damping) {}
virtual void setGravity(float x,float y,float z)=0;
virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,