From 3038fb1a0175ef5e3d595460a7f281c77028b5a1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 25 Apr 2009 07:17:36 +0000 Subject: [#18606] Writing to KX_GameObject.orientation causes crash Own bug, conversion function to get an orientation from python - PyOrientationTo() ignored user input completely :| (breaking the orientation attribute) Also made KX_GameObject worldOrientation writable and minor doc fixes. --- source/gameengine/Ketsji/KX_GameObject.cpp | 48 +++++++++++++++++++----------- source/gameengine/Ketsji/KX_GameObject.h | 1 + source/gameengine/Ketsji/KX_PyMath.cpp | 3 +- source/gameengine/PyDoc/KX_GameObject.py | 10 +++---- 4 files changed, 37 insertions(+), 25 deletions(-) (limited to 'source') diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 7629f9d8f1a..297d3048a3a 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1133,7 +1133,7 @@ PyAttributeDef KX_GameObject::Attributes[] = { 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("worldOrientation",KX_GameObject,pyattr_get_worldOrientation,pyattr_set_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), @@ -1515,6 +1515,26 @@ PyObject* KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYAT return PyObjectFrom(self->NodeGetWorldOrientation()); } +int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_GameObject* self= static_cast(self_v); + + /* if value is not a sequence PyOrientationTo makes an error */ + MT_Matrix3x3 rot; + if (!PyOrientationTo(value, rot, "gameOb.worldOrientation = sequence: KX_GameObject, ")) + return NULL; + + if (self->GetSGNode() && self->GetSGNode()->GetSGParent()) { + self->NodeSetLocalOrientation(self->GetSGNode()->GetSGParent()->GetWorldOrientation().inverse()*rot); + } + else { + self->NodeSetLocalOrientation(rot); + } + + self->NodeUpdateGS(0.f); + return 0; +} + PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); @@ -1530,7 +1550,7 @@ int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUT /* if value is not a sequence PyOrientationTo makes an error */ MT_Matrix3x3 rot; - if (!PyOrientationTo(value, rot, "gameOb.orientation = sequence: KX_GameObject, ")) + if (!PyOrientationTo(value, rot, "gameOb.localOrientation = sequence: KX_GameObject, ")) return NULL; self->NodeSetLocalOrientation(rot); @@ -2170,23 +2190,15 @@ PyObject* KX_GameObject::PyGetOrientation() //keywords PyObject* KX_GameObject::PySetOrientation(PyObject* value) { ShowDeprecationWarning("setOrientation()", "the orientation property"); - MT_Matrix3x3 matrix; - if (PyObject_IsMT_Matrix(value, 3) && PyMatTo(value, matrix)) - { - NodeSetLocalOrientation(matrix); - NodeUpdateGS(0.f); - Py_RETURN_NONE; - } + MT_Matrix3x3 rot; + + /* if value is not a sequence PyOrientationTo makes an error */ + if (!PyOrientationTo(value, rot, "gameOb.setOrientation(sequence): KX_GameObject, ")) + return NULL; - MT_Quaternion quat; - if (PyVecTo(value, quat)) - { - matrix.setRotation(quat); - NodeSetLocalOrientation(matrix); - NodeUpdateGS(0.f); - Py_RETURN_NONE; - } - return NULL; + NodeSetLocalOrientation(rot); + NodeUpdateGS(0.f); + Py_RETURN_NONE; } PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* args) diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 2ca4fc6a63f..fe9f39a6ed3 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -884,6 +884,7 @@ public: 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_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); 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); diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp index 0093a72808e..051d7ae7dba 100644 --- a/source/gameengine/Ketsji/KX_PyMath.cpp +++ b/source/gameengine/Ketsji/KX_PyMath.cpp @@ -75,9 +75,8 @@ bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank) return false; } -bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &mat, const char *error_prefix) +bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefix) { - MT_Matrix3x3 rot; int size= PySequence_Size(pyval); if (size == 4) diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index db0aebfc761..10abf8b8197 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -49,13 +49,13 @@ class KX_GameObject: # (SCA_IObject) @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. + @ivar worldOrientation: The object's world orientation. @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. + @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] @@ -87,10 +87,10 @@ class KX_GameObject: # (SCA_IObject) Delete this object, can be used inpace of the EndObject Actuator. The actual removal of the object from the scene is delayed. """ - def replaceMesh(mesh_name): + def replaceMesh(mesh): """ Replace the mesh of this object with a new mesh. This works the same was as the actuator. - @type mesh_name: string + @type mesh: L{KX_MeshProxy} or mesh name """ def getVisible(): """ @@ -468,7 +468,7 @@ class KX_GameObject: # (SCA_IObject) @type objfrom: L{KX_GameObject} or 3-tuple or None @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to to @type dist: float - @param prop: property name that object must have; can be omitted => detect any object + @param prop: property name that object must have; can be omitted or "" => detect any object @type prop: string @param face: normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin @type face: int -- cgit v1.2.3