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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs