From 7398f8a24aaba107bafb5ab5c55141b94e10027b Mon Sep 17 00:00:00 2001 From: hgn Date: Wed, 29 Mar 2023 19:48:06 +0100 Subject: [PATCH] YEAH --- common.h | 5 +- maps_src/mp_gridmap.mdl | Bin 670016 -> 703008 bytes models_src/ch_new.mdl | Bin 863080 -> 897936 bytes player_skate.c | 145 +++++++++++++++++++++++++++++----------- player_skate.h | 4 +- rigidbody.h | 3 +- 6 files changed, 116 insertions(+), 41 deletions(-) diff --git a/common.h b/common.h index fbcb7cf..4f854a3 100644 --- a/common.h +++ b/common.h @@ -86,7 +86,9 @@ VG_STATIC float k_board_length = 0.45f, k_board_width = 0.13f, k_board_end_radius = 0.1f, - k_board_radius = 0.14f; /* 0.07 */ + k_board_radius = 0.14f, /* 0.07 */ + + k_grind_balance = -40.0f; VG_STATIC float k_walkspeed = 10.0f, @@ -141,6 +143,7 @@ VG_STATIC void common_var_temp(void) VG_VAR_F32( k_grind_axel_min_vel ); VG_VAR_F32( k_grind_axel_max_angle ); VG_VAR_F32( k_grind_max_friction ); + VG_VAR_F32( k_grind_balance ); VG_VAR_F32( k_walkspeed ); VG_VAR_F32( k_stopspeed ); diff --git a/maps_src/mp_gridmap.mdl b/maps_src/mp_gridmap.mdl index cd1b8990e45d0f59711ec5dde2195cadcdda3392..59f176c26c80ebc4ad03f81612eee11ab2b4524a 100644 GIT binary patch delta 36456 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 a#>(A4|NA37JLGGbnRYR!e`b1aLD@gzMjh<{ delta 17071 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 delta 615 zcmYk3KS%;$7{;IP)HJg{RAhEU|Ac}pq{NE;kW)e5tHP*Zp~)ZpOI zBn5#(5e*FvwK+94xYZPn4Gle4XWR$R-S@lqz2|+u_shNqKVAb_ug4_;0zf*GiY0f_ z-2JUXZC)0)+NRu_wf$wxF_4JFw-Vt@G!+ZS^}LFv$)c*=$f8?&k!PRV0XILl8L8o9 zjM=fhBzd|MSXlr@jM#2;e>)XUM2S!^#=ViaAJzz_W_qC zJ{th8O!*r_z_p31!@#59Ksk; 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 ); diff --git a/player_skate.h b/player_skate.h index 1c23b58..72eb94e 100644 --- a/player_skate.h +++ b/player_skate.h @@ -81,7 +81,7 @@ struct player_skate /* animation */ struct skeleton_anim *anim_stand, *anim_highg, *anim_slide, - *anim_air, + *anim_air, *anim_grind, *anim_grind_jump, *anim_push, *anim_push_reverse, *anim_ollie, *anim_ollie_reverse, *anim_grabs, *anim_stop; @@ -93,6 +93,8 @@ struct player_skate blend_z, blend_x, blend_fly, + blend_grind, + blend_grind_balance, blend_stand, blend_push, blend_jump, diff --git a/rigidbody.h b/rigidbody.h index fe81975..dfacf36 100644 --- a/rigidbody.h +++ b/rigidbody.h @@ -2829,7 +2829,8 @@ VG_STATIC void rb_effect_spring_target_vector( rigidbody *rba, v3f ra, v3f rt, float spring, float dampening, float timestep ) { - float a = acosf( vg_clampf( v3_dot( rt, ra ), -1.0f, 1.0f ) ); + float d = v3_dot( rt, ra ); + float a = vg_signf( d ) * acosf( vg_clampf( d, -1.0f, 1.0f ) ); v3f axis; v3_cross( rt, ra, axis ); -- 2.25.1