From 57909f758f1c9f9ed1c840c11224d05e0bb4aa79 Mon Sep 17 00:00:00 2001 From: William Herald Snyder Date: Sun, 6 Dec 2020 04:11:12 -0500 Subject: [PATCH] Animations importing with expected rotation conversion issues --- addons/io_scene_swbf_msh/msh_anim_gather.py | 2 + addons/io_scene_swbf_msh/msh_reader.py | 1 + addons/io_scene_swbf_msh/msh_scene.py | 5 +- addons/io_scene_swbf_msh/msh_scene_save.py | 2 +- addons/io_scene_swbf_msh/msh_to_blend.py | 60 +++++++++++++++++++-- 5 files changed, 62 insertions(+), 8 deletions(-) diff --git a/addons/io_scene_swbf_msh/msh_anim_gather.py b/addons/io_scene_swbf_msh/msh_anim_gather.py index 40b90a2..100285d 100644 --- a/addons/io_scene_swbf_msh/msh_anim_gather.py +++ b/addons/io_scene_swbf_msh/msh_anim_gather.py @@ -11,6 +11,8 @@ from .msh_model_utilities import * from .msh_utilities import * from .msh_model_gather import * +from .crc import crc + def extract_anim(armature: bpy.types.Armature, root_name: str) -> Animation: diff --git a/addons/io_scene_swbf_msh/msh_reader.py b/addons/io_scene_swbf_msh/msh_reader.py index 2840013..c629b47 100644 --- a/addons/io_scene_swbf_msh/msh_reader.py +++ b/addons/io_scene_swbf_msh/msh_reader.py @@ -1,6 +1,7 @@ import io import struct +from mathutils import Vector, Quaternion class Reader: def __init__(self, file, parent=None, indent=0, debug=False): diff --git a/addons/io_scene_swbf_msh/msh_scene.py b/addons/io_scene_swbf_msh/msh_scene.py index ab29a67..755a365 100644 --- a/addons/io_scene_swbf_msh/msh_scene.py +++ b/addons/io_scene_swbf_msh/msh_scene.py @@ -6,14 +6,15 @@ from typing import List, Dict from copy import copy import bpy from mathutils import Vector -from .msh_model import Model, Animation +from .msh_model import Model, Animation, ModelType from .msh_model_gather import gather_models -from .msh_model_utilities import sort_by_parent, has_multiple_root_models, reparent_model_roots, get_model_world_matrix +from .msh_model_utilities import sort_by_parent, has_multiple_root_models, reparent_model_roots, get_model_world_matrix, inject_dummy_data from .msh_model_triangle_strips import create_models_triangle_strips from .msh_material import * from .msh_material_gather import gather_materials from .msh_material_utilities import remove_unused_materials from .msh_utilities import * +from .msh_anim_gather import extract_anim @dataclass class SceneAABB: diff --git a/addons/io_scene_swbf_msh/msh_scene_save.py b/addons/io_scene_swbf_msh/msh_scene_save.py index bb28ddc..7ca557c 100644 --- a/addons/io_scene_swbf_msh/msh_scene_save.py +++ b/addons/io_scene_swbf_msh/msh_scene_save.py @@ -288,7 +288,7 @@ def _write_anm2(anm2: Writer, anim: Animation): kfr3.write_u32(bone_crc) kfr3.write_u32(0) #what is keyframe type? - translation_frames, rotation_frames = anim.bone_frames[boneName] + translation_frames, rotation_frames = anim.bone_frames[bone_crc] kfr3.write_u32(len(translation_frames), len(rotation_frames)) diff --git a/addons/io_scene_swbf_msh/msh_to_blend.py b/addons/io_scene_swbf_msh/msh_to_blend.py index d28c116..9d50f97 100644 --- a/addons/io_scene_swbf_msh/msh_to_blend.py +++ b/addons/io_scene_swbf_msh/msh_to_blend.py @@ -18,8 +18,63 @@ import os +def extract_and_apply_anim(filename, scene): + + arma = bpy.context.view_layer.objects.active + + if 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] + action = bpy.data.actions.new(anim_name) + + if not arma.animation_data: + arma.animation_data_create() + + for bone in arma.pose.bones: + if crc(bone.name) in scene.animation.bone_frames: + print("Inserting anim data for bone: {}".format(bone.name)) + + bone_local_mat = arma.data.bones[bone.name].matrix_local + + translation_frames, rotation_frames = scene.animation.bone_frames[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) + fcurve_rot_x = action.fcurves.new(rot_data_path, index=1) + fcurve_rot_y = action.fcurves.new(rot_data_path, index=2) + fcurve_rot_z = action.fcurves.new(rot_data_path, index=3) + + for frame in rotation_frames: + i = frame.index + q = (bone_local_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) + fcurve_loc_y = action.fcurves.new(loc_data_path, index=1) + fcurve_loc_z = action.fcurves.new(loc_data_path, index=2) + + for frame in translation_frames: + i = frame.index + t = bone_local_mat @ convert_vector_space(Vector((0.0,0.0,0.0))) + + 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 @@ -40,11 +95,6 @@ def parent_object_to_bone(obj, armature, bone_name): - - - - - def refined_skeleton_to_armature(refined_skeleton : List[Model], model_map): armature = bpy.data.armatures.new("skeleton")