[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19746] trunk/blender/source/gameengine: BGE bug #18168: Get local orientation of object using game engine python script system.
Benoit Bolsee
benoit.bolsee at online.be
Wed Apr 15 23:17:08 CEST 2009
Revision: 19746
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19746
Author: ben2610
Date: 2009-04-15 23:17:08 +0200 (Wed, 15 Apr 2009)
Log Message:
-----------
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).
Modified Paths:
--------------
trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
trunk/blender/source/gameengine/Ketsji/KX_GameObject.h
trunk/blender/source/gameengine/PyDoc/KX_GameObject.py
Modified: trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp 2009-04-15 21:03:23 UTC (rev 19745)
+++ trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp 2009-04-15 21:17:08 UTC (rev 19746)
@@ -76,6 +76,10 @@
#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::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::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 @@
{
// 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 @@
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 @@
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 @@
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::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 @@
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_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 @@
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,19 +1466,40 @@
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;
+ if (!PyVecTo(value, pos))
+ return 1;
+
self->NodeSetLocalPosition(pos);
self->NodeUpdateGS(0.f);
return 0;
@@ -1476,15 +1515,24 @@
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)) {
PyErr_SetString(PyExc_AttributeError, "'orientation' attribute needs to be a sequence");
return 1;
@@ -1530,15 +1578,24 @@
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;
if (!PyVecTo(value, scale))
return 1;
@@ -1551,8 +1608,8 @@
PyObject* KX_GameObject::pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list