#include "player.h"
#include "audio.h"
-static void player_ragdoll_init(void)
-{
+static int dev_ragdoll_saveload(int argc, const char *argv[]){
+ if( argc != 2 ){
+ vg_info( "Usage: ragdoll load/save filepath\n" );
+ return 1;
+ }
+
+ if( !strcmp(argv[0],"save") ){
+ FILE *fp = fopen( argv[1], "wb" );
+ if( !fp ){
+ vg_error( "Failed to open file\n" );
+ return 1;
+ }
+ fwrite( &localplayer.ragdoll.parts,
+ sizeof(localplayer.ragdoll.parts), 1, fp );
+ fclose( fp );
+ }
+ else if( !strcmp(argv[0],"load") ){
+ FILE *fp = fopen( argv[1], "rb" );
+ if( !fp ){
+ vg_error( "Failed to open file\n" );
+ return 1;
+ }
+
+ fread( &localplayer.ragdoll.parts,
+ sizeof(localplayer.ragdoll.parts), 1, fp );
+ fclose( fp );
+ }
+ else {
+ vg_error( "Unknown command: %s (options are: save,load)\n", argv[0] );
+ return 1;
+ }
+
+ return 0;
+}
+
+static void player_ragdoll_init(void){
VG_VAR_F32( k_ragdoll_limit_scale );
VG_VAR_I32( k_ragdoll_div );
VG_VAR_I32( k_ragdoll_debug_collider );
VG_VAR_I32( k_ragdoll_debug_constraints );
+ vg_console_reg_cmd( "ragdoll", dev_ragdoll_saveload, NULL );
}
static void player_init_ragdoll_bone_collider( struct skeleton_bone *bone,
/*
* Make the ragdoll copy the player model
*/
-static void copy_localplayer_to_ragdoll( struct player_ragdoll *rd, v3f v ){
+static void copy_localplayer_to_ragdoll( struct player_ragdoll *rd,
+ enum player_die_type type ){
+ v3f centroid;
+
+ v3f *bone_mtx = localplayer.final_mtx[localplayer.id_hip];
+ m4x3_mulv( bone_mtx,
+ localplayer.skeleton.bones[localplayer.id_hip].co, centroid );
+
for( int i=0; i<rd->part_count; i++ ){
struct ragdoll_part *part = &rd->parts[i];
v3f pos, offset;
u32 bone = part->bone_id;
+
v3f *bone_mtx = localplayer.final_mtx[bone];
m4x3_mulv( bone_mtx, localplayer.skeleton.bones[bone].co, pos );
m3x3_mul( bone_mtx, part->collider_mtx, r );
m3x3_q( r, part->obj.rb.q );
- v3_copy( v, part->obj.rb.v );
- v3_zero( part->obj.rb.w );
+ v3f ra, v;
+ v3_sub( part->obj.rb.co, centroid, ra );
+ v3_cross( localplayer.rb.w, ra, v );
+ v3_add( localplayer.rb.v, v, part->obj.rb.v );
+
+ if( type == k_player_die_type_feet ){
+ if( (bone == localplayer.id_foot_l) ||
+ (bone == localplayer.id_foot_r) ){
+ v3_zero( part->obj.rb.v );
+ }
+ }
+
+ v3_copy( localplayer.rb.w, part->obj.rb.w );
v3_copy( part->obj.rb.co, part->prev_co );
v4_copy( part->obj.rb.q, part->prev_q );
rb_update_transform( &rd->parts[i].obj.rb );
rb_correct_swingtwist_constraints( rd->cone_constraints,
- rd->cone_constraints_count, 0.25f );
+ rd->cone_constraints_count, 0.125f );
rb_correct_position_constraints( rd->position_constraints,
- rd->position_constraints_count, 0.5f );
+ rd->position_constraints_count, 0.25f );
}
rb_ct *stress = NULL;