diff options
10 files changed, 48 insertions, 7 deletions
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h index e99430c00de..a11fc94ea11 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h @@ -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 } }; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index bffbcf73672..9739668c7c7 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -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; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index bda0348f2ca..0b0a97b7ec0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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) */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 9121f38be16..11fa44fe488 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -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 */ diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index b7039673dfc..b0ce3c8a95b 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -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; 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] }; |