 # Euler to Quaternion and back, but with respect to rotation_mode

How do I respect `rotation_mode` property on `Object` when turning `rotation_euler` into a `Quaternion` and back?

I have tried understanding the maths. I do not understand the maths.

`Quaternion.to_euler()` can take a rotation mode:

``````rot.to_euler(obj.rotation_mode)
``````

But the other way round, there is no such thing:

``````obj.rotation_euler.to_quaternion()
``````

Depending on what the rotation_mode is, I’ll get wildly different broken behavior. Should I just leave this broken? Does anyone actually use the non-XYZ euler rotation modes?

I have tried grepping the Python sources, but the amount of results is too overwhelming.

You can rotate a matrix pretty easy, what are you trying to do?

I’m trying to get the correct rotation of an object as quaternion even when the user has rotation_mode XZY, YXZ, YZX, ZXY or ZYX selected, modify it, then apply this rotation to the object again. I.e., fix whatever the bug is in the last line of each of these two functions:

``````def getObjectRotationQuaternion(obj: bpy.types.Object) -> Quaternion:
if obj.rotation_mode == "QUATERNION":
return Quaternion(obj.rotation_quaternion)
elif obj.rotation_mode == "AXIS_ANGLE":
return Quaternion(Vector((obj.rotation_axis_angle, obj.rotation_axis_angle, obj.rotation_axis_angle)), obj.rotation_axis_angle)
return obj.rotation_euler.to_quaternion()

def setObjectRotationQuaternion(obj: bpy.types.Object, rot: Quaternion):
if obj.rotation_mode == "QUATERNION":
obj.rotation_quaternion = rot
elif obj.rotation_mode == "AXIS_ANGLE":
axis, angle = rot.to_axis_angle()
obj.rotation_axis_angle = [angle, axis, axis, axis]
else:
obj.rotation_euler = rot.to_euler(obj.rotation_mode)
``````

why not simply rotate it’s matrix and set that?

I may be naïve, but what good is the other vector modes?

It isn’t clear to me why working with Matrix would be more simple than working with Quaternion. At least, accessing and writing `obj.matrix_local` seems to give the correct behavior for once. There is `matrix.decompose()` to get the components, but reassembling them requires some knowledge. This seems to work:

``````axis, angle = rot.to_axis_angle()
mat = mathutils.Matrix.Translation(pos) @ mathutils.Matrix.Rotation(angle, 4, axis) @ mathutils.Matrix.Diagonal(Vector((scale, scale, scale, 1)))
``````
1 Like