From b84f824f0e7e930fb11c3ee0e47978cd3868f5d6 Mon Sep 17 00:00:00 2001 From: Cameron Reikes Date: Tue, 4 Jul 2023 22:29:05 -0700 Subject: [PATCH] Export and import multiple animations, idle animation --- art/Exporter.py | 4 ++- art/art.blend | 4 +-- main.c | 83 ++++++++++++++++++++++++++++++++----------------- 3 files changed, 60 insertions(+), 31 deletions(-) diff --git a/art/Exporter.py b/art/Exporter.py index 7ec8be2..e8b2510 100644 --- a/art/Exporter.py +++ b/art/Exporter.py @@ -135,8 +135,10 @@ for o in D.objects: for strip in track.strips: anims.append(strip.action) print(f"Writing {len(anims)} animations") - assert len(anims) == 1, f"Expected the number of animations, {len(anims)}, to be 1, but it isn't" + write_u64(f, len(anims)) for animation in anims: + write_string(f, animation.name) + armature.animation_data.action = animation startFrame = int(animation.frame_range.x) endFrame = int(animation.frame_range.y) diff --git a/art/art.blend b/art/art.blend index a28eab4..bc581b4 100644 --- a/art/art.blend +++ b/art/art.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c56a9e5611239a62ce5e78be3ea34eeb4bd380d6818d18c44323364ec1576dd -size 13965244 +oid sha256:dd25f050fa91146c0150b0f0097fddf2ad55d26bef40de19f1efa7f5066da32b +size 17655220 diff --git a/main.c b/main.c index 83f6914..ce17cd3 100644 --- a/main.c +++ b/main.c @@ -851,13 +851,23 @@ typedef struct PoseBone typedef struct Bone { struct Bone *parent; - PoseBone *anim_poses; - MD_u64 anim_poses_length; Mat4 matrix_local; Mat4 inverse_model_space_pos; float length; } Bone; +typedef struct AnimationTrack +{ + PoseBone *poses; + MD_u64 poses_length; +} AnimationTrack; + +typedef struct Animation +{ + MD_String8 name; + // assumed to be the same as the number of bones in the armature the animation is in + AnimationTrack *tracks; +} Animation; typedef struct { @@ -969,6 +979,8 @@ typedef struct { Bone *bones; MD_u64 bones_length; + Animation *animations; + MD_u64 animations_length; ArmatureVertex *vertices; MD_u64 vertices_length; sg_buffer loaded_buffer; @@ -1027,29 +1039,43 @@ Armature load_armature(MD_Arena *arena, MD_String8 binary_file, MD_String8 armat } } - MD_u64 frames_in_anim; - ser_MD_u64(&ser, &frames_in_anim); - Log("There are %llu animation frames\n", frames_in_anim); + ser_MD_u64(&ser, &to_return.animations_length); + Log("Armature %.*s has %llu animations\n", MD_S8VArg(armature_name), to_return.animations_length); + to_return.animations = MD_PushArray(arena, Animation, to_return.animations_length); - for(MD_u64 i = 0; i < to_return.bones_length; i++) + for(MD_u64 i = 0; i < to_return.animations_length; i++) { - to_return.bones[i].anim_poses = MD_PushArray(arena, PoseBone, frames_in_anim); - to_return.bones[i].anim_poses_length = frames_in_anim; - } + Animation *new_anim = &to_return.animations[i]; + *new_anim = (Animation){0}; - for(MD_u64 anim_i = 0; anim_i < frames_in_anim; anim_i++) - { - float time_through; - ser_float(&ser, &time_through); - for(MD_u64 pose_bone_i = 0; pose_bone_i < to_return.bones_length; pose_bone_i++) + ser_MD_String8(&ser, &new_anim->name, arena); + + new_anim->tracks = MD_PushArray(arena, AnimationTrack, to_return.bones_length); + + MD_u64 frames_in_anim; + ser_MD_u64(&ser, &frames_in_anim); + Log("There are %llu animation frames in animation '%.*s'\n", frames_in_anim, MD_S8VArg(new_anim->name)); + + for(MD_u64 i = 0; i < to_return.bones_length; i++) { - PoseBone *next_pose_bone = &to_return.bones[pose_bone_i].anim_poses[anim_i]; + new_anim->tracks[i].poses = MD_PushArray(arena, PoseBone, frames_in_anim); + new_anim->tracks[i].poses_length = frames_in_anim; + } - ser_Vec3(&ser, &next_pose_bone->parent_space_pose.offset); - ser_Quat(&ser, &next_pose_bone->parent_space_pose.rotation); - ser_Vec3(&ser, &next_pose_bone->parent_space_pose.scale); + for(MD_u64 anim_i = 0; anim_i < frames_in_anim; anim_i++) + { + float time_through; + ser_float(&ser, &time_through); + for(MD_u64 pose_bone_i = 0; pose_bone_i < to_return.bones_length; pose_bone_i++) + { + PoseBone *next_pose_bone = &new_anim->tracks[pose_bone_i].poses[anim_i]; + + ser_Vec3(&ser, &next_pose_bone->parent_space_pose.offset); + ser_Quat(&ser, &next_pose_bone->parent_space_pose.rotation); + ser_Vec3(&ser, &next_pose_bone->parent_space_pose.scale); - next_pose_bone->time = time_through; + next_pose_bone->time = time_through; + } } } @@ -2690,17 +2716,17 @@ void draw_placed(Mat4 view, Mat4 projection, PlacedMesh *cur) sg_draw(0, (int)drawing->num_vertices, 1); } -Mat4 get_animated_bone_transform(Bone *bone, float time) +Mat4 get_animated_bone_transform(AnimationTrack *track, Bone *bone, float time) { - float total_anim_time = bone->anim_poses[bone->anim_poses_length - 1].time; + float total_anim_time = track->poses[track->poses_length - 1].time; assert(total_anim_time > 0.0f); time = fmodf(time, total_anim_time); - for(MD_u64 i = 0; i < bone->anim_poses_length - 1; i++) + for(MD_u64 i = 0; i < track->poses_length - 1; i++) { - if(bone->anim_poses[i].time <= time && time <= bone->anim_poses[i + 1].time) + if(track->poses[i].time <= time && time <= track->poses[i + 1].time) { - PoseBone from = bone->anim_poses[i]; - PoseBone to = bone->anim_poses[i + 1]; + PoseBone from = track->poses[i]; + PoseBone to = track->poses[i + 1]; float gap_btwn_keyframes = to.time - from.time; float t = (time - from.time)/gap_btwn_keyframes; assert(t >= 0.0f); @@ -2790,7 +2816,8 @@ void draw_armature(Mat4 view, Mat4 projection, Transform t, Armature *armature, for(Bone *cur_in_hierarchy = cur; cur_in_hierarchy; cur_in_hierarchy = cur_in_hierarchy->parent) { //final = MulM4(cur_in_hierarchy->anim_poses[0].parent_space_pose, final); - final = MulM4(get_animated_bone_transform(cur_in_hierarchy, elapsed_time), final); + int bone_index = (int)(cur_in_hierarchy - armature->bones); + final = MulM4(get_animated_bone_transform(&armature->animations[0].tracks[bone_index], cur_in_hierarchy, elapsed_time), final); } for(int col = 0; col < 4; col++) @@ -4879,7 +4906,6 @@ void frame(void) // debug draw armature for(MD_u64 i = 0; i < armature.bones_length; i++) { - PoseBone *cur_pose_bone = &armature.bones[i].anim_poses[0]; Bone *cur = &armature.bones[i]; Vec3 offset = V3(1.5, 0, 5); @@ -4899,7 +4925,8 @@ void frame(void) final_mat = MulM4(cur->inverse_model_space_pos, final_mat); for(Bone *cur_in_hierarchy = cur; cur_in_hierarchy; cur_in_hierarchy = cur_in_hierarchy->parent) { - final_mat = MulM4(get_animated_bone_transform(cur_in_hierarchy, (float)elapsed_time), final_mat); + int bone_index = (int)(cur_in_hierarchy - armature.bones); + final_mat = MulM4(get_animated_bone_transform(&armature.animations[0].tracks[bone_index], cur_in_hierarchy, (float)elapsed_time), final_mat); //final_mat = MulM4(cur_in_hierarchy->anim_poses[0].parent_space_pose, final_mat); }