X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_device_skate.h;h=d657b4a20440784e70d811d9ff0f9f96cf3261dc;hb=5430d708f058626a6c8fed7dd2aa8ba5f0a06c84;hp=04a2da1115242581249cece7b445d8d03d23c553;hpb=ff8fcac9582d07bc1ccbf08421d6ffec1758a755;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_device_skate.h b/player_device_skate.h index 04a2da1..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; @@ -44,9 +50,11 @@ struct player_device_skate double start_push, cur_push; - struct mixedcam_state cam; - v3f prev_pos; + + /* FIXME: Sensible names */ + v3f vl, /* 1st */ + posl, dirl; /* 3rd */ } state, state_gate_storage; @@ -55,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 { @@ -95,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; @@ -114,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" ); } /* @@ -208,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 ); @@ -278,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++ ) { @@ -291,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; @@ -331,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 ++ ] ); } @@ -352,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 @@ -372,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 */ @@ -395,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 ) @@ -432,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 ); + } } /* @@ -699,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 ); @@ -717,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) ) @@ -910,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(); @@ -1061,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; @@ -1076,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 ); @@ -1096,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; @@ -1126,13 +1176,39 @@ VG_STATIC void player_skate_update( player_interface *player, &s->sphere_front, manifold ), len_back = skate_collide_smooth( player, mtx_back, &s->sphere_back, &manifold[len_front] ), - interface_len = len_front + len_back; + /* try to slap both wheels onto the ground when landing to prevent mega + * angular velocities being added */ + if( (s->state.activity == k_skate_activity_air) && (len_front != len_back) ) + { + v3f trace_from, trace_dir; + v3_muls( player->rb.to_world[1], -1.0f, trace_dir ); + + if( len_front ) + v3_copy( mtx_back[3], trace_from ); + else + v3_copy( mtx_front[3], trace_from ); + + ray_hit ray; + ray.dist = 0.6f; + + if( ray_world( trace_from, trace_dir, &ray ) ) + { + rb_ct *ct = &manifold[ interface_len ]; + + v3_copy( ray.pos, ct->co ); + v3_copy( ray.normal, ct->n ); + ct->p = 0.0f; + + interface_len ++; + } + } + 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_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 ); +#endif v4f transport_rotation; m3x3_q( gate->transport, transport_rotation ); @@ -1184,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], @@ -1213,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; @@ -1381,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; @@ -1395,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 ); @@ -1427,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; @@ -1440,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 ) @@ -1472,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, @@ -1506,57 +1610,52 @@ VG_STATIC void skate_camera_firstperson( player_interface *player, //v3_normalize( flat_dir ); v3_lerp( flat_dir, vel_dir, vg_clampf( tti / 2.0f, 0.4f, 1.0f ), look_dir ); - v3_lerp( s->state.cam.vl, look_dir, 4.0f*vg.time_delta, s->state.cam.vl ); + v3_lerp( s->state.vl, look_dir, 4.0f*vg.time_delta, s->state.vl ); - skate_camera_vector_look( &at->cam_1st, s->state.cam.vl, 0.7f, 0.5f ); + skate_camera_vector_look( &dev->cam_1st, s->state.vl, 1.0f, 0.25f ); } -#if 0 -VG_STATIC void skate_camera_thirdperson( player_interface *player, - struct player_device_skate *s, - struct player_avatar *av, camera *cam ) +VG_STATIC void skate_camera_thirdperson( player_device *dev, + player_interface *player ) { - v3f prev_pos, cam_look_dir, d; + struct player_device_skate *s = dev->storage; + struct player_avatar *av = player->playeravatar; - v3_copy( s->state.cam.pos, prev_pos ); - skate_camera_thirdperson_nextpos( player, s, av, s->state.cam.pos, d); + v3f origin, dir, target; + v3_copy( player->rb.co, origin ); + v3_add( origin, (v3f){0.0f,1.35f,0.0f}, origin ); + v3_sub( origin, s->state.posl, dir ); + + if( v3_length2( dir ) < 0.1f*0.1f ) + v3_copy( (v3f){ 0.0f, 0.0f, 1.0f }, dir ); /* FIXME */ + else + v3_normalize( dir ); - if( s->state.cam.gate ) - { - v2f _; - if( gate_intersect_plane( s->state.cam.gate, - s->state.cam.pos, prev_pos, _ ) ) - { - m4x3_mulv( s->state.cam.gate->transport, - s->state.cam.pos, s->state.cam.pos ); - m3x3_mulv( s->state.cam.gate->transport, d, d ); - player_apply_transport_to_cam( s->state.cam.gate->transport ); + 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; - s->state.cam.gate = NULL; - } - } - - skate_camera_vector_look( cam, d, 1.0f, 0.0f ); - v3_copy( s->state.cam.pos, cam->pos ); + v3_muladds( origin, dir, -2.0f, target ); + + 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 ); } -#endif -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; -#if 0 - if( cl_thirdperson ) - skate_camera_thirdperson( player, s, av, cam ); - else -#endif - 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}, @@ -1566,32 +1665,105 @@ 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 mixedcam_reset( player, &s->state.cam ); +#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 */