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