now fall in immobile mode
[carveJwlIkooP6JGAAIwe30JlM.git] / player_walk.c
index 2c038431e175825427749f2f37f56c5acf0f56c8..841574142d12071831958f0c68e67df30b864e59 100644 (file)
@@ -146,8 +146,7 @@ VG_STATIC int player_walk_scan_for_drop_in( player_instance *player )
       ray_hit *ray = &samples[ sample_count ];
       ray->dist = 2.0f;
 
-      if( ray_world( world, pos, ray_dir, ray ) )
-      {
+      if( ray_world( world, pos, ray_dir, ray, 0 ) ){
          vg_line( pos, ray->pos, VG__RED );
          vg_line_point( ray->pos, 0.025f, VG__BLACK );
          
@@ -219,8 +218,7 @@ VG_STATIC int player_walk_scan_for_drop_in( player_instance *player )
          ray_hit ray;
          ray.dist = k_board_length*2.0f + 0.6f;
          
-         if( ray_world( world, va, v0, &ray ) )
-         {
+         if( ray_world( world, va, v0, &ray, 0 ) ){
             vg_line( va, vb, VG__RED );
             vg_line_point( ray.pos, 0.1f, VG__RED );
             vg_error( "invalidated\n" );
@@ -228,8 +226,7 @@ VG_STATIC int player_walk_scan_for_drop_in( player_instance *player )
          }
 
          v3_muls( v0, -1.0f, v0 );
-         if( ray_world( world, vb, v0, &ray ) )
-         {
+         if( ray_world( world, vb, v0, &ray, 0 ) ){
             vg_line( va, vb, VG__RED );
             vg_line_point( ray.pos, 0.1f, VG__RED );
             vg_error( "invalidated\n" );
@@ -370,6 +367,43 @@ VG_STATIC void player_friction( v3f v ){
    v3_muls( v, newspeed, v );
 }
 
+VG_STATIC void player_walk_custom_filter( world_instance *world,
+                                          rb_ct *man, int len, f32 w ){
+   for( int i=0; i<len; i++ ){
+      rb_ct *ci = &man[i];
+      if( ci->type == k_contact_type_disabled ||
+          ci->type == k_contact_type_edge ) 
+         continue;
+
+
+      float d1 = v3_dot( ci->co, ci->n );
+
+      for( int j=0; j<len; j++ ){
+         if( j == i )
+            continue;
+
+         rb_ct *cj = &man[j];
+         if( cj->type == k_contact_type_disabled ) 
+            continue;
+
+         struct world_surface *si = world_contact_surface( world, ci ),
+                              *sj = world_contact_surface( world, cj );
+
+         if(  (sj->info.flags & k_material_flag_walking) &&
+             !(si->info.flags & k_material_flag_walking)){
+            continue;
+         }
+         
+         float d2 = v3_dot( cj->co, ci->n ),
+               d  = d2-d1;
+
+         if( fabsf( d ) <= w ){
+            cj->type = k_contact_type_disabled;
+         }
+      }
+   }
+}
+
 VG_STATIC void player__walk_update( player_instance *player ){
    struct player_walk *w = &player->_walk;
    v3_copy( player->rb.co, w->state.prev_pos );
@@ -387,9 +421,6 @@ VG_STATIC void player__walk_update( player_instance *player ){
 
    enum walk_activity prev_state = w->state.activity;
 
-   if( player->immobile )
-      return;
-
    w->collider.height = 2.0f;
    w->collider.radius = 0.3f;
 
@@ -413,15 +444,15 @@ VG_STATIC void player__walk_update( player_instance *player ){
    v2f steer;
    joystick_state( k_srjoystick_steer, steer );
 
-   w->move_speed = v2_length( steer );
+   w->move_speed = player->immobile? 0.0f: v2_length( steer );
 
    /* 
     * Collision detection
     */
 
    len = rb_capsule__scene( mtx, &w->collider, NULL, 
-                            &world->rb_geo.inf.scene, manifold );
-   rb_manifold_filter_coplanar( manifold, len, 0.01f );
+                            &world->rb_geo.inf.scene, manifold, 0 );
+   player_walk_custom_filter( world, manifold, len, 0.01f );
    len = rb_manifold_apply_filtered( manifold, len );
 
    v3f surface_avg = { 0.0f, 0.0f, 0.0f };
@@ -533,7 +564,8 @@ VG_STATIC void player__walk_update( player_instance *player ){
 
       v3f n;
       float t;
-      if( spherecast_world( world, pa, pb, w->collider.radius, &t, n ) != -1 ){
+      if( spherecast_world( world, pa, pb, 
+                            w->collider.radius, &t, n, 0 ) != -1 ){
          if( player_walk_normal_standable( player, n ) ){
             v3_lerp( pa, pb, t, player->rb.co );
             v3_muladds( player->rb.co, player->basis[1], 
@@ -562,6 +594,11 @@ VG_STATIC void player__walk_update( player_instance *player ){
                   player->rb.v );
    }
 
+   if( player->immobile ){
+      player->rb.v[0] = 0.0f;
+      player->rb.v[2] = 0.0f;
+   }
+
    v3_muladds( player->rb.co, player->rb.v, k_rb_delta, player->rb.co );
    v3_add( player->rb.co, player->basis[1], mtx[3] );
    vg_line_capsule( mtx, w->collider.radius, w->collider.height, VG__GREEN );
@@ -587,13 +624,13 @@ VG_STATIC void player__walk_update( player_instance *player ){
       float t, sr = w->collider.radius-0.04f;
       v3f n;
 
-      if( spherecast_world( world, lwr_prev, lwr_now, sr, &t, n ) != -1 ){
+      if( spherecast_world( world, lwr_prev, lwr_now, sr, &t, n, 0 ) != -1 ){
          v3_lerp( lwr_prev, lwr_now, vg_maxf(0.01f,t), player->rb.co );
          player->rb.co[1] -= w->collider.radius;
          rb_update_transform( &player->rb );
 
          v3_add( player->rb.co, player->basis[1], mtx[3] );
-         vg_line_capsule( mtx, w->collider.radius, w->collider.height, VG__RED );
+         vg_line_capsule( mtx, w->collider.radius, w->collider.height, VG__RED);
       }
    }
 
@@ -660,12 +697,12 @@ VG_STATIC void player__walk_post_update( player_instance *player ){
 
 
    int walk_phase = 0;
-   if( vg_fractf(w->walk_timer) > 0.5f )
+   if( vg_fractf(w->state.walk_timer) > 0.5f )
       walk_phase = 1;
    else
       walk_phase = 0;
 
-   if( (w->step_phase != walk_phase) && 
+   if( (w->state.step_phase != walk_phase) && 
        (w->state.activity == k_walk_activity_ground ) )
    {
       audio_lock();
@@ -692,7 +729,7 @@ VG_STATIC void player__walk_post_update( player_instance *player ){
       audio_unlock();
    }
 
-   w->step_phase = walk_phase;
+   w->state.step_phase = walk_phase;
 }
 
 VG_STATIC void player__walk_animate( player_instance *player ){
@@ -720,11 +757,11 @@ VG_STATIC void player__walk_animate( player_instance *player ){
             run_norm  = 30.0f/(float)w->anim_run->length,
             walk_adv  = vg_lerpf( walk_norm, run_norm, w->move_speed );
 
-      w->walk_timer += walk_adv * vg.time_delta;
-   }
-   else{
-      w->walk_timer = 0.0f;
+      w->state.walk_timer += walk_adv * vg.time_delta;
    }
+   else
+      w->state.walk_timer = 0.0f;
+   animator->walk_timer = w->state.walk_timer;
 
    if( !player->immobile )
       rb_extrapolate( &player->rb, animator->root_co, animator->root_q );
@@ -787,19 +824,20 @@ VG_STATIC void player__walk_animate( player_instance *player ){
    q_normalize( animator->root_q );
 }
 
-VG_STATIC void player__walk_pose( player_instance *player ){
+VG_STATIC void player__walk_pose( player_instance *player, player_pose *pose ){
    struct player_walk *w = &player->_walk;
    struct player_walk_animator *animator = &w->animator;
    struct skeleton *sk = &player->playeravatar->sk;
    struct player_avatar *av = player->playeravatar;
 
-   player_pose *pose = &player->pose;
    v3_copy( animator->root_co, pose->root_co );
    v4_copy( animator->root_q, pose->root_q );
+   pose->board.lean = 0.0f;
+   pose->type = k_player_pose_type_ik;
 
    float walk_norm = (float)w->anim_walk->length/30.0f,
          run_norm  = (float)w->anim_run->length/30.0f,
-         t = w->walk_timer,
+         t = animator->walk_timer,
          l = vg_clampf( animator->run*15.0f, 0.0f, 1.0f ),
          idle_walk = vg_clampf( (animator->run-0.1f)/(1.0f-0.1f), 0.0f, 1.0f );
 
@@ -914,9 +952,15 @@ VG_STATIC void player__walk_bind( player_instance *player ){
    w->anim_intro        = skeleton_get_anim( sk, "into_skate" );
 }
 
-VG_STATIC void player__walk_transition( player_instance *player, v3f angles ){
+VG_STATIC void player__walk_transition( player_instance *player ){
    struct player_walk *w = &player->_walk;
    w->state.activity = k_walk_activity_air;
+   w->state.outro_type = k_walk_outro_none;
+   w->state.outro_start_time = 0.0;
+   w->state.jump_queued = 0;
+   w->state.jump_input_time = 0.0;
+   w->state.walk_timer = 0.0f;
+   w->state.step_phase = 0;
 
    v3f fwd = { 0.0f, 0.0f, 1.0f };
    q_mulv( player->rb.q, fwd, fwd );