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:
authorSybren A. Stüvel <sybren@stuvel.eu>2015-06-18 15:43:30 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2015-06-28 13:54:53 +0300
commitc5c2883ce039a35945282b770ad77f461cdf05ad (patch)
treed0a363da2847f3aecaf4e49d15484aa269c20d73 /source/gameengine/Physics
parent32319dd106970663d1b78bb25048b3ceccffc01a (diff)
BGE Fix: apply velocity clamping on every physics subtick
This patch uses the Bullet "internal tick callback" functionality to ensure that velocity clamping is performed after every physics update. This makes a difference when physics subticks > 1, as in that case the too-high velocity could have impacted the simulation. This patch follows the examples at [1] and [2]; the latter example also explains that the way we limit velocity in the BGE (before this patch) is wrong. [1] http://bulletphysics.org/mediawiki-1.5.8/index.php/Simulation_Tick_Callbacks [2] http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Code_Snippets#I_want_to_cap_the_speed_of_my_spaceship; Reviewed by: panzergame Differential Revision: https://developer.blender.org/D1364
Diffstat (limited to 'source/gameengine/Physics')
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp31
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h7
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp17
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h9
4 files changed, 51 insertions, 13 deletions
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 4fd1f10fad6..4306d6d0cd7 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -697,6 +697,24 @@ 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));
+ }
+}
+
/**
* SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
@@ -732,19 +750,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..2a15b6136e4 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -579,6 +579,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')
*/
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index 89c8c124bc8..14a19fdfb41 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -452,6 +452,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;
@@ -677,6 +678,22 @@ 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;
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index e1988478b71..d681298c195 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;
@@ -129,6 +130,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);