X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=skeleton.h;h=dc8342b9637c5078c2a9b6ee09d1f9ea27935ce5;hb=b4c9550f206c476bb38b0bb2855d35e6b31bee83;hp=e143fa2ec2038f34fb0d4fb5f890f10d568c8151;hpb=6a4dafa6fe9a3dd4bb88698bbe964154364390ec;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/skeleton.h b/skeleton.h index e143fa2..dc8342b 100644 --- a/skeleton.h +++ b/skeleton.h @@ -1,3 +1,7 @@ +/* + * Copyright (C) Mount0 Software, Harry Godden - All Rights Reserved + */ + #ifndef SKELETON_H #define SKELETON_H @@ -14,6 +18,13 @@ struct skeleton int defer; mdl_keyframe kf; + + u32 orig_node; + + int collider; + boxf hitbox; + + char name[16]; } *bones; m4x3f *final_mtx; @@ -36,18 +47,46 @@ struct skeleton u32 bone_count, ik_count, + collider_count, anim_count, bindable_count; /* TODO: try to place IK last in the rig from export so that we dont always upload transforms for useless cpu IK bones. */ }; +static u32 skeleton_bone_id( struct skeleton *skele, const char *name ) +{ + for( u32 i=0; ibone_count; i++ ) + { + if( !strcmp( skele->bones[i].name, name )) + return i; + } + return 0; +} + +static void keyframe_copy_pose( mdl_keyframe *kfa, mdl_keyframe *kfb, int num ) +{ + for( int i=0; i= 0.99f ) + { + keyframe_copy_pose( kfb, kfd, count ); + return; + } + for( int i=0; ilength-1) / anim->rate; + skeleton_sample_anim( skele, anim, vg_minf( end, time ), output ); + + if( time > end ) + return 0; + else + return 1; +} + typedef enum anim_apply { k_anim_apply_always, @@ -174,6 +227,9 @@ static void skeleton_inverse_for_ik( struct skeleton *skele, m3x3_transpose( inverse, inverse ); } +/* + * Creates inverse rotation matrices which the IK system uses. + */ static void skeleton_create_inverses( struct skeleton *skele ) { /* IK: inverse 'plane-bone space' axis '(^axis,^bone,...)[base] */ @@ -193,9 +249,11 @@ static void skeleton_create_inverses( struct skeleton *skele ) } } +/* + * Apply a model matrix to all bones, should be done last + */ static void skeleton_apply_transform( struct skeleton *skele, m4x3f transform ) { - /* bone space inverse matrix */ for( int i=0; ibone_count; i++ ) { struct skeleton_bone *sb = &skele->bones[i]; @@ -203,6 +261,10 @@ static 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 + */ static void skeleton_apply_inverses( struct skeleton *skele ) { for( int i=0; ibone_count; i++ ) @@ -295,6 +357,23 @@ 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 + */ +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 ); +} + +/* + * Get an animation by name + */ static struct skeleton_anim *skeleton_get_anim( struct skeleton *skele, const char *name ) { @@ -312,7 +391,7 @@ static struct skeleton_anim *skeleton_get_anim( struct skeleton *skele, /* Setup an animated skeleton from model */ static int skeleton_setup( struct skeleton *skele, mdl_header *mdl ) { - u32 bone_count = 1, skeleton_root = 0, ik_count = 0; + u32 bone_count = 1, skeleton_root = 0, ik_count = 0, collider_count = 0; skele->bone_count = 0; skele->bones = NULL; skele->final_mtx = NULL; @@ -335,14 +414,14 @@ static int skeleton_setup( struct skeleton *skele, mdl_header *mdl ) skele->bone_count = inf->channels; skele->ik_count = inf->ik_count; + skele->collider_count = inf->collider_count; skele->bones = malloc(sizeof(struct skeleton_bone)*skele->bone_count); skele->ik = malloc(sizeof(struct skeleton_ik)*skele->ik_count); skeleton_root = i; } else if( skele->bone_count ) { - int is_ik = pnode->classtype == k_classtype_ik_bone, - is_bone = (pnode->classtype == k_classtype_bone) || is_ik; + int is_bone = pnode->classtype == k_classtype_bone; if( is_bone ) { @@ -356,15 +435,17 @@ static int skeleton_setup( struct skeleton *skele, mdl_header *mdl ) } struct skeleton_bone *sb = &skele->bones[bone_count]; + struct classtype_bone *bone_inf = mdl_get_entdata( mdl, pnode ); + int is_ik = bone_inf->ik_target; v3_copy( pnode->co, sb->co ); v3_copy( pnode->s, sb->end ); sb->parent = pnode->parent-skeleton_root; + strncpy( sb->name, mdl_pstr(mdl,pnode->pstr_name), 15 ); + sb->deform = bone_inf->deform; if( is_ik ) { - struct classtype_ik_bone *ik_inf = mdl_get_entdata( mdl, pnode ); - sb->deform = ik_inf->deform; sb->ik = 1; /* TODO: place into new IK array */ skele->bones[ sb->parent ].ik = 1; @@ -377,16 +458,29 @@ static int skeleton_setup( struct skeleton *skele, mdl_header *mdl ) struct skeleton_ik *ik = &skele->ik[ ik_count ++ ]; ik->upper = bone_count; ik->lower = sb->parent; - ik->target = ik_inf->target; - ik->pole = ik_inf->pole; + ik->target = bone_inf->ik_target; + ik->pole = bone_inf->ik_pole; } else { - struct classtype_bone *bone_inf = mdl_get_entdata( mdl, pnode ); - sb->deform = bone_inf->deform; sb->ik = 0; } + sb->collider = bone_inf->collider; + sb->orig_node = i; + box_copy( bone_inf->hitbox, sb->hitbox ); + + if( bone_inf->collider ) + { + if( collider_count == skele->collider_count ) + { + vg_error( "Too many collider bones\n" ); + goto error_dealloc; + } + + collider_count ++; + } + bone_count ++; } else @@ -402,6 +496,13 @@ static int skeleton_setup( struct skeleton *skele, mdl_header *mdl ) return 0; } + if( collider_count != skele->collider_count ) + { + vg_error( "Loaded %u colliders out of %u\n", collider_count, + skele->collider_count ); + goto error_dealloc; + } + if( bone_count != skele->bone_count ) { vg_error( "Loaded %u bones out of %u\n", bone_count, skele->bone_count ); @@ -418,6 +519,7 @@ static int skeleton_setup( struct skeleton *skele, mdl_header *mdl ) v3_zero( skele->bones[0].co ); v3_copy( (v3f){0.0f,1.0f,0.0f}, skele->bones[0].end ); skele->bones[0].parent = 0xffffffff; + skele->bones[0].collider = 0; skele->final_mtx = malloc( sizeof(m4x3f) * skele->bone_count ); skele->anim_count = inf->anim_count; @@ -442,6 +544,7 @@ static int skeleton_setup( struct skeleton *skele, mdl_header *mdl ) skeleton_create_inverses( skele ); vg_success( "Loaded skeleton with %u bones\n", skele->bone_count ); + vg_success( " %u colliders\n", skele->collider_count ); return 1; error_dealloc: