From 7bf2284094c18d0e7de1c8823264bdfa36bc7f2e Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 11 Jun 2022 15:34:20 +0100 Subject: [PATCH] foot alignment --- character.h | 50 ++++++++++++++++++++++++++++++++++++++++++-------- main.c | 29 +++++++++++++++++++++-------- 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/character.h b/character.h index 51f2c16..70c1727 100644 --- a/character.h +++ b/character.h @@ -205,6 +205,37 @@ static int character_load( struct character *ch, const char *name ) return 1; } +static void align_to_board( struct character *ch, enum character_part id ) +{ + /* Calculate rotation between board and feet */ + m4x3f *mats = ch->matrices; + + v3f foot_pos, foot_fwd, foot_target, board_norm, board_origin; + v3_copy( mats[id][3], foot_pos ); + m3x3_mulv( mats[id], (v3f){1.0f,0.0f,0.0f}, foot_fwd ); + v3_add( foot_fwd, foot_pos, foot_target ); + + m3x3_mulv( mats[k_chpart_board], (v3f){0.0f,1.0f,0.0f}, board_norm ); + m4x3_mulv( mats[k_chpart_board], (v3f){0.0f,0.13f,0.0f}, board_origin ); + + vg_line( foot_pos, foot_target, 0xff00ff00 ); + + v3f v0; + v3_sub( board_origin, foot_target, v0 ); + float t = v3_dot( v0, board_norm ) / board_norm[1]; + foot_target[1] += t; + vg_line( foot_pos, foot_target, 0xff00ffff ); + + v3_sub( foot_target, foot_pos, foot_target ); + v3_normalize( foot_target ); + float ang = acosf( v3_dot( foot_target, foot_fwd ) ); + + v4f qcorrection; m3x3f correction; + q_axis_angle( qcorrection, (v3f){0.0f,0.0f,1.0f}, -ang ); + q_m3x3( qcorrection, correction ); + m3x3_mul( mats[id], correction, mats[id] ); +} + static void character_eval( struct character *ch ) { m4x3f *mats = ch->matrices; @@ -240,14 +271,6 @@ static void character_eval( struct character *ch ) k_ikY, k_iknX ); ik_basic( &ch->ik_leg_r, mats[k_chpart_leg_r0], mats[k_chpart_leg_r1], k_ikY, k_iknX ); - - /* Feet */ - m3x3_copy( mats[k_chpart_leg_l1], mats[k_chpart_foot_l] ); - m3x3_copy( mats[k_chpart_leg_r1], mats[k_chpart_foot_r] ); - m4x3_mulv( mats[k_chpart_leg_l1], offs[k_chpart_foot_l], - mats[k_chpart_foot_l][3] ); - m4x3_mulv( mats[k_chpart_leg_r1], offs[k_chpart_foot_r], - mats[k_chpart_foot_r][3] ); /* Hands */ m3x3_copy( mats[k_chpart_arm_l1], mats[k_chpart_hand_l] ); @@ -268,6 +291,17 @@ static void character_eval( struct character *ch ) //m3x3_mul( mats[k_chpart_neck], mats[k_chpart_head], mats[k_chpart_head] ); m4x3_mulv( mats[k_chpart_neck], offs[k_chpart_head], mats[k_chpart_head][3]); + /* Feet */ + m3x3_copy( mats[k_chpart_leg_l1], mats[k_chpart_foot_l] ); + m3x3_copy( mats[k_chpart_leg_r1], mats[k_chpart_foot_r] ); + m4x3_mulv( mats[k_chpart_leg_l1], offs[k_chpart_foot_l], + mats[k_chpart_foot_l][3] ); + m4x3_mulv( mats[k_chpart_leg_r1], offs[k_chpart_foot_r], + mats[k_chpart_foot_r][3] ); + + align_to_board( ch, k_chpart_foot_l ); + align_to_board( ch, k_chpart_foot_r ); + for( int i=0; imroot, ch->matrices[i], ch->matrices[i] ); } diff --git a/main.c b/main.c index 69d4df9..61f0a58 100644 --- a/main.c +++ b/main.c @@ -460,6 +460,16 @@ static int sample_if_resistant( v3f pos ) return 0; } +static float stable_force( float current, float diff ) +{ + float new = current + diff; + + if( new * current < 0.0f ) + return 0.0f; + + return new; +} + static void player_physics_ground(void) { /* @@ -543,10 +553,8 @@ static void player_physics_ground(void) float substep = ktimestep * 0.2f; for( int i=0; i<5; i++ ) { - if( fabsf(vel[2]) >= 0.02f*substep ) - vel[2] += vg_signf( vel[2] ) * -0.02f * substep; - if( fabsf(vel[0]) >= 7.0f*substep ) - vel[0] += vg_signf( vel[0] ) * -7.0f * substep; + vel[2] = stable_force( vel[2], vg_signf( vel[2] ) * -0.02f*substep ); + vel[0] = stable_force( vel[0], vg_signf( vel[0] ) * -7.0f *substep ); } m3x3_mulv( player.to_world, vel, player.v ); @@ -558,6 +566,10 @@ static void player_physics_ground(void) float steer = vg_get_axis( "horizontal" ); player.iY -= vg_signf(steer)*powf(steer,2.0f) * 1.5f * ktimestep; + + /* Too much lean and it starts to look like a snowboard here */ + v2_lerp( player.board_xy, (v2f){ slip*0.25f, 0.0f }, + ktimestep*5.0f, player.board_xy); } static void draw_cross(v3f pos,u32 colour) @@ -644,6 +656,11 @@ static void player_physics_air(void) } player.iY -= vg_get_axis( "horizontal" ) * 3.6f * ktimestep; + + v2f target = {0.0f,0.0f}; + v2_muladds( target, (v2f){ vg_get_axis("h1"), vg_get_axis("v1") }, + player.grab, target ); + v2_lerp( player.board_xy, target, ktimestep*3.0f, player.board_xy ); } static void player_animate(void); @@ -837,10 +854,6 @@ static void player_animate(void) /* New board transformation */ v4f board_rotation; v3f board_location; - - /* TODO: Move this out of animate into update */ - v2_lerp( player.board_xy, (v2f){ vg_get_axis("h1"), vg_get_axis("v1") }, - ktimestep*3.0f, player.board_xy ); v4f rz, rx; q_axis_angle( rz, (v3f){ 0.0f, 0.0f, 1.0f }, player.board_xy[0] ); -- 2.25.1