From 6a4dafa6fe9a3dd4bb88698bbe964154364390ec Mon Sep 17 00:00:00 2001 From: hgn Date: Fri, 9 Sep 2022 01:05:10 +0100 Subject: [PATCH] oops --- skeleton.h | 580 ----------------------------------------------------- 1 file changed, 580 deletions(-) diff --git a/skeleton.h b/skeleton.h index ac368cf..e143fa2 100644 --- a/skeleton.h +++ b/skeleton.h @@ -481,583 +481,3 @@ static void skeleton_debug( struct skeleton *skele ) } #endif /* SKELETON_H */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if 0 -#ifndef SKELETON_H -#define SKELETON_H - -#include "model.h" - -struct skeleton -{ - struct skeleton_bone - { - v3f co, end; - u32 parent; - - /* info, not real */ - int deform, ik; - int defer; - - mdl_keyframe kf; - } - *bones; - m4x3f *final_transforms; - - struct skeleton_ik - { - u32 lower, upper, target, pole; - } - *ik; - - struct skeleton_anim - { - float rate; - u32 length; - struct mdl_keyframe *anim_data; - char name[32]; - } - *anims; - - u32 bone_count, - ik_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. */ -}; - -/* - * Lerp between two sets of keyframes and store in dest. Rotations use Nlerp. - */ -static void keyframe_lerp_pose( mdl_keyframe *kfa, mdl_keyframe *kfb, float t, - mdl_keyframe *kfd, int count ) -{ - for( int i=0; ibone_count-1 ); -} - -/* - * Sample animation between 2 closest frames using time value. Output is a - * keyframe buffer that is allocated with an appropriate size - */ -static void skeleton_sample_anim( struct skeleton *skele, - struct skeleton_anim *anim, - float time, - mdl_keyframe *output ) -{ - float animtime = time*anim->rate; - - u32 frame = ((u32)animtime) % anim->length, - next = (frame+1) % anim->length; - - float t = vg_fractf( animtime ); - - mdl_keyframe *base = anim->anim_data + (skele->bone_count-1)*frame, - *nbase = anim->anim_data + (skele->bone_count-1)*next; - - skeleton_lerp_pose( skele, base, nbase, t, output ); -} - -typedef enum anim_apply -{ - k_anim_apply_always, - k_anim_apply_defer_ik, - k_anim_apply_deffered_only -} -anim_apply; - -static int should_apply_bone( struct skeleton *skele, u32 id, anim_apply type ) -{ - struct skeleton_bone *sb = &skele->bones[ id ], - *sp = &skele->bones[ sb->parent ]; - - if( type == k_anim_apply_defer_ik ) - { - if( sp->ik || sp->defer ) - { - sb->defer = 1; - return 0; - } - } - else if( type == k_anim_apply_deffered_only ) - { - if( !sp->defer ) - return 0; - } - - return 1; -} - -/* - * Apply block of keyframes to skeletons final pose - */ -static void skeleton_apply_pose( m4x3f transform, - struct skeleton *skele, mdl_keyframe *pose, - anim_apply passtype ) -{ - m4x3_copy( transform, skele->final_transforms[0] ); - skele->bones[0].defer = 0; - skele->bones[0].ik = 0; - - for( int i=1; ibone_count; i++ ) - { - struct skeleton_bone *sb = &skele->bones[i], - *sp = &skele->bones[ sb->parent ]; - - if( !should_apply_bone( skele, i, passtype ) ) - continue; - - sb->defer = 0; - - /* process pose */ - m4x3f posemtx; - - v3f temp_delta; - v3_sub( skele->bones[i].co, skele->bones[sb->parent].co, temp_delta ); - - /* pose matrix */ - mdl_keyframe *kf = &pose[i-1]; - q_m3x3( kf->q, posemtx ); - v3_copy( kf->co, posemtx[3] ); - v3_add( temp_delta, posemtx[3], posemtx[3] ); - - /* final matrix */ - m4x3_mul( skele->final_transforms[ sb->parent ], posemtx, - skele->final_transforms[i] ); - } - - /* bone space inverse matrix ( for verts ) TODO: move to seperate pass */ - for( int i=1; ibone_count; i++ ) - { - if( !should_apply_bone( skele, i, passtype ) ) - continue; - - m4x3f abmtx; - m3x3_identity( abmtx ); - v3_negate( skele->bones[i].co, abmtx[3] ); - m4x3_mul( skele->final_transforms[i], abmtx, skele->final_transforms[i] ); - } -} - -static void skeleton_apply_frame( m4x3f transform, - struct skeleton *skele, - struct skeleton_anim *anim, - float time ) -{ - float animtime = time*anim->rate; - - u32 frame = ((u32)animtime) % anim->length, - next = (frame+1) % anim->length; - - float t = vg_fractf( animtime ); - - mdl_keyframe *base = anim->anim_data + (skele->bone_count-1)*frame, - *nbase = anim->anim_data + (skele->bone_count-1)*next; - - m4x3_copy( transform, skele->final_transforms[0] ); - - for( int i=1; ibone_count; i++ ) - { - struct skeleton_bone *sb = &skele->bones[i]; - - /* process pose */ - m4x3f posemtx; - - v3f temp_delta; - v3_sub( skele->bones[i].co, skele->bones[sb->parent].co, temp_delta ); - - /* pose matrix */ - mdl_keyframe *kf = base+i-1, - *nkf = nbase+i-1; - - v3f co; - v4f q; - v3f s; - - v3_lerp( kf->co, nkf->co, t, co ); - q_nlerp( kf->q, nkf->q, t, q ); - v3_lerp( kf->s, nkf->s, t, s ); - - q_m3x3( q, posemtx ); - v3_copy( co, posemtx[3] ); - v3_add( temp_delta, posemtx[3], posemtx[3] ); - - /* final matrix */ - m4x3_mul( skele->final_transforms[ sb->parent ], posemtx, - skele->final_transforms[i] ); - } - - /* armature space -> bone space matrix ( for verts ) */ - for( int i=1; ibone_count; i++ ) - { - m4x3f abmtx; - m3x3_identity( abmtx ); - v3_negate( skele->bones[i].co, abmtx[3] ); - m4x3_mul( skele->final_transforms[i], abmtx, - skele->final_transforms[i] ); - } -} - -/* - * Get transformed position of bone - */ -static void skeleton_bone_posepos( struct skeleton *skele, u32 id, v3f co ) -{ - m4x3_mulv( skele->final_transforms[id], skele->bones[id].co, co ); -} - -/* - * 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.. - */ -static void skeleton_inverse_for_ik( struct skeleton *skele, - v3f ivaxis, - u32 id, m4x3f inverse ) -{ - v3_copy( ivaxis, inverse[0] ); - v3_copy( skele->bones[id].end, inverse[1] ); - v3_normalize( inverse[1] ); - v3_cross( inverse[0], inverse[1], inverse[2] ); - v3_copy( skele->bones[id].co, inverse[3] ); - m4x3_invert_affine( inverse, inverse ); -} - -/* - * Apply all IK modifiers (2 bone ik reference from blender is supported) - */ -static void skeleton_apply_ik_pass( struct skeleton *skele ) -{ - for( int i=0; iik_count; i++ ) - { - struct skeleton_ik *ik = &skele->ik[i]; - - v3f v0, /* base -> target */ - v1, /* base -> pole */ - vaxis; - - v3f co_base, - co_target, - co_pole; - - skeleton_bone_posepos( skele, ik->lower, co_base ); - skeleton_bone_posepos( skele, ik->target, co_target ); - skeleton_bone_posepos( skele, ik->pole, co_pole ); - - v3_sub( co_target, co_base, v0 ); - v3_sub( co_pole, co_base, v1 ); - v3_cross( v0, v1, vaxis ); - v3_normalize( vaxis ); - v3_normalize( v0 ); - v3_cross( vaxis, v0, v1 ); - - /* localize problem into [x:v0,y:v1] 2d plane */ - v2f base = { v3_dot( v0, co_base ), v3_dot( v1, co_base ) }, - end = { v3_dot( v0, co_target ), v3_dot( v1, co_target ) }, - knee; - - /* Compute angles (basic trig)*/ - v2f delta; - v2_sub( end, base, delta ); - - float - l1 = v3_length( skele->bones[ik->lower].end ), - l2 = v3_length( skele->bones[ik->upper].end ), - d = vg_clampf( v2_length(delta), fabsf(l1 - l2), l1+l2-0.00001f ), - c = acosf( (l1*l1 + d*d - l2*l2) / (2.0f*l1*d) ), - rot = atan2f( delta[1], delta[0] ) + c - VG_PIf/2.0f; - - knee[0] = sinf(-rot) * l1; - knee[1] = cosf(-rot) * l1; - - m4x3_identity( skele->final_transforms[ik->lower] ); - m4x3_identity( skele->final_transforms[ik->upper] ); - - /* inverse matrix axis '(^axis,^bone,...)[base] */ - m4x3f inverse; - v3f iv0, iv1, ivaxis; - v3_sub( skele->bones[ik->target].co, skele->bones[ik->lower].co, iv0 ); - v3_sub( skele->bones[ik->pole].co, skele->bones[ik->lower].co, iv1 ); - v3_cross( iv0, iv1, ivaxis ); - v3_normalize( ivaxis ); - - skeleton_inverse_for_ik( skele, ivaxis, ik->lower, inverse ); - - /* create rotation matrix */ - v3f co_knee; - v3_muladds( co_base, v0, knee[0], co_knee ); - v3_muladds( co_knee, v1, knee[1], co_knee ); - vg_line( co_base, co_knee, 0xff00ff00 ); - - m4x3f transform; - v3_copy( vaxis, transform[0] ); - v3_muls( v0, knee[0], transform[1] ); - v3_muladds( transform[1], v1, knee[1], transform[1] ); - v3_normalize( transform[1] ); - v3_cross( transform[0], transform[1], transform[2] ); - v3_copy( co_base, transform[3] ); - - m4x3_mul( transform, inverse, skele->final_transforms[ik->lower] ); - - /* 'upper' or knee bone */ - skeleton_inverse_for_ik( skele, ivaxis, ik->upper, inverse ); - - v3_copy( vaxis, transform[0] ); - v3_sub( co_target, co_knee, transform[1] ); - v3_normalize( transform[1] ); - v3_cross( transform[0], transform[1], transform[2] ); - v3_copy( co_knee, transform[3] ); - - m4x3_mul( transform, inverse, skele->final_transforms[ik->upper] ); - } -} - -static struct skeleton_anim *skeleton_get_anim( struct skeleton *skele, - const char *name ) -{ - for( int i=0; ianim_count; i++ ) - { - struct skeleton_anim *anim = &skele->anims[i]; - - if( !strcmp( anim->name, name ) ) - return anim; - } - - return NULL; -} - -/* 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; - skele->bone_count = 0; - skele->bones = NULL; - skele->final_transforms = NULL; - skele->anims = NULL; - - struct classtype_skeleton *inf = NULL; - - for( u32 i=0; inode_count; i++ ) - { - mdl_node *pnode = mdl_node_from_id( mdl, i ); - - if( pnode->classtype == k_classtype_skeleton ) - { - inf = mdl_get_entdata( mdl, pnode ); - if( skele->bone_count ) - { - vg_error( "Multiple skeletons in model file\n" ); - goto error_dealloc; - } - - skele->bone_count = inf->channels; - skele->ik_count = inf->ik_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; - - if( is_bone ) - { - if( bone_count == skele->bone_count ) - { - vg_error( "too many bones (%u/%u) @%s!\n", - bone_count, skele->bone_count, - mdl_pstr( mdl, pnode->pstr_name )); - - goto error_dealloc; - } - - struct skeleton_bone *sb = &skele->bones[bone_count]; - - v3_copy( pnode->co, sb->co ); - v3_copy( pnode->s, sb->end ); - sb->parent = pnode->parent-skeleton_root; - - 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; - - if( ik_count == skele->ik_count ) - { - vg_error( "Too many ik bones, corrupt model file\n" ); - goto error_dealloc; - } - - 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; - } - else - { - struct classtype_bone *bone_inf = mdl_get_entdata( mdl, pnode ); - sb->deform = bone_inf->deform; - sb->ik = 0; - } - - bone_count ++; - } - else - { - break; - } - } - } - - if( !inf ) - { - vg_error( "No skeleton in model\n" ); - return 0; - } - - if( bone_count != skele->bone_count ) - { - vg_error( "Loaded %u bones out of %u\n", bone_count, skele->bone_count ); - goto error_dealloc; - } - - if( ik_count != skele->ik_count ) - { - vg_error( "Loaded %u ik bones out of %u\n", ik_count, skele->ik_count ); - goto error_dealloc; - } - - /* fill in implicit root bone */ - 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->final_transforms = malloc( sizeof(m4x3f) * skele->bone_count ); - skele->anim_count = inf->anim_count; - skele->anims = malloc( sizeof(struct skeleton_anim) * inf->anim_count); - - for( int i=0; ianim_count; i++ ) - { - mdl_animation *anim = - mdl_animation_from_id( mdl, inf->anim_start+i ); - - skele->anims[i].rate = anim->rate; - skele->anims[i].length = anim->length; - strncpy( skele->anims[i].name, mdl_pstr(mdl, anim->pstr_name), 32 ); - - u32 total_keyframes = (skele->bone_count-1)*anim->length; - size_t block_size = sizeof(mdl_keyframe) * total_keyframes; - mdl_keyframe *dst = malloc( block_size ); - - skele->anims[i].anim_data = dst; - memcpy( dst, mdl_get_animdata( mdl, anim ), block_size ); - } - - vg_success( "Loaded skeleton with %u bones\n", skele->bone_count ); - return 1; - -error_dealloc: - free( skele->bones ); - free( skele->ik ); - return 0; -} - -static void skeleton_debug( struct skeleton *skele ) -{ - for( int i=0; ibone_count; i ++ ) - { - struct skeleton_bone *sb = &skele->bones[i]; - - v3f p0, p1; - v3_copy( sb->co, p0 ); - v3_add( p0, sb->end, p1 ); - //vg_line( p0, p1, 0xffffffff ); - - m4x3_mulv( skele->final_transforms[i], p0, p0 ); - m4x3_mulv( skele->final_transforms[i], p1, p1 ); - - if( sb->deform ) - { - if( sb->ik ) - { - vg_line( p0, p1, 0xff0000ff ); - } - else - { - vg_line( p0, p1, 0xffcccccc ); - } - } - else - vg_line( p0, p1, 0xff00ffff ); - } -} - -#endif /* SKELETON_H */ -#endif -- 2.25.1