a fairly major physics update
[carveJwlIkooP6JGAAIwe30JlM.git] / player.h
index c98f10c83654c9744c2e51802cdc2b7223dfd8e1..0e92f3aae5d6f5038bcd7703adb0c046c731844a 100644 (file)
--- a/player.h
+++ b/player.h
@@ -48,6 +48,7 @@ VG_STATIC float
 VG_STATIC int freecam = 0;
 VG_STATIC int walk_grid_iterations = 1;
 VG_STATIC float fc_speed = 10.0f;
+VG_STATIC int cl_thirdperson = 0;
 
 /* 
  * -----------------------------------------------------------------------------
@@ -69,8 +70,7 @@ VG_STATIC struct gplayer
 
       /* Utility */
       float vswitch, slip, slip_last, reverse;
-
-      float grab, jump, pushing, push_time;
+      float grab, jump, pushing, push_time, rise;
       v2f grab_mouse_delta;
 
       int lift_frames;
@@ -89,16 +89,25 @@ VG_STATIC struct gplayer
    int is_dead, death_tick_allowance, rewinding;
    int rewind_sound_wait;
 
-   v3f land_target;
-
-   struct land_log
+   struct land_prediction
    {
-      v3f positions[50];
-      u32 colour;
-      int count;
-   } 
-   land_log[22];
-   int land_log_count;
+      v3f   log[50];
+      v3f   n;
+      u32   log_length;
+      float score;
+
+      enum prediction_type
+      {
+         k_prediction_none,
+         k_prediction_land,
+         k_prediction_grind
+      }
+      type;
+
+      u32   colour;
+   }
+   predictions[22];
+   u32 prediction_count;
 
    v3f handl_target, handr_target,
        handl, handr;
@@ -185,17 +194,28 @@ VG_STATIC struct gplayer
       struct ragdoll_part
       {
          u32 bone_id;
-         v3f offset;
+         //v3f offset;
+         
+         /* Collider transform relative to bone */
+         m4x3f collider_mtx,
+               inv_collider_mtx;
 
          u32 use_limits;
          v3f limits[2];
 
          rigidbody  rb;
          u32 parent;
+         u32 colour;
       }
       ragdoll[32];
       u32 ragdoll_count;
 
+      rb_constr_pos  position_constraints[32];
+      u32            position_constraints_count;
+
+      rb_constr_swingtwist cone_constraints[32];
+      u32                  cone_constraints_count;
+
       int shoes[2];
    }
    mdl;
@@ -232,8 +252,10 @@ VG_STATIC void player_mouseview(void);
  *                                    Events
  * -----------------------------------------------------------------------------
  */
+VG_STATIC int kill_player( int argc, char const *argv[] );
+VG_STATIC int reset_player( int argc, char const *argv[] );
 
-VG_STATIC void player_init(void)                                            /* 1 */
+VG_STATIC void player_init(void)                                         /* 1 */
 {
    player.input_js1h = vg_create_named_input( "steer-h", k_input_type_axis );
    player.input_js1v = vg_create_named_input( "steer-v", k_input_type_axis );
@@ -339,6 +361,14 @@ VG_STATIC void player_init(void)                                            /* 1
       .persistent = 1
    });
 
+   vg_convar_push( (struct vg_convar){
+      .name = "cl_thirdperson",
+      .data = &cl_thirdperson,
+      .data_type = k_convar_dtype_i32,
+      .opt_i32 = { .min=0, .max=1, .clamp=1 },
+      .persistent = 1
+   });
+
    vg_convar_push( (struct vg_convar){
       .name = "fcs",
       .data = &fc_speed,
@@ -347,11 +377,51 @@ VG_STATIC void player_init(void)                                            /* 1
       .persistent = 1
    });
 
+   vg_convar_push( (struct vg_convar){
+      .name = "k_ragdoll_limit_scale",
+      .data = &k_ragdoll_limit_scale,
+      .data_type = k_convar_dtype_f32,
+      .opt_f32 = { .clamp = 0 },
+      .persistent = 1
+   });
+
+   vg_convar_push( (struct vg_convar){
+      .name = "k_ragdoll_div",
+      .data = &k_ragdoll_div,
+      .data_type = k_convar_dtype_i32,
+      .opt_i32 = { .clamp=0 },
+      .persistent = 1
+   });
+
+   vg_convar_push( (struct vg_convar){
+      .name = "k_ragdoll_debug_collider",
+      .data = &k_ragdoll_debug_collider,
+      .data_type = k_convar_dtype_i32,
+      .opt_i32 = { .clamp=0 },
+      .persistent = 1
+   });
+
+   vg_convar_push( (struct vg_convar){
+      .name = "k_ragdoll_debug_constraints",
+      .data = &k_ragdoll_debug_constraints,
+      .data_type = k_convar_dtype_i32,
+      .opt_i32 = { .clamp=0 },
+      .persistent = 1
+   });
+
        vg_function_push( (struct vg_cmd){
                .name = "reset",
                .function = reset_player
        });
 
+       vg_function_push( (struct vg_cmd){
+               .name = "kill",
+               .function = kill_player
+       });
+
+   /* HACK */
+   rb_register_cvar();
+
    player.rewind_length = 0;
    player.rewind_buffer = 
       vg_linear_alloc( vg_mem.rtmemory, 
@@ -437,64 +507,87 @@ VG_STATIC void player_update_pre(void)
 {
    struct player_phys *phys = &player.phys;
 
-   if( player.rewinding )
+
    {
-      return;
+      v3f ra, rb, rx;
+      v3_copy( main_camera.pos, ra );
+      v3_muladds( ra, main_camera.transform[2], -10.0f, rb );
+
+      float t;
+      if( spherecast_world( ra, rb, 0.4f, &t, rx ) != -1 )
+      {
+         m4x3f mtx;
+         m3x3_identity( mtx );
+         v3_lerp( ra, rb, t, mtx[3] );
+
+         debug_sphere( mtx, 0.4f, 0xff00ff00 );
+
+         v3f x1;
+         v3_muladds( mtx[3], rx, 0.4f, x1 );
+         vg_line( mtx[3], x1, 0xffffffff );
+      }
    }
 
+
+
+
+
+
+
+
+   if( player.rewinding )
+      return;
+
    if( vg_input_button_down( player.input_reset ) && !menu_enabled() )
    {
-      if( player.is_dead )
+      double delta = world.time - world.last_use;
+
+      if( (delta <= RESET_MAX_TIME) && (world.last_use != 0.0) )
       {
-         reset_player( 0, NULL );
+         player.rewinding = 1;
+         player.rewind_sound_wait = 1;
+         player.rewind_time = (float)player.rewind_length - 0.0001f;
+         player_save_rewind_frame();
          audio_lock();
-         audio_play_oneshot( &audio_ui[0], 1.0f );
+         audio_play_oneshot( &audio_rewind[0], 1.0f );
          audio_unlock();
-      }
-      else
-      {
-         double delta = world.time - world.last_use;
-
-         if( (delta <= RESET_MAX_TIME) && (world.last_use != 0.0) )
-         {
-            player.rewinding = 1;
-            player.rewind_sound_wait = 1;
-            player.rewind_time = (float)player.rewind_length - 0.0001f;
-            player_save_rewind_frame();
-            audio_lock();
-            audio_play_oneshot( &audio_rewind[0], 1.0f );
-            audio_unlock();
 
-            /* based on analytical testing. DONT CHANGE!
-             
-             *    time taken: y = (x^(4/5)) * 74.5
-             *    inverse   : x = (2/149)^(4/5) * y^(4/5)
-             */
+         /* based on analytical testing. DONT CHANGE!
+          * 
+          *    time taken: y = (x^(4/5)) * 74.5
+          *    inverse   : x = (2/149)^(4/5) * y^(4/5)
+          */
 
-            float constant = powf( 2.0f/149.0f, 4.0f/5.0f ),
-                  curve    = powf( player.rewind_total_length, 4.0f/5.0f );
-            
-            player.rewind_predicted_time = constant * curve;
-            player.diag_rewind_start = vg.time;
-            player.diag_rewind_time  = player.rewind_time;
+         float constant = powf( 2.0f/149.0f, 4.0f/5.0f ),
+               curve    = powf( player.rewind_total_length, 4.0f/5.0f );
+         
+         player.rewind_predicted_time = constant * curve;
+         player.diag_rewind_start = vg.time;
+         player.diag_rewind_time  = player.rewind_time;
 
-            player.is_dead = 0;
-            player.death_tick_allowance = 30;
-            player_restore_frame();
+         player.is_dead = 0;
+         player.death_tick_allowance = 30;
+         player_restore_frame();
 
-            if( !phys->on_board )
-            {
-               player.angles[0] = atan2f( -phys->rb.forward[2], 
-                                          -phys->rb.forward[0] );
-            }
+         if( !phys->on_board )
+         {
+            player.angles[0] = atan2f( -phys->rb.forward[2], 
+                                       -phys->rb.forward[0] );
+         }
 
-            player.mdl.shoes[0] = 1;
-            player.mdl.shoes[1] = 1;
+         player.mdl.shoes[0] = 1;
+         player.mdl.shoes[1] = 1;
 
-            world_routes_notify_reset();
+         world_routes_notify_reset();
 
-            /* apply 1 frame of movement */
-            player_do_motion();
+         /* apply 1 frame of movement */
+         player_do_motion();
+      }
+      else
+      {
+         if( player.is_dead )
+         {
+            reset_player( 0, NULL );
          }
          else
          {
@@ -557,14 +650,18 @@ VG_STATIC void player_update_fixed(void)                                 /* 2 */
 
 VG_STATIC void player_update_post(void)
 {
-   for( int i=0; i<player.land_log_count; i++ )
+   for( int i=0; i<player.prediction_count; i++ )
    {
-      struct land_log *log = &player.land_log[i];
+      struct land_prediction *p = &player.predictions[i];
       
-      for( int j=0; j<log->count - 1; j ++ )
-         vg_line( log->positions[j], log->positions[j+1], log->colour );
+      for( int j=0; j<p->log_length - 1; j ++ )
+         vg_line( p->log[j], p->log[j+1], p->colour );
 
-      vg_line_cross( log->positions[log->count-1], log->colour, 0.25f );
+      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 );
    }
 
    if( player.is_dead )
@@ -579,13 +676,17 @@ VG_STATIC void player_update_post(void)
       player_animate();
 
       if( !freecam )
-         player_animate_camera();
+      {
+         if( cl_thirdperson )
+            player_animate_camera_thirdperson();
+         else
+            player_animate_camera();
+      }
    }
 
    if( freecam )
       player_freecam();
 
-
    /* CAMERA POSITIONING: LAYER 0 */
    v2_copy( player.angles, main_camera.angles );
    v3_copy( player.camera_pos, main_camera.pos );
@@ -746,7 +847,6 @@ VG_STATIC void player_kill(void)
    {
       player.is_dead = 1;
       player_ragdoll_copy_model( player.phys.rb.v );
-      world_routes_clear();
    }
 }