diff options
8 files changed, 99 insertions, 9 deletions
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp index eebd0c99fcb..846c9b9b989 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp @@ -17,7 +17,9 @@ subject to the following restrictions: #include "btCollisionObject.h" btCollisionObject::btCollisionObject() - : m_broadphaseHandle(0), + : m_anisotropicFriction(1.f,1.f,1.f), + m_hasAnisotropicFriction(false), + m_broadphaseHandle(0), m_collisionShape(0), m_rootCollisionShape(0), m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT), diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h index 0961f3e75c9..8442868cf89 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h @@ -49,6 +49,9 @@ protected: //without destroying the continuous interpolated motion (which uses this interpolation velocities) btVector3 m_interpolationLinearVelocity; btVector3 m_interpolationAngularVelocity; + btVector3 m_anisotropicFriction; + bool m_hasAnisotropicFriction; + btBroadphaseProxy* m_broadphaseHandle; btCollisionShape* m_collisionShape; @@ -119,6 +122,20 @@ public: return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0); } + const btVector3& getAnisotropicFriction() const + { + return m_anisotropicFriction; + } + void setAnisotropicFriction(const btVector3& anisotropicFriction) + { + m_anisotropicFriction = anisotropicFriction; + m_hasAnisotropicFriction = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f); + } + bool hasAnisotropicFriction() const + { + return m_hasAnisotropicFriction; + } + SIMD_FORCE_INLINE bool isStaticObject() const { return (m_collisionFlags & CF_STATIC_OBJECT) != 0; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp index b8afbd6aac5..2911d52e5ea 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp @@ -149,6 +149,7 @@ void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject solverBody->m_originalBody = 0; solverBody->m_angularFactor = 1.f; } + solverBody->m_pushVelocity.setValue(0.f,0.f,0.f); solverBody->m_turnVelocity.setValue(0.f,0.f,0.f); } @@ -292,7 +293,7 @@ btScalar resolveSingleCollisionCombinedCacheFriendly( return normalImpulse; } - +//#define NO_FRICTION_TANGENTIALS 1 #ifndef NO_FRICTION_TANGENTIALS btScalar resolveSingleFrictionCacheFriendly( @@ -396,7 +397,7 @@ btScalar resolveSingleFrictionCacheFriendly( return 0.f; - body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1); + body1.getVelocityInLocalPoint(contactConstraint.m_relpos1CrossNormal,vel1); body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2); btVector3 vel = vel1 - vel2; btScalar rel_vel; @@ -421,9 +422,9 @@ btScalar resolveSingleFrictionCacheFriendly( (body1.m_invMass + body2.m_invMass + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); btScalar normal_impulse = contactConstraint.m_appliedImpulse * combinedFriction; - GEN_set_min(friction_impulse, normal_impulse); - GEN_set_max(friction_impulse, -normal_impulse); - body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1); + btSetMin(friction_impulse, normal_impulse); + btSetMin(friction_impulse, -normal_impulse); + body1.internalApplyImpulse(lat_vel * -friction_impulse, rel_pos1); body2.applyImpulse(lat_vel * friction_impulse, rel_pos2); } } @@ -495,6 +496,23 @@ void btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& } +void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection); +void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection) +{ + if (colObj && colObj->hasAnisotropicFriction()) + { + // transform to local coordinates + btVector3 loc_lateral = frictionDirection * colObj->getWorldTransform().getBasis(); + const btVector3& friction_scaling = colObj->getAnisotropicFriction(); + //apply anisotropic friction + loc_lateral *= friction_scaling; + // ... and transform it back to global coordinates + frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral; + } +} + + + btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** /*bodies */,int /*numBodies */,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc) { @@ -755,19 +773,31 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol if (!cp.m_lateralFrictionInitialized) { cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel; + + //scale anisotropic friction + + applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1); + applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1); + btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2(); + + if (lat_rel_vel > SIMD_EPSILON)//0.0f) { cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel); addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); - cp.m_lateralFrictionDir2.normalize();//?? + cp.m_lateralFrictionDir2.normalize(); + applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2); + applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2); + addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); } else { //re-calculate friction direction every frame, todo: check if this is really needed - btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2); + applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2); + applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2); addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); } diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp index e2afb687ac6..93d70de39d8 100644 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp @@ -45,6 +45,7 @@ void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& m_linearVelocity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); m_angularFactor = btScalar(1.); + m_anisotropicFriction.setValue(1.f,1.f,1.f); m_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)), diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 58fb2d456b9..3d6a82aef57 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -3072,6 +3072,25 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) xco, yco, 118, 19, &ob->margin, 0.0, 1.0, 1, 0, "Collision margin"); } + uiDefButBitI(block, TOG, OB_ANISOTROPIC_FRICTION, B_REDR, "Anisotropic", + xco+120, yco, 120, 19, + &ob->gameflag, 0.0, 1.0, 10, 0, + "Enable anisotropic friction"); + + yco-=25; + + if (ob->gameflag & OB_ANISOTROPIC_FRICTION) { + uiDefButF(block, NUM, 0, "X:", + xco, yco, 80, 19,&ob->anisotropicFriction[0], 0.0, 1.0, 10, 0, + "Relative friction coefficient in the x-direction."); + uiDefButF(block, NUM, 0, "Y:", + xco+80, yco, 80, 19,&ob->anisotropicFriction[1], 0.0, 1.0, 10, 0, + "Relative friction coefficient in the y-direction."); + uiDefButF(block, NUM, 0, "Z:", + xco+160, yco, 80, 19,&ob->anisotropicFriction[2], 0.0, 1.0, 10, 0, + "Relative friction coefficient in the z-direction."); + } + } uiBlockSetDirection(block, UI_TOP); @@ -3110,6 +3129,9 @@ void buttons_bullet(uiBlock *block, Object *ob) uiBlockSetCol(block, TH_BUT_SETTING2); uiBlockBeginAlign(block); + + + uiDefButBitI(block, TOG, OB_GHOST, 0, "Ghost", 10, 182, 60, 19, &ob->gameflag, 0, 0, 0, 0, "Objects that don't restitute collisions (like a ghost)"); diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index e4c7e7f9317..68e0997aec0 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -1025,6 +1025,14 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, //need a bit of damping, else system doesn't behave well ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behaviour + ci.m_do_anisotropic = shapeprops->m_do_anisotropic; + ci.m_anisotropicFriction.setValue(shapeprops->m_friction_scaling[0],shapeprops->m_friction_scaling[1],shapeprops->m_friction_scaling[2]); + + //smprop->m_do_fh = kxshapeprops->m_do_fh; + //smprop->m_do_rot_fh = kxshapeprops->m_do_rot_fh ; + + + /////////////////// ci.m_gamesoftFlag = objprop->m_gamesoftFlag; diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 166731459e7..8ec040e89ee 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -500,6 +500,11 @@ void CcdPhysicsController::CreateRigidbody() body->setAngularFactor(0.f); } } + if (m_object && m_cci.m_do_anisotropic) + { + m_object->setAnisotropicFriction(m_cci.m_anisotropicFriction); + } + } static void DeleteBulletShape(btCollisionShape* shape) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 1366764eb63..f001d6043cb 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -186,7 +186,9 @@ struct CcdConstructionInfo m_MotionState(0), m_shapeInfo(0), m_physicsEnv(0), - m_inertiaFactor(1.f) + m_inertiaFactor(1.f), + m_do_anisotropic(false), + m_anisotropicFriction(1.f,1.f,1.f) { } @@ -259,6 +261,9 @@ struct CcdConstructionInfo CcdPhysicsEnvironment* m_physicsEnv; //needed for self-replication float m_inertiaFactor;//tweak the inertia (hooked up to Blender 'formfactor' + bool m_do_anisotropic; + btVector3 m_anisotropicFriction; + }; |