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-23 16:02:28 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2015-06-28 13:54:53 +0300
commit9f48aa45adb34e03f42d8960fa6d47c5e8b061ab (patch)
tree85573468ed4c7bc2d5e632df288582851ad1b8ce /source/gameengine
parentc5c2883ce039a35945282b770ad77f461cdf05ad (diff)
BGE: added clamping of angular velocity.
Angular velocity clamping was missing from the BGE. It is implemented similarly to the linear velocity clamping. It is needed to be able to drive physical simulations of systems that have a limited rotational speed. Reviewed by: campbellbarton, panzergame, ton Differential Revision: https://developer.blender.org/D1365
Diffstat (limited to 'source/gameengine')
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp50
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h4
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp11
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h21
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp2
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h5
-rw-r--r--source/gameengine/Physics/common/PHY_Pro.h2
8 files changed, 98 insertions, 1 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 3da0863508b..4899eafd84c 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1200,7 +1200,9 @@ static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blendero
// velocity clamping XXX
shapeProps->m_clamp_vel_min = blenderobject->min_vel;
shapeProps->m_clamp_vel_max = blenderobject->max_vel;
-
+ shapeProps->m_clamp_angvel_min = blenderobject->min_angvel;
+ shapeProps->m_clamp_angvel_max = blenderobject->max_angvel;
+
// Character physics properties
shapeProps->m_step_height = blenderobject->step_height;
shapeProps->m_jump_speed = blenderobject->jump_speed;
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 34d50e24741..5701d0e54a0 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -1965,6 +1965,8 @@ PyAttributeDef KX_GameObject::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("isSuspendDynamics", KX_GameObject, pyattr_get_is_suspend_dynamics),
KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMin", KX_GameObject, pyattr_get_lin_vel_min, pyattr_set_lin_vel_min),
KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMax", KX_GameObject, pyattr_get_lin_vel_max, pyattr_set_lin_vel_max),
+ KX_PYATTRIBUTE_RW_FUNCTION("angularVelocityMin", KX_GameObject, pyattr_get_ang_vel_min, pyattr_set_ang_vel_min),
+ KX_PYATTRIBUTE_RW_FUNCTION("angularVelocityMax", KX_GameObject, pyattr_get_ang_vel_max, pyattr_set_ang_vel_max),
KX_PYATTRIBUTE_RW_FUNCTION("visible", KX_GameObject, pyattr_get_visible, pyattr_set_visible),
KX_PYATTRIBUTE_RW_FUNCTION("record_animation", KX_GameObject, pyattr_get_record_animation, pyattr_set_record_animation),
KX_PYATTRIBUTE_BOOL_RW ("occlusion", KX_GameObject, m_bOccluder),
@@ -2487,6 +2489,54 @@ int KX_GameObject::pyattr_set_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF
return PY_SET_ATTR_SUCCESS;
}
+PyObject *KX_GameObject::pyattr_get_ang_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject *self = static_cast<KX_GameObject*>(self_v);
+ PHY_IPhysicsController *spc = self->GetPhysicsController();
+ return PyFloat_FromDouble(spc ? spc->GetAngularVelocityMin() : 0.0f);
+}
+
+int KX_GameObject::pyattr_set_ang_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject *self = static_cast<KX_GameObject*>(self_v);
+ PHY_IPhysicsController *spc = self->GetPhysicsController();
+ MT_Scalar val = PyFloat_AsDouble(value);
+ if (val < 0.0f) { /* also accounts for non float */
+ PyErr_SetString(PyExc_AttributeError,
+ "gameOb.angularVelocityMin = float: KX_GameObject, expected a nonnegative float");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ if (spc)
+ spc->SetAngularVelocityMin(val);
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject *KX_GameObject::pyattr_get_ang_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject *self = static_cast<KX_GameObject*>(self_v);
+ PHY_IPhysicsController *spc = self->GetPhysicsController();
+ return PyFloat_FromDouble(spc ? spc->GetAngularVelocityMax() : 0.0f);
+}
+
+int KX_GameObject::pyattr_set_ang_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject *self = static_cast<KX_GameObject*>(self_v);
+ PHY_IPhysicsController *spc = self->GetPhysicsController();
+ MT_Scalar val = PyFloat_AsDouble(value);
+ if (val < 0.0f) { /* also accounts for non float */
+ PyErr_SetString(PyExc_AttributeError,
+ "gameOb.angularVelocityMax = float: KX_GameObject, expected a nonnegative float");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ if (spc)
+ spc->SetAngularVelocityMax(val);
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
PyObject *KX_GameObject::pyattr_get_visible(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 9c081b449ec..670fcd6fb6e 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -1054,6 +1054,10 @@ public:
static int pyattr_set_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_ang_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_ang_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_ang_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_ang_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_visible(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_record_animation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 4306d6d0cd7..692704b5080 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -713,6 +713,17 @@ void CcdPhysicsController::SimulationTick(float timestep)
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));
+ }
}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 2a15b6136e4..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;
@@ -708,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 14a19fdfb41..82451e6a3ed 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -3111,6 +3111,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/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?