From 48aabaf8d4f234b475ebc420db64190b0f81331b Mon Sep 17 00:00:00 2001 From: William Herald Snyder Date: Sat, 1 Oct 2022 15:10:00 -0400 Subject: [PATCH] Anim import code moved to new file --- addons/io_scene_swbf_msh/__init__.py | 1 + addons/io_scene_swbf_msh/msh_anim_to_blend.py | 106 ++++++++++++++++++ .../io_scene_swbf_msh/msh_scene_to_blend.py | 86 -------------- 3 files changed, 107 insertions(+), 86 deletions(-) create mode 100644 addons/io_scene_swbf_msh/msh_anim_to_blend.py diff --git a/addons/io_scene_swbf_msh/__init__.py b/addons/io_scene_swbf_msh/__init__.py index a62b65c..ef3e350 100644 --- a/addons/io_scene_swbf_msh/__init__.py +++ b/addons/io_scene_swbf_msh/__init__.py @@ -64,6 +64,7 @@ from .msh_skeleton_properties import * from .msh_collision_prim_properties import * from .msh_material_operators import * from .msh_scene_to_blend import * +from .msh_anim_to_blend import * from .zaa_to_blend import * diff --git a/addons/io_scene_swbf_msh/msh_anim_to_blend.py b/addons/io_scene_swbf_msh/msh_anim_to_blend.py new file mode 100644 index 0000000..6a822a9 --- /dev/null +++ b/addons/io_scene_swbf_msh/msh_anim_to_blend.py @@ -0,0 +1,106 @@ +""" Gathers the Blender objects from the current scene and returns them as a list of + Model objects. """ + +import bpy +import bmesh +import math + +from enum import Enum +from typing import List, Set, Dict, Tuple + +from .msh_scene import Scene +from .msh_material_to_blend import * +from .msh_model import * +from .msh_skeleton_utilities import * +from .msh_skeleton_to_blend import * +from .msh_model_gather import get_is_model_hidden +from .msh_mesh_to_blend import model_to_mesh_object + + +from .crc import * + +import os + + +# Extracts and applies anims in the scene to the currently selected armature +def extract_and_apply_anim(filename : str, scene : Scene): + + arma = bpy.context.view_layer.objects.active + + if not arma or arma.type != 'ARMATURE': + raise Exception("Select an armature to attach the imported animation to!") + + if scene.animation is None: + raise Exception("No animation found in msh file!") + + else: + head, tail = os.path.split(filename) + anim_name = tail.split(".")[0] + + if anim_name in bpy.data.actions: + bpy.data.actions.remove(bpy.data.actions[anim_name], do_unlink=True) + + action = bpy.data.actions.new(anim_name) + action.use_fake_user = True + + if not arma.animation_data: + arma.animation_data_create() + + + # Record the starting transforms of each bone. Pose space is relative + # to bones starting transforms. Starting = in edit mode + bone_bind_poses = {} + + bpy.context.view_layer.objects.active = arma + bpy.ops.object.mode_set(mode='EDIT') + + for edit_bone in arma.data.edit_bones: + if edit_bone.parent: + bone_local = edit_bone.parent.matrix.inverted() @ edit_bone.matrix + else: + bone_local = arma.matrix_local @ edit_bone.matrix + + bone_bind_poses[edit_bone.name] = bone_local.inverted() + + bpy.ops.object.mode_set(mode='OBJECT') + + + for bone in arma.pose.bones: + if to_crc(bone.name) in scene.animation.bone_frames: + + bind_mat = bone_bind_poses[bone.name] + + translation_frames, rotation_frames = scene.animation.bone_frames[to_crc(bone.name)] + + loc_data_path = "pose.bones[\"{}\"].location".format(bone.name) + rot_data_path = "pose.bones[\"{}\"].rotation_quaternion".format(bone.name) + + + fcurve_rot_w = action.fcurves.new(rot_data_path, index=0, action_group=bone.name) + fcurve_rot_x = action.fcurves.new(rot_data_path, index=1, action_group=bone.name) + fcurve_rot_y = action.fcurves.new(rot_data_path, index=2, action_group=bone.name) + fcurve_rot_z = action.fcurves.new(rot_data_path, index=3, action_group=bone.name) + + for frame in rotation_frames: + i = frame.index + q = (bind_mat @ convert_rotation_space(frame.rotation).to_matrix().to_4x4()).to_quaternion() + + fcurve_rot_w.keyframe_points.insert(i,q.w) + fcurve_rot_x.keyframe_points.insert(i,q.x) + fcurve_rot_y.keyframe_points.insert(i,q.y) + fcurve_rot_z.keyframe_points.insert(i,q.z) + + fcurve_loc_x = action.fcurves.new(loc_data_path, index=0, action_group=bone.name) + fcurve_loc_y = action.fcurves.new(loc_data_path, index=1, action_group=bone.name) + fcurve_loc_z = action.fcurves.new(loc_data_path, index=2, action_group=bone.name) + + for frame in translation_frames: + i = frame.index + t = (bind_mat @ Matrix.Translation(convert_vector_space(frame.translation))).translation + + fcurve_loc_x.keyframe_points.insert(i,t.x) + fcurve_loc_y.keyframe_points.insert(i,t.y) + fcurve_loc_z.keyframe_points.insert(i,t.z) + + arma.animation_data.action = action + diff --git a/addons/io_scene_swbf_msh/msh_scene_to_blend.py b/addons/io_scene_swbf_msh/msh_scene_to_blend.py index efbfb62..8cd40ea 100644 --- a/addons/io_scene_swbf_msh/msh_scene_to_blend.py +++ b/addons/io_scene_swbf_msh/msh_scene_to_blend.py @@ -23,92 +23,6 @@ import os -# Extracts and applies anims in the scene to the currently selected armature -def extract_and_apply_anim(filename : str, scene : Scene): - - arma = bpy.context.view_layer.objects.active - - if not arma or arma.type != 'ARMATURE': - raise Exception("Select an armature to attach the imported animation to!") - - if scene.animation is None: - raise Exception("No animation found in msh file!") - - else: - head, tail = os.path.split(filename) - anim_name = tail.split(".")[0] - - if anim_name in bpy.data.actions: - bpy.data.actions.remove(bpy.data.actions[anim_name], do_unlink=True) - - action = bpy.data.actions.new(anim_name) - action.use_fake_user = True - - if not arma.animation_data: - arma.animation_data_create() - - - # Record the starting transforms of each bone. Pose space is relative - # to bones starting transforms. Starting = in edit mode - bone_bind_poses = {} - - bpy.context.view_layer.objects.active = arma - bpy.ops.object.mode_set(mode='EDIT') - - for edit_bone in arma.data.edit_bones: - if edit_bone.parent: - bone_local = edit_bone.parent.matrix.inverted() @ edit_bone.matrix - else: - bone_local = arma.matrix_local @ edit_bone.matrix - - bone_bind_poses[edit_bone.name] = bone_local.inverted() - - bpy.ops.object.mode_set(mode='OBJECT') - - - for bone in arma.pose.bones: - if to_crc(bone.name) in scene.animation.bone_frames: - - bind_mat = bone_bind_poses[bone.name] - - translation_frames, rotation_frames = scene.animation.bone_frames[to_crc(bone.name)] - - loc_data_path = "pose.bones[\"{}\"].location".format(bone.name) - rot_data_path = "pose.bones[\"{}\"].rotation_quaternion".format(bone.name) - - - fcurve_rot_w = action.fcurves.new(rot_data_path, index=0, action_group=bone.name) - fcurve_rot_x = action.fcurves.new(rot_data_path, index=1, action_group=bone.name) - fcurve_rot_y = action.fcurves.new(rot_data_path, index=2, action_group=bone.name) - fcurve_rot_z = action.fcurves.new(rot_data_path, index=3, action_group=bone.name) - - for frame in rotation_frames: - i = frame.index - q = (bind_mat @ convert_rotation_space(frame.rotation).to_matrix().to_4x4()).to_quaternion() - - fcurve_rot_w.keyframe_points.insert(i,q.w) - fcurve_rot_x.keyframe_points.insert(i,q.x) - fcurve_rot_y.keyframe_points.insert(i,q.y) - fcurve_rot_z.keyframe_points.insert(i,q.z) - - fcurve_loc_x = action.fcurves.new(loc_data_path, index=0, action_group=bone.name) - fcurve_loc_y = action.fcurves.new(loc_data_path, index=1, action_group=bone.name) - fcurve_loc_z = action.fcurves.new(loc_data_path, index=2, action_group=bone.name) - - for frame in translation_frames: - i = frame.index - t = (bind_mat @ Matrix.Translation(convert_vector_space(frame.translation))).translation - - fcurve_loc_x.keyframe_points.insert(i,t.x) - fcurve_loc_y.keyframe_points.insert(i,t.y) - fcurve_loc_z.keyframe_points.insert(i,t.z) - - arma.animation_data.action = action - - - - - # Create the msh hierachy. Armatures are not created here. def extract_models(scene: Scene, materials_map : Dict[str, bpy.types.Material]) -> Dict[str, bpy.types.Object]: