X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_ragdoll.h;h=6f5a33137a8e5a48ef53b21da64d86b1a21555d7;hb=1fd91b77f23ce1593037e01b9abb62859545b400;hp=6193bf73e4f8bd4ca59fed263d1c6654fa05d670;hpb=47941822dae18a018c985847b052e70214a3ccc6;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_ragdoll.h b/player_ragdoll.h index 6193bf7..6f5a331 100644 --- a/player_ragdoll.h +++ b/player_ragdoll.h @@ -1,217 +1,74 @@ #ifndef PLAYER_RAGDOLL_H #define PLAYER_RAGDOLL_H -#include "player.h" - -VG_STATIC float k_ragdoll_floatyiness = 20.0f, - k_ragdoll_floatydrag = 1.0f; - -/* - * Setup ragdoll colliders - */ -VG_STATIC void player_init_ragdoll(void) -{ - struct player_model *mdl = &player.mdl; - mdl_context *src = &mdl->meta; - - if( !mdl->sk.collider_count ) - { - mdl->ragdoll_count = 0; - return; - } - - mdl->ragdoll_count = 0; - - for( u32 i=0; isk.bone_count; i ++ ) - { - struct skeleton_bone *bone = &mdl->sk.bones[i]; +#include "player_api.h" +#include "skeleton.h" +#include "rigidbody.h" +#include "player_render.h" + +struct player_ragdoll{ + struct ragdoll_part{ + u32 bone_id; - if( bone->collider ) - { - if( mdl->ragdoll_count > vg_list_size(player.mdl.ragdoll) ) - vg_fatal_exit_loop( "Playermodel has too many colliders" ); + /* Collider transform relative to bone */ + m4x3f collider_mtx, + inv_collider_mtx; - struct ragdoll_part *rp = &mdl->ragdoll[ mdl->ragdoll_count ++ ]; - rp->bone_id = i; - - v3f delta; - v3_sub( bone->hitbox[1], bone->hitbox[0], delta ); - v3_muls( delta, 0.5f, delta ); + v4f prev_q; + v3f prev_co; - v3_add( bone->hitbox[0], delta, rp->offset ); + u32 use_limits; + v3f limits[2]; - v3_copy( delta, rp->rb.bbx[1] ); - v3_muls( delta, -1.0f, rp->rb.bbx[0] ); - - q_identity( rp->rb.q ); - v3_add( bone->co, rp->offset, rp->rb.co ); - rp->rb.type = k_rb_shape_box; - rp->rb.is_world = 0; - rp->parent = 0xffffffff; - - if( bone->parent ) - { - for( u32 j=0; jragdoll_count; j++ ) - { - if( mdl->ragdoll[ j ].bone_id == bone->parent ) - { - rp->parent = j; - break; - } - } - } - - struct mdl_node *pnode = mdl_node_from_id( src, bone->orig_node ); - struct classtype_bone *bone_inf = mdl_get_entdata( src, pnode ); - - rp->use_limits = bone_inf->use_limits; - v3_copy( bone_inf->angle_limits[0], rp->limits[0] ); - v3_copy( bone_inf->angle_limits[1], rp->limits[1] ); - - rb_init( &rp->rb ); - } + rb_object obj; + u32 parent; + u32 colour; } -} - -/* - * Make the player model copy the ragdoll - */ -VG_STATIC void player_model_copy_ragdoll(void) -{ - struct player_model *mdl = &player.mdl; - - for( int i=0; iragdoll_count; i++ ) - { - struct ragdoll_part *part = &mdl->ragdoll[i]; - m4x3f offset; - m3x3_identity(offset); - v3_negate( part->offset, offset[3] ); - m4x3_mul( part->rb.to_world, offset, mdl->sk.final_mtx[part->bone_id] ); - } - - skeleton_apply_inverses( &mdl->sk ); -} - -/* - * Make the ragdoll copy the player model - */ -VG_STATIC void player_ragdoll_copy_model( v3f v ) -{ - struct player_model *mdl = &player.mdl; - - for( int i=0; iragdoll_count; i++ ) - { - struct ragdoll_part *part = &mdl->ragdoll[i]; - - v3f pos, offset; - u32 bone = part->bone_id; - - m4x3_mulv( mdl->sk.final_mtx[bone], mdl->sk.bones[bone].co, pos ); - m3x3_mulv( mdl->sk.final_mtx[bone], part->offset, offset ); - v3_add( pos, offset, part->rb.co ); - m3x3_q( mdl->sk.final_mtx[bone], part->rb.q ); - v3_copy( v, part->rb.v ); - v3_zero( part->rb.w ); - - rb_update_transform( &part->rb ); - } -} - -/* - * Draw rigidbody colliders for ragdoll - */ -VG_STATIC void player_debug_ragdoll(void) -{ - struct player_model *mdl = &player.mdl; - - for( u32 i=0; iragdoll_count; i ++ ) - rb_debug( &mdl->ragdoll[i].rb, 0xff00ff00 ); -} - -/* - * Ragdoll physics step - */ -VG_STATIC void player_ragdoll_iter(void) -{ - struct player_model *mdl = &player.mdl; - rb_solver_reset(); - - for( int i=0; iragdoll_count; i ++ ) - rb_collide( &mdl->ragdoll[i].rb, &world.rb_geo ); - - rb_presolve_contacts( rb_contact_buffer, rb_contact_count ); - - v3f rv; - -#if 0 - float shoe_vel[2] = {0.0f,0.0f}; - for( int i=0; i<2; i++ ) - if( mdl->shoes[i] ) - shoe_vel[i] = v3_length( mdl->ragdoll[i].rb.v ); -#endif - - for( int j=0; jragdoll_count; j++ ) - { - struct ragdoll_part *pj = &mdl->ragdoll[j]; - struct skeleton_bone *bj = &mdl->sk.bones[pj->bone_id]; - - if( pj->parent != 0xffffffff ) - { - struct ragdoll_part *pp = &mdl->ragdoll[pj->parent]; - struct skeleton_bone *bp = &mdl->sk.bones[pp->bone_id]; - - v3f lca, lcb; - v3_negate( pj->offset, lca ); - v3_add( bp->co, pp->offset, lcb ); - v3_sub( bj->co, lcb, lcb ); - - rb_debug_constraint_position( &pj->rb, lca, &pp->rb, lcb ); - - if( pj->use_limits ) - { - rb_debug_constraint_limits( &pj->rb, &pp->rb, lca, pj->limits ); - } - } - - v4f plane = {0.0f,1.0f,0.0f,0.0f}; - rb_effect_simple_bouyency( &pj->rb, plane, k_ragdoll_floatyiness, - k_ragdoll_floatydrag ); - } - - /* CONSTRAINTS */ - for( int i=0; i<10; i++ ) - { - rb_solve_contacts( rb_contact_buffer, rb_contact_count ); - - for( int j=0; jragdoll_count; j++ ) - { - struct ragdoll_part *pj = &mdl->ragdoll[j]; - struct skeleton_bone *bj = &mdl->sk.bones[pj->bone_id]; - - if( (pj->parent != 0xffffffff) && pj->use_limits ) - { - struct ragdoll_part *pp = &mdl->ragdoll[pj->parent]; - struct skeleton_bone *bp = &mdl->sk.bones[pp->bone_id]; - - v3f lca, lcb; - v3_negate( pj->offset, lca ); - v3_add( bp->co, pp->offset, lcb ); - v3_sub( bj->co, lcb, lcb ); - - rb_constraint_position( &pj->rb, lca, &pp->rb, lcb ); - - rb_constraint_limits( &pj->rb, lca, &pp->rb, lcb, pj->limits ); - } - } - } - - /* INTEGRATION */ - for( int i=0; iragdoll_count; i++ ) - rb_iter( &mdl->ragdoll[i].rb ); - - /* SHOES */ - for( int i=0; iragdoll_count; i++ ) - rb_update_transform( &mdl->ragdoll[i].rb ); -} + parts[32]; + u32 part_count; + + rb_constr_pos position_constraints[32]; + u32 position_constraints_count; + + rb_constr_swingtwist cone_constraints[32]; + u32 cone_constraints_count; + + /* TODO: Fix duplicated data */ + u32 constraint_associations[32][2]; + int shoes[2]; +}; + +static float k_ragdoll_floatyiness = 20.0f, + k_ragdoll_floatydrag = 1.0f, + k_ragdoll_limit_scale = 1.0f, + k_ragdoll_spring = 127.0f, + k_ragdoll_dampening = 15.0f, + k_ragdoll_correction = 0.5f, + k_ragdoll_angular_drag = 0.08f, + k_ragdoll_active_threshold = 5.0f; + +static int k_ragdoll_div = 1, + ragdoll_frame = 0, + k_ragdoll_debug_collider = 1, + k_ragdoll_debug_constraints = 0; + +enum player_die_type { + k_player_die_type_generic, + k_player_die_type_head, + k_player_die_type_feet +}; + +static void player_ragdoll_init(void); +static void player_init_ragdoll_bone_collider( struct skeleton_bone *bone, + struct ragdoll_part *rp ); +static u32 ragdoll_bone_parent( struct player_ragdoll *rd, u32 bone_id ); +static void setup_ragdoll_from_skeleton( struct skeleton *sk, + struct player_ragdoll *rd ); +static void copy_ragdoll_pose_to_localplayer( struct player_ragdoll *rd ); +static void copy_localplayer_to_ragdoll( struct player_ragdoll *rd, + enum player_die_type type ); + +static void player_debug_ragdoll(void); +static void player_ragdoll_iter( struct player_ragdoll *rd ); #endif /* PLAYER_RAGDOLL_H */