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:
-rw-r--r--source/blender/makesdna/DNA_object_types.h4
-rw-r--r--source/blender/src/buttons_logic.c18
-rw-r--r--source/blender/src/editobject.c13
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp27
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.h6
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp49
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h4
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.h6
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp14
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h23
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h6
-rw-r--r--source/gameengine/Physics/common/PHY_Pro.h6
-rw-r--r--source/gameengine/PyDoc/KX_GameObject.py14
15 files changed, 176 insertions, 20 deletions
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 3a408404b0b..82da883df4a 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -157,7 +157,9 @@ typedef struct Object {
float formfactor;
float rdamping, sizefac;
float margin;
- int pad3;
+ 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 */
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 2f68720acb0..67531e9b3b8 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -3139,6 +3139,7 @@ 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)
@@ -3166,7 +3167,24 @@ 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;
}
+ xco = 0;
+
+ uiBlockEndAlign(block);
+
+ uiDefBut(block, LABEL, 0, "Clamp Velocity (zero disables)", xco, yco, 180*2, 19, NULL, 0, 0, 0, 0, "");
+
+ uiBlockBeginAlign(block);
+
+ uiDefButF(block, NUM, 0, "Min",
+ xco+=180, yco, 90, 19, &ob->min_vel, 0.0, 1000.0, 1, 0,
+ "Clamp velocity to this minimum speed (except when totally still)");
+ uiDefButF(block, NUM, 0, "Max",
+ xco+=90, yco, 90, 19, &ob->max_vel, 0.0, 1000.0, 1, 0,
+ "Clamp velocity to this maximum speed");
+ uiBlockEndAlign(block);
+
/*
uiDefButBitI(block, TOG, OB_BSB_COL_CL_RS, 0, "Cluster Collision RS",
xco, yco, 180, 19, &ob->bsoft->collisionflags, 0, 0, 0, 0,
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index bb9be49c347..2f127f9a3ec 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -3205,14 +3205,12 @@ static void copymenu_properties(Object *ob)
prop= prop->next;
}
- if(tot==0) {
- error("No properties in the active object to copy");
- return;
- }
-
str= MEM_callocN(50 + 33*tot, "copymenu prop");
- strcpy(str, "Copy Property %t|Replace All|Merge All|%l");
+ if (tot)
+ strcpy(str, "Copy Property %t|Replace All|Merge All|%l");
+ else
+ strcpy(str, "Copy Property %t|Clear All (no properties on active)");
tot= 0;
prop= ob->prop.first;
@@ -3526,7 +3524,8 @@ void copy_attr(short event)
base->object->formfactor = ob->formfactor;
base->object->damping= ob->damping;
base->object->rdamping= ob->rdamping;
- base->object->mass= ob->mass;
+ base->object->min_vel= ob->min_vel;
+ base->object->max_vel= ob->max_vel;
if (ob->gameflag & OB_BOUNDS) {
base->object->boundtype = ob->boundtype;
}
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 5de2c4a2fe7..2ae47e47d74 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1107,6 +1107,10 @@ static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blendero
shapeProps->m_do_fh = (blenderobject->gameflag & OB_DO_FH) != 0;
shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0;
+// velocity clamping XXX
+ shapeProps->m_clamp_vel_min = blenderobject->min_vel;
+ shapeProps->m_clamp_vel_max = blenderobject->max_vel;
+
return shapeProps;
}
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index c621f11994a..831f9241fec 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -59,6 +59,24 @@ void KX_BulletPhysicsController::applyImpulse(const MT_Point3& attach, const MT_
}
+float KX_BulletPhysicsController::GetLinVelocityMin()
+{
+ return (float)CcdPhysicsController::GetLinVelocityMin();
+}
+void KX_BulletPhysicsController::SetLinVelocityMin(float val)
+{
+ CcdPhysicsController::SetLinVelocityMin(val);
+}
+
+float KX_BulletPhysicsController::GetLinVelocityMax()
+{
+ return (float)CcdPhysicsController::GetLinVelocityMax();
+}
+void KX_BulletPhysicsController::SetLinVelocityMax(float val)
+{
+ CcdPhysicsController::SetLinVelocityMax(val);
+}
+
void KX_BulletPhysicsController::SetObject (SG_IObject* object)
{
SG_Controller::SetObject(object);
@@ -73,6 +91,10 @@ void KX_BulletPhysicsController::SetObject (SG_IObject* object)
}
+MT_Scalar KX_BulletPhysicsController::GetRadius()
+{
+ return MT_Scalar(CcdPhysicsController::GetRadius());
+}
void KX_BulletPhysicsController::setMargin (float collisionMargin)
{
@@ -176,11 +198,6 @@ MT_Vector3 KX_BulletPhysicsController::GetLocalInertia()
return inertia;
}
-MT_Scalar KX_BulletPhysicsController::GetRadius()
-{
- return MT_Scalar(CcdPhysicsController::GetRadius());
-}
-
MT_Vector3 KX_BulletPhysicsController::getReactionForce()
{
assert(0);
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
index 9821b3fd253..b39098206f7 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
@@ -56,7 +56,11 @@ public:
virtual SG_Controller* GetReplica(class SG_Node* destnode);
virtual MT_Scalar GetRadius();
-
+
+ virtual float GetLinVelocityMin();
+ virtual void SetLinVelocityMin(float val);
+ virtual float GetLinVelocityMax();
+ virtual void SetLinVelocityMax(float val);
virtual void SetSumoTransform(bool nondynaonly);
// todo: remove next line !
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index 03149859f4d..08e2ea30414 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -801,6 +801,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
ci.m_gravity = btVector3(0,0,0);
ci.m_localInertiaTensor =btVector3(0,0,0);
ci.m_mass = objprop->m_dyna ? 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_margin = objprop->m_margin;
shapeInfo->m_radius = objprop->m_radius;
isbulletdyna = objprop->m_dyna;
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 16cf3d9ae32..a399d3b477a 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -1086,6 +1086,8 @@ PyAttributeDef KX_GameObject::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name),
KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent),
KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass),
+ 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("visible", KX_GameObject, pyattr_get_visible, pyattr_set_visible),
KX_PYATTRIBUTE_BOOL_RW ("occlusion", KX_GameObject, m_bOccluder),
KX_PYATTRIBUTE_RW_FUNCTION("position", KX_GameObject, pyattr_get_position, pyattr_set_position),
@@ -1364,6 +1366,53 @@ int KX_GameObject::pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrd
return 0;
}
+PyObject* KX_GameObject::pyattr_get_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_IPhysicsController *spc = self->GetPhysicsController();
+ return PyFloat_FromDouble(spc ? spc->GetLinVelocityMax() : 0.0f);
+}
+
+int KX_GameObject::pyattr_set_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_IPhysicsController *spc = self->GetPhysicsController();
+ MT_Scalar val = PyFloat_AsDouble(value);
+ if (val < 0.0f) { /* also accounts for non float */
+ PyErr_SetString(PyExc_AttributeError, "expected a float zero or above");
+ return 1;
+ }
+
+ if (spc)
+ spc->SetLinVelocityMin(val);
+
+ return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_IPhysicsController *spc = self->GetPhysicsController();
+ return PyFloat_FromDouble(spc ? spc->GetLinVelocityMax() : 0.0f);
+}
+
+int KX_GameObject::pyattr_set_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_IPhysicsController *spc = self->GetPhysicsController();
+ MT_Scalar val = PyFloat_AsDouble(value);
+ if (val < 0.0f) { /* also accounts for non float */
+ PyErr_SetString(PyExc_AttributeError, "expected a float zero or above");
+ return 1;
+ }
+
+ if (spc)
+ spc->SetLinVelocityMax(val);
+
+ return 0;
+}
+
+
PyObject* KX_GameObject::pyattr_get_visible(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index c389d6cc776..94192580859 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -960,6 +960,10 @@ public:
static PyObject* pyattr_get_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ 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_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_position(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h
index b7603203241..10b66da7b76 100644
--- a/source/gameengine/Ketsji/KX_IPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_IPhysicsController.h
@@ -79,6 +79,12 @@ public:
virtual void setScaling(const MT_Vector3& scaling)=0;
virtual MT_Scalar GetMass()=0;
virtual void SetMass(MT_Scalar newmass)=0;
+
+ virtual float GetLinVelocityMin()=0;
+ virtual void SetLinVelocityMin(float newmass)=0;
+ virtual float GetLinVelocityMax()=0;
+ virtual void SetLinVelocityMax(float newmass)=0;
+
virtual MT_Vector3 GetLocalInertia()=0;
virtual MT_Vector3 getReactionForce()=0;
virtual void setRigidBody(bool rigid)=0;
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 2283968801f..0b9da8f46d3 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -584,7 +584,19 @@ 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 btVector3& worldPos = body->getCenterOfMassPosition();
m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 245cde2baaa..c7638b36728 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -214,6 +214,8 @@ struct CcdConstructionInfo
m_gravity(0,0,0),
m_scaling(1.f,1.f,1.f),
m_mass(0.f),
+ m_clamp_vel_min(-1.f),
+ m_clamp_vel_max(-1.f),
m_restitution(0.1f),
m_friction(0.5f),
m_linearDamping(0.1f),
@@ -239,6 +241,8 @@ struct CcdConstructionInfo
btVector3 m_gravity;
btVector3 m_scaling;
btScalar m_mass;
+ btScalar m_clamp_vel_min;
+ btScalar m_clamp_vel_max;
btScalar m_restitution;
btScalar m_friction;
btScalar m_linearDamping;
@@ -479,7 +483,24 @@ class CcdPhysicsController : public PHY_IPhysicsController
}
m_cci.m_radius = margin;
}
-
+
+ // velocity clamping
+ virtual void SetLinVelocityMin(float val)
+ {
+ m_cci.m_clamp_vel_min= val;
+ }
+ virtual float GetLinVelocityMin() const
+ {
+ return m_cci.m_clamp_vel_min;
+ }
+ virtual void SetLinVelocityMax(float val)
+ {
+ m_cci.m_clamp_vel_max= val;
+ }
+ virtual float GetLinVelocityMax() const
+ {
+ return m_cci.m_clamp_vel_max;
+ }
bool wantsSleeping();
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h
index 6cba6fa88af..770426b48db 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsController.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h
@@ -90,6 +90,12 @@ class PHY_IPhysicsController : public PHY_IController
virtual float GetMargin() const=0;
virtual float GetRadius() const=0;
virtual void SetRadius(float margin) = 0;
+
+ virtual float GetLinVelocityMin() const=0;
+ virtual void SetLinVelocityMin(float val) = 0;
+ virtual float GetLinVelocityMax() const=0;
+ virtual void SetLinVelocityMax(float val) = 0;
+
PHY__Vector3 GetWorldPosition(PHY__Vector3& localpos);
};
diff --git a/source/gameengine/Physics/common/PHY_Pro.h b/source/gameengine/Physics/common/PHY_Pro.h
index 32e63ac2f6d..0249fc3118a 100644
--- a/source/gameengine/Physics/common/PHY_Pro.h
+++ b/source/gameengine/Physics/common/PHY_Pro.h
@@ -35,9 +35,11 @@
struct PHY_ShapeProps {
MT_Scalar m_mass; // Total mass
MT_Scalar m_inertia; // Inertia, should be a tensor some time
- MT_Scalar m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum
- MT_Scalar m_ang_drag; // Angular drag
+ MT_Scalar m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum, inverted and called dampening in blenders UI
+ MT_Scalar m_ang_drag; // Angular drag, inverted and called dampening in blenders UI
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
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?
diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py
index fa4641c3e2f..44b84d44d8d 100644
--- a/source/gameengine/PyDoc/KX_GameObject.py
+++ b/source/gameengine/PyDoc/KX_GameObject.py
@@ -16,8 +16,18 @@ class KX_GameObject: # (SCA_IObject)
@ivar name: The object's name. (Read only)
- note: Currently (Blender 2.49) the prefix "OB" is added to all objects name. This may change in blender 2.5.
@type name: string.
- @ivar mass: The object's mass (provided the object has a physics controller).
+ @ivar mass: The object's mass
+ - note: The object must have a physics controller for the mass to be applied, otherwise the mass value will be returned as 0.0
@type mass: float
+ @ivar linVelocityMin: Enforces the object keeps moving at a minimum velocity.
+ - note: Applies to dynamic and rigid body objects only.
+ - note: A value of 0.0 disables this option.
+ - note: While objects are stationary the minimum velocity will not be applied.
+ @type linVelocityMin: float
+ @ivar linVelocityMax: Clamp the maximum linear velocity to prevent objects moving beyond a set speed.
+ - note: Applies to dynamic and rigid body objects only.
+ - note: A value of 0.0 disables this option (rather then setting it stationary).
+ @type linVelocityMax: float
@ivar localInertia: the object's inertia vector in local coordinates. Read only.
@type localInertia: list [ix, iy, iz]
@ivar parent: The object's parent object. (Read only)
@@ -35,7 +45,7 @@ class KX_GameObject: # (SCA_IObject)
@type scaling: list [sx, sy, sz]
@ivar timeOffset: adjust the slowparent delay at runtime.
@type timeOffset: float
- @ivar state: the game object's state bitmask.
+ @ivar state: the game object's state bitmask, using the first 30 bits, one bit must always be set.
@type state: int
@ivar meshes: a list meshes for this object.
- note: Most objects use only 1 mesh.