-/*
- * Constants
- */
-
-static float
- k_walkspeed = 2.0f,
- k_board_radius = 0.3f,
- k_board_length = 0.45f,
- k_board_allowance = 0.04f,
- k_friction_lat = 8.8f,
- k_friction_resistance = 0.01f,
- k_max_push_speed = 16.0f,
- k_push_accel = 10.0f,
- k_push_cycle_rate = 8.0f,
- k_steer_ground = 2.5f,
- k_steer_air = 3.6f,
- k_steer_air_lerp = 0.3f,
- k_pump_force = 000.0f,
- k_downforce = 5.0f,
- k_jump_charge_speed = (1.0f/1.0f),
- k_jump_force = 5.0f;
-
-static int freecam = 0;
-static int walk_grid_iterations = 1;
-static float fc_speed = 10.0f;
-
-static struct gplayer
-{
- /* Physics */
- rigidbody rb, collide_front, collide_back, rb_gate_frame;
-
- v3f a, v_last, m, bob, vl;
-
- /* Utility */
- float vswitch, slip, slip_last,
- reverse;
-
- float iY; /* Yaw inertia */
- int in_air, is_dead, on_board;
-
- v2f board_xy;
- float grab;
- float pitch;
- float pushing, push_time;
- float jump;
- int jump_charge;
-
- v3f land_target;
- v3f land_target_log[22];
- u32 land_target_colours[22];
- int land_log_count;
- m3x3f vr,vr_pstep;
-
- struct character mdl;
-
- v3f handl_target, handr_target,
- handl, handr;
-
- /* Camera */
- float air_blend;
-
- v3f camera_pos, smooth_localcam;
- v2f angles;
- m4x3f camera, camera_inverse;
-
- /* animation */
- double jump_time;
- float fslide,
- fdirz, fdirx,
- fstand,
- ffly,
- fpush,
- fairdir,
- fsetup;
-}
-player =
-{
- .on_board = 1,
-
- .collide_front = { .type = k_rb_shape_sphere, .inf.sphere.radius = 0.3f },
- .collide_back = { .type = k_rb_shape_sphere, .inf.sphere.radius = 0.3f }
-};
-
-/*
- * Player API
- */
-
-
-/*
- * Free camera movement
- */
-
-static void player_mouseview(void)
-{
- if( gui_want_mouse() )
- return;
-
- static v2f mouse_last,
- view_vel = { 0.0f, 0.0f };
-
- if( vg_get_button_down( "primary" ) )
- v2_copy( vg_mouse, mouse_last );
-
- else if( vg_get_button( "primary" ) )
- {
- v2f delta;
- v2_sub( vg_mouse, mouse_last, delta );
- v2_copy( vg_mouse, mouse_last );
-
- v2_muladds( view_vel, delta, 0.001f, view_vel );
- }
-
- v2_muladds( view_vel,
- (v2f){ vg_get_axis("h1"), vg_get_axis("v1") },
- 0.05f, view_vel );
- v2_muls( view_vel, 0.93f, view_vel );
- v2_add( view_vel, player.angles, player.angles );
- player.angles[1] = vg_clampf( player.angles[1], -VG_PIf*0.5f, VG_PIf*0.5f );
-}
-
-static void player_freecam(void)
-{
- player_mouseview();
-
- float movespeed = fc_speed;
- v3f lookdir = { 0.0f, 0.0f, -1.0f },
- sidedir = { 1.0f, 0.0f, 0.0f };
-
- m3x3_mulv( player.camera, lookdir, lookdir );
- m3x3_mulv( player.camera, sidedir, sidedir );
-
- static v3f move_vel = { 0.0f, 0.0f, 0.0f };
- if( vg_get_button( "forward" ) )
- v3_muladds( move_vel, lookdir, ktimestep * movespeed, move_vel );
- if( vg_get_button( "back" ) )
- v3_muladds( move_vel, lookdir, ktimestep *-movespeed, move_vel );
- if( vg_get_button( "left" ) )
- v3_muladds( move_vel, sidedir, ktimestep *-movespeed, move_vel );
- if( vg_get_button( "right" ) )
- v3_muladds( move_vel, sidedir, ktimestep * movespeed, move_vel );
-
- v3_muls( move_vel, 0.7f, move_vel );
- v3_add( move_vel, player.camera_pos, player.camera_pos );
-}
-
-/*
- * Player Physics Implementation
- */
-
-static void apply_gravity( v3f vel, float const timestep )
-{
- v3f gravity = { 0.0f, -9.6f, 0.0f };
- v3_muladds( vel, gravity, timestep, vel );
-}
-
-/*
- * TODO: The angle bias should become greater when launching from a steeper
- * angle and skewed towords more 'downwards' angles when launching from
- * shallower trajectories
- *
- * it should also be tweaked by the controller left stick being pushed
- * up or down
- */
-static void player_start_air(void)
-{
- if( player.in_air )
- return;
-
- player.in_air = 1;
-
- float pstep = ktimestep*10.0f;
- float best_velocity_delta = -9999.9f;
- float k_bias = 0.96f;
-
- v3f axis;
- v3_cross( player.rb.up, player.rb.v, axis );
- v3_normalize( axis );
- player.land_log_count = 0;
-
- m3x3_identity( player.vr );
-
- for( int m=-3;m<=12; m++ )
- {
- float vmod = ((float)m / 15.0f)*0.09f;
-
- v3f pco, pco1, pv;
- v3_copy( player.rb.co, pco );
- v3_muls( player.rb.v, k_bias, pv );
-
- /*
- * Try different 'rotations' of the velocity to find the best possible
- * landing normal. This conserves magnitude at the expense of slightly
- * unrealistic results
- */
-
- m3x3f vr;
- v4f vr_q;
-
- q_axis_angle( vr_q, axis, vmod );
- q_m3x3( vr_q, vr );
-
- m3x3_mulv( vr, pv, pv );
- v3_muladds( pco, pv, pstep, pco );
-
- for( int i=0; i<50; i++ )
- {
- v3_copy( pco, pco1 );
- apply_gravity( pv, pstep );
-
- m3x3_mulv( vr, pv, pv );
- v3_muladds( pco, pv, pstep, pco );
-
- ray_hit contact;
- v3f vdir;
-
- v3_sub( pco, pco1, vdir );
- contact.dist = v3_length( vdir );
- v3_divs( vdir, contact.dist, vdir);
-
- if( ray_world( pco1, vdir, &contact ))
- {
- float land_delta = v3_dot( pv, contact.normal );
- u32 scolour = (u8)(vg_minf(-land_delta * 2.0f, 255.0f));
-
- /* Bias prediction towords ramps */
- if( ray_hit_is_ramp( &contact ) )
- {
- land_delta *= 0.1f;
- scolour |= 0x0000a000;
- }
-
- if( (land_delta < 0.0f) && (land_delta > best_velocity_delta) )
- {
- best_velocity_delta = land_delta;