Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Physics')
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp42
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h28
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp74
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h14
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h5
-rw-r--r--source/gameengine/Physics/common/PHY_Pro.h2
6 files changed, 143 insertions, 22 deletions
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 4fd1f10fad6..8ecb586f77e 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -697,6 +697,35 @@ CcdPhysicsController::~CcdPhysicsController()
}
}
+void CcdPhysicsController::SimulationTick(float timestep)
+{
+ btRigidBody *body = GetRigidBody();
+ if (!body || body->isStaticObject())
+ return;
+
+ // Clamp linear velocity
+ if (m_cci.m_clamp_vel_max > 0.0f || m_cci.m_clamp_vel_min > 0.0f) {
+ const btVector3 &linvel = body->getLinearVelocity();
+ btScalar len = linvel.length();
+
+ if (m_cci.m_clamp_vel_max > 0.0f && len > m_cci.m_clamp_vel_max)
+ body->setLinearVelocity(linvel * (m_cci.m_clamp_vel_max / len));
+ else if (m_cci.m_clamp_vel_min > 0.0f && !btFuzzyZero(len) && len < m_cci.m_clamp_vel_min)
+ body->setLinearVelocity(linvel * (m_cci.m_clamp_vel_min / len));
+ }
+
+ // Clamp angular velocity
+ if (m_cci.m_clamp_angvel_max > 0.0f || m_cci.m_clamp_angvel_min > 0.0f) {
+ const btVector3 &angvel = body->getAngularVelocity();
+ btScalar len = angvel.length();
+
+ if (m_cci.m_clamp_angvel_max > 0.0f && len > m_cci.m_clamp_angvel_max)
+ body->setAngularVelocity(angvel * (m_cci.m_clamp_angvel_max / len));
+ else if (m_cci.m_clamp_angvel_min > 0.0f && !btFuzzyZero(len) && len < m_cci.m_clamp_angvel_min)
+ body->setAngularVelocity(angvel * (m_cci.m_clamp_angvel_min / len));
+ }
+}
+
/**
* SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
@@ -732,19 +761,6 @@ bool CcdPhysicsController::SynchronizeMotionStates(float time)
if (body && !body->isStaticObject())
{
-
- if ((m_cci.m_clamp_vel_max>0.0) || (m_cci.m_clamp_vel_min>0.0))
- {
- const btVector3& linvel = body->getLinearVelocity();
- float len= linvel.length();
-
- if ((m_cci.m_clamp_vel_max>0.0) && (len > m_cci.m_clamp_vel_max))
- body->setLinearVelocity(linvel * (m_cci.m_clamp_vel_max / len));
-
- else if ((m_cci.m_clamp_vel_min>0.0) && btFuzzyZero(len)==0 && (len < m_cci.m_clamp_vel_min))
- body->setLinearVelocity(linvel * (m_cci.m_clamp_vel_min / len));
- }
-
const btTransform& xform = body->getCenterOfMassTransform();
const btMatrix3x3& worldOri = xform.getBasis();
const btVector3& worldPos = xform.getOrigin();
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index b1d38763fbb..c49ae8d20e1 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -236,6 +236,8 @@ struct CcdConstructionInfo
m_mass(0.f),
m_clamp_vel_min(-1.f),
m_clamp_vel_max(-1.f),
+ m_clamp_angvel_min(0.0f),
+ m_clamp_angvel_max(0.0f),
m_restitution(0.1f),
m_friction(0.5f),
m_linearDamping(0.1f),
@@ -302,6 +304,8 @@ struct CcdConstructionInfo
btScalar m_mass;
btScalar m_clamp_vel_min;
btScalar m_clamp_vel_max;
+ btScalar m_clamp_angvel_min; // Minimum angular velocity, in radians/sec.
+ btScalar m_clamp_angvel_max; // Maximum angular velocity, in radians/sec.
btScalar m_restitution;
btScalar m_friction;
btScalar m_linearDamping;
@@ -579,6 +583,13 @@ protected:
* SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
*/
virtual bool SynchronizeMotionStates(float time);
+
+ /**
+ * Called for every physics simulation step. Use this method for
+ * things like limiting linear and angular velocity.
+ */
+ void SimulationTick(float timestep);
+
/**
* WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
*/
@@ -701,6 +712,23 @@ protected:
return m_cci.m_clamp_vel_max;
}
+ virtual void SetAngularVelocityMin(float val)
+ {
+ m_cci.m_clamp_angvel_min = val;
+ }
+ virtual float GetAngularVelocityMin() const
+ {
+ return m_cci.m_clamp_angvel_min;
+ }
+ virtual void SetAngularVelocityMax(float val)
+ {
+ m_cci.m_clamp_angvel_max = val;
+ }
+ virtual float GetAngularVelocityMax() const
+ {
+ return m_cci.m_clamp_angvel_max;
+ }
+
bool WantsSleeping();
void UpdateDeactivation(float timeStep);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index 89c8c124bc8..759e8bd6f7e 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -410,6 +410,10 @@ m_ccdMode(0),
m_solverType(-1),
m_profileTimings(0),
m_enableSatCollisionDetection(false),
+m_deactivationTime(2.0f),
+m_linearDeactivationThreshold(0.8f),
+m_angularDeactivationThreshold(1.0f),
+m_contactBreakingThreshold(0.02f),
m_solver(NULL),
m_ownPairCache(NULL),
m_filterCallback(NULL),
@@ -452,6 +456,7 @@ m_scalingPropagated(false)
SetSolverType(1);//issues with quickstep and memory allocations
// m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
m_dynamicsWorld = new btSoftRigidDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
+ m_dynamicsWorld->setInternalTickCallback(&CcdPhysicsEnvironment::StaticSimulationSubtickCallback, this);
//m_dynamicsWorld->getSolverInfo().m_linearSlop = 0.01f;
//m_dynamicsWorld->getSolverInfo().m_solverMode= SOLVER_USE_WARMSTARTING + SOLVER_USE_2_FRICTION_DIRECTIONS + SOLVER_RANDMIZE_ORDER + SOLVER_USE_FRICTION_WARMSTARTING;
@@ -471,8 +476,10 @@ void CcdPhysicsEnvironment::AddCcdPhysicsController(CcdPhysicsController* ctrl)
//this m_userPointer is just used for triggers, see CallbackTriggers
obj->setUserPointer(ctrl);
- if (body)
- body->setGravity( m_gravity );
+ if (body) {
+ body->setGravity(m_gravity);
+ body->setSleepingThresholds(m_linearDeactivationThreshold, m_angularDeactivationThreshold);
+ }
if (body)
{
@@ -677,11 +684,31 @@ void CcdPhysicsEnvironment::DebugDrawWorld()
m_dynamicsWorld->debugDrawWorld();
}
+void CcdPhysicsEnvironment::StaticSimulationSubtickCallback(btDynamicsWorld *world, btScalar timeStep)
+{
+ // Get the pointer to the CcdPhysicsEnvironment associated with this Bullet world.
+ CcdPhysicsEnvironment *this_ = static_cast<CcdPhysicsEnvironment*>(world->getWorldUserInfo());
+ this_->SimulationSubtickCallback(timeStep);
+}
+
+void CcdPhysicsEnvironment::SimulationSubtickCallback(btScalar timeStep)
+{
+ std::set<CcdPhysicsController*>::iterator it;
+
+ for (it = m_controllers.begin(); it != m_controllers.end(); it++) {
+ (*it)->SimulationTick(timeStep);
+ }
+}
+
bool CcdPhysicsEnvironment::ProceedDeltaTime(double curTime,float timeStep,float interval)
{
std::set<CcdPhysicsController*>::iterator it;
int i;
+ // Update Bullet global variables.
+ gDeactivationTime = m_deactivationTime;
+ gContactBreakingThreshold = m_contactBreakingThreshold;
+
for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
{
(*it)->SynchronizeMotionStates(timeStep);
@@ -901,21 +928,32 @@ void CcdPhysicsEnvironment::SetNumIterations(int numIter)
}
void CcdPhysicsEnvironment::SetDeactivationTime(float dTime)
{
- gDeactivationTime = dTime;
+ m_deactivationTime = dTime;
}
void CcdPhysicsEnvironment::SetDeactivationLinearTreshold(float linTresh)
{
- gLinearSleepingTreshold = linTresh;
+ m_linearDeactivationThreshold = linTresh;
+
+ // Update from all controllers.
+ for (std::set<CcdPhysicsController*>::iterator it = m_controllers.begin(); it != m_controllers.end(); it++) {
+ if ((*it)->GetRigidBody())
+ (*it)->GetRigidBody()->setSleepingThresholds(m_linearDeactivationThreshold, m_angularDeactivationThreshold);
+ }
}
void CcdPhysicsEnvironment::SetDeactivationAngularTreshold(float angTresh)
{
- gAngularSleepingTreshold = angTresh;
+ m_angularDeactivationThreshold = angTresh;
+
+ // Update from all controllers.
+ for (std::set<CcdPhysicsController*>::iterator it = m_controllers.begin(); it != m_controllers.end(); it++) {
+ if ((*it)->GetRigidBody())
+ (*it)->GetRigidBody()->setSleepingThresholds(m_linearDeactivationThreshold, m_angularDeactivationThreshold);
+ }
}
void CcdPhysicsEnvironment::SetContactBreakingTreshold(float contactBreakingTreshold)
{
- gContactBreakingThreshold = contactBreakingTreshold;
-
+ m_contactBreakingThreshold = contactBreakingTreshold;
}
@@ -1065,7 +1103,10 @@ int CcdPhysicsEnvironment::CreateUniversalD6Constraint(
void CcdPhysicsEnvironment::RemoveConstraint(int constraintId)
{
-
+ // For soft body constraints
+ if (constraintId == 0)
+ return;
+
int i;
int numConstraints = m_dynamicsWorld->getNumConstraints();
for (i=0;i<numConstraints;i++)
@@ -2009,6 +2050,9 @@ CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
float CcdPhysicsEnvironment::GetConstraintParam(int constraintId,int param)
{
btTypedConstraint* typedConstraint = GetConstraintById(constraintId);
+ if (!typedConstraint)
+ return 0.0f;
+
switch (typedConstraint->getUserConstraintType())
{
case PHY_GENERIC_6DOF_CONSTRAINT:
@@ -2048,6 +2092,9 @@ float CcdPhysicsEnvironment::GetConstraintParam(int constraintId,int param)
void CcdPhysicsEnvironment::SetConstraintParam(int constraintId,int param,float value0,float value1)
{
btTypedConstraint* typedConstraint = GetConstraintById(constraintId);
+ if (!typedConstraint)
+ return;
+
switch (typedConstraint->getUserConstraintType())
{
case PHY_GENERIC_6DOF_CONSTRAINT:
@@ -2157,6 +2204,9 @@ void CcdPhysicsEnvironment::SetConstraintParam(int constraintId,int param,float
btTypedConstraint* CcdPhysicsEnvironment::GetConstraintById(int constraintId)
{
+ // For soft body constraints
+ if (constraintId == 0)
+ return NULL;
int numConstraints = m_dynamicsWorld->getNumConstraints();
int i;
@@ -2225,7 +2275,7 @@ void CcdPhysicsEnvironment::AddTouchCallback(int response_class, PHY_ResponseCal
bool CcdPhysicsEnvironment::RequestCollisionCallback(PHY_IPhysicsController* ctrl)
{
CcdPhysicsController* ccdCtrl = static_cast<CcdPhysicsController*>(ctrl);
- return !ccdCtrl->Register();
+ return ccdCtrl->Register();
}
void CcdPhysicsEnvironment::CallbackTriggers()
@@ -2937,6 +2987,10 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float conera
float CcdPhysicsEnvironment::getAppliedImpulse(int constraintid)
{
+ // For soft body constraints
+ if (constraintid == 0)
+ return 0.0f;
+
int i;
int numConstraints = m_dynamicsWorld->getNumConstraints();
for (i=0;i<numConstraints;i++)
@@ -3094,6 +3148,8 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject
ci.m_mass = isbulletdyna ? shapeprops->m_mass : 0.f;
ci.m_clamp_vel_min = shapeprops->m_clamp_vel_min;
ci.m_clamp_vel_max = shapeprops->m_clamp_vel_max;
+ ci.m_clamp_angvel_min = shapeprops->m_clamp_angvel_min;
+ ci.m_clamp_angvel_max = shapeprops->m_clamp_angvel_max;
ci.m_stepHeight = isbulletchar ? shapeprops->m_step_height : 0.f;
ci.m_jumpSpeed = isbulletchar ? shapeprops->m_jump_speed : 0.f;
ci.m_fallSpeed = isbulletchar ? shapeprops->m_fall_speed : 0.f;
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index e1988478b71..3d7e3943f98 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -52,6 +52,7 @@ class btBroadphaseInterface;
struct btDbvtBroadphase;
class btOverlappingPairCache;
class btIDebugDraw;
+class btDynamicsWorld;
class PHY_IVehicle;
class CcdOverlapFilterCallBack;
class CcdShapeConstructionInfo;
@@ -87,6 +88,11 @@ protected:
int m_profileTimings;
bool m_enableSatCollisionDetection;
+ float m_deactivationTime;
+ float m_linearDeactivationThreshold;
+ float m_angularDeactivationThreshold;
+ float m_contactBreakingThreshold;
+
void ProcessFhSprings(double curTime,float timeStep);
public:
@@ -129,6 +135,14 @@ protected:
/// Perform an integration step of duration 'timeStep'.
virtual bool ProceedDeltaTime(double curTime,float timeStep,float interval);
+ /**
+ * Called by Bullet for every physical simulation (sub)tick.
+ * Our constructor registers this callback to Bullet, which stores a pointer to 'this' in
+ * the btDynamicsWorld::getWorldUserInfo() pointer.
+ */
+ static void StaticSimulationSubtickCallback(btDynamicsWorld *world, btScalar timeStep);
+ void SimulationSubtickCallback(btScalar timeStep);
+
virtual void DebugDrawWorld();
// virtual bool proceedDeltaTimeOneStep(float timeStep);
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h
index 3e2337f01ea..62b163536dd 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsController.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h
@@ -125,6 +125,11 @@ class PHY_IPhysicsController : public PHY_IController
virtual float GetLinVelocityMax() const=0;
virtual void SetLinVelocityMax(float val) = 0;
+ virtual void SetAngularVelocityMin(float val) = 0;
+ virtual float GetAngularVelocityMin() const = 0;
+ virtual void SetAngularVelocityMax(float val) = 0;
+ virtual float GetAngularVelocityMax() const = 0;
+
MT_Vector3 GetWorldPosition(MT_Vector3& localpos);
// Shape control
diff --git a/source/gameengine/Physics/common/PHY_Pro.h b/source/gameengine/Physics/common/PHY_Pro.h
index 7c5d9c9638e..c9b91b06a3c 100644
--- a/source/gameengine/Physics/common/PHY_Pro.h
+++ b/source/gameengine/Physics/common/PHY_Pro.h
@@ -43,6 +43,8 @@ struct PHY_ShapeProps {
MT_Scalar m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1]
MT_Scalar m_clamp_vel_min; // Clamp the minimum velocity, this ensures an object moves at a minimum speed unless its stationary
MT_Scalar m_clamp_vel_max; // Clamp max velocity
+ MT_Scalar m_clamp_angvel_min; // Clamp the minimum angular velocity.
+ MT_Scalar m_clamp_angvel_max; // Clamp the maximum angular velocity.
bool m_do_anisotropic; // Should I do anisotropic friction?
bool m_do_fh; // Should the object have a linear Fh spring?
bool m_do_rot_fh; // Should the object have an angular Fh spring?