0
$\begingroup$

I'm trying to write a custom exporter for cameras from/to Blender, but I'm having some problems with rotations and rotation order. In my mind I should be able to extract euler values from the world matrix in whatever rotation order I want, and as long as I make sure my camera in my other app use the same rotation order it should all work. But no.

Here's some example code:

import bpy
import mathutils
import math

item = bpy.data.objects["Camera"]

rot_mat = mathutils.Matrix.Rotation(math.radians(-90.0), 4, "X")

wm_src = item.matrix_world.copy()

wm = wm_src @ rot_mat

wm.transpose()

# Only works if rotation order is set to this.
rot = wm.to_euler("ZXY")

rotx = -math.degrees(rot.x)
roty = math.degrees(rot.y)
rotz = -math.degrees(rot.z)

rot_fix = (rotx, rotz, roty)

print(rot_fix)

This code works and the values match with the Alembic exporter.

However, it only works when I set the rotation order to ZXY. If I don't use ZXY, the camera is not rotated correctly. Am I missing something to be able to use whatever rotation order I want?

I'm not great with C++ code but is the Alembic exporter hardcoded to this order as well? It seems so.

Also, why do I need to transpose the matrix?

$\endgroup$
  • $\begingroup$ For example, If I take the default camera in Blender (which is set to XYZ rotation order) and run the above code I get (-26.4, 46.7, 0.0). If I change the rotation order in the code snippet above to XYZ and keep the camera unchanged I get (-18.8, 43.5, 18.9). When applying those values to cameras with the correct rotation order the one with XYZ does not match. $\endgroup$ – Simon Björk Nov 14 '19 at 21:24
  • 1
    $\begingroup$ I think this could be just a matter of converting the axes?, Blender uses Y forward Z up. The camera object in blender looks -Z forward Y up. I don't know how it is in alembic. There is a helper method see from bpy_extras.io_utils import axis_conversion which creates a transform matrix from one def to the other. On the transpose, my guess is it is a quick way to invert an orthonormal matrix (eg a rotation matrix) $\endgroup$ – batFINGER Nov 15 '19 at 1:56
  • 1
    $\begingroup$ (* -Y forward) Related blender.stackexchange.com/a/102356/15543 $\endgroup$ – batFINGER Nov 15 '19 at 2:07
  • $\begingroup$ Thanks a lot. I did play with this before, but I must have missed something. Works perfectly now :). I did have to remove the transpose now though, not sure why. $\endgroup$ – Simon Björk Nov 15 '19 at 12:19
1
$\begingroup$

With ther help of batFINGER and the other post, here's the working code:

import bpy
import mathutils
import math
from bpy_extras.io_utils import axis_conversion

item = bpy.data.objects["Camera"]

wm_src = item.matrix_world.copy()

m = axis_conversion(from_forward='-Y', 
        from_up='Z',
        to_forward='Z',
        to_up='Y').to_4x4()

wm = m @ wm_src

rot = wm.to_euler("XYZ")

rotx = math.degrees(rot.x)
roty = math.degrees(rot.y)
rotz = math.degrees(rot.z)

rot_fix = (rotx, roty, rotz)

print(rot_fix)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.