From f4ff299e4e073b71495a3e2a385fa96d65fb6f80 Mon Sep 17 00:00:00 2001 From: Owl Date: Wed, 27 Aug 2025 23:54:31 -0400 Subject: rotations people, rotations... --- bck_import.py | 66 ++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 19 deletions(-) (limited to 'bck_import.py') diff --git a/bck_import.py b/bck_import.py index e9ec6e8..47e99ad 100644 --- a/bck_import.py +++ b/bck_import.py @@ -10,7 +10,7 @@ import mathutils # import BCK animation into the selected armature object # creates a new "action" and writes the data into that action slot -def import_bck_func(context, filepath, import_type, angle_limit): +def import_bck_func(context, options): # # this thing is always needed for stuff scene = bpy.context.scene @@ -25,11 +25,11 @@ def import_bck_func(context, filepath, import_type, angle_limit): return {"FINISHED"} # open the binary file and read its data - anim = bck_funcs.read_bck_file(filepath) + anim = bck_funcs.read_bck_file(options.filepath) print(anim) if (anim == None): blender_funcs.disp_msg("Animation file: \"%s\" is malformed." - % (file_ops.get_file_name(filepath))) + % (file_ops.get_file_name(options.filepath))) return {"FINISHED"} # select the armature object @@ -40,14 +40,17 @@ def import_bck_func(context, filepath, import_type, angle_limit): # check if the bone count matches (the only check it can be done) if (len(armature.data.bones) != anim.bone_count): blender_funcs.disp_msg("Animation file \"%s\" contains incorrect number of bones" - % (file_ops.get_file_name(filepath))) + % (file_ops.get_file_name(options.filepath))) return {"FINISHED"} # check import_type to know what to do - file_name = file_ops.get_file_name(filepath) + file_name = file_ops.get_file_name(options.filepath) + + # change the bones's rotation mode to match the rotation mode going to be imported? + # (thing to think later) # clear rest pose and import the animation data directly - if (import_type == "OPT_A"): + if (options.import_type == "OPT_A"): # # select the armature object and its children meshes and duplicate it old_armature = armature @@ -202,7 +205,7 @@ def import_bck_func(context, filepath, import_type, angle_limit): # mantain rest pose and import the animation data respect to rest pose # "OPT_B" --> sample everything # "OPT_C" --> sample everything and find "best" interpolator fit - elif (import_type == "OPT_B" or import_type == "OPT_C"): + elif (options.import_type == "OPT_B" or options.import_type == "OPT_C"): # its matrix time @@ -374,10 +377,12 @@ def import_bck_func(context, filepath, import_type, angle_limit): # ~ print(rot) # ~ print(transl) # convert the just got frame anim values to be rest pose relative - mat = rest_mat.inverted() * math_funcs.calc_transf_mat(scale, rot, transl) + mat = rest_mat.inverted() * math_funcs.calc_transf_mat(scale, rot, transl, + options.euler_mode, + options.mult_order) # extract the new animation data new_scale = mat.to_scale() - new_rot = mat.to_euler("XYZ") + new_rot = mat.to_euler(options.euler_mode) new_transl = mat.to_translation() # check if new data must be added @@ -441,7 +446,7 @@ def import_bck_func(context, filepath, import_type, angle_limit): # now, if this has not been hard enough... # find the "best" interpolator fits to be able to simplify the keyframe count - if (import_type == "OPT_C"): + if (options.import_type == "OPT_C"): # lets start for fcurve in action.fcurves: # skip 1 frame animations @@ -453,7 +458,7 @@ def import_bck_func(context, filepath, import_type, angle_limit): for i in range(lowest_anim_frame, greatest_anim_frame + 1): values.append(fcurve.evaluate(i)) print(fcurve.data_path) - new_kfs = math_funcs.find_best_cubic_hermite_spline_fit(lowest_anim_frame, values, angle_limit) + new_kfs = math_funcs.find_best_cubic_hermite_spline_fit(lowest_anim_frame, values, options.angle_limit) print(new_kfs) # remove all keyframe points and add the new ones @@ -496,13 +501,13 @@ def import_bck_func(context, filepath, import_type, angle_limit): # check if nothing touched the type of this property import idprop if (type(armature.data["loop_mode"]) != idprop.types.IDPropertyGroup): - armature.data["loop_mode"] = {file_ops.get_file_name(filepath) : anim.loop_mode} + armature.data["loop_mode"] = {file_ops.get_file_name(options.filepath) : anim.loop_mode} else: - armature.data["loop_mode"][file_ops.get_file_name(filepath)] = anim.loop_mode + armature.data["loop_mode"][file_ops.get_file_name(options.filepath)] = anim.loop_mode else: - armature.data["loop_mode"] = {file_ops.get_file_name(filepath) : anim.loop_mode} + armature.data["loop_mode"] = {file_ops.get_file_name(options.filepath) : anim.loop_mode} # display some message - blender_funcs.disp_msg("Animation file \"%s\" imported." % (file_ops.get_file_name(filepath))) + blender_funcs.disp_msg("Animation file \"%s\" imported." % (file_ops.get_file_name(options.filepath))) # done! return {"FINISHED"} @@ -543,13 +548,36 @@ class import_bck(Operator, ExportHelper): min = 0, max = 180, ) + euler_mode = EnumProperty( + name = "Euler order", + description = "Import rotation animations in the specified Euler angles order", + default = "XYZ", + items = ( + ("XYZ", "XYZ", "X rotation first, Y rotation second, Z rotation last"), + ("XZY", "XZY", "X rotation first, Z rotation second, Y rotation last"), + ("YXZ", "YXZ", "Y rotation first, X rotation second, Z rotation last"), + ("YZX", "YZX", "Y rotation first, Z rotation second, X rotation last"), + ("ZXY", "ZXY", "Z rotation first, X rotation second, Y rotation last"), + ("ZYX", "ZYX", "Z rotation first, Y rotation second, X rotation last") + ) + ) + mult_order = EnumProperty( + name = "Scale/Rot/Transl mult order", + description = "Import animations in the specified matrix multiplication order", + default = "SRT", + items = ( + ("TRS", "TRS", "Translation first, Rotation second, Scaling last"), + ("TSR", "TSR", "Translation first, Scaling second, Rotation last"), + ("RTS", "RTS", "Rotation first, Translation second, Scaling last"), + ("RST", "RST", "Rotation first, Scaling second, Translation last"), + ("STR", "STR", "Scaling first, Translation second, Rotation last"), + ("SRT", "SRT", "Scaling first, Rotation second, Translation last") + ) + ) # what the importer actually does def execute(self, context): - return import_bck_func(context, - self.filepath, - self.import_type, - self.angle_limit) + return import_bck_func(context, self) # stuff to append the item to the File -> Import/Export menu def menu_import_bck(self, context): -- cgit v1.2.3-70-g09d2