2 #include "vg_rigidbody.h"
3 #include "vg_rigidbody_constraints.h"
8 * -----------------------------------------------------------------------------
10 * -----------------------------------------------------------------------------
13 void rb_debug_position_constraints( rb_constr_pos
*buffer
, int len
)
15 for( int i
=0; i
<len
; i
++ ){
16 rb_constr_pos
*constr
= &buffer
[i
];
17 rigidbody
*rba
= constr
->rba
, *rbb
= constr
->rbb
;
20 m3x3_mulv( rba
->to_world
, constr
->lca
, wca
);
21 m3x3_mulv( rbb
->to_world
, constr
->lcb
, wcb
);
24 v3_add( wca
, rba
->co
, p0
);
25 v3_add( wcb
, rbb
->co
, p1
);
26 vg_line_point( p0
, 0.0025f
, 0xff000000 );
27 vg_line_point( p1
, 0.0025f
, 0xffffffff );
28 vg_line2( p0
, p1
, 0xff000000, 0xffffffff );
32 void rb_presolve_swingtwist_constraints( rb_constr_swingtwist
*buf
, int len
)
34 for( int i
=0; i
<len
; i
++ ){
35 rb_constr_swingtwist
*st
= &buf
[ i
];
37 v3f vx
, vy
, va
, vxb
, axis
, center
;
39 m3x3_mulv( st
->rba
->to_world
, st
->conevx
, vx
);
40 m3x3_mulv( st
->rbb
->to_world
, st
->conevxb
, vxb
);
41 m3x3_mulv( st
->rba
->to_world
, st
->conevy
, vy
);
42 m3x3_mulv( st
->rbb
->to_world
, st
->coneva
, va
);
43 m4x3_mulv( st
->rba
->to_world
, st
->view_offset
, center
);
44 v3_cross( vy
, vx
, axis
);
46 /* Constraint violated ? */
47 float fx
= v3_dot( vx
, va
), /* projection world */
48 fy
= v3_dot( vy
, va
),
49 fn
= v3_dot( va
, axis
),
51 rx
= st
->conevx
[3], /* elipse radii */
54 lx
= fx
/rx
, /* projection local (fn==lz) */
57 st
->tangent_violation
= ((lx
*lx
+ ly
*ly
) > fn
*fn
) || (fn
<= 0.0f
);
58 if( st
->tangent_violation
){
59 /* Calculate a good position and the axis to solve on */
61 p
= { fx
/fabsf(fn
), fy
/fabsf(fn
) };
63 closest_point_elipse( p
, (v2f
){rx
,ry
}, closest
);
64 tangent
[0] = -closest
[1] / (ry
*ry
);
65 tangent
[1] = closest
[0] / (rx
*rx
);
66 v2_normalize( tangent
);
69 v3_muladds( axis
, vx
, closest
[0], v0
);
70 v3_muladds( v0
, vy
, closest
[1], v0
);
73 v3_muls( vx
, tangent
[0], v1
);
74 v3_muladds( v1
, vy
, tangent
[1], v1
);
76 v3_copy( v0
, st
->tangent_target
);
77 v3_copy( v1
, st
->tangent_axis
);
81 m3x3_mulv( st
->rba
->iIw
, st
->tangent_axis
, aIw
);
82 m3x3_mulv( st
->rbb
->iIw
, st
->tangent_axis
, bIw
);
83 st
->tangent_mass
= 1.0f
/ (v3_dot( st
->tangent_axis
, aIw
) +
84 v3_dot( st
->tangent_axis
, bIw
));
86 float angle
= v3_dot( va
, st
->tangent_target
);
90 v3_cross( vy
, va
, refaxis
); /* our default rotation */
91 v3_normalize( refaxis
);
93 float angle
= v3_dot( refaxis
, vxb
);
94 st
->axis_violation
= fabsf(angle
) < st
->conet
;
96 if( st
->axis_violation
){
98 v3_cross( refaxis
, vxb
, dir_test
);
100 if( v3_dot(dir_test
, va
) < 0.0f
)
101 st
->axis_violation
= -st
->axis_violation
;
103 float newang
= (float)st
->axis_violation
* acosf(st
->conet
-0.0001f
);
106 v3_cross( va
, refaxis
, refaxis_up
);
107 v3_muls( refaxis_up
, sinf(newang
), st
->axis_target
);
108 v3_muladds( st
->axis_target
, refaxis
, -cosf(newang
), st
->axis_target
);
111 v3_copy( va
, st
->axis
);
113 m3x3_mulv( st
->rba
->iIw
, st
->axis
, aIw
);
114 m3x3_mulv( st
->rbb
->iIw
, st
->axis
, bIw
);
115 st
->axis_mass
= 1.0f
/ (v3_dot( st
->axis
, aIw
) +
116 v3_dot( st
->axis
, bIw
));
121 void rb_debug_swingtwist_constraints( rb_constr_swingtwist
*buf
, int len
)
125 for( int i
=0; i
<len
; i
++ ){
126 rb_constr_swingtwist
*st
= &buf
[ i
];
128 v3f vx
, vxb
, vy
, va
, axis
, center
;
130 m3x3_mulv( st
->rba
->to_world
, st
->conevx
, vx
);
131 m3x3_mulv( st
->rbb
->to_world
, st
->conevxb
, vxb
);
132 m3x3_mulv( st
->rba
->to_world
, st
->conevy
, vy
);
133 m3x3_mulv( st
->rbb
->to_world
, st
->coneva
, va
);
134 m4x3_mulv( st
->rba
->to_world
, st
->view_offset
, center
);
135 v3_cross( vy
, vx
, axis
);
137 float rx
= st
->conevx
[3], /* elipse radii */
141 v3_muladds( center
, va
, size
, p1
);
142 vg_line( center
, p1
, 0xffffffff );
143 vg_line_point( p1
, 0.00025f
, 0xffffffff );
145 if( st
->tangent_violation
){
146 v3_muladds( center
, st
->tangent_target
, size
, p0
);
148 vg_line( center
, p0
, 0xff00ff00 );
149 vg_line_point( p0
, 0.00025f
, 0xff00ff00 );
150 vg_line( p1
, p0
, 0xff000000 );
153 for( int x
=0; x
<32; x
++ ){
154 float t0
= ((float)x
* (1.0f
/32.0f
)) * VG_TAUf
,
155 t1
= (((float)x
+1.0f
) * (1.0f
/32.0f
)) * VG_TAUf
,
162 v3_muladds( axis
, vx
, c0
*rx
, v0
);
163 v3_muladds( v0
, vy
, s0
*ry
, v0
);
164 v3_muladds( axis
, vx
, c1
*rx
, v1
);
165 v3_muladds( v1
, vy
, s1
*ry
, v1
);
170 v3_muladds( center
, v0
, size
, p0
);
171 v3_muladds( center
, v1
, size
, p1
);
173 u32 col0r
= fabsf(c0
) * 255.0f
,
174 col0g
= fabsf(s0
) * 255.0f
,
175 col1r
= fabsf(c1
) * 255.0f
,
176 col1g
= fabsf(s1
) * 255.0f
,
177 col
= st
->tangent_violation
? 0xff0000ff: 0xff000000,
178 col0
= col
| (col0r
<<16) | (col0g
<< 8),
179 col1
= col
| (col1r
<<16) | (col1g
<< 8);
181 vg_line2( center
, p0
, VG__NONE
, col0
);
182 vg_line2( p0
, p1
, col0
, col1
);
186 v3_muladds( center
, va
, size
, p0
);
187 v3_muladds( p0
, vxb
, size
, p1
);
189 vg_line( p0
, p1
, 0xff0000ff );
191 if( st
->axis_violation
){
192 v3_muladds( p0
, st
->axis_target
, size
*1.25f
, p1
);
193 vg_line( p0
, p1
, 0xffffff00 );
194 vg_line_point( p1
, 0.0025f
, 0xffffff80 );
198 v3_cross( vy
, va
, refaxis
); /* our default rotation */
199 v3_normalize( refaxis
);
201 v3_cross( va
, refaxis
, refaxis_up
);
202 float newang
= acosf(st
->conet
-0.0001f
);
204 v3_muladds( p0
, refaxis_up
, sinf(newang
)*size
, p1
);
205 v3_muladds( p1
, refaxis
, -cosf(newang
)*size
, p1
);
206 vg_line( p0
, p1
, 0xff000000 );
208 v3_muladds( p0
, refaxis_up
, sinf(-newang
)*size
, p1
);
209 v3_muladds( p1
, refaxis
, -cosf(-newang
)*size
, p1
);
210 vg_line( p0
, p1
, 0xff404040 );
214 void rb_solve_position_constraints( rb_constr_pos
*buf
, int len
)
216 for( int i
=0; i
<len
; i
++ ){
217 rb_constr_pos
*constr
= &buf
[i
];
218 rigidbody
*rba
= constr
->rba
, *rbb
= constr
->rbb
;
221 m3x3_mulv( rba
->to_world
, constr
->lca
, wa
);
222 m3x3_mulv( rbb
->to_world
, constr
->lcb
, wb
);
224 m3x3f ssra
, ssrat
, ssrb
, ssrbt
;
226 m3x3_skew_symetric( ssrat
, wa
);
227 m3x3_skew_symetric( ssrbt
, wb
);
228 m3x3_transpose( ssrat
, ssra
);
229 m3x3_transpose( ssrbt
, ssrb
);
231 v3f b
, b_wa
, b_wb
, b_a
, b_b
;
232 m3x3_mulv( ssra
, rba
->w
, b_wa
);
233 m3x3_mulv( ssrb
, rbb
->w
, b_wb
);
234 v3_add( rba
->v
, b_wa
, b
);
235 v3_sub( b
, rbb
->v
, b
);
236 v3_sub( b
, b_wb
, b
);
237 v3_muls( b
, -1.0f
, b
);
240 m3x3_diagonal( invMa
, rba
->inv_mass
);
241 m3x3_diagonal( invMb
, rbb
->inv_mass
);
244 m3x3_mul( ssra
, rba
->iIw
, ia
);
245 m3x3_mul( ia
, ssrat
, ia
);
246 m3x3_mul( ssrb
, rbb
->iIw
, ib
);
247 m3x3_mul( ib
, ssrbt
, ib
);
250 m3x3_add( invMa
, ia
, cma
);
251 m3x3_add( invMb
, ib
, cmb
);
254 m3x3_add( cma
, cmb
, A
);
256 /* Solve Ax = b ( A^-1*b = x ) */
260 m3x3_mulv( invA
, b
, impulse
);
262 v3f delta_va
, delta_wa
, delta_vb
, delta_wb
;
264 m3x3_mul( rba
->iIw
, ssrat
, iwa
);
265 m3x3_mul( rbb
->iIw
, ssrbt
, iwb
);
267 m3x3_mulv( invMa
, impulse
, delta_va
);
268 m3x3_mulv( invMb
, impulse
, delta_vb
);
269 m3x3_mulv( iwa
, impulse
, delta_wa
);
270 m3x3_mulv( iwb
, impulse
, delta_wb
);
272 v3_add( rba
->v
, delta_va
, rba
->v
);
273 v3_add( rba
->w
, delta_wa
, rba
->w
);
274 v3_sub( rbb
->v
, delta_vb
, rbb
->v
);
275 v3_sub( rbb
->w
, delta_wb
, rbb
->w
);
279 void rb_solve_swingtwist_constraints( rb_constr_swingtwist
*buf
, int len
)
281 for( int i
=0; i
<len
; i
++ ){
282 rb_constr_swingtwist
*st
= &buf
[ i
];
284 if( !st
->axis_violation
)
287 float rv
= v3_dot( st
->axis
, st
->rbb
->w
) -
288 v3_dot( st
->axis
, st
->rba
->w
);
290 if( rv
* (float)st
->axis_violation
> 0.0f
)
294 v3_muls( st
->axis
, rv
*st
->axis_mass
, impulse
);
295 m3x3_mulv( st
->rba
->iIw
, impulse
, wa
);
296 v3_add( st
->rba
->w
, wa
, st
->rba
->w
);
298 v3_muls( impulse
, -1.0f
, impulse
);
299 m3x3_mulv( st
->rbb
->iIw
, impulse
, wb
);
300 v3_add( st
->rbb
->w
, wb
, st
->rbb
->w
);
302 float rv2
= v3_dot( st
->axis
, st
->rbb
->w
) -
303 v3_dot( st
->axis
, st
->rba
->w
);
306 for( int i
=0; i
<len
; i
++ ){
307 rb_constr_swingtwist
*st
= &buf
[ i
];
309 if( !st
->tangent_violation
)
312 float rv
= v3_dot( st
->tangent_axis
, st
->rbb
->w
) -
313 v3_dot( st
->tangent_axis
, st
->rba
->w
);
319 v3_muls( st
->tangent_axis
, rv
*st
->tangent_mass
, impulse
);
320 m3x3_mulv( st
->rba
->iIw
, impulse
, wa
);
321 v3_add( st
->rba
->w
, wa
, st
->rba
->w
);
323 v3_muls( impulse
, -1.0f
, impulse
);
324 m3x3_mulv( st
->rbb
->iIw
, impulse
, wb
);
325 v3_add( st
->rbb
->w
, wb
, st
->rbb
->w
);
327 float rv2
= v3_dot( st
->tangent_axis
, st
->rbb
->w
) -
328 v3_dot( st
->tangent_axis
, st
->rba
->w
);
333 void rb_postsolve_swingtwist_constraints( rb_constr_swingtwist
*buf
, u32 len
)
335 for( int i
=0; i
<len
; i
++ ){
336 rb_constr_swingtwist
*st
= &buf
[ i
];
338 if( !st
->axis_violation
){
339 st
->conv_axis
= 0.0f
;
343 f32 rv
= v3_dot( st
->axis
, st
->rbb
->w
) -
344 v3_dot( st
->axis
, st
->rba
->w
);
346 if( rv
* (f32
)st
->axis_violation
> 0.0f
)
347 st
->conv_axis
= 0.0f
;
352 for( int i
=0; i
<len
; i
++ ){
353 rb_constr_swingtwist
*st
= &buf
[ i
];
355 if( !st
->tangent_violation
){
356 st
->conv_tangent
= 0.0f
;
360 f32 rv
= v3_dot( st
->tangent_axis
, st
->rbb
->w
) -
361 v3_dot( st
->tangent_axis
, st
->rba
->w
);
364 st
->conv_tangent
= 0.0f
;
366 st
->conv_tangent
= rv
;
370 void rb_solve_constr_angle( rigidbody
*rba
, rigidbody
*rbb
, v3f ra
, v3f rb
)
372 m3x3f ssra
, ssrb
, ssrat
, ssrbt
;
375 m3x3_skew_symetric( ssrat
, ra
);
376 m3x3_skew_symetric( ssrbt
, rb
);
377 m3x3_transpose( ssrat
, ssra
);
378 m3x3_transpose( ssrbt
, ssrb
);
380 m3x3_mul( ssra
, rba
->iIw
, cma
);
381 m3x3_mul( cma
, ssrat
, cma
);
382 m3x3_mul( ssrb
, rbb
->iIw
, cmb
);
383 m3x3_mul( cmb
, ssrbt
, cmb
);
386 m3x3_add( cma
, cmb
, A
);
390 m3x3_mulv( ssra
, rba
->w
, b_wa
);
391 m3x3_mulv( ssrb
, rbb
->w
, b_wb
);
392 v3_add( b_wa
, b_wb
, b
);
396 m3x3_mulv( invA
, b
, impulse
);
398 v3f delta_wa
, delta_wb
;
400 m3x3_mul( rba
->iIw
, ssrat
, iwa
);
401 m3x3_mul( rbb
->iIw
, ssrbt
, iwb
);
402 m3x3_mulv( iwa
, impulse
, delta_wa
);
403 m3x3_mulv( iwb
, impulse
, delta_wb
);
404 v3_add( rba
->w
, delta_wa
, rba
->w
);
405 v3_sub( rbb
->w
, delta_wb
, rbb
->w
);
408 void rb_correct_position_constraints( rb_constr_pos
*buf
, int len
, f32 amt
)
410 for( int i
=0; i
<len
; i
++ ){
411 rb_constr_pos
*constr
= &buf
[i
];
412 rigidbody
*rba
= constr
->rba
, *rbb
= constr
->rbb
;
415 m3x3_mulv( rba
->to_world
, constr
->lca
, p0
);
416 m3x3_mulv( rbb
->to_world
, constr
->lcb
, p1
);
417 v3_add( rba
->co
, p0
, p0
);
418 v3_add( rbb
->co
, p1
, p1
);
422 v3_muladds( rbb
->co
, d
, -1.0f
* amt
, rbb
->co
);
423 rb_update_matrices( rbb
);
425 f32 mt
= 1.0f
/(rba
->inv_mass
+rbb
->inv_mass
),
426 a
= mt
* (k_phys_baumgarte
/k_rb_delta
);
428 v3_muladds( rba
->v
, d
, a
* rba
->inv_mass
, rba
->v
);
429 v3_muladds( rbb
->v
, d
, a
*-rbb
->inv_mass
, rbb
->v
);
434 void rb_correct_swingtwist_constraints( rb_constr_swingtwist
*buf
,
437 for( int i
=0; i
<len
; i
++ ){
438 rb_constr_swingtwist
*st
= &buf
[i
];
440 if( !st
->tangent_violation
)
444 m3x3_mulv( st
->rbb
->to_world
, st
->coneva
, va
);
446 f32 angle
= v3_dot( va
, st
->tangent_target
);
448 if( fabsf(angle
) < 0.9999f
){
450 v3_cross( va
, st
->tangent_target
, axis
);
452 angle
= acosf(angle
) * amt
;
454 q_axis_angle( correction
, axis
, angle
);
455 q_mul( correction
, st
->rbb
->q
, st
->rbb
->q
);
456 q_normalize( st
->rbb
->q
);
457 rb_update_matrices( st
->rbb
);
459 f32 mt
= 1.0f
/(st
->rba
->inv_mass
+st
->rbb
->inv_mass
),
460 wa
= mt
* acosf(angle
) * (k_phys_baumgarte
/k_rb_delta
);
461 //v3_muladds( st->rba->w, axis, wa*-st->rba->inv_mass, st->rba->w );
462 v3_muladds( st
->rbb
->w
, axis
, wa
* st
->rbb
->inv_mass
, st
->rbb
->w
);
467 for( int i
=0; i
<len
; i
++ ){
468 rb_constr_swingtwist
*st
= &buf
[i
];
470 if( !st
->axis_violation
)
474 m3x3_mulv( st
->rbb
->to_world
, st
->conevxb
, vxb
);
476 f32 angle
= v3_dot( vxb
, st
->axis_target
);
478 if( fabsf(angle
) < 0.9999f
){
480 v3_cross( vxb
, st
->axis_target
, axis
);
483 angle
= acosf(angle
) * amt
;
485 q_axis_angle( correction
, axis
, angle
);
486 q_mul( correction
, st
->rbb
->q
, st
->rbb
->q
);
487 q_normalize( st
->rbb
->q
);
488 rb_update_matrices( st
->rbb
);
490 f32 mt
= 1.0f
/(st
->rba
->inv_mass
+st
->rbb
->inv_mass
),
491 wa
= mt
* acosf(angle
) * (k_phys_baumgarte
/k_rb_delta
);
492 //v3_muladds( st->rba->w, axis, wa*-0.5f, st->rba->w );
493 v3_muladds( st
->rbb
->w
, axis
, wa
* st
->rbb
->inv_mass
, st
->rbb
->w
);