diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-06-23 17:34:45 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-06-23 17:34:45 +0400 |
commit | eb22a7b2102cceb432e3545cd342956e92873a49 (patch) | |
tree | c87ad1de81cc216403568b44f289ff9af3a2ae9e /source/gameengine | |
parent | bf74f105bc5ec98980fa087347203244750fb669 (diff) |
PyRNA API support for matrix types as Mathutils matrix (with callbacks) rather then a generic rna sequence of floats.
Any 3x3 or 4x4 rna matrix will automatically be returned as a Mathutils matrix.
This makes useful stuff like multiplying a vector location by an object matrix possible.
ob = bpy.data.scenes[0].objects[0]
print (ob.data.verts[0].co * ob.matrix)
Also added mathutils matrix types to the BGE GameObject.localOrientation, worldOrientation
* MT_Matrix3x3 added getValue3x3 and setValue3x3, assumed a 4x3 float array.
* KX_GameObject.cpp convenience functions NodeSetGlobalOrientation, NodeGetLocalOrientation, NodeGetLocalScaling, NodeGetLocalPosition.
* 2.5 python api now initializes modules BGL, Mathutils and Geometry
* modules py3 PyModuleDef's use PyModuleDef_HEAD_INIT, rather then {}, was making msvc fail to build.
* added macros for Vector_ReadCallback, Vector_WriteCallback etc. to check if the callback pointer is set before calling the function.
Diffstat (limited to 'source/gameengine')
-rw-r--r-- | source/gameengine/Ketsji/KX_GameObject.cpp | 140 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_GameObject.h | 21 |
2 files changed, 116 insertions, 45 deletions
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 081549db686..a3b2ba79e11 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -983,7 +983,17 @@ void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot) GetSGNode()->SetLocalOrientation(rot); } +void KX_GameObject::NodeSetGlobalOrientation(const MT_Matrix3x3& rot) +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return; + if (GetSGNode()->GetSGParent()) + GetSGNode()->SetLocalOrientation(GetSGNode()->GetSGParent()->GetWorldOrientation().inverse()*rot); + else + GetSGNode()->SetLocalOrientation(rot); +} void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale) { @@ -1062,7 +1072,13 @@ const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const return GetSGNode()->GetWorldOrientation(); } - +const MT_Matrix3x3& KX_GameObject::NodeGetLocalOrientation() const +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return dummy_orientation; + return GetSGNode()->GetLocalOrientation(); +} const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const { @@ -1073,7 +1089,14 @@ const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const return GetSGNode()->GetWorldScaling(); } +const MT_Vector3& KX_GameObject::NodeGetLocalScaling() const +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return dummy_scaling; + return GetSGNode()->GetLocalScale(); +} const MT_Point3& KX_GameObject::NodeGetWorldPosition() const { @@ -1084,6 +1107,16 @@ const MT_Point3& KX_GameObject::NodeGetWorldPosition() const return dummy_point; } +const MT_Point3& KX_GameObject::NodeGetLocalPosition() const +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (GetSGNode()) + return GetSGNode()->GetLocalPosition(); + else + return dummy_point; +} + + /* Suspend/ resume: for the dynamic behaviour, there is a simple * method. For the residual motion, there is not. I wonder what the * correct solution is for Sumo. Remove from the motion-update tree? @@ -1164,10 +1197,9 @@ extern "C" { #define MATHUTILS_VEC_CB_SCALE_GLOBAL 4 #define MATHUTILS_VEC_CB_INERTIA_LOCAL 5 - static int mathutils_kxgameob_vector_cb_index= -1; /* index for our callbacks */ -static int mathutils_kxgameob_vector_check(PyObject *self_v) +static int mathutils_kxgameob_generic_check(PyObject *self_v) { KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v); if(self==NULL) @@ -1184,26 +1216,21 @@ static int mathutils_kxgameob_vector_get(PyObject *self_v, int subtype, float *v switch(subtype) { case MATHUTILS_VEC_CB_POS_LOCAL: - if(!self->GetSGNode()) return 0; - self->GetSGNode()->GetLocalPosition().getValue(vec_from); + self->NodeGetLocalPosition().getValue(vec_from); break; case MATHUTILS_VEC_CB_POS_GLOBAL: - if(!self->GetSGNode()) return 0; - self->GetSGNode()->GetWorldPosition().getValue(vec_from); + self->NodeGetWorldPosition().getValue(vec_from); break; case MATHUTILS_VEC_CB_SCALE_LOCAL: - if(!self->GetSGNode()) return 0; - self->GetSGNode()->GetLocalScale().getValue(vec_from); + self->NodeGetLocalScaling().getValue(vec_from); break; case MATHUTILS_VEC_CB_SCALE_GLOBAL: self->NodeGetWorldScaling().getValue(vec_from); break; case MATHUTILS_VEC_CB_INERTIA_LOCAL: - if(!self->GetSGNode()) return 0; + if(!self->GetPhysicsController()) return 0; self->GetPhysicsController()->GetLocalInertia().getValue(vec_from); break; - - } return 1; @@ -1215,11 +1242,6 @@ static int mathutils_kxgameob_vector_set(PyObject *self_v, int subtype, float *v if(self==NULL) return 0; - /* first */ - SG_Node* sg = self->GetSGNode(); - if(sg==NULL) - return 0; - switch(subtype) { case MATHUTILS_VEC_CB_POS_LOCAL: self->NodeSetLocalPosition(MT_Point3(vec_to)); @@ -1269,18 +1291,75 @@ static int mathutils_kxgameob_vector_set_index(PyObject *self_v, int subtype, fl } Mathutils_Callback mathutils_kxgameob_vector_cb = { - mathutils_kxgameob_vector_check, + mathutils_kxgameob_generic_check, mathutils_kxgameob_vector_get, mathutils_kxgameob_vector_set, mathutils_kxgameob_vector_get_index, mathutils_kxgameob_vector_set_index }; +/* Matrix */ +#define MATHUTILS_MAT_CB_ORI_LOCAL 1 +#define MATHUTILS_MAT_CB_ORI_GLOBAL 2 + +static int mathutils_kxgameob_matrix_cb_index= -1; /* index for our callbacks */ + +static int mathutils_kxgameob_matrix_get(PyObject *self_v, int subtype, float *mat_from) +{ + KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_MAT_CB_ORI_LOCAL: + self->NodeGetLocalOrientation().getValue3x3(mat_from); + break; + case MATHUTILS_MAT_CB_ORI_GLOBAL: + self->NodeGetWorldOrientation().getValue3x3(mat_from); + break; + } + + return 1; +} + + +static int mathutils_kxgameob_matrix_set(PyObject *self_v, int subtype, float *mat_to) +{ + KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + MT_Matrix3x3 mat3x3; + switch(subtype) { + case MATHUTILS_MAT_CB_ORI_LOCAL: + mat3x3.setValue3x3(mat_to); + self->NodeSetLocalOrientation(mat3x3); + self->NodeUpdateGS(0.f); + break; + case MATHUTILS_MAT_CB_ORI_GLOBAL: + mat3x3.setValue3x3(mat_to); + self->NodeSetLocalOrientation(mat3x3); + self->NodeUpdateGS(0.f); + break; + } + + return 1; +} + +Mathutils_Callback mathutils_kxgameob_matrix_cb = { + mathutils_kxgameob_generic_check, + mathutils_kxgameob_matrix_get, + mathutils_kxgameob_matrix_set, + NULL, + NULL +}; + void KX_GameObject_Mathutils_Callback_Init(void) { // register mathutils callbacks, ok to run more then once. mathutils_kxgameob_vector_cb_index= Mathutils_RegisterCallback(&mathutils_kxgameob_vector_cb); + mathutils_kxgameob_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_kxgameob_matrix_cb); } #endif // USE_MATHUTILS @@ -1754,10 +1833,7 @@ PyObject* KX_GameObject::pyattr_get_localPosition(void *self_v, const KX_PYATTRI #ifdef USE_MATHUTILS return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_LOCAL); #else - if (self->GetSGNode()) - return PyObjectFrom(self->GetSGNode()->GetLocalPosition()); - else - return PyObjectFrom(dummy_point); + return PyObjectFrom(self->NodeGetLocalPosition()); #endif } @@ -1782,13 +1858,17 @@ PyObject* KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIB if (self->GetPhysicsController()) return PyObjectFrom(self->GetPhysicsController()->GetLocalInertia()); return Py_BuildValue("fff", 0.0f, 0.0f, 0.0f); - #endif +#endif } PyObject* KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { +#ifdef USE_MATHUTILS + return newMatrixObject_cb((PyObject *)self_v, 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_GLOBAL); +#else KX_GameObject* self= static_cast<KX_GameObject*>(self_v); return PyObjectFrom(self->NodeGetWorldOrientation()); +#endif } int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1813,11 +1893,12 @@ int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUT PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { +#ifdef USE_MATHUTILS + return newMatrixObject_cb((PyObject *)self_v, 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_LOCAL); +#else KX_GameObject* self= static_cast<KX_GameObject*>(self_v); - if (self->GetSGNode()) - return PyObjectFrom(self->GetSGNode()->GetLocalOrientation()); - else - return PyObjectFrom(dummy_orientation); + return PyObjectFrom(self->NodeGetLocalOrientation()); +#endif } int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1850,10 +1931,7 @@ PyObject* KX_GameObject::pyattr_get_localScaling(void *self_v, const KX_PYATTRIB #ifdef USE_MATHUTILS return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_LOCAL); #else - if (self->GetSGNode()) - return PyObjectFrom(self->GetSGNode()->GetLocalScale()); - else - return PyObjectFrom(dummy_scaling); + return PyObjectFrom(self->NodeGetLocalScale()); #endif } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index b01b0cae641..59285714950 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -397,6 +397,7 @@ public: void NodeSetLocalPosition(const MT_Point3& trans ); void NodeSetLocalOrientation(const MT_Matrix3x3& rot ); + void NodeSetGlobalOrientation(const MT_Matrix3x3& rot ); void NodeSetLocalScale( const MT_Vector3& scale ); @@ -410,21 +411,13 @@ public: double time ); - const - MT_Matrix3x3& - NodeGetWorldOrientation( - ) const; - - const - MT_Vector3& - NodeGetWorldScaling( - ) const; - - const - MT_Point3& - NodeGetWorldPosition( - ) const; + const MT_Matrix3x3& NodeGetWorldOrientation( ) const; + const MT_Vector3& NodeGetWorldScaling( ) const; + const MT_Point3& NodeGetWorldPosition( ) const; + const MT_Matrix3x3& NodeGetLocalOrientation( ) const; + const MT_Vector3& NodeGetLocalScaling( ) const; + const MT_Point3& NodeGetLocalPosition( ) const; /** * @section scene graph node accessor functions. |