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$
4
  • $\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$ Nov 14, 2019 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, 2019 at 1:56
  • 1
    $\begingroup$ (* -Y forward) Related blender.stackexchange.com/a/102356/15543 $\endgroup$
    – batFINGER
    Nov 15, 2019 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$ Nov 15, 2019 at 12:19

1 Answer 1

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$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .