1 #ifndef PLAYER_RAGDOLL_H
2 #define PLAYER_RAGDOLL_H
6 VG_STATIC
float k_ragdoll_floatyiness
= 20.0f
,
7 k_ragdoll_floatydrag
= 1.0f
;
10 * Setup ragdoll colliders
12 VG_STATIC
void player_init_ragdoll(void)
14 struct player_model
*mdl
= &player
.mdl
;
15 mdl_context
*src
= &mdl
->meta
;
17 if( !mdl
->sk
.collider_count
)
19 mdl
->ragdoll_count
= 0;
23 mdl
->ragdoll_count
= 0;
25 for( u32 i
=0; i
<mdl
->sk
.bone_count
; i
++ )
27 struct skeleton_bone
*bone
= &mdl
->sk
.bones
[i
];
31 if( mdl
->ragdoll_count
> vg_list_size(player
.mdl
.ragdoll
) )
32 vg_fatal_exit_loop( "Playermodel has too many colliders" );
34 struct ragdoll_part
*rp
= &mdl
->ragdoll
[ mdl
->ragdoll_count
++ ];
38 v3_sub( bone
->hitbox
[1], bone
->hitbox
[0], delta
);
39 v3_muls( delta
, 0.5f
, delta
);
41 v3_add( bone
->hitbox
[0], delta
, rp
->offset
);
43 v3_copy( delta
, rp
->rb
.bbx
[1] );
44 v3_muls( delta
, -1.0f
, rp
->rb
.bbx
[0] );
46 q_identity( rp
->rb
.q
);
47 v3_add( bone
->co
, rp
->offset
, rp
->rb
.co
);
48 rp
->rb
.type
= k_rb_shape_box
;
50 rp
->parent
= 0xffffffff;
54 for( u32 j
=0; j
<mdl
->ragdoll_count
; j
++ )
56 if( mdl
->ragdoll
[ j
].bone_id
== bone
->parent
)
64 struct mdl_node
*pnode
= mdl_node_from_id( src
, bone
->orig_node
);
65 struct classtype_bone
*bone_inf
= mdl_get_entdata( src
, pnode
);
67 rp
->use_limits
= bone_inf
->use_limits
;
68 v3_copy( bone_inf
->angle_limits
[0], rp
->limits
[0] );
69 v3_copy( bone_inf
->angle_limits
[1], rp
->limits
[1] );
77 * Make the player model copy the ragdoll
79 VG_STATIC
void player_model_copy_ragdoll(void)
81 struct player_model
*mdl
= &player
.mdl
;
83 for( int i
=0; i
<mdl
->ragdoll_count
; i
++ )
85 struct ragdoll_part
*part
= &mdl
->ragdoll
[i
];
87 m3x3_identity(offset
);
88 v3_negate( part
->offset
, offset
[3] );
89 m4x3_mul( part
->rb
.to_world
, offset
, mdl
->sk
.final_mtx
[part
->bone_id
] );
92 skeleton_apply_inverses( &mdl
->sk
);
96 * Make the ragdoll copy the player model
98 VG_STATIC
void player_ragdoll_copy_model( v3f v
)
100 struct player_model
*mdl
= &player
.mdl
;
102 for( int i
=0; i
<mdl
->ragdoll_count
; i
++ )
104 struct ragdoll_part
*part
= &mdl
->ragdoll
[i
];
107 u32 bone
= part
->bone_id
;
109 m4x3_mulv( mdl
->sk
.final_mtx
[bone
], mdl
->sk
.bones
[bone
].co
, pos
);
110 m3x3_mulv( mdl
->sk
.final_mtx
[bone
], part
->offset
, offset
);
111 v3_add( pos
, offset
, part
->rb
.co
);
112 m3x3_q( mdl
->sk
.final_mtx
[bone
], part
->rb
.q
);
113 v3_copy( v
, part
->rb
.v
);
114 v3_zero( part
->rb
.w
);
116 rb_update_transform( &part
->rb
);
121 * Draw rigidbody colliders for ragdoll
123 VG_STATIC
void player_debug_ragdoll(void)
125 struct player_model
*mdl
= &player
.mdl
;
127 for( u32 i
=0; i
<mdl
->ragdoll_count
; i
++ )
128 rb_debug( &mdl
->ragdoll
[i
].rb
, 0xff00ff00 );
132 * Ragdoll physics step
134 VG_STATIC
void player_ragdoll_iter(void)
136 struct player_model
*mdl
= &player
.mdl
;
139 for( int i
=0; i
<mdl
->ragdoll_count
; i
++ )
140 rb_collide( &mdl
->ragdoll
[i
].rb
, &world
.rb_geo
);
142 rb_presolve_contacts( rb_contact_buffer
, rb_contact_count
);
147 float shoe_vel
[2] = {0.0f
,0.0f
};
148 for( int i
=0; i
<2; i
++ )
150 shoe_vel
[i
] = v3_length( mdl
->ragdoll
[i
].rb
.v
);
153 for( int j
=0; j
<mdl
->ragdoll_count
; j
++ )
155 struct ragdoll_part
*pj
= &mdl
->ragdoll
[j
];
156 struct skeleton_bone
*bj
= &mdl
->sk
.bones
[pj
->bone_id
];
158 if( pj
->parent
!= 0xffffffff )
160 struct ragdoll_part
*pp
= &mdl
->ragdoll
[pj
->parent
];
161 struct skeleton_bone
*bp
= &mdl
->sk
.bones
[pp
->bone_id
];
164 v3_negate( pj
->offset
, lca
);
165 v3_add( bp
->co
, pp
->offset
, lcb
);
166 v3_sub( bj
->co
, lcb
, lcb
);
168 rb_debug_constraint_position( &pj
->rb
, lca
, &pp
->rb
, lcb
);
172 rb_debug_constraint_limits( &pj
->rb
, &pp
->rb
, lca
, pj
->limits
);
176 v4f plane
= {0.0f
,1.0f
,0.0f
,0.0f
};
177 rb_effect_simple_bouyency( &pj
->rb
, plane
, k_ragdoll_floatyiness
,
178 k_ragdoll_floatydrag
);
182 for( int i
=0; i
<10; i
++ )
184 rb_solve_contacts( rb_contact_buffer
, rb_contact_count
);
186 for( int j
=0; j
<mdl
->ragdoll_count
; j
++ )
188 struct ragdoll_part
*pj
= &mdl
->ragdoll
[j
];
189 struct skeleton_bone
*bj
= &mdl
->sk
.bones
[pj
->bone_id
];
191 if( (pj
->parent
!= 0xffffffff) && pj
->use_limits
)
193 struct ragdoll_part
*pp
= &mdl
->ragdoll
[pj
->parent
];
194 struct skeleton_bone
*bp
= &mdl
->sk
.bones
[pp
->bone_id
];
197 v3_negate( pj
->offset
, lca
);
198 v3_add( bp
->co
, pp
->offset
, lcb
);
199 v3_sub( bj
->co
, lcb
, lcb
);
201 rb_constraint_position( &pj
->rb
, lca
, &pp
->rb
, lcb
);
203 rb_constraint_limits( &pj
->rb
, lca
, &pp
->rb
, lcb
, pj
->limits
);
209 for( int i
=0; i
<mdl
->ragdoll_count
; i
++ )
210 rb_iter( &mdl
->ragdoll
[i
].rb
);
213 for( int i
=0; i
<mdl
->ragdoll_count
; i
++ )
214 rb_update_transform( &mdl
->ragdoll
[i
].rb
);
217 #endif /* PLAYER_RAGDOLL_H */