stepping
[carveJwlIkooP6JGAAIwe30JlM.git] / player_ragdoll.h
index 3fd552471001449920d1fe49d589f5add73352d9..e4711634a218e6f3e79c60a105c4165ed070777c 100644 (file)
@@ -7,6 +7,7 @@
 #include "rigidbody.h"
 #include "player_model.h"
 #include "world.h"
+#include "audio.h"
 
 struct player_ragdoll
 {
@@ -89,8 +90,10 @@ VG_STATIC void player_init_ragdoll_bone_collider( struct skeleton_bone *bone,
 
       rp->colour = 0xff000000 | (0xff << (major_axis*8));
    }
-   else
+   else{
+      vg_warn( "type: %u\n", bone->collider );
       vg_fatal_exit_loop( "Invalid bone collider type" );
+   }
 
    m4x3_invert_affine( rp->collider_mtx, rp->inv_collider_mtx );
 
@@ -129,7 +132,7 @@ VG_STATIC void player_setup_ragdoll_from_avatar( struct player_ragdoll *rd,
    rd->position_constraints_count = 0;
    rd->cone_constraints_count = 0;
 
-   for( u32 i=0; i<av->sk.bone_count; i ++ ){
+   for( u32 i=1; i<av->sk.bone_count; i ++ ){
       struct skeleton_bone *bone = &av->sk.bones[i];
 
       /*
@@ -219,6 +222,22 @@ VG_STATIC void copy_ragdoll_pose_to_avatar( struct player_ragdoll *rd,
                   av->sk.final_mtx[part->bone_id] );
    }
 
+   for( u32 i=1; i<av->sk.bone_count; i++ ){
+      struct skeleton_bone *sb = &av->sk.bones[i];
+
+      if( sb->parent && !sb->collider ){
+         v3f delta;
+         v3_sub( av->sk.bones[i].co, av->sk.bones[sb->parent].co, delta );
+
+         m4x3f posemtx;
+         m3x3_identity( posemtx );
+         v3_copy( delta, posemtx[3] );
+
+         /* final matrix */
+         m4x3_mul( av->sk.final_mtx[sb->parent], posemtx, av->sk.final_mtx[i] );
+      }
+   }
+
    skeleton_apply_inverses( &av->sk );
 }
 
@@ -273,6 +292,9 @@ VG_STATIC void player_ragdoll_iter( struct player_ragdoll *rd )
    }
 
    rb_solver_reset();
+   
+   float contact_velocities[256];
+
    for( int i=0; i<rd->part_count; i ++ ){
       if( rb_global_has_space() ){
          rb_ct *buf = rb_global_buffer();
@@ -346,6 +368,18 @@ VG_STATIC void player_ragdoll_iter( struct player_ragdoll *rd )
    /*
     * PRESOLVE
     */
+   for( u32 i=0; i<rb_contact_count; i++ ){
+      rb_ct *ct = &rb_contact_buffer[i];
+
+      v3f rv, ra, rb;
+      v3_sub( ct->co, ct->rba->co, ra );
+      v3_sub( ct->co, ct->rbb->co, rb );
+      rb_rcv( ct->rba, ct->rbb, ra, rb, rv );
+      float     vn = v3_dot( rv, ct->n );
+
+      contact_velocities[i] = vn;
+   }
+
    rb_presolve_contacts( rb_contact_buffer, rb_contact_count );
    rb_presolve_swingtwist_constraints( rd->cone_constraints,
                                        rd->cone_constraints_count );
@@ -391,6 +425,38 @@ VG_STATIC void player_ragdoll_iter( struct player_ragdoll *rd )
                                        rd->position_constraints_count, 0.5f );
    }
 
+   rb_ct *stress = NULL;
+   float max_stress = 1.0f;
+
+   for( u32 i=0; i<rb_contact_count; i++ ){
+      rb_ct *ct = &rb_contact_buffer[i];
+
+      v3f rv, ra, rb;
+      v3_sub( ct->co, ct->rba->co, ra );
+      v3_sub( ct->co, ct->rbb->co, rb );
+      rb_rcv( ct->rba, ct->rbb, ra, rb, rv );
+      float     vn = v3_dot( rv, ct->n );
+
+      float s = fabsf(vn - contact_velocities[i]);
+      if( s > max_stress ){
+         stress = ct;
+         max_stress = s;
+      }
+   }
+
+   static u32 temp_filter = 0;
+
+   if( temp_filter ){
+      temp_filter --;
+      return;
+   }
+
+   if( stress ){
+      temp_filter = 20;
+      audio_lock();
+      audio_oneshot_3d( &audio_hits[rand()%5], stress->co, 20.0f, 1.0f );
+      audio_unlock();
+   }
 }
 
 #endif /* PLAYER_RAGDOLL_H */