Set default constraint solver mode more compatible to Blender 2.48 settings, this fixes rigid body stacking in this blend file:

http://blenderartists.org/forum/showpost.php?p=1382653&postcount=102

(todo: expose this setting in World setting GUI)

Expose contact processing threshold in Advanced GUI, next to rigid body margin, called CPT.
Default to 1, makes rigid body stacking a bit more stable, smaller values makes sliding easier (at the cost of easier jittering).
Disabled for 'dynamic' objects that don't rotate, because characters etc. always need smooth sliding.
This commit is contained in:
Erwin Coumans 2009-05-23 22:35:47 +00:00
parent a96ce9453f
commit eb8c5f3272
10 changed files with 48 additions and 7 deletions

@ -77,7 +77,7 @@ struct btContactSolverInfo : public btContactSolverInfoData
m_splitImpulsePenetrationThreshold = -0.02f;
m_linearSlop = btScalar(0.0);
m_warmstartingFactor=btScalar(0.85);
m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD ;//SOLVER_RANDMIZE_ORDER
m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_USE_2_FRICTION_DIRECTIONS |SOLVER_SIMD | SOLVER_RANDMIZE_ORDER;
m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution
}
};

@ -984,6 +984,8 @@ Object *add_only_object(int type, char *name)
ob->anisotropicFriction[2] = 1.0f;
ob->gameflag= OB_PROP|OB_COLLISION;
ob->margin = 0.0;
/* ob->pad3 == Contact Processing Threshold */
ob->pad3 = 1.;
/* NT fluid sim defaults */
ob->fluidsimFlag = 0;

@ -8083,7 +8083,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
/* Adjustments needed after Bullets update */
for(ob = main->object.first; ob; ob= ob->id.next) {
ob->damping *= 0.635f;
ob->rdamping = 0.1 + (0.59f * ob->rdamping);
ob->rdamping = 0.1 + (0.8f * ob->rdamping);
}
}
@ -8105,11 +8105,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
wrld->occlusionRes = 128;
}
}
if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 5)) {
Object *ob;
World *wrld;
for(ob = main->object.first; ob; ob= ob->id.next) {
ob->pad3 = 1.; //pad3 is used for m_contactProcessingThreshold
if(ob->parent) {
/* check if top parent has compound shape set and if yes, set this object
to compound shaper as well (was the behaviour before, now it's optional) */

@ -159,7 +159,7 @@ typedef struct Object {
float margin;
float max_vel; /* clamp the maximum velocity 0.0 is disabled */
float min_vel; /* clamp the maximum velocity 0.0 is disabled */
float pad3; /* clamp the maximum velocity 0.0 is disabled */
float pad3; /* pad3 is now used for m_contactProcessingThreshold, can we still rename it? */
char dt, dtx;
char totcol; /* copy of mesh or curve or meta */

@ -3198,11 +3198,17 @@ static uiBlock *advanced_bullet_menu(void *arg_ob)
uiDefButF(block, NUM, 0, "Margin",
xco, yco, 180, 19, &ob->margin, 0.001, 1.0, 1, 0,
"Collision margin");
yco -= 20;
if (ob->gameflag & OB_RIGID_BODY)
{
uiDefButF(block, NUM, 0, "CPT",
xco+180, yco, 180, 19, &ob->pad3, 0.00, 1., 1, 0,
"Contact Processing Threshold");
yco -= 20;
uiDefButBitI(block, TOG, OB_LOCK_RIGID_BODY_X_AXIS, 0, "Lock X Axis",
xco, yco, 180, 19, &ob->gameflag2, 0, 0, 0, 0,
"Disable simulation of linear motion along the X axis");
@ -3226,8 +3232,9 @@ static uiBlock *advanced_bullet_menu(void *arg_ob)
uiDefButBitI(block, TOG, OB_LOCK_RIGID_BODY_Z_ROT_AXIS, 0, "Lock Z Rot Axis",
xco+=180, yco, 180, 19, &ob->gameflag2, 0, 0, 0, 0,
"Disable simulation of angular motion along the Z axis");
yco -= 20;
}
yco -= 20;
xco = 0;
uiBlockEndAlign(block);
@ -3279,6 +3286,10 @@ static uiBlock *advanced_bullet_menu(void *arg_ob)
uiDefButF(block, NUM, 0, "Margin",
xco, yco, 180, 19, &ob->margin, 0.0, 1.0, 1, 0,
"Collision margin");
uiDefButF(block, NUM, 0, "CPT",
xco+180, yco, 180, 19, &ob->pad3, 0.00, 1., 1, 0,
"Contact Processing Threshold");
}
yco -= 20;
xco = 0;

@ -1412,11 +1412,22 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
objprop.m_isCompoundChild = isCompoundChild;
objprop.m_hasCompoundChildren = hasCompoundChildren;
objprop.m_margin = blenderobject->margin;
// ACTOR is now a separate feature
objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic'
if (objprop.m_angular_rigidbody || !objprop.m_dyna )
{
objprop.m_contactProcessingThreshold = blenderobject->pad3;
} else
{
objprop.m_contactProcessingThreshold = 0.f;
}
objprop.m_sensor = (blenderobject->gameflag & OB_SENSOR) != 0;
if (objprop.m_softbody)
@ -1461,6 +1472,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/
objprop.m_soft_welding = blenderobject->bsoft->welding; /* welding */
objprop.m_margin = blenderobject->bsoft->margin;
objprop.m_contactProcessingThreshold = 0.f;
} else
{
objprop.m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT;
@ -1501,6 +1513,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
objprop.m_soft_numclusteriterations= 16;
objprop.m_soft_welding = 0.f;
objprop.m_margin = 0.f;
objprop.m_contactProcessingThreshold = 0.f;
}
}

@ -139,6 +139,8 @@ struct KX_ObjectProperties
/////////////////////////
double m_margin;
float m_contactProcessingThreshold;
KX_BoundBoxClass m_boundclass;
union {
KX_BoxBounds box;

@ -1103,6 +1103,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
(isbulletdyna) ? short(CcdConstructionInfo::AllFilter) :
short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
ci.m_contactProcessingThreshold = objprop->m_contactProcessingThreshold;//todo: expose this in advanced settings, just like margin, default to 10000 or so
ci.m_bSoft = objprop->m_softbody;
ci.m_bSensor = isbulletsensor;
MT_Vector3 scaling = gameobj->NodeGetWorldScaling();

@ -519,6 +519,8 @@ void CcdPhysicsController::CreateRigidbody()
{
body->setAngularFactor(0.f);
}
body->setContactProcessingThreshold(m_cci.m_contactProcessingThreshold);
}
if (m_object && m_cci.m_do_anisotropic)
{

@ -231,7 +231,8 @@ struct CcdConstructionInfo
m_physicsEnv(0),
m_inertiaFactor(1.f),
m_do_anisotropic(false),
m_anisotropicFriction(1.f,1.f,1.f)
m_anisotropicFriction(1.f,1.f,1.f),
m_contactProcessingThreshold(1e10)
{
}
@ -317,6 +318,13 @@ struct CcdConstructionInfo
btScalar m_fh_distance; ///< The range above the surface where Fh is active.
bool m_fh_normal; ///< Should the object slide off slopes?
float m_radius;//for fh backwards compatibility
///m_contactProcessingThreshold allows to process contact points with positive distance
///normally only contacts with negative distance (penetration) are solved
///however, rigid body stacking is more stable when positive contacts are still passed into the constraint solver
///this might sometimes lead to collisions with 'internal edges' such as a sliding character controller
///so disable/set m_contactProcessingThreshold to zero for sliding characters etc.
float m_contactProcessingThreshold;///< Process contacts with positive distance in range [0..INF]
};