X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=skeleton.h;h=9729b64c04a95b7b052ba1daa3f280f444670a44;hb=5fa590f62aa7e62a8b6b07e10556c2ecc54cdca6;hp=2be9a9aaff7ac7bd8945f9b5e37ed5d0ca0ff7ff;hpb=09fc72b08113fa157a3abb2ded6086babedd10cf;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/skeleton.h b/skeleton.h index 2be9a9a..9729b64 100644 --- a/skeleton.h +++ b/skeleton.h @@ -2,9 +2,8 @@ * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved */ -#ifndef SKELETON_H -#define SKELETON_H - +#pragma once +#include "vg/vg_lines.h" #include "model.h" struct skeleton @@ -38,7 +37,9 @@ struct skeleton *anims; u32 anim_count; +#if 0 m4x3f *final_mtx; +#endif struct skeleton_ik { @@ -53,7 +54,7 @@ struct skeleton bindable_count; }; -VG_STATIC u32 skeleton_bone_id( struct skeleton *skele, const char *name ) +static u32 skeleton_bone_id( struct skeleton *skele, const char *name ) { for( u32 i=1; ibone_count; i++ ){ if( !strcmp( skele->bones[i].name, name )) @@ -66,7 +67,7 @@ VG_STATIC u32 skeleton_bone_id( struct skeleton *skele, const char *name ) return 0; } -VG_STATIC void keyframe_copy_pose( mdl_keyframe *kfa, mdl_keyframe *kfb, +static void keyframe_copy_pose( mdl_keyframe *kfa, mdl_keyframe *kfb, int num ) { for( int i=0; ico, offset, co ); @@ -89,12 +90,18 @@ VG_STATIC void keyframe_rotate_around( mdl_keyframe *kf, q_normalize( kf->q ); } +static void keyframe_lerp( mdl_keyframe *kfa, mdl_keyframe *kfb, f32 t, + mdl_keyframe *kfd ){ + v3_lerp( kfa->co, kfb->co, t, kfd->co ); + q_nlerp( kfa->q, kfb->q, t, kfd->q ); + v3_lerp( kfa->s, kfb->s, t, kfd->s ); +} + /* * Lerp between two sets of keyframes and store in dest. Rotations use Nlerp. */ -VG_STATIC void keyframe_lerp_pose( mdl_keyframe *kfa, mdl_keyframe *kfb, - float t, mdl_keyframe *kfd, int count ) -{ +static void keyframe_lerp_pose( mdl_keyframe *kfa, mdl_keyframe *kfb, + float t, mdl_keyframe *kfd, int count ){ if( t <= 0.0001f ){ keyframe_copy_pose( kfa, kfd, count ); return; @@ -104,14 +111,11 @@ VG_STATIC void keyframe_lerp_pose( mdl_keyframe *kfa, mdl_keyframe *kfb, return; } - for( int i=0; ibone_count-1 ); } -VG_STATIC void skeleton_copy_pose( struct skeleton *skele, +static void skeleton_copy_pose( struct skeleton *skele, mdl_keyframe *kfa, mdl_keyframe *kfd ) { keyframe_copy_pose( kfa, kfd, skele->bone_count-1 ); @@ -129,7 +133,7 @@ VG_STATIC void skeleton_copy_pose( struct skeleton *skele, * Sample animation between 2 closest frames using time value. Output is a * keyframe buffer that is allocated with an appropriate size */ -VG_STATIC void skeleton_sample_anim( struct skeleton *skele, +static void skeleton_sample_anim( struct skeleton *skele, struct skeleton_anim *anim, float time, mdl_keyframe *output ) @@ -147,7 +151,7 @@ VG_STATIC void skeleton_sample_anim( struct skeleton *skele, skeleton_lerp_pose( skele, base, nbase, t, output ); } -VG_STATIC int skeleton_sample_anim_clamped( struct skeleton *skele, +static int skeleton_sample_anim_clamped( struct skeleton *skele, struct skeleton_anim *anim, float time, mdl_keyframe *output ) @@ -170,7 +174,7 @@ typedef enum anim_apply } anim_apply; -VG_STATIC +static int should_apply_bone( struct skeleton *skele, u32 id, anim_apply type ) { struct skeleton_bone *sb = &skele->bones[ id ], @@ -201,22 +205,22 @@ int should_apply_bone( struct skeleton *skele, u32 id, anim_apply type ) /* * Apply block of keyframes to skeletons final pose */ -VG_STATIC void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose, - anim_apply passtype ) -{ +static void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose, + anim_apply passtype, m4x3f *final_mtx ){ if( passtype == k_anim_apply_absolute ){ for( u32 i=1; ibone_count; i++ ){ mdl_keyframe *kf = &pose[i-1]; - v3f *posemtx = skele->final_mtx[i]; + v3f *posemtx = final_mtx[i]; q_m3x3( kf->q, posemtx ); + m3x3_scale( posemtx, kf->s ); v3_copy( kf->co, posemtx[3] ); } return; } - m4x3_identity( skele->final_mtx[0] ); + m4x3_identity( final_mtx[0] ); skele->bones[0].defer = 0; skele->bones[0].flags &= ~k_bone_flag_ik; @@ -238,23 +242,25 @@ VG_STATIC void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose, /* pose matrix */ mdl_keyframe *kf = &pose[i-1]; q_m3x3( kf->q, posemtx ); + m3x3_scale( posemtx, kf->s ); v3_copy( kf->co, posemtx[3] ); v3_add( temp_delta, posemtx[3], posemtx[3] ); /* final matrix */ - m4x3_mul( skele->final_mtx[ sb->parent ], posemtx, skele->final_mtx[i] ); + m4x3_mul( final_mtx[ sb->parent ], posemtx, final_mtx[i] ); } } /* * Take the final matrices and decompose it into an absolute positioned anim */ -VG_STATIC void skeleton_decompose_mtx_absolute( struct skeleton *skele, - mdl_keyframe *anim ){ +static void skeleton_decompose_mtx_absolute( struct skeleton *skele, + mdl_keyframe *anim, + m4x3f *final_mtx ){ for( u32 i=1; ibone_count; i++ ){ struct skeleton_bone *sb = &skele->bones[i]; mdl_keyframe *kf = &anim[i-1]; - m4x3_decompose( skele->final_mtx[i], kf->co, kf->q, kf->s ); + m4x3_decompose( final_mtx[i], kf->co, kf->q, kf->s ); } } @@ -262,7 +268,7 @@ VG_STATIC void skeleton_decompose_mtx_absolute( struct skeleton *skele, * creates the reference inverse matrix for an IK bone, as it has an initial * intrisic rotation based on the direction that the IK is setup.. */ -VG_STATIC void skeleton_inverse_for_ik( struct skeleton *skele, +static void skeleton_inverse_for_ik( struct skeleton *skele, v3f ivaxis, u32 id, m3x3f inverse ) { @@ -276,7 +282,7 @@ VG_STATIC void skeleton_inverse_for_ik( struct skeleton *skele, /* * Creates inverse rotation matrices which the IK system uses. */ -VG_STATIC void skeleton_create_inverses( struct skeleton *skele ) +static void skeleton_create_inverses( struct skeleton *skele ) { /* IK: inverse 'plane-bone space' axis '(^axis,^bone,...)[base] */ for( u32 i=0; iik_count; i++ ){ @@ -297,12 +303,13 @@ VG_STATIC void skeleton_create_inverses( struct skeleton *skele ) /* * Apply a model matrix to all bones, should be done last */ -VG_STATIC -void skeleton_apply_transform( struct skeleton *skele, m4x3f transform ) +static +void skeleton_apply_transform( struct skeleton *skele, m4x3f transform, + m4x3f *final_mtx ) { for( u32 i=0; ibone_count; i++ ){ struct skeleton_bone *sb = &skele->bones[i]; - m4x3_mul( transform, skele->final_mtx[i], skele->final_mtx[i] ); + m4x3_mul( transform, final_mtx[i], final_mtx[i] ); } } @@ -310,23 +317,21 @@ void skeleton_apply_transform( struct skeleton *skele, m4x3f transform ) * Apply an inverse matrix to all bones which maps vertices from bind space into * bone relative positions */ -VG_STATIC void skeleton_apply_inverses( struct skeleton *skele ) -{ +static void skeleton_apply_inverses( struct skeleton *skele, m4x3f *final_mtx ){ for( u32 i=0; ibone_count; i++ ){ struct skeleton_bone *sb = &skele->bones[i]; m4x3f inverse; m3x3_identity( inverse ); v3_negate( sb->co, inverse[3] ); - m4x3_mul( skele->final_mtx[i], inverse, skele->final_mtx[i] ); + m4x3_mul( final_mtx[i], inverse, final_mtx[i] ); } } /* * Apply all IK modifiers (2 bone ik reference from blender is supported) */ -VG_STATIC void skeleton_apply_ik_pass( struct skeleton *skele ) -{ +static void skeleton_apply_ik_pass( struct skeleton *skele, m4x3f *final_mtx ){ for( u32 i=0; iik_count; i++ ){ struct skeleton_ik *ik = &skele->ik[i]; @@ -338,9 +343,9 @@ VG_STATIC void skeleton_apply_ik_pass( struct skeleton *skele ) co_target, co_pole; - v3_copy( skele->final_mtx[ik->lower][3], co_base ); - v3_copy( skele->final_mtx[ik->target][3], co_target ); - v3_copy( skele->final_mtx[ik->pole][3], co_pole ); + v3_copy( final_mtx[ik->lower][3], co_base ); + v3_copy( final_mtx[ik->target][3], co_target ); + v3_copy( final_mtx[ik->pole][3], co_pole ); v3_sub( co_target, co_base, v0 ); v3_sub( co_pole, co_base, v1 ); @@ -368,8 +373,8 @@ VG_STATIC void skeleton_apply_ik_pass( struct skeleton *skele ) knee[0] = sinf(-rot) * l1; knee[1] = cosf(-rot) * l1; - m4x3_identity( skele->final_mtx[ik->lower] ); - m4x3_identity( skele->final_mtx[ik->upper] ); + m4x3_identity( final_mtx[ik->lower] ); + m4x3_identity( final_mtx[ik->upper] ); /* create rotation matrix */ v3f co_knee; @@ -386,7 +391,7 @@ VG_STATIC void skeleton_apply_ik_pass( struct skeleton *skele ) v3_copy( co_base, transform[3] ); m3x3_mul( transform, ik->ia, transform ); - m4x3_copy( transform, skele->final_mtx[ik->lower] ); + m4x3_copy( transform, final_mtx[ik->lower] ); /* upper/knee bone */ v3_copy( vaxis, transform[0] ); @@ -396,7 +401,7 @@ VG_STATIC void skeleton_apply_ik_pass( struct skeleton *skele ) v3_copy( co_knee, transform[3] ); m3x3_mul( transform, ik->ib, transform ); - m4x3_copy( transform, skele->final_mtx[ik->upper] ); + m4x3_copy( transform, final_mtx[ik->upper] ); } } @@ -404,22 +409,20 @@ VG_STATIC void skeleton_apply_ik_pass( struct skeleton *skele ) * Applies the typical operations that you want for an IK rig: * Pose, IK, Pose(deferred), Inverses, Transform */ -VG_STATIC void skeleton_apply_standard( struct skeleton *skele, mdl_keyframe *pose, - m4x3f transform ) -{ - skeleton_apply_pose( skele, pose, k_anim_apply_defer_ik ); - skeleton_apply_ik_pass( skele ); - skeleton_apply_pose( skele, pose, k_anim_apply_deffered_only ); - skeleton_apply_inverses( skele ); - skeleton_apply_transform( skele, transform ); +static void skeleton_apply_standard( struct skeleton *skele, mdl_keyframe *pose, + m4x3f transform, m4x3f *final_mtx ){ + skeleton_apply_pose( skele, pose, k_anim_apply_defer_ik, final_mtx ); + skeleton_apply_ik_pass( skele, final_mtx ); + skeleton_apply_pose( skele, pose, k_anim_apply_deffered_only, final_mtx ); + skeleton_apply_inverses( skele, final_mtx ); + skeleton_apply_transform( skele, transform, final_mtx ); } /* * Get an animation by name */ -VG_STATIC struct skeleton_anim *skeleton_get_anim( struct skeleton *skele, - const char *name ) -{ +static struct skeleton_anim *skeleton_get_anim( struct skeleton *skele, + const char *name ){ for( u32 i=0; ianim_count; i++ ){ struct skeleton_anim *anim = &skele->anims[i]; @@ -433,11 +436,10 @@ VG_STATIC struct skeleton_anim *skeleton_get_anim( struct skeleton *skele, return NULL; } -VG_STATIC void skeleton_alloc_from( struct skeleton *skele, +static void skeleton_alloc_from( struct skeleton *skele, void *lin_alloc, mdl_context *mdl, - mdl_armature *armature ) -{ + mdl_armature *armature ){ skele->bone_count = armature->bone_count+1; skele->anim_count = armature->anim_count; skele->ik_count = 0; @@ -460,28 +462,26 @@ VG_STATIC void skeleton_alloc_from( struct skeleton *skele, skele->bones = vg_linear_alloc( lin_alloc, bone_size ); skele->ik = vg_linear_alloc( lin_alloc, ik_size ); - skele->final_mtx = vg_linear_alloc( lin_alloc, mtx_size ); + //skele->final_mtx = vg_linear_alloc( lin_alloc, mtx_size ); skele->anims = vg_linear_alloc( lin_alloc, anim_size ); memset( skele->bones, 0, bone_size ); memset( skele->ik, 0, ik_size ); - memset( skele->final_mtx, 0, mtx_size ); + //memset( skele->final_mtx, 0, mtx_size ); memset( skele->anims, 0, anim_size ); } -VG_STATIC void skeleton_fatal_err(void) -{ +static void skeleton_fatal_err(void){ vg_fatal_error( "Skeleton setup failed" ); } /* Setup an animated skeleton from model. mdl's metadata should stick around */ -VG_STATIC void skeleton_setup( struct skeleton *skele, - void *lin_alloc, mdl_context *mdl ) -{ +static void skeleton_setup( struct skeleton *skele, + void *lin_alloc, mdl_context *mdl ){ u32 ik_count = 0, collider_count = 0; skele->bone_count = 0; skele->bones = NULL; - skele->final_mtx = NULL; + //skele->final_mtx = NULL; skele->anims = NULL; if( !mdl->armatures.count ){ @@ -560,8 +560,7 @@ VG_STATIC void skeleton_setup( struct skeleton *skele, vg_success( " %u colliders\n", skele->collider_count ); } -VG_STATIC void skeleton_debug( struct skeleton *skele ) -{ +static void skeleton_debug( struct skeleton *skele, m4x3f *final_mtx ){ for( u32 i=1; ibone_count; i ++ ){ struct skeleton_bone *sb = &skele->bones[i]; @@ -569,8 +568,8 @@ VG_STATIC void skeleton_debug( struct skeleton *skele ) v3_copy( sb->co, p0 ); v3_add( p0, sb->end, p1 ); - m4x3_mulv( skele->final_mtx[i], p0, p0 ); - m4x3_mulv( skele->final_mtx[i], p1, p1 ); + m4x3_mulv( final_mtx[i], p0, p0 ); + m4x3_mulv( final_mtx[i], p1, p1 ); if( sb->flags & k_bone_flag_deform ){ if( sb->flags & k_bone_flag_ik ){ @@ -584,5 +583,3 @@ VG_STATIC void skeleton_debug( struct skeleton *skele ) vg_line( p0, p1, 0xff00ffff ); } } - -#endif /* SKELETON_H */