Set default constraint solver mode more compatible to Blender 2.48 settings, this...
authorErwin Coumans <blender@erwincoumans.com>
Sat, 23 May 2009 22:35:47 +0000 (22:35 +0000)
committerErwin Coumans <blender@erwincoumans.com>
Sat, 23 May 2009 22:35:47 +0000 (22:35 +0000)
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.

extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
source/blender/blenkernel/intern/object.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_object_types.h
source/blender/src/buttons_logic.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h

index e99430c00de95f970bf9366564d526a299f94657..a11fc94ea1135a3cd0304442aea71dd7884b711e 100644 (file)
@@ -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
        }
 };
index bffbcf736720a5d491f7b3c7bb561143bc590180..9739668c7c7d96e2ff2512acdc18bf1ac29bd63d 100644 (file)
@@ -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;
index bda0348f2ca4ea587cee5ae0ef0d17e03e112f55..0b0a97b7ec004bf01a4cced71d38ff18f10181ed 100644 (file)
@@ -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) */
index 9121f38be16184fc67384bd3346d1465f14fe3af..11fa44fe488422ebedbfe8fb08bec3d45a55a26e 100644 (file)
@@ -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 */
index b7039673dfcb832d681cf8122e7b8a6699304a64..b0ce3c8a95b79bb26815569803061fb8b70e6df7 100644 (file)
@@ -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;
index 06a4da4fce02bf9d736136ce292446df5deb9ebc..a9c839595c2c89a674512ba36cb0d8608609d0bd 100644 (file)
@@ -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;
                }
        }
 
index e48fddb30bd6736c117c1c001414c7a87f184bd9..74042366baec9865b81fbf4c4def93d7941cbdad 100644 (file)
@@ -139,6 +139,8 @@ struct KX_ObjectProperties
 
        /////////////////////////
        double  m_margin;
+       float   m_contactProcessingThreshold;
+
        KX_BoundBoxClass        m_boundclass;
        union {
                KX_BoxBounds    box;
index 76642649afc5a0fc88c22386c88c2e2dc97fd689..cdba59dd9ca561e7c912ee0bb2bb28b8a0b7c044 100644 (file)
@@ -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();
index 6b00011b693d9639934711628208a6f05ac7c976..710d0656f6d1c58aa880d46a25940004d35535b6 100644 (file)
@@ -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)
        {
index fc8de0e2dedf3f82c596f41b210a14ef4b284f6d..d73759bac76847b57e5a6fefb621117edb088ec7 100644 (file)
@@ -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]
 
 };