dont remember
[carveJwlIkooP6JGAAIwe30JlM.git] / player_ragdoll.h
1 #ifndef PLAYER_RAGDOLL_H
2 #define PLAYER_RAGDOLL_H
3
4 #include "player.h"
5
6 static float k_ragdoll_floatyiness = 40.0f,
7 k_ragdoll_floatydrag = 1.0f;
8
9 /*
10 * Setup ragdoll colliders
11 */
12 static void player_init_ragdoll( mdl_header *src )
13 {
14 struct player_model *mdl = &player.mdl;
15
16 if( !mdl->sk.collider_count )
17 {
18 mdl->ragdoll_count = 0;
19 return;
20 }
21
22 mdl->ragdoll = vg_alloc(sizeof(struct ragdoll_part)*mdl->sk.collider_count);
23 mdl->ragdoll_count = 0;
24
25 for( u32 i=0; i<mdl->sk.bone_count; i ++ )
26 {
27 struct skeleton_bone *bone = &mdl->sk.bones[i];
28
29 if( bone->collider )
30 {
31 struct ragdoll_part *rp = &mdl->ragdoll[ mdl->ragdoll_count ++ ];
32 rp->bone_id = i;
33
34 v3f delta;
35 v3_sub( bone->hitbox[1], bone->hitbox[0], delta );
36 v3_muls( delta, 0.5f, delta );
37
38 v3_add( bone->hitbox[0], delta, rp->offset );
39
40 v3_copy( delta, rp->rb.bbx[1] );
41 v3_muls( delta, -1.0f, rp->rb.bbx[0] );
42
43 q_identity( rp->rb.q );
44 v3_add( bone->co, rp->offset, rp->rb.co );
45 rp->rb.type = k_rb_shape_box;
46 rp->rb.is_world = 0;
47 rp->parent = 0xffffffff;
48
49 if( bone->parent )
50 {
51 for( u32 j=0; j<mdl->ragdoll_count; j++ )
52 {
53 if( mdl->ragdoll[ j ].bone_id == bone->parent )
54 {
55 rp->parent = j;
56 break;
57 }
58 }
59 }
60
61 struct mdl_node *pnode = mdl_node_from_id( src, bone->orig_node );
62 struct classtype_bone *bone_inf = mdl_get_entdata( src, pnode );
63
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] );
67
68 rb_init( &rp->rb );
69 }
70 }
71 }
72
73 /*
74 * Make the player model copy the ragdoll
75 */
76 static void player_model_copy_ragdoll(void)
77 {
78 struct player_model *mdl = &player.mdl;
79
80 for( int i=0; i<mdl->ragdoll_count; i++ )
81 {
82 struct ragdoll_part *part = &mdl->ragdoll[i];
83 m4x3f offset;
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] );
87 }
88
89 skeleton_apply_inverses( &mdl->sk );
90 }
91
92 /*
93 * Make the ragdoll copy the player model
94 */
95 static void player_ragdoll_copy_model( v3f v )
96 {
97 struct player_model *mdl = &player.mdl;
98
99 for( int i=0; i<mdl->ragdoll_count; i++ )
100 {
101 struct ragdoll_part *part = &mdl->ragdoll[i];
102
103 v3f pos, offset;
104 u32 bone = part->bone_id;
105
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 );
112
113 rb_update_transform( &part->rb );
114 }
115 }
116
117 /*
118 * Draw rigidbody colliders for ragdoll
119 */
120 static void player_debug_ragdoll(void)
121 {
122 struct player_model *mdl = &player.mdl;
123
124 for( u32 i=0; i<mdl->ragdoll_count; i ++ )
125 rb_debug( &mdl->ragdoll[i].rb, 0xff00ff00 );
126 }
127
128 /*
129 * Ragdoll physics step
130 */
131 static void player_ragdoll_iter(void)
132 {
133 struct player_model *mdl = &player.mdl;
134 rb_solver_reset();
135
136 for( int i=0; i<mdl->ragdoll_count; i ++ )
137 rb_collide( &mdl->ragdoll[i].rb, &world.rb_geo );
138
139 rb_presolve_contacts( rb_contact_buffer, rb_contact_count );
140
141 v3f rv;
142
143 #if 0
144 float shoe_vel[2] = {0.0f,0.0f};
145 for( int i=0; i<2; i++ )
146 if( mdl->shoes[i] )
147 shoe_vel[i] = v3_length( mdl->ragdoll[i].rb.v );
148 #endif
149
150 for( int j=0; j<mdl->ragdoll_count; j++ )
151 {
152 struct ragdoll_part *pj = &mdl->ragdoll[j];
153 struct skeleton_bone *bj = &mdl->sk.bones[pj->bone_id];
154
155 if( pj->parent != 0xffffffff )
156 {
157 struct ragdoll_part *pp = &mdl->ragdoll[pj->parent];
158 struct skeleton_bone *bp = &mdl->sk.bones[pp->bone_id];
159
160 v3f lca, lcb;
161 v3_negate( pj->offset, lca );
162 v3_add( bp->co, pp->offset, lcb );
163 v3_sub( bj->co, lcb, lcb );
164
165 rb_debug_constraint_position( &pj->rb, lca, &pp->rb, lcb );
166
167 if( pj->use_limits )
168 {
169 rb_debug_constraint_limits( &pj->rb, &pp->rb, lca, pj->limits );
170 }
171 }
172
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 );
176 }
177
178 /* CONSTRAINTS */
179 for( int i=0; i<10; i++ )
180 {
181 rb_solve_contacts( rb_contact_buffer, rb_contact_count );
182
183 for( int j=0; j<mdl->ragdoll_count; j++ )
184 {
185 struct ragdoll_part *pj = &mdl->ragdoll[j];
186 struct skeleton_bone *bj = &mdl->sk.bones[pj->bone_id];
187
188 if( (pj->parent != 0xffffffff) && pj->use_limits )
189 {
190 struct ragdoll_part *pp = &mdl->ragdoll[pj->parent];
191 struct skeleton_bone *bp = &mdl->sk.bones[pp->bone_id];
192
193 v3f lca, lcb;
194 v3_negate( pj->offset, lca );
195 v3_add( bp->co, pp->offset, lcb );
196 v3_sub( bj->co, lcb, lcb );
197
198 rb_constraint_position( &pj->rb, lca, &pp->rb, lcb );
199
200 rb_constraint_limits( &pj->rb, lca, &pp->rb, lcb, pj->limits );
201 }
202 }
203 }
204
205 /* INTEGRATION */
206 for( int i=0; i<mdl->ragdoll_count; i++ )
207 rb_iter( &mdl->ragdoll[i].rb );
208
209 /* SHOES */
210 for( int i=0; i<mdl->ragdoll_count; i++ )
211 rb_update_transform( &mdl->ragdoll[i].rb );
212 }
213
214 #endif /* PLAYER_RAGDOLL_H */