From a83c74ebf7f02dd2e90fb19ec2ae86206f33c996 Mon Sep 17 00:00:00 2001 From: Will Snyder Date: Sun, 29 Nov 2020 15:45:32 -0500 Subject: [PATCH] Better anim abstraction --- addons/io_scene_swbf_msh/msh_anim_gather.py | 28 +++++++++++---------- addons/io_scene_swbf_msh/msh_model.py | 18 +++++++++++-- addons/io_scene_swbf_msh/msh_scene_save.py | 26 +++++++++---------- 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/addons/io_scene_swbf_msh/msh_anim_gather.py b/addons/io_scene_swbf_msh/msh_anim_gather.py index 1da0003..f959a19 100644 --- a/addons/io_scene_swbf_msh/msh_anim_gather.py +++ b/addons/io_scene_swbf_msh/msh_anim_gather.py @@ -27,19 +27,23 @@ def extract_anim(armature: bpy.types.Armature) -> Animation: anim.end_index = num_frames - 1 - anim.bone_transforms["DummyRoot"] = [] + anim.bone_frames["DummyRoot"] = ([], []) for bone in armature.data.bones: - anim.bone_transforms[bone.name] = [] + anim.bone_frames[bone.name] = ([], []) for frame in range(num_frames): - - #if frame % 10 == 0: - # print("Sample frame {}:".format(frame)) - + frame_time = framerange.x + frame * increment bpy.context.scene.frame_set(frame_time) - anim.bone_transforms["DummyRoot"].append(ModelTransform()) + + rframe_dummy = RotationFrame(frame, convert_rotation_space(Quaternion())) + tframe_dummy = TranslationFrame(frame, Vector((0.0,0.0,0.0))) + + anim.bone_frames["DummyRoot"][0].append(tframe_dummy) + anim.bone_frames["DummyRoot"][1].append(rframe_dummy) + + for bone in armature.pose.bones: transform = bone.matrix @@ -49,13 +53,11 @@ def extract_anim(armature: bpy.types.Armature) -> Animation: loc, rot, _ = transform.decompose() - xform = ModelTransform() - xform.rotation = convert_rotation_space(rot) - xform.translation = convert_vector_space(loc) + rframe = RotationFrame(frame, convert_rotation_space(rot)) + tframe = TranslationFrame(frame, convert_vector_space(loc)) - #if frame % 10 == 0: - # print("\t{:10}: loc {:15} rot {:15}".format(bone.name, vec_to_str(xform.translation), quat_to_str(xform.rotation))) + anim.bone_frames[bone.name][0].append(tframe) + anim.bone_frames[bone.name][1].append(rframe) - anim.bone_transforms[bone.name].append(xform) return anim diff --git a/addons/io_scene_swbf_msh/msh_model.py b/addons/io_scene_swbf_msh/msh_model.py index fbf5dc8..af75efd 100644 --- a/addons/io_scene_swbf_msh/msh_model.py +++ b/addons/io_scene_swbf_msh/msh_model.py @@ -76,14 +76,28 @@ class Model: geometry: List[GeometrySegment] = None collisionprimitive: CollisionPrimitive = None + +@dataclass +class RotationFrame: + + index : int = 0 + rotation : Quaternion = field(default_factory=Quaternion) + + +@dataclass +class TranslationFrame: + + index : int = 0 + translation : Vector = field(default_factory=Vector) + + @dataclass class Animation: """ Class representing 'CYCL' + 'KFR3' sections in a .msh file """ name: str = "fullanimation" - bone_transforms: Dict[str, List[ModelTransform]] = field(default_factory=dict) + bone_frames: Dict[str, Tuple[List[TranslationFrame], List[RotationFrame]]] = field(default_factory=dict) framerate: float = 29.97 start_index : int = 0 end_index : int = 0 - diff --git a/addons/io_scene_swbf_msh/msh_scene_save.py b/addons/io_scene_swbf_msh/msh_scene_save.py index 6507b17..ed7a75b 100644 --- a/addons/io_scene_swbf_msh/msh_scene_save.py +++ b/addons/io_scene_swbf_msh/msh_scene_save.py @@ -248,14 +248,14 @@ def _write_envl(envl: Writer, model: Model, model_index: Dict[str, int]): SKELETON CHUNKS ''' def _write_bln2(bln2: Writer, scene: Scene): - bones = scene.anims[0].bone_transforms.keys() + bones = scene.anims[0].bone_frames.keys() bln2.write_u32(len(bones)) for boneName in bones: bln2.write_u32(crc(boneName), 0) def _write_skl2(skl2: Writer, scene: Scene): - bones = scene.anims[0].bone_transforms.keys() + bones = scene.anims[0].bone_frames.keys() skl2.write_u32(len(bones)) for boneName in bones: @@ -282,22 +282,20 @@ def _write_anm2(anm2: Writer, anim: Animation): with anm2.create_child("KFR3") as kfr3: - kfr3.write_u32(len(anim.bone_transforms.keys())) + kfr3.write_u32(len(anim.bone_frames)) - for boneName in anim.bone_transforms.keys(): + for boneName in anim.bone_frames: kfr3.write_u32(crc(boneName)) kfr3.write_u32(0) #what is keyframe type? - num_frames = 1 + anim.end_index - anim.start_index - kfr3.write_u32(num_frames, num_frames) #basic testing - - for i, xform in enumerate(anim.bone_transforms[boneName]): - kfr3.write_u32(i) - kfr3.write_f32(xform.translation.x, xform.translation.y, xform.translation.z) - - for i, xform in enumerate(anim.bone_transforms[boneName]): - kfr3.write_u32(i) - kfr3.write_f32(xform.rotation.x, xform.rotation.y, xform.rotation.z, xform.rotation.w) + translation_frames, rotation_frames = anim.bone_frames[boneName] + kfr3.write_u32(len(translation_frames), len(rotation_frames)) + for frame in translation_frames: + kfr3.write_u32(frame.index) + kfr3.write_f32(frame.translation.x, frame.translation.y, frame.translation.z) + for frame in rotation_frames: + kfr3.write_u32(frame.index) + kfr3.write_f32(frame.rotation.x, frame.rotation.y, frame.rotation.z, frame.rotation.w)