Merge branch 'blender-v3.3-release'
[blender-addons.git] / io_anim_nuke_chan / import_nuke_chan.py
blob635ebae038453f6d0cef03ba99a48f98956a7e9a
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
12 scene = context.scene
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()
19 # read the file
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()
28 # strip the line
29 data = line.split()
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]),
39 float(data[2]),
40 float(data[3])))
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]))))
52 e_rot.order = rot_ord
53 mrot_mat = e_rot.to_matrix()
54 mrot_mat.resize_4x4()
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)
61 if z_up:
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")
80 del tmp_rot
81 else:
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")
92 filehandle.close()
94 return {'FINISHED'}