better? grinds
[carveJwlIkooP6JGAAIwe30JlM.git] / player_walk.c
index a2a2ed80198a0fd3dff2c08a1b2b141e3222b0e1..d5f4aa0c28df9d57a1200ff762b6723f3f5c5bcb 100644 (file)
@@ -49,6 +49,7 @@ VG_STATIC void player_walk_generic_to_skate( player_instance *player,
    player__skate_reset_animator( player );
    player__skate_clear_mechanics( player );
    rb_update_transform( &player->rb );
+   v3_copy( (v3f){0.0f,0.0f,0.0f}, s->state.trick_euler );
 
    if( init == k_skate_activity_air )
       player__approximate_best_trajectory( player );
@@ -74,6 +75,33 @@ VG_STATIC void player_walk_drop_in_to_skate( player_instance *player )
    v3_copy( init_velocity, s->state.cog_v );
    v3_copy( init_velocity, player->rb.v );
    v3_copy( init_velocity, player->cam_velocity_smooth );
+   v3_copy( (v3f){1.0f,0.0f,0.0f}, s->state.trick_euler );
+}
+
+VG_STATIC void player_walk_drop_in_overhang_transform( player_instance *player,
+                                                       float t,
+                                                       v3f co, v4f q )
+{
+   struct player_walk *w = &player->_walk;
+
+   v3f axis;
+   v3_cross( (v3f){0.0f,1.0f,0.0f}, w->state.drop_in_normal, axis );
+   v3_normalize( axis );
+
+   float a = acosf( w->state.drop_in_normal[1] ) * t;
+
+   q_axis_angle( q, axis, a );
+
+   float l = t * 0.5f,
+         heading_angle = w->state.drop_in_angle;
+
+   v3f overhang;
+   overhang[0] = sinf( heading_angle ) * l;
+   overhang[1] = 0.28f * l;
+   overhang[2] = cosf( heading_angle ) * l;
+
+   q_mulv( q, overhang, overhang );
+   v3_add( w->state.drop_in_target, overhang, co );
 }
 
 VG_STATIC int player_walk_scan_for_drop_in( player_instance *player )
@@ -153,6 +181,48 @@ VG_STATIC int player_walk_scan_for_drop_in( player_instance *player )
       {
          v3_copy( edge, w->state.drop_in_target );
          v3_copy( s1->normal, w->state.drop_in_normal );
+         v3_copy( player->rb.co, w->state.drop_in_start );
+
+         w->state.drop_in_start_angle = player_get_heading_yaw( player );
+         w->state.drop_in_angle = atan2f( w->state.drop_in_normal[0],
+                                          w->state.drop_in_normal[2] );
+
+         /* TODO: scan multiple of these? */
+         v3f oco;
+         v4f oq;
+         player_walk_drop_in_overhang_transform( player, 1.0f, oco, oq );
+
+         v3f va = {0.0f,0.0f,-k_board_length - 0.3f},
+             vb = {0.0f,0.0f, k_board_length + 0.3f};
+
+         q_mulv( oq, va, va );
+         q_mulv( oq, vb, vb );
+         v3_add( oco, va, va );
+         v3_add( oco, vb, vb );
+
+         v3f v0;
+         v3_sub( vb, va, v0 );
+         v3_normalize( v0 );
+
+         ray_hit ray;
+         ray.dist = k_board_length*2.0f + 0.6f;
+         
+         if( ray_world( va, v0, &ray ) )
+         {
+            vg_line( va, vb, VG__RED );
+            vg_line_pt3( ray.pos, 0.1f, VG__RED );
+            vg_error( "invalidated\n" );
+            return 0;
+         }
+
+         v3_muls( v0, -1.0f, v0 );
+         if( ray_world( vb, v0, &ray ) )
+         {
+            vg_line( va, vb, VG__RED );
+            vg_line_pt3( ray.pos, 0.1f, VG__RED );
+            vg_error( "invalidated\n" );
+            return 0;
+         }
 
          player_walk_drop_in_vector( player, player->rb.v );
          return 1;
@@ -203,11 +273,6 @@ VG_STATIC void player__walk_pre_update( player_instance *player )
             w->state.outro_anim = w->anim_drop_in;
             w->state.outro_start_time = vg.time;
             w->state.activity = k_walk_activity_immobile;
-            v3_copy( player->rb.co, w->state.drop_in_start );
-
-            w->state.drop_in_start_angle = player_get_heading_yaw( player );
-            w->state.drop_in_angle = atan2f( w->state.drop_in_normal[0],
-                                             w->state.drop_in_normal[2] );
 
             struct player_avatar *av = player->playeravatar;
             m4x3_mulv( av->sk.final_mtx[ av->id_ik_foot_r ], 
@@ -319,7 +384,7 @@ VG_STATIC void player__walk_update( player_instance *player )
          v3_add( surface_avg, ct->n, surface_avg );
       }
 
-      rb_prepare_contact( ct );
+      rb_prepare_contact( ct, k_rb_delta );
    }
 
    /* 
@@ -399,20 +464,7 @@ VG_STATIC void player__walk_update( player_instance *player )
     * Depenetrate
     */
    v3f dt;
-   v3_zero( dt );
-   for( int j=0; j<8; j++ )
-   {
-      for( int i=0; i<len; i++ )
-      {
-         struct contact *ct = &manifold[i];
-
-         float resolved_amt = v3_dot( ct->n, dt ),
-               remaining    = (ct->p-k_penetration_slop) - resolved_amt,
-               apply        = vg_maxf( remaining, 0.0f ) * 0.3f;
-
-         v3_muladds( dt, ct->n, apply, dt );
-      }
-   }
+   rb_depenetrate( manifold, len, dt );
    v3_add( dt, player->rb.co, player->rb.co );
 
    /* TODO: Stepping......
@@ -506,7 +558,7 @@ VG_STATIC void player__walk_post_update( player_instance *player )
    struct player_walk *w = &player->_walk;
 
    m4x3f mtx;
-   m3x3_identity( mtx );
+   m3x3_copy( player->rb.to_world, mtx );
    v3_add( player->rb.co, (v3f){0.0f, 1.0f, 0.0f}, mtx[3] );
 
    float substep = vg_clampf( vg.accumulator / k_rb_delta, 0.0f, 1.0f );
@@ -658,37 +710,26 @@ VG_STATIC void player__walk_animate( player_instance *player,
          if( step_t >= 1.0f )
          {
             v4f final_q;
-            v3f axis;
-            v3_cross( (v3f){0.0f,1.0f,0.0f}, w->state.drop_in_normal, axis );
-            v3_normalize( axis );
-
-            float a = acosf( w->state.drop_in_normal[1] ) * dop_t;
-
-            q_axis_angle( final_q, axis, a );
+            player_walk_drop_in_overhang_transform( player, dop_t, 
+                                                    player->rb.co, final_q );
             q_mul( final_q, dest->root_q, dest->root_q );
 
-            float l = dop_t * 0.5f,
-                  heading_angle = w->state.drop_in_angle;
-
-            v3f overhang;
-            overhang[0] = sinf( heading_angle ) * l;
-            overhang[1] = 0.28f * l;
-            overhang[2] = cosf( heading_angle ) * l;
-
-            q_mulv( final_q, overhang, overhang );
-
-            v3f overhang_pos;
-            v3_add( w->state.drop_in_target, overhang, player->rb.co );
             v4_copy( dest->root_q, player->rb.q );
             v3_muladds( dest->root_co, player->rb.to_world[1], 
-                        -0.28f * dop_t, dest->root_co );
+                        -0.1f * dop_t, dest->root_co );
+
+            skeleton_copy_pose( sk, dest->pose, player->holdout_pose );
+            player->holdout_time = 1.0f;
          }
          return;
       }
       else
       {
          v3_muladds( dest->root_co, player->rb.to_world[1], 
-                     -0.28f * outro_t, dest->root_co );
+                     -0.1f * outro_t, dest->root_co );
+
+         skeleton_copy_pose( sk, dest->pose, player->holdout_pose );
+         player->holdout_time = 1.0f;
       }
    }
    else