diff options
author | Erwin Coumans <blender@erwincoumans.com> | 2009-05-24 02:35:47 +0400 |
---|---|---|
committer | Erwin Coumans <blender@erwincoumans.com> | 2009-05-24 02:35:47 +0400 |
commit | eb8c5f3272b87fffaf017badf55f761de9a04fd1 (patch) | |
tree | 6ce64cb7c6c1a2028a8bdb75bb951f6ad0e01bec /source/gameengine | |
parent | a96ce9453f2a8d39e238d20c1c4dec9fe5becfb5 (diff) |
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.
Diffstat (limited to 'source/gameengine')
5 files changed, 28 insertions, 1 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 06a4da4fce0..a9c839595c2 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -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; } } diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index e48fddb30bd..74042366bae 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -139,6 +139,8 @@ struct KX_ObjectProperties ///////////////////////// double m_margin; + float m_contactProcessingThreshold; + KX_BoundBoxClass m_boundclass; union { KX_BoxBounds box; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 76642649afc..cdba59dd9ca 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -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(); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 6b00011b693..710d0656f6d 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -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) { diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index fc8de0e2ded..d73759bac76 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -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] }; |