X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_skate.c;h=1f99991b1846841b16540ecef2a2e1cd7df8fd49;hb=7398f8a24aaba107bafb5ab5c55141b94e10027b;hp=3a78f4f9b3fed274b95417904edb590a05bba123;hpb=9d5997f1e611b66c7220f7eb388f427032d8da79;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_skate.c b/player_skate.c index 3a78f4f..1f99991 100644 --- a/player_skate.c +++ b/player_skate.c @@ -11,6 +11,8 @@ VG_STATIC void player__skate_bind( player_instance *player ) struct skeleton *sk = &av->sk; rb_update_transform( &player->rb ); + s->anim_grind = skeleton_get_anim( sk, "pose_grind" ); + s->anim_grind_jump = skeleton_get_anim( sk, "pose_grind_jump" ); s->anim_stand = skeleton_get_anim( sk, "pose_stand" ); s->anim_highg = skeleton_get_anim( sk, "pose_highg" ); s->anim_air = skeleton_get_anim( sk, "pose_air" ); @@ -405,6 +407,19 @@ void player__approximate_best_trajectory( player_instance *player ) int grind_located = 0; float grind_located_gravity = k_gravity; + + v3f launch_v_bounds[2]; + + for( int i=0; i<2; i++ ){ + v3_copy( player->rb.v, launch_v_bounds[i] ); + float ang = (float[]){ angle_begin, angle_end }[ i ]; + ang *= 0.15f; + + v4f qbias; + q_axis_angle( qbias, axis, ang ); + q_mulv( qbias, launch_v_bounds[i], launch_v_bounds[i] ); + } + for( int m=0;m<=30; m++ ){ jump_info *inf = &s->possible_jumps[ s->possible_jump_count ++ ]; reset_jump_info( inf ); @@ -444,35 +459,59 @@ void player__approximate_best_trajectory( player_instance *player ) v3_add( launch_co, co1, co1 ); float launch_vy = v3_dot( launch_v,basis[1] ); - if( !grind_located && (launch_vy - gravity*t < 0.0f) ){ - v3f closest; + + int search_for_grind = 1; + if( grind_located ) search_for_grind = 0; + if( launch_vy - gravity*t > 0.0f ) search_for_grind = 0; + + /* TODO Cleanup */ + + v3f closest; + if( search_for_grind ){ if( bh_closest_point( world->geo_bh, co1, closest, 1.0f ) != -1 ){ - v3f ve; - v3_copy( launch_v, ve ); - v3_muladds( ve, basis[1], -gravity * t, ve ); + v3f bound[2]; - if( skate_grind_scansq( player, closest, ve, 0.5f, &grind ) ){ - /* check alignment */ - v2f v0 = { v3_dot( ve, basis[0] ), - v3_dot( ve, basis[2] ) }, - v1 = { v3_dot( grind.dir, basis[0] ), - v3_dot( grind.dir, basis[2] ) }; + for( int j=0; j<2; j++ ){ + v3_muls( launch_v_bounds[j], t, bound[j] ); + v3_muladds( bound[j], basis[1], -0.5f*gravity*t*t, bound[j] ); + v3_add( launch_co, bound[j], bound[j] ); + } - v2_normalize( v0 ); - v2_normalize( v1 ); + float minh = vg_minf( bound[0][1], bound[1][1] ), + maxh = vg_maxf( bound[0][1], bound[1][1] ); - float a = v2_dot( v0, v1 ); + vg_info( "%f [%f:%f]\n", closest[1], minh, maxh ); -#if 0 - if( a >= cosf( VG_PIf * /*0.185f*/ 0.02f ) ){ -#endif - grind_located = 1; - grind_located_gravity = inf->gravity; + if( (closest[1] < minh) || (closest[1] > maxh) ){ + search_for_grind = 0; + } + } + else + search_for_grind = 0; + } - vg_success( "Grind located\n" ); -#if 0 - } -#endif + if( search_for_grind ){ + v3f ve; + v3_copy( launch_v, ve ); + v3_muladds( ve, basis[1], -gravity * t, ve ); + + if( skate_grind_scansq( player, closest, ve, 0.5f, &grind ) ){ + /* check alignment */ + v2f v0 = { v3_dot( ve, basis[0] ), + v3_dot( ve, basis[2] ) }, + v1 = { v3_dot( grind.dir, basis[0] ), + v3_dot( grind.dir, basis[2] ) }; + + v2_normalize( v0 ); + v2_normalize( v1 ); + + float a = v2_dot( v0, v1 ); + + if( a >= cosf( VG_PIf * 0.185f ) ){ + grind_located = 1; + grind_located_gravity = inf->gravity; + + vg_success( "Grind located\n" ); } } } @@ -887,8 +926,11 @@ VG_STATIC void skate_apply_friction_model( player_instance *player ) s->state.slip = slip; s->state.reverse = -vg_signf(vel[2]); - vel[0] += vg_cfrictf( vel[0], k_friction_lat * k_rb_delta ); - vel[2] += vg_cfrictf( vel[2], k_friction_resistance * k_rb_delta ); + float S = (float)s->grind_cooldown * (1.0f/20.0f); + S = vg_minf( S, 1.0f ); + + vel[0] += vg_cfrictf( vel[0], S * k_friction_lat * k_rb_delta ); + vel[2] += vg_cfrictf( vel[2], S * k_friction_resistance * k_rb_delta ); /* Pushing additive force */ @@ -1610,7 +1652,6 @@ VG_STATIC void skate_5050_apply( player_instance *player, v3_normalize( axis ); v3_cross( axis, inf_avg.dir, inf_avg.n ); - skate_grind_decay( player, &inf_avg, 1.0f ); @@ -1778,7 +1819,7 @@ VG_STATIC void skate_boardslide_apply( player_instance *player, intersection ); v3_copy( intersection, s->weight_distribution ); - skate_grind_decay( player, inf, 0.1f ); + skate_grind_decay( player, inf, 0.0125f ); skate_grind_friction( player, inf, 0.25f ); /* direction alignment */ @@ -1790,6 +1831,10 @@ VG_STATIC void skate_boardslide_apply( player_instance *player, m3x3_mulv( player->rb.to_world, dir, dir ); m3x3_mulv( player->rb.to_world, perp, perp ); + v4f qbalance; + q_axis_angle( qbalance, dir, local_co[0]*k_grind_balance ); + q_mulv( qbalance, perp, perp ); + rb_effect_spring_target_vector( &player->rb, player->rb.to_world[0], dir, k_grind_spring, k_grind_dampener, @@ -1941,24 +1986,20 @@ VG_STATIC enum skate_activity skate_availible_grind( player_instance *player ) } , new_activity = table[ res_slide << 2 | res_back50 << 1 | res_front50 ]; - if( new_activity == k_skate_activity_undefined ) - { + if( new_activity == k_skate_activity_undefined ){ if( s->state.activity >= k_skate_activity_grind_any ) s->grind_cooldown = 5; } - else if( new_activity == k_skate_activity_grind_boardslide ) - { + else if( new_activity == k_skate_activity_grind_boardslide ){ skate_boardslide_apply( player, &inf_slide ); } - else if( new_activity == k_skate_activity_grind_back50 ) - { + else if( new_activity == k_skate_activity_grind_back50 ){ if( s->state.activity != k_skate_activity_grind_back50 ) skate_store_grind_vec( player, &inf_back50 ); skate_grind_truck_apply( player, 1.0f, &inf_back50, 1.0f ); } - else if( new_activity == k_skate_activity_grind_front50 ) - { + else if( new_activity == k_skate_activity_grind_front50 ){ if( s->state.activity != k_skate_activity_grind_front50 ) skate_store_grind_vec( player, &inf_front50 ); @@ -2127,8 +2168,7 @@ begin_collision:; v4f future_q; v3_muladds( player->rb.co, player->rb.v, s->substep, future_co ); - if( v3_length2( player->rb.w ) > 0.0f ) - { + if( v3_length2( player->rb.w ) > 0.0f ){ v4f rotation; v3f axis; v3_copy( player->rb.w, axis ); @@ -2564,6 +2604,9 @@ VG_STATIC void player__skate_animate( player_instance *player, fly = iair? 1.0f: 0.0f, wdist= s->weight_distribution[2] / k_board_length; + if( s->state.activity >= k_skate_activity_grind_any ) + wdist = 0.0f; + s->blend_z = vg_lerpf( s->blend_z, dirz, 2.4f*vg.time_delta ); s->blend_x = vg_lerpf( s->blend_x, dirx, 0.6f*vg.time_delta ); s->blend_fly = vg_lerpf( s->blend_fly, fly, 3.4f*vg.time_delta ); @@ -2664,6 +2707,31 @@ VG_STATIC void player__skate_animate( player_instance *player, skeleton_lerp_pose( sk, ground_pose, air_pose, s->blend_fly, dest->pose ); + + mdl_keyframe grind_pose[32]; + { + /* TODO: factor balance into this sampler */ + float grind_frame = 0.5f; + + if( s->state.activity == k_skate_activity_grind_front50 ){ + grind_frame = 0.0f; + } else if( s->state.activity == k_skate_activity_grind_back50 ){ + grind_frame = 1.0f; + } + + float grind=s->state.activity >= k_skate_activity_grind_any? 1.0f: 0.0f; + s->blend_grind = vg_lerpf( s->blend_grind, grind, 5.0f*vg.time_delta ); + s->blend_grind_balance=vg_lerpf( s->blend_grind_balance, + grind_frame, 5.0f*vg.time_delta ); + + grind_frame = s->blend_grind_balance * (15.0f/30.0f); + + skeleton_sample_anim( sk, s->anim_grind, grind_frame, apose ); + skeleton_sample_anim( sk, s->anim_grind_jump, grind_frame, bpose ); + skeleton_lerp_pose( sk, apose, bpose, s->blend_jump, grind_pose ); + } + skeleton_lerp_pose( sk, dest->pose, grind_pose, s->blend_grind, dest->pose ); + float add_grab_mod = 1.0f - s->blend_fly; /* additive effects */ @@ -2789,9 +2857,10 @@ VG_STATIC void player__skate_animate( player_instance *player, float jump_t = vg.time-s->state.jump_time; - float k=10.0f; + float k=17.0f; float h = k*jump_t; float extra = h*exp(1.0-h) * (s->state.jump_dir?1.0f:-1.0f); + extra *= s->state.slap * 4.0f; q_axis_angle( qyaw, (v3f){0.0f,1.0f,0.0f}, euler[0] * 0.5f ); q_axis_angle( qpitch, (v3f){1.0f,0.0f,0.0f}, euler[1] + extra );