X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_walk.c;h=717411c88476cdd7bd56f74f060e186c22cd005a;hb=e311bbe2fa903a7e2a922f202f389b799193195d;hp=ec025a17630e4e52bf2cb77d7982802ed4abdfd1;hpb=074fa69f479724f9800849430bad5caf730b01ef;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_walk.c b/player_walk.c index ec025a1..717411c 100644 --- a/player_walk.c +++ b/player_walk.c @@ -7,18 +7,14 @@ static void player_walk_drop_in_vector( v3f vec ){ v3f axis, init_dir; - v3_cross( localplayer.basis[1], player_walk.state.drop_in_normal, axis ); + v3_cross( (v3f){0.0f,1.0f,0.0f}, player_walk.state.drop_in_normal, axis ); v3_cross( axis, player_walk.state.drop_in_normal, init_dir ); v3_normalize( init_dir ); - v3_muls( init_dir, 7.0f, vec ); + v3_muls( init_dir, 4.25f, vec ); } static float player_xyspeed2(void){ - v3f xy; - v3_muladds( localplayer.rb.v, localplayer.basis[1], - -v3_dot( localplayer.basis[1], localplayer.rb.v ), xy ); - - return v3_length2(xy); + return v3_length2( (v3f){localplayer.rb.v[0], 0.0f, localplayer.rb.v[2]} ); } static void player_walk_generic_to_skate( enum skate_activity init, f32 yaw ){ @@ -37,11 +33,9 @@ static void player_walk_generic_to_skate( enum skate_activity init, f32 yaw ){ v3f dir; v3_copy( v, dir ); v3_normalize( dir ); - m3x3_mulv( localplayer.invbasis, dir, dir ); q_axis_angle( localplayer.rb.q, (v3f){0.0f,1.0f,0.0f}, atan2f(-dir[0],-dir[2]) ); - q_mul( localplayer.qbasis, localplayer.rb.q, localplayer.rb.q ); q_normalize( localplayer.rb.q ); q_mulv( localplayer.rb.q, (v3f){0.0f,1.0f,0.0f}, player_skate.state.cog ); @@ -50,7 +44,7 @@ static void player_walk_generic_to_skate( enum skate_activity init, f32 yaw ){ v3_copy( v, player_skate.state.cog_v ); v3_copy( v, localplayer.rb.v ); - player__begin_holdout(); + player__begin_holdout( (v3f){0.0f,0.0f,0.0f} ); player__skate_reset_animator(); player__skate_clear_mechanics(); rb_update_transform( &localplayer.rb ); @@ -67,7 +61,7 @@ static void player_walk_drop_in_to_skate(void){ player_skate.state.activity_prev = k_skate_activity_ground; player_skate.state.activity = k_skate_activity_ground; - player__begin_holdout(); + player__begin_holdout( (v3f){0.0f,0.0f,0.0f} ); player__skate_clear_mechanics(); player__skate_reset_animator(); @@ -85,7 +79,7 @@ static void player_walk_drop_in_to_skate(void){ static void player_walk_drop_in_overhang_transform( f32 t, v3f co, v4f q ){ v3f axis; - v3_cross( localplayer.basis[1], player_walk.state.drop_in_normal, axis ); + v3_cross( (v3f){0,1,0}, player_walk.state.drop_in_normal, axis ); v3_normalize( axis ); float a = acosf( player_walk.state.drop_in_normal[1] ) * t; @@ -228,6 +222,9 @@ static int player_walk_scan_for_drop_in(void){ static struct skeleton_anim *player_walk_outro_anim( enum walk_outro type ){ struct player_walk *w = &player_walk; + if( type >= k_walk_outro_max ) + return NULL; + return (struct skeleton_anim *[]){ [k_walk_outro_none] = NULL, [k_walk_outro_jump_to_air] = w->anim_jump_to_air, @@ -243,6 +240,40 @@ static void player__walk_pre_update(void){ if( !localplayer.immobile ) player_look( localplayer.angles, skaterift.time_rate ); + v2f steer; + joystick_state( k_srjoystick_steer, steer ); + + if( w->state.activity == k_walk_activity_sit ){ + if( w->state.sit_t < 1.0f ) + w->state.sit_t = vg_minf( 1.0f, w->state.sit_t + vg.time_delta ); + + if( button_down(k_srbind_sit) || (v2_length2(steer)>0.2f) || + button_down(k_srbind_jump) ){ + w->state.activity = k_walk_activity_sit_up; + } + return; + } + else if( w->state.activity == k_walk_activity_sit_up ){ + if( w->state.sit_t > 0.0f ) + w->state.sit_t = vg_maxf( 0.0f, w->state.sit_t - vg.time_delta ); + else + w->state.activity = k_walk_activity_ground; + + if( button_down(k_srbind_sit) ) + w->state.activity = k_walk_activity_sit; + + return; + } + else if( w->state.activity == k_walk_activity_ground ){ + if( button_down(k_srbind_sit) ){ + v3_zero( localplayer.rb.v ); + w->state.activity = k_walk_activity_sit; + return; + } + } + + w->state.sit_t = 0.0f; + if( w->state.outro_type ){ struct skeleton_anim *anim = player_walk_outro_anim(w->state.outro_type); @@ -265,7 +296,7 @@ static void player__walk_pre_update(void){ } } else if( button_down( k_srbind_use ) && !localplayer.immobile ){ - if( v3_dist2( localplayer.rb.co, gzoomer.obj.rb.co ) <= 4.0f*4.0f ){ + if( 0 && (v3_dist2(localplayer.rb.co,gzoomer.obj.rb.co) <= 4.0f*4.0f) ){ localplayer.subsystem = k_player_subsystem_drive; } else{ @@ -281,9 +312,10 @@ static void player__walk_pre_update(void){ w->state.outro_start_time = vg.time; localplayer.immobile = 1; - struct player_avatar *av = localplayer.playeravatar; - m4x3_mulv( localplayer.final_mtx[ av->id_ik_foot_r ], - av->sk.bones[ av->id_ik_foot_r ].co, + u32 foot_id = localplayer.id_ik_foot_r; + + m4x3_mulv( localplayer.final_mtx[ foot_id ], + localplayer.skeleton.bones[ foot_id ].co, w->state.drop_in_foot_anchor ); } else{ @@ -311,7 +343,7 @@ static void player__walk_pre_update(void){ } static int player_walk_normal_standable( v3f n ){ - return v3_dot( n, localplayer.basis[1] ) > 0.70710678118f; + return n[1] > 0.70710678118f; } static void player_accelerate( v3f v, v3f movedir, f32 speed, f32 accel ){ @@ -384,6 +416,15 @@ static void player_walk_custom_filter( world_instance *world, static void player__walk_update(void){ struct player_walk *w = &player_walk; + + v2f steer; + joystick_state( k_srjoystick_steer, steer ); + + if( (w->state.activity == k_walk_activity_sit) || + (w->state.activity == k_walk_activity_sit_up) ){ + return; + } + v3_copy( localplayer.rb.co, w->state.prev_pos ); v3_zero( localplayer.rb.w ); @@ -391,7 +432,9 @@ static void player__walk_update(void){ if( world->water.enabled ){ if( localplayer.rb.co[1]+0.4f < world->water.height ){ - audio_oneshot_3d( &audio_splash, localplayer.rb.co, 40.0f, 1.0f ); + player__networked_sfx( k_player_subsystem_walk, 32, + k_player_walk_soundeffect_splash, + localplayer.rb.co, 1.0f ); player__dead_transition(); return; } @@ -404,7 +447,7 @@ static void player__walk_update(void){ m4x3f mtx; m3x3_copy( localplayer.rb.to_world, mtx ); - v3_add( localplayer.rb.co, localplayer.basis[1], mtx[3] ); + v3_add( localplayer.rb.co, (v3f){0,1,0}, mtx[3] ); vg_line_capsule( mtx, w->collider.radius, w->collider.height, VG__WHITE ); @@ -416,12 +459,6 @@ static void player__walk_update(void){ v3f forward_dir = { -sinf(yaw), 0.0f, cosf(yaw) }; v3f right_dir = { forward_dir[2], 0.0f, -forward_dir[0] }; - m3x3_mulv( localplayer.basis, forward_dir, forward_dir ); - m3x3_mulv( localplayer.basis, right_dir, right_dir ); - - v2f steer; - joystick_state( k_srjoystick_steer, steer ); - w->move_speed = localplayer.immobile? 0.0f: v2_length( steer ); /* @@ -488,11 +525,7 @@ static void player__walk_update(void){ f32 t = vg.time - w->state.jump_input_time; if( t < PLAYER_JUMP_EPSILON ){ - float d = v3_dot( localplayer.basis[1], localplayer.rb.v ); - v3_muladds( localplayer.rb.v, localplayer.basis[1], -d, - localplayer.rb.v ); - v3_muladds( localplayer.rb.v, localplayer.basis[1], 5.0f, - localplayer.rb.v ); + localplayer.rb.v[1] = 5.0f; w->state.activity = k_walk_activity_air; prev_state = k_walk_activity_air; accel_speed = k_walk_air_accel; @@ -539,8 +572,8 @@ static void player__walk_update(void){ v3f pa, pb; v3_copy( localplayer.rb.co, pa ); - v3_muladds( pa, localplayer.basis[1], w->collider.radius + max_dist, pa ); - v3_muladds( pa, localplayer.basis[1], -max_dist * 2.0f, pb ); + pa[1] += w->collider.radius + max_dist; + v3_add( pa, (v3f){0, -max_dist * 2.0f, 0}, pb ); vg_line( pa, pb, 0xff000000 ); v3f n; @@ -549,16 +582,12 @@ static void player__walk_update(void){ w->collider.radius, &t, n, 0 ) != -1 ){ if( player_walk_normal_standable(n) ){ v3_lerp( pa, pb, t, localplayer.rb.co ); - v3_muladds( localplayer.rb.co, localplayer.basis[1], - -w->collider.radius - k_penetration_slop, - localplayer.rb.co ); + localplayer.rb.co[1] += -w->collider.radius - k_penetration_slop; w->state.activity = k_walk_activity_ground; - float d = -v3_dot(n,localplayer.rb.v), - g = -k_gravity * k_rb_delta; + float d = -v3_dot(n,localplayer.rb.v); v3_muladds( localplayer.rb.v, n, d, localplayer.rb.v ); - v3_muladds( localplayer.rb.v, localplayer.basis[1], g, - localplayer.rb.v ); + localplayer.rb.v[1] += -k_gravity * k_rb_delta; } } } @@ -572,8 +601,7 @@ static void player__walk_update(void){ /* integrate */ if( w->state.activity == k_walk_activity_air ){ - v3_muladds( localplayer.rb.v, localplayer.basis[1], -k_gravity*k_rb_delta, - localplayer.rb.v ); + localplayer.rb.v[1] += -k_gravity*k_rb_delta; } if( localplayer.immobile ){ @@ -583,7 +611,7 @@ static void player__walk_update(void){ v3_muladds( localplayer.rb.co, localplayer.rb.v, k_rb_delta, localplayer.rb.co ); - v3_add( localplayer.rb.co, localplayer.basis[1], mtx[3] ); + v3_add( localplayer.rb.co, (v3f){0,1,0}, mtx[3] ); vg_line_capsule( mtx, w->collider.radius, w->collider.height, VG__GREEN ); /* @@ -612,7 +640,7 @@ static void player__walk_update(void){ localplayer.rb.co[1] -= w->collider.radius; rb_update_transform( &localplayer.rb ); - v3_add( localplayer.rb.co, localplayer.basis[1], mtx[3] ); + v3_add( localplayer.rb.co, (v3f){0,1,0}, mtx[3] ); vg_line_capsule( mtx, w->collider.radius, w->collider.height, VG__RED); } } @@ -638,7 +666,7 @@ static void player__walk_post_update(void){ m4x3f mtx; m3x3_copy( localplayer.rb.to_world, mtx ); - v3_add( localplayer.rb.co, localplayer.basis[1], mtx[3] ); + v3_add( localplayer.rb.co, (v3f){0,1,0}, mtx[3] ); float substep = vg.time_fixed_extrapolate; v3_muladds( mtx[3], localplayer.rb.v, k_rb_delta*substep, mtx[3] ); @@ -647,15 +675,9 @@ static void player__walk_post_update(void){ /* Calculate header */ v3f v; - if( player_xyspeed2() > 0.1f*0.1f ) - { - v3f v_xy; - m3x3_mulv( localplayer.invbasis, localplayer.rb.v, v_xy ); - float a = atan2f( v_xy[0], v_xy[2] ); - + if( player_xyspeed2() > 0.1f*0.1f ){ + float a = atan2f( localplayer.rb.v[0], localplayer.rb.v[2] ); q_axis_angle( localplayer.rb.q, (v3f){0.0f,1.0f,0.0f}, a ); - q_mul( localplayer.qbasis, localplayer.rb.q, localplayer.rb.q ); - q_normalize( localplayer.rb.q ); } vg_line_point( w->state.drop_in_target, 0.1f, VG__GREEN ); @@ -673,12 +695,10 @@ static void player__walk_post_update(void){ p1[0] = sinf( a ); p1[1] = 0.0f; p1[2] = cosf( a ); - m3x3_mulv( localplayer.basis, p1, p1 ); v3_add( localplayer.rb.co, p1, p1 ); vg_line( localplayer.rb.co, p1, VG__PINK ); - int walk_phase = 0; if( vg_fractf(w->state.walk_timer) > 0.5f ) walk_phase = 1; @@ -746,16 +766,35 @@ static void player__walk_animate(void){ w->state.walk_timer = 0.0f; animator->walk_timer = w->state.walk_timer; - if( !localplayer.immobile ) - rb_extrapolate( &localplayer.rb, animator->root_co, animator->root_q ); - else{ + + if( localplayer.immobile || (w->state.outro_type == k_walk_outro_drop_in) ){ v3_copy( localplayer.rb.co, animator->root_co ); v4_copy( localplayer.rb.q, animator->root_q ); } + else{ + rb_extrapolate( &localplayer.rb, animator->root_co, animator->root_q ); + } f32 walk_yaw = player_get_heading_yaw(); + + /* sitting */ + animator->sit_t = w->state.sit_t; + + { + f32 head_yaw = localplayer.angles[0] + VG_PIf, + y = vg_angle_diff( head_yaw, -walk_yaw ), + p = vg_clampf( localplayer.angles[1], + -k_sit_pitch_limit, k_sit_pitch_limit ); + + if( fabsf(y) > k_sit_yaw_limit ){ + y = 0.0f; + p = 0.0f; + } + animator->yaw = vg_lerpf( animator->yaw, y, vg.time_delta*2.0f ); + animator->pitch = vg_lerpf( animator->pitch, p, vg.time_delta*2.8f ); + } + if( w->state.outro_type ){ - struct player_avatar *av = localplayer.playeravatar; struct skeleton_anim *anim = player_walk_outro_anim( w->state.outro_type ); f32 outro_length = (f32)anim->length / anim->rate, @@ -778,6 +817,15 @@ static void player__walk_animate(void){ v3_lerp( w->state.drop_in_start, w->state.drop_in_target, step_t, localplayer.rb.co ); + v3_copy( localplayer.rb.co, animator->root_co ); + + /* for the camera purposes only */ + v3f init_velocity; + player_walk_drop_in_vector( init_velocity ); + v3_muls( init_velocity, dop_t, localplayer.rb.v ); + v3_copy( localplayer.rb.v, + localplayer.cam_control.cam_velocity_smooth ); + q_axis_angle( animator->root_q, (v3f){0.0f,1.0f,0.0f}, walk_yaw + VG_PIf ); @@ -785,15 +833,22 @@ static void player__walk_animate(void){ /* the drop in bit */ if( step_t >= 1.0f ){ + v3f final_co; v4f final_q; - player_walk_drop_in_overhang_transform( dop_t, localplayer.rb.co, - final_q ); + player_walk_drop_in_overhang_transform( dop_t, final_co, final_q ); + q_mul( final_q, animator->root_q, animator->root_q ); + v3_copy( final_co, animator->root_co ); + v4_copy( animator->root_q, localplayer.rb.q ); + rb_update_transform( &localplayer.rb ); + v3_muladds( animator->root_co, localplayer.rb.to_world[1], -0.1f*dop_t, animator->root_co ); + v3_copy( animator->root_co, localplayer.rb.co ); } + return; } else{ @@ -803,15 +858,12 @@ static void player__walk_animate(void){ } q_axis_angle( animator->root_q, (v3f){0.0f,1.0f,0.0f}, walk_yaw + VG_PIf ); - q_mul( localplayer.qbasis, animator->root_q, animator->root_q ); - q_normalize( animator->root_q ); } static void player__walk_pose( void *_animator, player_pose *pose ){ struct player_walk *w = &player_walk; struct player_walk_animator *animator = _animator; - struct skeleton *sk = &localplayer.playeravatar->sk; - struct player_avatar *av = localplayer.playeravatar; + struct skeleton *sk = &localplayer.skeleton; v3_copy( animator->root_co, pose->root_co ); v4_copy( animator->root_q, pose->root_q ); @@ -839,8 +891,35 @@ static void player__walk_pose( void *_animator, player_pose *pose ){ skeleton_sample_anim( sk, w->anim_jump, vg.time*0.6f, bpose ); skeleton_lerp_pose( sk, apose, bpose, animator->fly, apose ); + /* sit */ + if( animator->sit_t > 0.0f ){ + f32 sit_norm = (f32)(w->anim_sit->length-1)/30.0f, + st = vg_minf( 1.0f, animator->sit_t ); + skeleton_sample_anim( sk, w->anim_sit, st*sit_norm, bpose ); + + v4f qy,qp; + f32 *qh = bpose[localplayer.id_head-1].q; + q_axis_angle( qy, (v3f){0.0f,1.0f,0.0f}, animator->yaw*0.5f*st ); + q_axis_angle( qp, (v3f){0.0f,0.0f,1.0f}, animator->pitch*st ); + q_mul( qy, qh, qh ); + q_mul( qh, qp, qh ); + q_normalize( qh ); + + qh = bpose[localplayer.id_chest-1].q; + q_axis_angle( qy, (v3f){0.0f,1.0f,0.0f}, animator->yaw*0.5f*st ); + q_mul( qy, qh, qh ); + q_normalize( qh ); + + skeleton_lerp_pose( sk, apose, bpose, vg_minf(1.0f,st*10.0f), apose ); + } + if( animator->outro_type ){ struct skeleton_anim *anim = player_walk_outro_anim(animator->outro_type); + + if( !anim ){ + skeleton_copy_pose( sk, apose, pose->keyframes ); + return; + } f32 outro_length = (f32)anim->length / anim->rate, outro_time = animator->outro_t*outro_length; @@ -858,9 +937,10 @@ static void player__walk_pose( void *_animator, player_pose *pose ){ v3f anchored_pos; m4x3_mulv( inverse, animator->foot_anchor, anchored_pos ); - v3_lerp( pose->keyframes[ av->id_ik_foot_r-1 ].co, anchored_pos, + v3_lerp( pose->keyframes[ localplayer.id_ik_foot_r-1 ].co, + anchored_pos, 1.0f-animator->commit_t, - pose->keyframes[ av->id_ik_foot_r-1 ].co ); + pose->keyframes[ localplayer.id_ik_foot_r-1 ].co ); } } else @@ -872,7 +952,6 @@ static void player__walk_post_animate(void){ * Camera */ struct player_walk *w = &player_walk; - struct player_avatar *av = localplayer.playeravatar; if( w->state.outro_type ){ struct skeleton_anim *anim = player_walk_outro_anim(w->state.outro_type); @@ -899,7 +978,9 @@ static void player__walk_im_gui(void){ (const char *[]){ "k_walk_activity_air", "k_walk_activity_ground", "k_walk_activity_sleep", - "k_walk_activity_lockedmove" } + "k_walk_activity_lockedmove", + "k_walk_activity_sit", + "k_walk_activity_sit_up" } [w->state.activity] ); player__debugtext( 1, "surface: %s\n", (const char *[]){ "concrete", @@ -921,8 +1002,7 @@ static void player__walk_im_gui(void){ static void player__walk_bind(void){ struct player_walk *w = &player_walk; - struct player_avatar *av = localplayer.playeravatar; - struct skeleton *sk = &av->sk; + struct skeleton *sk = &localplayer.skeleton; w->anim_idle = skeleton_get_anim( sk, "idle_cycle+y" ); w->anim_walk = skeleton_get_anim( sk, "walk+y" ); @@ -931,6 +1011,7 @@ static void player__walk_bind(void){ w->anim_jump_to_air = skeleton_get_anim( sk, "jump_to_air" ); w->anim_drop_in = skeleton_get_anim( sk, "drop_in" ); w->anim_intro = skeleton_get_anim( sk, "into_skate" ); + w->anim_sit = skeleton_get_anim( sk, "sit" ); } static void player__walk_transition(void){ @@ -945,21 +1026,61 @@ static void player__walk_transition(void){ v3f fwd = { 0.0f, 0.0f, 1.0f }; q_mulv( localplayer.rb.q, fwd, fwd ); - m3x3_mulv( localplayer.invbasis, fwd, fwd ); - q_axis_angle( localplayer.rb.q, (v3f){0.0f,1.0f,0.0f}, atan2f(fwd[0], fwd[2]) ); - q_mul( localplayer.qbasis, localplayer.rb.q, localplayer.rb.q ); - q_normalize( localplayer.rb.q ); rb_update_transform( &localplayer.rb ); } -static void player__walk_reset( ent_spawn *rp ){ +static void player__walk_reset(void){ struct player_walk *w = &player_walk; w->state.activity = k_walk_activity_air; w->state.outro_type = k_walk_outro_none; w->state.outro_start_time = 0.0; + + v3f fwd = { 0.0f, 0.0f, 1.0f }; + q_mulv( localplayer.rb.q, fwd, fwd ); + q_axis_angle( localplayer.rb.q, (v3f){0.0f,1.0f,0.0f}, + atan2f(fwd[0], fwd[2]) ); + + rb_update_transform( &localplayer.rb ); } +static void player__walk_animator_exchange( bitpack_ctx *ctx, void *data ){ + struct player_walk_animator *animator = data; + + bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->root_co ); + bitpack_qquat( ctx, animator->root_q ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->fly ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->run ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->walk ); + bitpack_qf32( ctx, 16, 0.0f, 120.0f, &animator->walk_timer ); + + for( int i=0; i<1; i++ ){ /* without this you get a warning from gcc. lol */ + bitpack_bytes( ctx, 8, &animator->outro_type ); + if( animator->outro_type ){ + bitpack_bytes( ctx, sizeof(animator->foot_anchor), + animator->foot_anchor ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->outro_t ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->commit_t ); + } + } + + u32 code = bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->sit_t ); + if( code ){ + bitpack_qf32( ctx, 8, -k_sit_yaw_limit, k_sit_yaw_limit, &animator->yaw ); + bitpack_qf32( ctx, 8, -k_sit_pitch_limit, k_sit_pitch_limit, + &animator->pitch ); + } +} + +static void player__walk_sfx_oneshot( u8 id, v3f pos, f32 volume ){ + audio_lock(); + + if( id == k_player_walk_soundeffect_splash ){ + audio_oneshot_3d( &audio_splash, pos, 40.0f, 1.0f ); + } + + audio_unlock(); +} #endif /* PLAYER_DEVICE_WALK_H */