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
path: root/source
diff options
context:
space:
mode:
authorBenoit Bolsee <benoit.bolsee@online.be>2009-04-16 01:17:08 +0400
committerBenoit Bolsee <benoit.bolsee@online.be>2009-04-16 01:17:08 +0400
commitbbdaa03d6598a6f09e7272ade1ef96abf3ce1d53 (patch)
tree46b5db859f6428f51c0d7f39ecc4431fd54c173d /source
parent0c1bfa4a37d9ba40b8ad66656363ecfa77e0db1d (diff)
BGE bug #18168: Get local orientation of object using game engine python script system. Added localOrientation and worldOrientation. orientation attribute deprecated. Same for position and scaling. World attributes are read-only except for worldPosition. Add systematic check on NULL SGNode in all python functions. This is necessary to handle zombie objects (deleted by the game but kept alive by a reference in a list).
Diffstat (limited to 'source')
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp171
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h16
-rw-r--r--source/gameengine/PyDoc/KX_GameObject.py21
3 files changed, 143 insertions, 65 deletions
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 36fb9142adc..283b78c2947 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -76,6 +76,10 @@ typedef unsigned long uint_ptr;
#include "KX_SG_NodeRelationships.h"
static MT_Point3 dummy_point= MT_Point3(0.0, 0.0, 0.0);
+static MT_Vector3 dummy_scaling = MT_Vector3(1.0, 1.0, 1.0);
+static MT_Matrix3x3 dummy_orientation = MT_Matrix3x3( 1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
KX_GameObject::KX_GameObject(
void* sgReplicationInfo,
@@ -373,11 +377,14 @@ void KX_GameObject::ApplyTorque(const MT_Vector3& torque,bool local)
void KX_GameObject::ApplyMovement(const MT_Vector3& dloc,bool local)
{
- if (m_pPhysicsController1) // (IsDynamic())
+ if (GetSGNode())
{
- m_pPhysicsController1->RelativeTranslate(dloc,local);
+ if (m_pPhysicsController1) // (IsDynamic())
+ {
+ m_pPhysicsController1->RelativeTranslate(dloc,local);
+ }
+ GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local);
}
- GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local);
}
@@ -385,11 +392,13 @@ void KX_GameObject::ApplyMovement(const MT_Vector3& dloc,bool local)
void KX_GameObject::ApplyRotation(const MT_Vector3& drot,bool local)
{
MT_Matrix3x3 rotmat(drot);
+
+ if (GetSGNode()) {
+ GetSGNode()->RelativeRotate(rotmat,local);
- GetSGNode()->RelativeRotate(rotmat,local);
-
- if (m_pPhysicsController1) { // (IsDynamic())
- m_pPhysicsController1->RelativeRotate(rotmat,local);
+ if (m_pPhysicsController1) { // (IsDynamic())
+ m_pPhysicsController1->RelativeRotate(rotmat,local);
+ }
}
}
@@ -402,16 +411,17 @@ double* KX_GameObject::GetOpenGLMatrix()
{
// todo: optimize and only update if necessary
double* fl = m_OpenGL_4x4Matrix.getPointer();
- MT_Transform trans;
+ if (GetSGNode()) {
+ MT_Transform trans;
- trans.setOrigin(GetSGNode()->GetWorldPosition());
- trans.setBasis(GetSGNode()->GetWorldOrientation());
+ trans.setOrigin(GetSGNode()->GetWorldPosition());
+ trans.setBasis(GetSGNode()->GetWorldOrientation());
- MT_Vector3 scaling = GetSGNode()->GetWorldScaling();
- m_bIsNegativeScaling = ((scaling[0] < 0.0) ^ (scaling[1] < 0.0) ^ (scaling[2] < 0.0)) ? true : false;
- trans.scale(scaling[0], scaling[1], scaling[2]);
- trans.getValue(fl);
-
+ MT_Vector3 scaling = GetSGNode()->GetWorldScaling();
+ m_bIsNegativeScaling = ((scaling[0] < 0.0) ^ (scaling[1] < 0.0) ^ (scaling[2] < 0.0)) ? true : false;
+ trans.scale(scaling[0], scaling[1], scaling[2]);
+ trans.getValue(fl);
+ }
return fl;
}
@@ -442,13 +452,15 @@ static void UpdateBuckets_recursive(SG_Node* node)
void KX_GameObject::UpdateBuckets( bool recursive )
{
- double* fl = GetOpenGLMatrixPtr()->getPointer();
+ if (GetSGNode()) {
+ double* fl = GetOpenGLMatrixPtr()->getPointer();
- for (size_t i=0;i<m_meshes.size();i++)
- m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
+ for (size_t i=0;i<m_meshes.size();i++)
+ m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
- if (recursive) {
- UpdateBuckets_recursive(m_pSGNode);
+ if (recursive) {
+ UpdateBuckets_recursive(GetSGNode());
+ }
}
}
@@ -599,9 +611,11 @@ KX_GameObject::SetVisible(
bool recursive
)
{
- m_bVisible = v;
- if (recursive)
- setVisible_recursive(m_pSGNode, v);
+ if (GetSGNode()) {
+ m_bVisible = v;
+ if (recursive)
+ setVisible_recursive(GetSGNode(), v);
+ }
}
static void setOccluder_recursive(SG_Node* node, bool v)
@@ -627,9 +641,11 @@ KX_GameObject::SetOccluder(
bool recursive
)
{
- m_bOccluder = v;
- if (recursive)
- setOccluder_recursive(m_pSGNode, v);
+ if (GetSGNode()) {
+ m_bOccluder = v;
+ if (recursive)
+ setOccluder_recursive(GetSGNode(), v);
+ }
}
void
@@ -929,7 +945,9 @@ void KX_GameObject::NodeSetRelativeScale(const MT_Vector3& scale)
void KX_GameObject::NodeSetWorldPosition(const MT_Point3& trans)
{
- SG_Node* parent = m_pSGNode->GetSGParent();
+ if (!GetSGNode())
+ return;
+ SG_Node* parent = GetSGNode()->GetSGParent();
if (parent != NULL)
{
// Make sure the objects have some scale
@@ -964,13 +982,9 @@ void KX_GameObject::NodeUpdateGS(double time)
const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const
{
- static MT_Matrix3x3 defaultOrientation = MT_Matrix3x3( 1.0, 0.0, 0.0,
- 0.0, 1.0, 0.0,
- 0.0, 0.0, 1.0);
-
// check on valid node in case a python controller holds a reference to a deleted object
if (!GetSGNode())
- return defaultOrientation;
+ return dummy_orientation;
return GetSGNode()->GetWorldOrientation();
}
@@ -978,11 +992,9 @@ const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const
const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const
{
- static MT_Vector3 defaultScaling = MT_Vector3(1.0, 1.0, 1.0);
-
// check on valid node in case a python controller holds a reference to a deleted object
if (!GetSGNode())
- return defaultScaling;
+ return dummy_scaling;
return GetSGNode()->GetWorldScaling();
}
@@ -1091,13 +1103,19 @@ PyAttributeDef KX_GameObject::Attributes[] = {
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),
+ KX_PYATTRIBUTE_RW_FUNCTION("position", KX_GameObject, pyattr_get_worldPosition, pyattr_set_localPosition),
KX_PYATTRIBUTE_RO_FUNCTION("localInertia", KX_GameObject, pyattr_get_localInertia),
- KX_PYATTRIBUTE_RW_FUNCTION("orientation",KX_GameObject,pyattr_get_orientation,pyattr_set_orientation),
- KX_PYATTRIBUTE_RW_FUNCTION("scaling", KX_GameObject, pyattr_get_scaling, pyattr_set_scaling),
+ KX_PYATTRIBUTE_RW_FUNCTION("orientation",KX_GameObject,pyattr_get_worldOrientation,pyattr_set_localOrientation),
+ KX_PYATTRIBUTE_RW_FUNCTION("scaling", KX_GameObject, pyattr_get_worldScaling, pyattr_set_localScaling),
KX_PYATTRIBUTE_RW_FUNCTION("timeOffset",KX_GameObject, pyattr_get_timeOffset,pyattr_set_timeOffset),
KX_PYATTRIBUTE_RW_FUNCTION("state", KX_GameObject, pyattr_get_state, pyattr_set_state),
KX_PYATTRIBUTE_RO_FUNCTION("meshes", KX_GameObject, pyattr_get_meshes),
+ KX_PYATTRIBUTE_RW_FUNCTION("localOrientation",KX_GameObject,pyattr_get_localOrientation,pyattr_set_localOrientation),
+ KX_PYATTRIBUTE_RO_FUNCTION("worldOrientation",KX_GameObject,pyattr_get_worldOrientation),
+ KX_PYATTRIBUTE_RW_FUNCTION("localPosition", KX_GameObject, pyattr_get_localPosition, pyattr_set_localPosition),
+ KX_PYATTRIBUTE_RW_FUNCTION("worldPosition", KX_GameObject, pyattr_get_worldPosition, pyattr_set_worldPosition),
+ KX_PYATTRIBUTE_RW_FUNCTION("localScaling", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling),
+ KX_PYATTRIBUTE_RO_FUNCTION("worldScaling", KX_GameObject, pyattr_get_worldScaling),
KX_PYATTRIBUTE_RO_FUNCTION("__dict__", KX_GameObject, pyattr_get_dir_dict),
@@ -1448,13 +1466,34 @@ int KX_GameObject::pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *at
return 0;
}
-PyObject* KX_GameObject::pyattr_get_position(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+PyObject* KX_GameObject::pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(self->NodeGetWorldPosition());
}
-int KX_GameObject::pyattr_set_position(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ MT_Point3 pos;
+ if (!PyVecTo(value, pos))
+ return 1;
+
+ self->NodeSetWorldPosition(pos);
+ self->NodeUpdateGS(0.f);
+ return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ if (self->GetSGNode())
+ return PyObjectFrom(self->GetSGNode()->GetLocalPosition());
+ else
+ return PyObjectFrom(dummy_point);
+}
+
+int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
MT_Point3 pos;
@@ -1476,13 +1515,22 @@ PyObject* KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIB
return Py_BuildValue("fff", 0.0f, 0.0f, 0.0f);
}
-PyObject* KX_GameObject::pyattr_get_orientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+PyObject* KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(self->NodeGetWorldOrientation());
}
-int KX_GameObject::pyattr_set_orientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ if (self->GetSGNode())
+ return PyObjectFrom(self->GetSGNode()->GetLocalOrientation());
+ else
+ return PyObjectFrom(dummy_orientation);
+}
+
+int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
if (!PySequence_Check(value)) {
@@ -1530,13 +1578,22 @@ int KX_GameObject::pyattr_set_orientation(void *self_v, const KX_PYATTRIBUTE_DEF
return 1;
}
-PyObject* KX_GameObject::pyattr_get_scaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(self->NodeGetWorldScaling());
}
-int KX_GameObject::pyattr_set_scaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+PyObject* KX_GameObject::pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ if (self->GetSGNode())
+ return PyObjectFrom(self->GetSGNode()->GetLocalScale());
+ else
+ return PyObjectFrom(dummy_scaling);
+}
+
+int KX_GameObject::pyattr_set_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
MT_Vector3 scale;
@@ -1551,8 +1608,8 @@ int KX_GameObject::pyattr_set_scaling(void *self_v, const KX_PYATTRIBUTE_DEF *at
PyObject* KX_GameObject::pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
- SG_Node* sg_parent= self->GetSGNode()->GetSGParent(); /* GetSGNode() is valid or exception would be raised */
- if (sg_parent && sg_parent->IsSlowParent()) {
+ SG_Node* sg_parent;
+ if (self->GetSGNode() && (sg_parent = self->GetSGNode()->GetSGParent()) != NULL && sg_parent->IsSlowParent()) {
return PyFloat_FromDouble(static_cast<KX_SlowParentRelation *>(sg_parent->GetParentRelation())->GetTimeOffset());
} else {
return PyFloat_FromDouble(0.0);
@@ -1562,16 +1619,16 @@ PyObject* KX_GameObject::pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUT
int KX_GameObject::pyattr_set_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
- MT_Scalar val = PyFloat_AsDouble(value);
- SG_Node* sg_parent= self->GetSGNode()->GetSGParent(); /* GetSGNode() is valid or exception would be raised */
- if (val < 0.0f) { /* also accounts for non float */
- PyErr_SetString(PyExc_AttributeError, "expected a float zero or above");
- return 1;
+ if (self->GetSGNode()) {
+ MT_Scalar val = PyFloat_AsDouble(value);
+ SG_Node* sg_parent= self->GetSGNode()->GetSGParent();
+ if (val < 0.0f) { /* also accounts for non float */
+ PyErr_SetString(PyExc_AttributeError, "expected a float zero or above");
+ return 1;
+ }
+ if (sg_parent && sg_parent->IsSlowParent())
+ static_cast<KX_SlowParentRelation *>(sg_parent->GetParentRelation())->SetTimeOffset(val);
}
-
- if (sg_parent && sg_parent->IsSlowParent())
- static_cast<KX_SlowParentRelation *>(sg_parent->GetParentRelation())->SetTimeOffset(val);
-
return 0;
}
@@ -2092,6 +2149,8 @@ PyObject* KX_GameObject::PyRemoveParent(PyObject* self)
static void walk_children(SG_Node* node, CListValue* list, bool recursive)
{
+ if (!node)
+ return;
NodeList& children = node->GetSGChildren();
for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
@@ -2122,7 +2181,7 @@ PyObject* KX_GameObject::PyGetChildren(PyObject* self)
PyObject* KX_GameObject::PyGetChildrenRecursive(PyObject* self)
{
CListValue* list = new CListValue();
- walk_children(m_pSGNode, list, 1);
+ walk_children(GetSGNode(), list, 1);
return list;
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 0bf3e60f34b..cf0c0e6b0f5 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -880,14 +880,18 @@ public:
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);
- static int pyattr_set_position(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
- static PyObject* pyattr_get_orientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
- static int pyattr_set_orientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
- static PyObject* pyattr_get_scaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
- static int pyattr_set_scaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py
index 4aa9de2fe86..21ddf439924 100644
--- a/source/gameengine/PyDoc/KX_GameObject.py
+++ b/source/gameengine/PyDoc/KX_GameObject.py
@@ -39,11 +39,26 @@ class KX_GameObject: # (SCA_IObject)
@ivar occlusion: occlusion capability flag.
@type occlusion: boolean
@ivar position: The object's position.
- @type position: list [x, y, z]
+ DEPRECATED: use localPosition and worldPosition
+ @type position: list [x, y, z] On write: local position, on read: world position
@ivar orientation: The object's orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector.
- @type orientation: 3x3 Matrix [[float]]
+ DEPRECATED: use localOrientation and worldOrientation
+ @type orientation: 3x3 Matrix [[float]] On write: local orientation, on read: world orientation
@ivar scaling: The object's scaling factor. list [sx, sy, sz]
- @type scaling: list [sx, sy, sz]
+ DEPRECATED: use localScaling and worldScaling
+ @type scaling: list [sx, sy, sz] On write: local scaling, on read: world scaling
+ @ivar localOrientation: The object's local orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector.
+ @type localOrientation: 3x3 Matrix [[float]]
+ @ivar worldOrientation: The object's world orientation. Read-only.
+ @type worldOrientation: 3x3 Matrix [[float]]
+ @ivar localScaling: The object's local scaling factor.
+ @type localScaling: list [sx, sy, sz]
+ @ivar worldScaling: The object's world scaling factor. Read-only
+ @type worldScaling: list [sx, sy, sz]
+ @ivar localPosition: The object's local position.
+ @type localPosition: list [x, y, z]
+ @ivar worldPosition: The object's world position.
+ @type worldPosition: list [x, y, z]
@ivar timeOffset: adjust the slowparent delay at runtime.
@type timeOffset: float
@ivar state: the game object's state bitmask, using the first 30 bits, one bit must always be set.