X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_device_skate.h;h=d657b4a20440784e70d811d9ff0f9f96cf3261dc;hb=5430d708f058626a6c8fed7dd2aa8ba5f0a06c84;hp=13f6398a0b549d37f338b2b25ffd0bacb7062320;hpb=2f1dca88d325b4eebd030232c694627f5791ebce;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_device_skate.h b/player_device_skate.h index 13f6398..d657b4a 100644 --- a/player_device_skate.h +++ b/player_device_skate.h @@ -6,6 +6,7 @@ #include "player_model.h" #include "player_device_common.h" +VG_STATIC struct player_device_skate { struct @@ -26,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; @@ -46,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; @@ -57,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 { @@ -97,12 +105,14 @@ struct player_device_skate v2f wobble; float debug_normal_pressure; -}; + u32 device_id_walk; +} +localplayer_device_skate; -VG_STATIC void player_skate_bind( player_interface *player, - player_attachment *at ) +VG_STATIC void player_skate_bind( player_device *dev, + player_interface *player ) { - struct player_device_skate *s = at->storage; + struct player_device_skate *s = dev->storage; struct player_avatar *av = player->playeravatar; struct skeleton *sk = &av->sk; @@ -116,11 +126,8 @@ VG_STATIC void player_skate_bind( player_interface *player, s->anim_ollie = skeleton_get_anim( sk, "ollie" ); s->anim_ollie_reverse = skeleton_get_anim( sk, "ollie_reverse" ); s->anim_grabs = skeleton_get_anim( sk, "grabs" ); -} -VG_STATIC void player_skate_pre_update( player_interface *player, - player_attachment *at ) -{ + s->device_id_walk = player_get_device( player, "walk" ); } /* @@ -210,8 +217,9 @@ VG_STATIC struct grind_edge *skate_collect_grind_edge( v3f p0, v3f p1, return closest_edge; } -VG_STATIC int skate_grind_collide( player_interface *player, - player_attachment *at, rb_ct *contact ) +VG_STATIC int skate_grind_collide( player_device *dev, + player_interface *player, + rb_ct *contact ) { v3f p0, p1, c0, c1; v3_muladds( player->rb.co, player->rb.to_world[2], 0.5f, p0 ); @@ -280,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++ ) { @@ -293,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; @@ -333,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 ++ ] ); } @@ -354,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 @@ -374,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 */ @@ -397,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 ) @@ -434,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 ); + } } /* @@ -701,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 ); @@ -719,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) ) @@ -912,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(); @@ -1063,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; @@ -1078,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 ); @@ -1098,13 +1145,14 @@ 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 ); } -VG_STATIC void player_skate_update( player_interface *player, - player_attachment *at ) +VG_STATIC void player_skate_update( player_device *dev, + player_interface *player ) { - struct player_device_skate *s = at->storage; + struct player_device_skate *s = dev->storage; v3_copy( player->rb.co, s->state.prev_pos ); s->state.activity_prev = s->state.activity; @@ -1160,7 +1208,7 @@ VG_STATIC void player_skate_update( player_interface *player, interface_manifold = manifold; grind_manifold = manifold + interface_len; - int grind_len = skate_grind_collide( player, at, grind_manifold ); + int grind_len = skate_grind_collide( dev, player, grind_manifold ); for( int i=0; itransport, 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 ); @@ -1216,15 +1267,9 @@ VG_STATIC void player_skate_update( player_interface *player, } } -VG_STATIC void player_skate_post_update( player_interface *player, - player_attachment *at ) -{ -} - -VG_STATIC void player_skate_ui( player_interface *player, - player_attachment *at ) +VG_STATIC void player_skate_ui( player_device *dev, player_interface *player ) { - struct player_device_skate *s = at->storage; + struct player_device_skate *s = dev->storage; /* FIXME: Compression */ player_debugtext( 1, "V: %5.2f %5.2f %5.2f",player->rb.v[0], @@ -1245,12 +1290,14 @@ VG_STATIC void player_skate_ui( 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_interface *player, - player_attachment *at ) +VG_STATIC void player_skate_animate( player_device *dev, + player_interface *player ) { - struct player_device_skate *s = at->storage; + struct player_device_skate *s = dev->storage; struct player_avatar *av = player->playeravatar; struct skeleton *sk = &av->sk; @@ -1413,7 +1460,7 @@ VG_STATIC void player_skate_animate( player_interface *player, skeleton_lerp_pose( sk, apose, bpose, s->state.grabbing, air_pose ); } - skeleton_lerp_pose( sk, ground_pose, air_pose, s->blend_fly, at->pose ); + skeleton_lerp_pose( sk, ground_pose, air_pose, s->blend_fly, dev->pose ); float add_grab_mod = 1.0f - s->blend_fly; @@ -1427,13 +1474,13 @@ VG_STATIC void player_skate_animate( player_interface *player, for( int i=0; ipose[apply_to[i]-1].co[0] += offset[0]*add_grab_mod; - at->pose[apply_to[i]-1].co[2] += offset[2]*add_grab_mod; + dev->pose[apply_to[i]-1].co[0] += offset[0]*add_grab_mod; + dev->pose[apply_to[i]-1].co[2] += offset[2]*add_grab_mod; } - mdl_keyframe *kf_board = &at->pose[av->id_board-1], - *kf_foot_l = &at->pose[av->id_ik_foot_l-1], - *kf_foot_r = &at->pose[av->id_ik_foot_r-1]; + mdl_keyframe *kf_board = &dev->pose[av->id_board-1], + *kf_foot_l = &dev->pose[av->id_ik_foot_l-1], + *kf_foot_r = &dev->pose[av->id_ik_foot_r-1]; v3f bo; v3_muls( s->board_offset, add_grab_mod, bo ); @@ -1459,10 +1506,10 @@ VG_STATIC void player_skate_animate( player_interface *player, } /* transform */ - rb_extrapolate( &player->rb, at->pose_root_co, at->pose_root_q ); + rb_extrapolate( &player->rb, dev->pose_root_co, dev->pose_root_q ); - v3_muladds( at->pose_root_co, player->rb.to_world[1], -0.28f, - at->pose_root_co ); + v3_muladds( dev->pose_root_co, player->rb.to_world[1], -0.28f, + dev->pose_root_co ); v4f qresy, qresx, qresidual; m3x3f mtx_residual; @@ -1472,8 +1519,33 @@ VG_STATIC void player_skate_animate( player_interface *player, q_mul( qresy, qresx, qresidual ); q_normalize( qresidual ); - q_mul( at->pose_root_q, qresidual, at->pose_root_q ); - q_normalize( at->pose_root_q ); + 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 ) @@ -1504,18 +1576,18 @@ VG_STATIC void skate_camera_vector_look( camera *cam, v3f v, float C, float k ) cam->angles[1] = pitch; } -VG_STATIC void skate_camera_firstperson( player_interface *player, - player_attachment *at ) +VG_STATIC void skate_camera_firstperson( player_device *dev, + player_interface *player ) { - struct player_device_skate *s = at->storage; + struct player_device_skate *s = dev->storage; struct player_avatar *av = player->playeravatar; /* FIXME: viewpoint entity */ v3f vp = {-0.1f,1.8f,0.0f}; - m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, at->cam_1st.pos ); + m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, dev->cam_1st.pos ); - v3_zero( at->cam_1st.angles ); - at->cam_1st.fov = 119.0f; + v3_zero( dev->cam_1st.angles ); + dev->cam_1st.fov = 119.0f; v3f flat_dir, vel_dir, @@ -1540,13 +1612,13 @@ VG_STATIC void skate_camera_firstperson( player_interface *player, v3_lerp( flat_dir, vel_dir, vg_clampf( tti / 2.0f, 0.4f, 1.0f ), look_dir ); v3_lerp( s->state.vl, look_dir, 4.0f*vg.time_delta, s->state.vl ); - skate_camera_vector_look( &at->cam_1st, s->state.vl, 1.0f, 0.25f ); + skate_camera_vector_look( &dev->cam_1st, s->state.vl, 1.0f, 0.25f ); } -VG_STATIC void skate_camera_thirdperson( player_interface *player, - player_attachment *at ) +VG_STATIC void skate_camera_thirdperson( player_device *dev, + player_interface *player ) { - struct player_device_skate *s = at->storage; + struct player_device_skate *s = dev->storage; struct player_avatar *av = player->playeravatar; v3f origin, dir, target; @@ -1559,26 +1631,31 @@ VG_STATIC void skate_camera_thirdperson( player_interface *player, 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_copy( s->state.posl, at->cam_3rd.pos ); - skate_camera_vector_look( &at->cam_3rd, dir, 1.0f, 0.0f ); - at->cam_3rd.fov = 100.0f; + 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, s->state.dirl, 1.0f, 0.2f ); } -VG_STATIC void player_skate_post_animate( player_interface *player, - player_attachment *at ) +VG_STATIC void player_skate_post_animate( player_device *dev, + player_interface *player ) { - struct player_device_skate *s = at->storage; + struct player_device_skate *s = dev->storage; struct player_avatar *av = player->playeravatar; - v3_zero( at->cam_1st.pos ); - v3_zero( at->cam_1st.angles ); - at->cam_1st.fov = 90.0f; + v3_zero( dev->cam_1st.pos ); + v3_zero( dev->cam_1st.angles ); + dev->cam_1st.fov = 90.0f; - skate_camera_thirdperson( player, at ); - skate_camera_firstperson( player, at ); + skate_camera_thirdperson( dev, player ); + skate_camera_firstperson( dev, player ); /* FIXME: Organize this. Its int wrong fucking place */ v3f vp0 = {0.0f,0.1f, 0.6f}, @@ -1588,17 +1665,11 @@ VG_STATIC void player_skate_post_animate( player_interface *player, m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp1, TEMP_BOARD_1 ); } -VG_STATIC void player_skate_transport( player_interface *player, - player_attachment *at, - teleport_gate *gate ) -{ -} - -VG_STATIC void player_skate_reset( player_interface *player, - player_attachment *at, +VG_STATIC void player_skate_reset( player_device *dev, + player_interface *player, struct respawn_point *rp ) { - struct player_device_skate *s = at->storage; + struct player_device_skate *s = dev->storage; v3_muladds( player->rb.co, player->rb.to_world[1], 1.0f, s->state.cog ); #if 0 @@ -1606,16 +1677,93 @@ VG_STATIC void player_skate_reset( player_interface *player, #endif } +VG_STATIC int player_skate_event( player_device *dev, player_interface *player, + enum player_device_event_type ev, + void *data ) +{ + struct player_device_skate *s = dev->storage; + + if( ev == k_player_device_event_bind ) + player_skate_bind( dev, player ); + else if( ev == k_player_device_event_respawn ) + player_skate_reset( dev, player, data ); + else if( ev == k_player_device_event_pre_update ) + { + if( vg_input_button_down( player->input_use ) ) + { + struct device_transition_walk inf; + v3_copy( player->cam.angles, inf.angles ); + inf.angles[2] = 0.0f; + + player_transition_to_device( player, s->device_id_walk, &inf ); + return 1; + } + } + else if( ev == k_player_device_event_custom_transition ) + { + /* transition coming in from walking */ + struct device_transition_skateboard *inf = data; + + q_axis_angle( player->rb.q, (v3f){0.0f,1.0f,0.0f}, + 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 ); + } + else if( ev == k_player_device_event_update ) + { + 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 ); + } + else if( ev == k_player_device_event_post_animate ) + { + player_skate_post_animate( dev, player ); + } + else if( ev == k_player_device_event_debug_ui ) + { + player_skate_ui( dev, player ); + } + else + return 0; + + return 1; +} + VG_STATIC player_device player_device_skate = { - .pre_update = player_skate_pre_update, - .update = player_skate_update, - .post_update = player_skate_post_update, - .animate = player_skate_animate, - .post_animate = player_skate_post_animate, - .debug_ui = player_skate_ui, - .bind = player_skate_bind, - .reset = player_skate_reset + .name = "skateboard", + .event = player_skate_event, + .storage = &localplayer_device_skate }; #endif /* PLAYER_DEVICE_SKATE_H */