1 #ifndef PLAYER_RAGDOLL_H
2 #define PLAYER_RAGDOLL_H
6 static float k_ragdoll_floatyiness
= 20.0f
,
7 k_ragdoll_floatydrag
= 1.0f
;
10 * Setup ragdoll colliders
12 static void player_init_ragdoll( mdl_header
*src
)
14 struct player_model
*mdl
= &player
.mdl
;
16 if( !mdl
->sk
.collider_count
)
18 mdl
->ragdoll_count
= 0;
22 mdl
->ragdoll
= vg_alloc(sizeof(struct ragdoll_part
)*mdl
->sk
.collider_count
);
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 struct ragdoll_part
*rp
= &mdl
->ragdoll
[ mdl
->ragdoll_count
++ ];
35 v3_sub( bone
->hitbox
[1], bone
->hitbox
[0], delta
);
36 v3_muls( delta
, 0.5f
, delta
);
38 v3_add( bone
->hitbox
[0], delta
, rp
->offset
);
40 v3_copy( delta
, rp
->rb
.bbx
[1] );
41 v3_muls( delta
, -1.0f
, rp
->rb
.bbx
[0] );
43 q_identity( rp
->rb
.q
);
44 v3_add( bone
->co
, rp
->offset
, rp
->rb
.co
);
45 rp
->rb
.type
= k_rb_shape_box
;
47 rp
->parent
= 0xffffffff;
51 for( u32 j
=0; j
<mdl
->ragdoll_count
; j
++ )
53 if( mdl
->ragdoll
[ j
].bone_id
== bone
->parent
)
61 struct mdl_node
*pnode
= mdl_node_from_id( src
, bone
->orig_node
);
62 struct classtype_bone
*bone_inf
= mdl_get_entdata( src
, pnode
);
64 rp
->use_limits
= bone_inf
->use_limits
;
65 v3_copy( bone_inf
->angle_limits
[0], rp
->limits
[0] );
66 v3_copy( bone_inf
->angle_limits
[1], rp
->limits
[1] );
74 * Make the player model copy the ragdoll
76 static void player_model_copy_ragdoll(void)
78 struct player_model
*mdl
= &player
.mdl
;
80 for( int i
=0; i
<mdl
->ragdoll_count
; i
++ )
82 struct ragdoll_part
*part
= &mdl
->ragdoll
[i
];
84 m3x3_identity(offset
);
85 v3_negate( part
->offset
, offset
[3] );
86 m4x3_mul( part
->rb
.to_world
, offset
, mdl
->sk
.final_mtx
[part
->bone_id
] );
89 skeleton_apply_inverses( &mdl
->sk
);
93 * Make the ragdoll copy the player model
95 static void player_ragdoll_copy_model( v3f v
)
97 struct player_model
*mdl
= &player
.mdl
;
99 for( int i
=0; i
<mdl
->ragdoll_count
; i
++ )
101 struct ragdoll_part
*part
= &mdl
->ragdoll
[i
];
104 u32 bone
= part
->bone_id
;
106 m4x3_mulv( mdl
->sk
.final_mtx
[bone
], mdl
->sk
.bones
[bone
].co
, pos
);
107 m3x3_mulv( mdl
->sk
.final_mtx
[bone
], part
->offset
, offset
);
108 v3_add( pos
, offset
, part
->rb
.co
);
109 m3x3_q( mdl
->sk
.final_mtx
[bone
], part
->rb
.q
);
110 v3_copy( v
, part
->rb
.v
);
111 v3_zero( part
->rb
.w
);
113 rb_update_transform( &part
->rb
);
118 * Draw rigidbody colliders for ragdoll
120 static void player_debug_ragdoll(void)
122 struct player_model
*mdl
= &player
.mdl
;
124 for( u32 i
=0; i
<mdl
->ragdoll_count
; i
++ )
125 rb_debug( &mdl
->ragdoll
[i
].rb
, 0xff00ff00 );
129 * Ragdoll physics step
131 static void player_ragdoll_iter(void)
133 struct player_model
*mdl
= &player
.mdl
;
136 for( int i
=0; i
<mdl
->ragdoll_count
; i
++ )
137 rb_collide( &mdl
->ragdoll
[i
].rb
, &world
.rb_geo
);
139 rb_presolve_contacts( rb_contact_buffer
, rb_contact_count
);
144 float shoe_vel
[2] = {0.0f
,0.0f
};
145 for( int i
=0; i
<2; i
++ )
147 shoe_vel
[i
] = v3_length( mdl
->ragdoll
[i
].rb
.v
);
150 for( int j
=0; j
<mdl
->ragdoll_count
; j
++ )
152 struct ragdoll_part
*pj
= &mdl
->ragdoll
[j
];
153 struct skeleton_bone
*bj
= &mdl
->sk
.bones
[pj
->bone_id
];
155 if( pj
->parent
!= 0xffffffff )
157 struct ragdoll_part
*pp
= &mdl
->ragdoll
[pj
->parent
];
158 struct skeleton_bone
*bp
= &mdl
->sk
.bones
[pp
->bone_id
];
161 v3_negate( pj
->offset
, lca
);
162 v3_add( bp
->co
, pp
->offset
, lcb
);
163 v3_sub( bj
->co
, lcb
, lcb
);
165 rb_debug_constraint_position( &pj
->rb
, lca
, &pp
->rb
, lcb
);
169 rb_debug_constraint_limits( &pj
->rb
, &pp
->rb
, lca
, pj
->limits
);
173 v4f plane
= {0.0f
,1.0f
,0.0f
,0.0f
};
174 rb_effect_simple_bouyency( &pj
->rb
, plane
, k_ragdoll_floatyiness
,
175 k_ragdoll_floatydrag
);
179 for( int i
=0; i
<10; i
++ )
181 rb_solve_contacts( rb_contact_buffer
, rb_contact_count
);
183 for( int j
=0; j
<mdl
->ragdoll_count
; j
++ )
185 struct ragdoll_part
*pj
= &mdl
->ragdoll
[j
];
186 struct skeleton_bone
*bj
= &mdl
->sk
.bones
[pj
->bone_id
];
188 if( (pj
->parent
!= 0xffffffff) && pj
->use_limits
)
190 struct ragdoll_part
*pp
= &mdl
->ragdoll
[pj
->parent
];
191 struct skeleton_bone
*bp
= &mdl
->sk
.bones
[pp
->bone_id
];
194 v3_negate( pj
->offset
, lca
);
195 v3_add( bp
->co
, pp
->offset
, lcb
);
196 v3_sub( bj
->co
, lcb
, lcb
);
198 rb_constraint_position( &pj
->rb
, lca
, &pp
->rb
, lcb
);
200 rb_constraint_limits( &pj
->rb
, lca
, &pp
->rb
, lcb
, pj
->limits
);
206 for( int i
=0; i
<mdl
->ragdoll_count
; i
++ )
207 rb_iter( &mdl
->ragdoll
[i
].rb
);
210 for( int i
=0; i
<mdl
->ragdoll_count
; i
++ )
211 rb_update_transform( &mdl
->ragdoll
[i
].rb
);
214 #endif /* PLAYER_RAGDOLL_H */