[#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.
This commit is contained in:
Campbell Barton 2009-04-25 07:17:36 +00:00
parent 0c482f7607
commit 3038fb1a01
4 changed files with 37 additions and 25 deletions

@ -1133,7 +1133,7 @@ PyAttributeDef KX_GameObject::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("state", KX_GameObject, pyattr_get_state, pyattr_set_state), 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_RO_FUNCTION("meshes", KX_GameObject, pyattr_get_meshes),
KX_PYATTRIBUTE_RW_FUNCTION("localOrientation",KX_GameObject,pyattr_get_localOrientation,pyattr_set_localOrientation), 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("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("worldPosition", KX_GameObject, pyattr_get_worldPosition, pyattr_set_worldPosition),
KX_PYATTRIBUTE_RW_FUNCTION("localScaling", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling), 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()); 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<KX_GameObject*>(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) PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{ {
KX_GameObject* self= static_cast<KX_GameObject*>(self_v); KX_GameObject* self= static_cast<KX_GameObject*>(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 */ /* if value is not a sequence PyOrientationTo makes an error */
MT_Matrix3x3 rot; MT_Matrix3x3 rot;
if (!PyOrientationTo(value, rot, "gameOb.orientation = sequence: KX_GameObject, ")) if (!PyOrientationTo(value, rot, "gameOb.localOrientation = sequence: KX_GameObject, "))
return NULL; return NULL;
self->NodeSetLocalOrientation(rot); self->NodeSetLocalOrientation(rot);
@ -2170,23 +2190,15 @@ PyObject* KX_GameObject::PyGetOrientation() //keywords
PyObject* KX_GameObject::PySetOrientation(PyObject* value) PyObject* KX_GameObject::PySetOrientation(PyObject* value)
{ {
ShowDeprecationWarning("setOrientation()", "the orientation property"); ShowDeprecationWarning("setOrientation()", "the orientation property");
MT_Matrix3x3 matrix; MT_Matrix3x3 rot;
if (PyObject_IsMT_Matrix(value, 3) && PyMatTo(value, matrix))
{
NodeSetLocalOrientation(matrix);
NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
MT_Quaternion quat; /* if value is not a sequence PyOrientationTo makes an error */
if (PyVecTo(value, quat)) if (!PyOrientationTo(value, rot, "gameOb.setOrientation(sequence): KX_GameObject, "))
{ return NULL;
matrix.setRotation(quat);
NodeSetLocalOrientation(matrix); NodeSetLocalOrientation(rot);
NodeUpdateGS(0.f); NodeUpdateGS(0.f);
Py_RETURN_NONE; Py_RETURN_NONE;
}
return NULL;
} }
PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* args) PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* args)

@ -884,6 +884,7 @@ public:
static PyObject* pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); 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 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 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 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 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_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);

@ -75,9 +75,8 @@ bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank)
return false; 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); int size= PySequence_Size(pyval);
if (size == 4) if (size == 4)

@ -49,7 +49,7 @@ class KX_GameObject: # (SCA_IObject)
@type scaling: list [sx, sy, sz] On write: local scaling, on read: world scaling @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. @ivar localOrientation: The object's local orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector.
@type localOrientation: 3x3 Matrix [[float]] @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]] @type worldOrientation: 3x3 Matrix [[float]]
@ivar localScaling: The object's local scaling factor. @ivar localScaling: The object's local scaling factor.
@type localScaling: list [sx, sy, sz] @type localScaling: list [sx, sy, sz]
@ -87,10 +87,10 @@ class KX_GameObject: # (SCA_IObject)
Delete this object, can be used inpace of the EndObject Actuator. Delete this object, can be used inpace of the EndObject Actuator.
The actual removal of the object from the scene is delayed. 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. 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<KX_MeshProxy.KX_MeshProxy>} or mesh name
""" """
def getVisible(): def getVisible():
""" """
@ -468,7 +468,7 @@ class KX_GameObject: # (SCA_IObject)
@type objfrom: L{KX_GameObject} or 3-tuple or None @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 @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to to
@type dist: float @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 @type prop: string
@param face: normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin @param face: normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin
@type face: int @type face: int