X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_device_skate.h;fp=player_device_skate.h;h=d657b4a20440784e70d811d9ff0f9f96cf3261dc;hb=5430d708f058626a6c8fed7dd2aa8ba5f0a06c84;hp=5ae2a9bb0f30d95faa662d2c593c3f304fb0b224;hpb=2383f834f7c7890b12fd4fee9387f4cd3ca3b1e0;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_device_skate.h b/player_device_skate.h index 5ae2a9b..d657b4a 100644 --- a/player_device_skate.h +++ b/player_device_skate.h @@ -27,8 +27,13 @@ struct player_device_skate reverse, slip; + v3f flip_axis; + float flip_time, + flip_rate; + m3x3f velocity_bias, velocity_bias_pstep; + v3f apex; int lift_frames; @@ -47,9 +52,9 @@ struct player_device_skate v3f prev_pos; - - v3f vl, /* 1st */ - posl; /* 3rd */ + /* FIXME: Sensible names */ + v3f vl, /* 1st */ + posl, dirl; /* 3rd */ } state, state_gate_storage; @@ -58,8 +63,10 @@ struct player_device_skate { v3f log[50]; v3f n; + v3f apex; u32 log_length; - float score; + float score, + land_dist; enum prediction_type { @@ -281,10 +288,12 @@ VG_STATIC void skate_score_biased_path( v3f co, v3f v, m3x3f vr, struct grind_edge *best_grind = NULL; float closest_grind = INFINITY; - float grind_score = INFINITY, - air_score = INFINITY; + float grind_score = INFINITY, + air_score = INFINITY, + time_to_impact = 0.0f; prediction->log_length = 0; + v3_copy( pco, prediction->apex ); for( int i=0; ilog); i++ ) { @@ -294,6 +303,9 @@ VG_STATIC void skate_score_biased_path( v3f co, v3f v, m3x3f vr, m3x3_mulv( vr, pv, pv ); v3_muladds( pco, pv, pstep, pco ); + + if( pco[1] > prediction->apex[1] ) + v3_copy( pco, prediction->apex ); v3f vdir; @@ -334,9 +346,11 @@ VG_STATIC void skate_score_biased_path( v3f co, v3f v, m3x3f vr, air_score *= 0.1f; v3_lerp( pco1, pco, t1, prediction->log[ prediction->log_length ++ ] ); + time_to_impact += t1 * pstep; break; } + time_to_impact += pstep; v3_copy( pco, prediction->log[ prediction->log_length ++ ] ); } @@ -355,6 +369,8 @@ VG_STATIC void skate_score_biased_path( v3f co, v3f v, m3x3f vr, prediction->score = INFINITY; prediction->type = k_prediction_none; } + + prediction->land_dist = time_to_impact; } VG_STATIC @@ -375,6 +391,9 @@ void player_approximate_best_trajectory( player_interface *player, min_score = INFINITY, max_score = -INFINITY; + v3_zero( s->state.apex ); + s->land_dist = 0.0f; + /* * Search a broad selection of futures */ @@ -398,6 +417,8 @@ void player_approximate_best_trajectory( player_interface *player, { min_score = p->score; best_vmod = vmod; + s->land_dist = p->land_dist; + v3_copy( p->apex, s->state.apex ); } if( p->score > max_score ) @@ -435,6 +456,24 @@ void player_approximate_best_trajectory( player_interface *player, p->colour <<= 8; p->colour |= 0xff000000; } + + + v2f steer = { player->input_js1h->axis.value, + player->input_js1v->axis.value }; + v2_normalize_clamp( steer ); + + if( (fabsf(steer[1]) > 0.5f) && (s->land_dist >= 1.0f) ) + { + s->state.flip_rate = (1.0f/s->land_dist) * vg_signf(steer[1]) * + s->state.reverse ; + s->state.flip_time = 0.0f; + v3_copy( player->rb.to_world[0], s->state.flip_axis ); + } + else + { + s->state.flip_rate = 0.0f; + v3_zero( s->state.flip_axis ); + } } /* @@ -702,8 +741,8 @@ VG_STATIC void skate_apply_interface_model( player_interface *player, v3f spring0, spring1; skate_get_board_points( player, s, spring1, spring0 ); - int spring_hit0 = skate_simulate_spring( player, s, spring0 ), - spring_hit1 = skate_simulate_spring( player, s, spring1 ); + int spring_hit0 = 0, //skate_simulate_spring( player, s, spring0 ), + spring_hit1 = 0; //skate_simulate_spring( player, s, spring1 ); v3f animavg, animdelta; v3_add( spring0, spring1, animavg ); @@ -720,7 +759,7 @@ VG_STATIC void skate_apply_interface_model( player_interface *player, float angle = -atan2f( dy, dx ); q_axis_angle( s->board_rotation, (v3f){1.0f,0.0f,0.0f}, angle ); - int lift_frames_limit = 1; + int lift_frames_limit = 6; /* Surface connection */ if( len == 0 && !(spring_hit0 && spring_hit1) ) @@ -913,10 +952,8 @@ VG_STATIC void skate_apply_jump_model( player_interface *player, float maxspin = k_steer_air * k_rb_delta * k_spin_boost; s->state.steery_s = -steer[0] * maxspin; - s->state.steerx_s = steer[1] * s->state.reverse * maxspin; s->state.steerx = s->state.steerx_s; - s->state.steery = s->state.steery_s; - + /* FIXME audio events */ #if 0 audio_lock(); @@ -1064,7 +1101,16 @@ VG_STATIC void skate_integrate( player_interface *player, v3_muladds( player->rb.v, gravity, k_rb_delta, player->rb.v ); v3_muladds( player->rb.co, player->rb.v, k_rb_delta, player->rb.co ); - v3_lerp( player->rb.w, (v3f){0.0f,0.0f,0.0f}, 0.125f*0.5f, player->rb.w ); + float decay_rate = 0.5f*0.125f; + + if( s->state.activity == k_skate_activity_air ) + { + float dist = 1.0f-(s->land_dist/4.0f); + decay_rate = 0.5f * vg_maxf( dist*dist, 0.0f ); + } + + v3_lerp( player->rb.w, (v3f){0.0f,0.0f,0.0f}, decay_rate, player->rb.w ); + if( v3_length2( player->rb.w ) > 0.0f ) { v4f rotation; @@ -1079,7 +1125,7 @@ VG_STATIC void skate_integrate( player_interface *player, /* integrate steering velocities */ v4f rotate; - float l = (s->state.activity == k_skate_activity_air)? 0.04f: 0.3f; + float l = (s->state.activity == k_skate_activity_air)? 0.04f: 0.24f; s->state.steery_s = vg_lerpf( s->state.steery_s, s->state.steery, l ); s->state.steerx_s = vg_lerpf( s->state.steerx_s, s->state.steerx, l ); @@ -1099,6 +1145,7 @@ VG_STATIC void skate_integrate( player_interface *player, v3_copy( player.rb.v, s->phys.v_prev ); #endif + s->state.flip_time += s->state.flip_rate * k_rb_delta; rb_update_transform( &player->rb ); } @@ -1200,8 +1247,11 @@ VG_STATIC void player_skate_update( player_device *dev, m4x3_mulv( gate->transport, s->state.cog, s->state.cog ); m3x3_mulv( gate->transport, s->state.cog_v, s->state.cog_v ); m3x3_mulv( gate->transport, s->state.throw_v, s->state.throw_v ); + + /*camera */ m4x3_mulv( gate->transport, s->state.posl, s->state.posl ); m3x3_mulv( gate->transport, s->state.vl, s->state.vl ); + m3x3_mulv( gate->transport, s->state.dirl, s->state.dirl ); #if 0 mixedcam_transport( &s->state.cam, gate ); @@ -1240,6 +1290,8 @@ VG_STATIC void player_skate_ui( player_device *dev, player_interface *player ) player_debugtext( 1, "steer_s: %5.2f %5.2f [%.2f %.2f]\n", s->state.steerx_s, s->state.steery_s, k_steer_ground, k_steer_air ); + player_debugtext( 1, "flip: %.4f %.4f\n", s->state.flip_rate, + s->state.flip_time ); } VG_STATIC void player_skate_animate( player_device *dev, @@ -1470,6 +1522,31 @@ VG_STATIC void player_skate_animate( player_device *dev, q_mul( dev->pose_root_q, qresidual, dev->pose_root_q ); q_normalize( dev->pose_root_q ); + v4f qflip; + if( (s->state.activity == k_skate_activity_air) && + (fabsf(s->state.flip_rate) > 0.01f) ) + { + float angle = vg_clampf( s->state.flip_time, -1.0f, 1.0f ) * VG_TAUf, + distm = s->land_dist * fabsf(s->state.flip_rate) * 3.0f, + blend = vg_clampf( 1.0f-distm, 0.0f, 1.0f ); + + angle = vg_lerpf( angle, vg_signf(s->state.flip_rate) * VG_TAUf, blend ); + + q_axis_angle( qflip, s->state.flip_axis, angle ); + q_mul( qflip, dev->pose_root_q, dev->pose_root_q ); + q_normalize( dev->pose_root_q ); + + v3f rotation_point, rco; + v3_muladds( player->rb.co, player->rb.to_world[1], 0.5f, rotation_point ); + v3_sub( dev->pose_root_co, rotation_point, rco ); + + /* FIXME: q_mul v3 */ + m3x3f TEMP; + q_m3x3( qflip, TEMP ); + m3x3_mulv( TEMP, rco, rco ); + v3_add( rco, rotation_point, dev->pose_root_co ); + } + #if 0 if( cl_thirdperson ) { @@ -1554,12 +1631,17 @@ VG_STATIC void skate_camera_thirdperson( player_device *dev, else v3_normalize( dir ); + if( s->state.activity == k_skate_activity_air ) + dir[1] *= vg_maxf( 0.0f, 1.0f - (s->land_dist/2.0f) ); + dir[1] *= 0.0f; + v3_muladds( origin, dir, -2.0f, target ); - v3_lerp( s->state.posl, target, vg.frame_delta * 12.0f, s->state.posl ); + + v3_lerp( s->state.posl, target, vg.frame_delta * 15.0f, s->state.posl ); + v3_lerp( s->state.dirl, dir, 18.0f*vg.time_delta, s->state.dirl ); v3_copy( s->state.posl, dev->cam_3rd.pos ); - skate_camera_vector_look( &dev->cam_3rd, dir, 1.0f, 0.0f ); - dev->cam_3rd.fov = 100.0f; + skate_camera_vector_look( &dev->cam_3rd, s->state.dirl, 1.0f, 0.2f ); } VG_STATIC void player_skate_post_animate( player_device *dev, @@ -1626,6 +1708,10 @@ VG_STATIC int player_skate_event( player_device *dev, player_interface *player, atan2f( inf->dir[0], inf->dir[2] ) ); v3_copy( player->cam.pos, s->state.posl ); + m3x3f temp; + euler_m3x3( player->cam.angles, temp ); + v3_muls( temp[2], -1.0f, s->state.dirl ); + rb_update_transform( &player->rb ); v3_muladds( player->rb.co, player->rb.to_world[1], 1.0f, s->state.cog ); v3_copy( player->rb.v, s->state.cog_v ); @@ -1634,6 +1720,27 @@ VG_STATIC int player_skate_event( player_device *dev, player_interface *player, { player_skate_update( dev, player ); } + else if( ev == k_player_device_event_post_update ) + { + for( int i=0; iprediction_count; i++ ) + { + struct land_prediction *p = &s->predictions[i]; + + for( int j=0; jlog_length - 1; j ++ ) + vg_line( p->log[j], p->log[j+1], p->colour ); + + vg_line_cross( p->log[p->log_length-1], p->colour, 0.25f ); + + v3f p1; + v3_add( p->log[p->log_length-1], p->n, p1 ); + vg_line( p->log[p->log_length-1], p1, 0xffffffff ); + + vg_line_pt3( p->apex, 0.02f, 0xffffffff ); + } + + vg_line_pt3( s->state.apex, 0.200f, 0xff0000ff ); + vg_line_pt3( s->state.apex, 0.201f, 0xff00ffff ); + } else if( ev == k_player_device_event_animate ) { player_skate_animate( dev, player );