0
$\begingroup$

I'm trying to use python to get world space location and rotation values of an animated camera, including transformations applied trough parents and constraints.

I need the Values as XYZ coordinates and XYZ rotation in degrees. I can achieve this by manually selecting object>animation>bake action with the options "Visual Keying", "Clear Constraints" and "Clear Parents" enabled: bake action options

And then accessing the data from the baked camera with python using

import bpy
import sys
import mathutils
from math import degrees

    cameraRotationX = degrees(bpy.data.objects["Camera"].rotation_euler[0])
    cameraRotationY = degrees(bpy.data.objects["Camera"].rotation_euler[1])
    cameraRotationZ = degrees(bpy.data.objects["Camera"].rotation_euler[2])
    
    cameraLocationX = bpy.data.objects["Camera"].location[0]
    cameraLocationY = bpy.data.objects["Camera"].location[1]
    cameraLocationZ = bpy.data.objects["Camera"].location[2]

    print("Camera rotation X: ","%.7f" %cameraRotationX)
    print("Camera rotation Y: ","%.7f" %cameraRotationY)
    print("Camera rotation Z: ","%.7f" %cameraRotationZ)

    print("Camera Location X: ","%.7f" %cameraLocationX)
    print("Camera Location Y: ","%.7f" %cameraLocationY)
    print("Camera Location Z: ","%.7f" %cameraLocationZ)

This works fine and it gives me the correct Values, including multiple rotations of the camera, for example 720°. However, I need to go through the process of baking first and I can't change the animation after that, unless I duplicate the object before baking to preserve the editable animation.

Is there a way to get the same values directly in python without going through the baking process first? I tried

rotation=bpy.data.objects['Camera'].matrix_world.to_euler('XYZ')
location=bpy.data.objects['Camera'].matrix_world.to_translation()

rotationX=degrees(rotation[0])
rotationY=degrees(rotation[1])
rotationZ=degrees(rotation[2])

locationX=location[0]
locationY=location[1]
locationZ=location[2]

But this does not result in the same rotation values.

I am a newbie to python and blender, as well as to matrices and the corresponding calculations. So maybe I am missing something obvious.

Can somebody please pint me in the right direction? If there is a way to programmatically bake the animation without losing the original animation, that would help as well.

The reason for this is that I am using the location and rotation values to control a robot arm. I want wo be able to adjust the animation and get the resulting Values without having to go back and forth with baking. I hope that makes sense.

Any input would be appreciated. Thanks.

$\endgroup$
1
$\begingroup$

The baking code is actually in Python, so you can copy what it does. The relevant part is this I think.

The way it knows if rotations should be >360° is it remembers the Euler from the previous frame and makes the current Euler "compatible" with it (adds or subtracts multiples of 360° so its close to the previous one I assume). There's a make_compatible function, but you can also pass the previous Euler to to_euler.

So try this to get it at a bunch of different frames:

euler_prev = None
ob = bpy.data.objects['Camera']

for f in range(start_frame, end_frame):
    bpy.context.scene.frame_set(f)
    bpy.context.view_layer.update()
    matrix = ob.matrix_world

    # Location
    loc = matrix.to_translation()

    # Euler Rotation
    if euler_prev is None:
        euler = matrix.to_euler(ob.rotation_mode)
    else:
        euler = matrix.to_euler(ob.rotation_mode, euler_prev)
    euler_prev = euler.copy()

    # Do something with loc and euler...
$\endgroup$
1
  • 1
    $\begingroup$ Awesome, this way it works exactly as needed! Thanks so much for the quick and detailed reply! Make compatible was the part that was missing. I spent hours on this but did not manage to find the right solution. Made my day. $\endgroup$
    – Dave
    Sep 25 '21 at 16:25

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.