1 # SPDX-FileCopyrightText: 2011-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 """ This script is an importer for the nuke's .chan files"""
7 from mathutils
import Vector
, Matrix
, Euler
8 from math
import radians
11 def read_chan(context
, filepath
, z_up
, rot_ord
, sensor_width
, sensor_height
):
13 # get the active object
15 obj
= context
.active_object
16 camera
= obj
.data
if obj
.type == 'CAMERA' else None
18 # prepare the correcting matrix
19 rot_mat
= Matrix
.Rotation(radians(90.0), 4, 'X').to_4x4()
22 filehandle
= open(filepath
, 'r')
24 # iterate through the files lines
25 for line
in filehandle
:
26 # reset the target objects matrix
27 # (the one from which one we'll extract the final transforms)
28 m_trans_mat
= Matrix()
33 # test if the line is not commented out
34 if data
and not data
[0].startswith("#"):
36 # set the frame number basing on the chan file
37 scene
.frame_set(int(data
[0]))
39 # read the translation values from the first three columns of line
40 v_transl
= Vector((float(data
[1]),
43 translation_mat
= Matrix
.Translation(v_transl
)
44 translation_mat
.to_4x4()
46 # read the rotations, and set the rotation order basing on the
47 # order set during the export (it's not being saved in the chan
48 # file you have to keep it noted somewhere
49 # the actual objects rotation order doesn't matter since the
50 # rotations are being extracted from the matrix afterwards
51 e_rot
= Euler((radians(float(data
[4])),
52 radians(float(data
[5])),
53 radians(float(data
[6]))))
55 mrot_mat
= e_rot
.to_matrix()
58 # merge the rotation and translation
59 m_trans_mat
= translation_mat
@ mrot_mat
61 # correct the world space
62 # (nuke's and blenders scene spaces are different)
64 m_trans_mat
= rot_mat
@ m_trans_mat
66 # break the matrix into a set of the coordinates
67 trns
= m_trans_mat
.decompose()
69 # set the location and the location's keyframe
70 obj
.location
= trns
[0]
71 obj
.keyframe_insert("location")
73 # convert the rotation to euler angles (or not)
74 # basing on the objects rotation mode
75 if obj
.rotation_mode
== 'QUATERNION':
76 obj
.rotation_quaternion
= trns
[1]
77 obj
.keyframe_insert("rotation_quaternion")
78 elif obj
.rotation_mode
== 'AXIS_ANGLE':
79 tmp_rot
= trns
[1].to_axis_angle()
80 obj
.rotation_axis_angle
= (tmp_rot
[1], *tmp_rot
[0])
81 obj
.keyframe_insert("rotation_axis_angle")
84 obj
.rotation_euler
= trns
[1].to_euler(obj
.rotation_mode
)
85 obj
.keyframe_insert("rotation_euler")
87 # check if the object is camera and fov data is present
88 if camera
and len(data
) > 7:
89 camera
.sensor_fit
= 'HORIZONTAL'
90 camera
.sensor_width
= sensor_width
91 camera
.sensor_height
= sensor_height
92 camera
.angle_y
= radians(float(data
[7]))
93 camera
.keyframe_insert("lens")