Fix major overstep with last commit
[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 = 10.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 /* TODO: refactor to use this style elswhere */
62 struct mdl_node *pnode = mdl_node_from_id( src, bone->orig_node );
63 struct classtype_bone *bone_inf = mdl_get_entdata( src, pnode );
64
65 rp->use_limits = bone_inf->use_limits;
66 v3_copy( bone_inf->angle_limits[0], rp->limits[0] );
67 v3_copy( bone_inf->angle_limits[1], rp->limits[1] );
68
69 rb_init( &rp->rb );
70 }
71 }
72 }
73
74 /*
75 * Make the player model copy the ragdoll
76 */
77 static void player_model_copy_ragdoll(void)
78 {
79 struct player_model *mdl = &player.mdl;
80
81 for( int i=0; i<mdl->ragdoll_count; i++ )
82 {
83 struct ragdoll_part *part = &mdl->ragdoll[i];
84 m4x3f offset;
85 m3x3_identity(offset);
86 v3_negate( part->offset, offset[3] );
87 m4x3_mul( part->rb.to_world, offset, mdl->sk.final_mtx[part->bone_id] );
88 }
89
90 skeleton_apply_inverses( &mdl->sk );
91 }
92
93 /*
94 * Make the ragdoll copy the player model
95 */
96 static void player_ragdoll_copy_model( v3f v )
97 {
98 struct player_model *mdl = &player.mdl;
99
100 for( int i=0; i<mdl->ragdoll_count; i++ )
101 {
102 struct ragdoll_part *part = &mdl->ragdoll[i];
103
104 v3f pos, offset;
105 u32 bone = part->bone_id;
106
107 m4x3_mulv( mdl->sk.final_mtx[bone], mdl->sk.bones[bone].co, pos );
108 m3x3_mulv( mdl->sk.final_mtx[bone], part->offset, offset );
109 v3_add( pos, offset, part->rb.co );
110 m3x3_q( mdl->sk.final_mtx[bone], part->rb.q );
111 v3_copy( v, part->rb.v );
112 v3_zero( part->rb.w );
113
114 rb_update_transform( &part->rb );
115 }
116 }
117
118 /*
119 * Draw rigidbody colliders for ragdoll
120 */
121 static void player_debug_ragdoll(void)
122 {
123 struct player_model *mdl = &player.mdl;
124
125 for( u32 i=0; i<mdl->ragdoll_count; i ++ )
126 rb_debug( &mdl->ragdoll[i].rb, 0xff00ff00 );
127 }
128
129 /*
130 * Ragdoll physics step
131 */
132 static void player_ragdoll_iter(void)
133 {
134 struct player_model *mdl = &player.mdl;
135 rb_solver_reset();
136
137 for( int i=0; i<mdl->ragdoll_count; i ++ )
138 rb_collide( &mdl->ragdoll[i].rb, &world.rb_geo );
139
140 rb_presolve_contacts( rb_contact_buffer, rb_contact_count );
141
142 v3f rv;
143
144 #if 0
145 float shoe_vel[2] = {0.0f,0.0f};
146 for( int i=0; i<2; i++ )
147 if( mdl->shoes[i] )
148 shoe_vel[i] = v3_length( mdl->ragdoll[i].rb.v );
149 #endif
150
151 for( int j=0; j<mdl->ragdoll_count; j++ )
152 {
153 struct ragdoll_part *pj = &mdl->ragdoll[j];
154 struct skeleton_bone *bj = &mdl->sk.bones[pj->bone_id];
155
156 if( pj->parent != 0xffffffff )
157 {
158 struct ragdoll_part *pp = &mdl->ragdoll[pj->parent];
159 struct skeleton_bone *bp = &mdl->sk.bones[pp->bone_id];
160
161 v3f lca, lcb;
162 v3_negate( pj->offset, lca );
163 v3_add( bp->co, pp->offset, lcb );
164 v3_sub( bj->co, lcb, lcb );
165
166 rb_debug_constraint_position( &pj->rb, lca, &pp->rb, lcb );
167
168 if( pj->use_limits )
169 {
170 rb_debug_constraint_limits( &pj->rb, &pp->rb, lca, pj->limits );
171 }
172 }
173
174 v4f plane = {0.0f,1.0f,0.0f,0.0f};
175 rb_effect_simple_bouyency( &pj->rb, plane, k_ragdoll_floatyiness,
176 k_ragdoll_floatydrag );
177 }
178
179 /* CONSTRAINTS */
180 for( int i=0; i<10; i++ )
181 {
182 rb_solve_contacts( rb_contact_buffer, rb_contact_count );
183
184 for( int j=0; j<mdl->ragdoll_count; j++ )
185 {
186 struct ragdoll_part *pj = &mdl->ragdoll[j];
187 struct skeleton_bone *bj = &mdl->sk.bones[pj->bone_id];
188
189 if( (pj->parent != 0xffffffff) && pj->use_limits )
190 {
191 struct ragdoll_part *pp = &mdl->ragdoll[pj->parent];
192 struct skeleton_bone *bp = &mdl->sk.bones[pp->bone_id];
193
194 v3f lca, lcb;
195 v3_negate( pj->offset, lca );
196 v3_add( bp->co, pp->offset, lcb );
197 v3_sub( bj->co, lcb, lcb );
198
199 rb_constraint_position( &pj->rb, lca, &pp->rb, lcb );
200
201 rb_constraint_limits( &pj->rb, lca, &pp->rb, lcb, pj->limits );
202 }
203 }
204 }
205
206 /* INTEGRATION */
207 for( int i=0; i<mdl->ragdoll_count; i++ )
208 rb_iter( &mdl->ragdoll[i].rb );
209
210 /* SHOES */
211 for( int i=0; i<mdl->ragdoll_count; i++ )
212 rb_update_transform( &mdl->ragdoll[i].rb );
213 }
214
215 #endif /* PLAYER_RAGDOLL_H */