Extracting Quaternion's public w, x, y, z?


25-05-2006 05:49:13

Any ideas why pyOgre does not expose the constituent Reals x,y,z,w of the Quaternion class? For example:

>>> q = ogre.Quaternion()
>>> q.x
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'Quaternion' object has no attribute 'x'

Contrast this with the Vector3() class which does expose its x,y,z:

>>> v = ogre.Vector3()
>>> v.x

According to the Ogre header http://www.ogre3d.org/docs/api/html/OgreQuaternion_8h-source.html, these are public ...

My specific need for this is trying to store/restore the orientation of an ogre.SceneNode. Just assigning q=node.orientation or q=copy.copy(node.orientation) doesn't work. These are reference copies of the underlying c++ instance. It seems you need to save the data members instead ...


25-05-2006 10:07:09

Swig has problems properly wrapping public variables and anonymous unions. Not too sure why Quaternion wasn't done. There must have been some reason for not doing so. I'll have to double check on that. There should be at the very least getters for x,y,z,w.

Meanwhile update OgreQuaternion.i and after %include OgreQuaternion.h add:

%ogre_member(Ogre::Quaternion, Ogre::Real, x, x);
%ogre_member(Ogre::Quaternion, Ogre::Real, y, y);
%ogre_member(Ogre::Quaternion, Ogre::Real, z, z);
%ogre_member(Ogre::Quaternion, Ogre::Real, w, w);

https://developer.berlios.de/patch/inde ... up_id=3464


26-05-2006 01:37:13

Thanks Dermont, that worked wonderfully.


26-05-2006 02:29:34

How would you feel about incorporating the following? The str function is pretty innocuous; the second one though .... ;-)

%extend Ogre::Quaternion
PyObject *__str__(void)
char buffer[128];
PyOS_snprintf(buffer, 127, "Quaternion(%f, %f, %f, %f)",
self->w, self->x, self->y, self->z);
buffer[127] = '\0';
return PyString_FromString(buffer);

// Ogre doesn't offer [] access to Quaternion's data members.
// In the python world, this is beneficial for tuple uppacking,
// e.g., w, x, y, z = ogre.Quaternion()
PyObject *__getitem__(size_t i)
switch( i )
case 0:
return PyFloat_FromDouble((double)self->w);
case 1:
return PyFloat_FromDouble((double)self->x);
case 2:
return PyFloat_FromDouble((double)self->y);
case 3:
return PyFloat_FromDouble((double)self->z);
PyErr_SetString(PyExc_IndexError, "quaternion index out of range");
return NULL;