Merge branch 'blender-v2.92-release'
[blender-addons.git] / io_anim_nuke_chan / import_nuke_chan.py
blob3f9793abc74a160ba4904dd06009542b663542c3
1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
19 # <pep8-80 compliant>
21 """ This script is an importer for the nuke's .chan files"""
23 from mathutils import Vector, Matrix, Euler
24 from math import radians
27 def read_chan(context, filepath, z_up, rot_ord, sensor_width, sensor_height):
29 # get the active object
30 scene = context.scene
31 obj = context.active_object
32 camera = obj.data if obj.type == 'CAMERA' else None
34 # prepare the correcting matrix
35 rot_mat = Matrix.Rotation(radians(90.0), 4, 'X').to_4x4()
37 # read the file
38 filehandle = open(filepath, 'r')
40 # iterate through the files lines
41 for line in filehandle:
42 # reset the target objects matrix
43 # (the one from which one we'll extract the final transforms)
44 m_trans_mat = Matrix()
46 # strip the line
47 data = line.split()
49 # test if the line is not commented out
50 if data and not data[0].startswith("#"):
52 # set the frame number basing on the chan file
53 scene.frame_set(int(data[0]))
55 # read the translation values from the first three columns of line
56 v_transl = Vector((float(data[1]),
57 float(data[2]),
58 float(data[3])))
59 translation_mat = Matrix.Translation(v_transl)
60 translation_mat.to_4x4()
62 # read the rotations, and set the rotation order basing on the
63 # order set during the export (it's not being saved in the chan
64 # file you have to keep it noted somewhere
65 # the actual objects rotation order doesn't matter since the
66 # rotations are being extracted from the matrix afterwards
67 e_rot = Euler((radians(float(data[4])),
68 radians(float(data[5])),
69 radians(float(data[6]))))
70 e_rot.order = rot_ord
71 mrot_mat = e_rot.to_matrix()
72 mrot_mat.resize_4x4()
74 # merge the rotation and translation
75 m_trans_mat = translation_mat @ mrot_mat
77 # correct the world space
78 # (nuke's and blenders scene spaces are different)
79 if z_up:
80 m_trans_mat = rot_mat @ m_trans_mat
82 # break the matrix into a set of the coordinates
83 trns = m_trans_mat.decompose()
85 # set the location and the location's keyframe
86 obj.location = trns[0]
87 obj.keyframe_insert("location")
89 # convert the rotation to euler angles (or not)
90 # basing on the objects rotation mode
91 if obj.rotation_mode == 'QUATERNION':
92 obj.rotation_quaternion = trns[1]
93 obj.keyframe_insert("rotation_quaternion")
94 elif obj.rotation_mode == 'AXIS_ANGLE':
95 tmp_rot = trns[1].to_axis_angle()
96 obj.rotation_axis_angle = (tmp_rot[1], *tmp_rot[0])
97 obj.keyframe_insert("rotation_axis_angle")
98 del tmp_rot
99 else:
100 obj.rotation_euler = trns[1].to_euler(obj.rotation_mode)
101 obj.keyframe_insert("rotation_euler")
103 # check if the object is camera and fov data is present
104 if camera and len(data) > 7:
105 camera.sensor_fit = 'HORIZONTAL'
106 camera.sensor_width = sensor_width
107 camera.sensor_height = sensor_height
108 camera.angle_y = radians(float(data[7]))
109 camera.keyframe_insert("lens")
110 filehandle.close()
112 return {'FINISHED'}