X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=blobdiff_plain;f=vg_rigidbody.h;fp=vg_rigidbody.h;h=f6b9417a2b90e2fabb62b37d0d2fcc87cf5888fd;hp=c44aa5d9e649b2504b8f266f7357e0a2bf630ebf;hb=fce86711735b15bff37de0f70716808410fcf269;hpb=1c305409e8eca9cf8449d681df73208956ce14df diff --git a/vg_rigidbody.h b/vg_rigidbody.h index c44aa5d..f6b9417 100644 --- a/vg_rigidbody.h +++ b/vg_rigidbody.h @@ -18,8 +18,8 @@ */ static const float - k_rb_rate = (1.0/VG_TIMESTEP_FIXED), - k_rb_delta = (1.0/k_rb_rate), + //k_rb_rate = (1.0/VG_TIMESTEP_FIXED), + //k_rb_delta = (1.0/k_rb_rate), k_friction = 0.4f, k_damp_linear = 0.1f, /* scale velocity 1/(1+x) */ k_damp_angular = 0.1f, /* scale angular 1/(1+x) */ @@ -130,7 +130,7 @@ static void rb_update_matrices( rigidbody *rb ){ */ static void rb_extrapolate( rigidbody *rb, v3f co, v4f q ){ float substep = vg.time_fixed_extrapolate; - v3_muladds( rb->co, rb->v, k_rb_delta*substep, co ); + v3_muladds( rb->co, rb->v, vg.time_fixed_delta*substep, co ); if( v3_length2( rb->w ) > 0.0f ){ v4f rotation; @@ -139,7 +139,7 @@ static void rb_extrapolate( rigidbody *rb, v3f co, v4f q ){ float mag = v3_length( axis ); v3_divs( axis, mag, axis ); - q_axis_angle( rotation, axis, mag*k_rb_delta*substep ); + q_axis_angle( rotation, axis, mag*vg.time_fixed_delta*substep ); q_mul( rotation, rb->q, q ); q_normalize( q ); } @@ -157,11 +157,13 @@ static void rb_iter( rigidbody *rb ){ } v3f gravity = { 0.0f, -9.8f, 0.0f }; - v3_muladds( rb->v, gravity, k_rb_delta, rb->v ); + v3_muladds( rb->v, gravity, vg.time_fixed_delta, rb->v ); /* intergrate velocity */ - v3_muladds( rb->co, rb->v, k_rb_delta, rb->co ); + v3_muladds( rb->co, rb->v, vg.time_fixed_delta, rb->co ); +#if 0 v3_lerp( rb->w, (v3f){0.0f,0.0f,0.0f}, 0.0025f, rb->w ); +#endif /* inegrate inertia */ if( v3_length2( rb->w ) > 0.0f ){ @@ -171,12 +173,46 @@ static void rb_iter( rigidbody *rb ){ float mag = v3_length( axis ); v3_divs( axis, mag, axis ); - q_axis_angle( rotation, axis, mag*k_rb_delta ); + q_axis_angle( rotation, axis, mag*vg.time_fixed_delta ); q_mul( rotation, rb->q, rb->q ); q_normalize( rb->q ); } } +/* + * based on: https://box2d.org/files/ErinCatto_NumericalMethods_GDC2015.pdf, + * page 76. + */ +static void rb_solve_gyroscopic( rigidbody *rb, m3x3f I, f32 h ){ + /* convert to body coordinates */ + v3f w_local; + m3x3_mulv( rb->to_local, rb->w, w_local ); + + /* Residual vector */ + v3f f, v0; + m3x3_mulv( I, w_local, v0 ); + v3_cross( w_local, v0, f ); + v3_muls( f, h, f ); + + /* Jacobian */ + m3x3f iJ, J, skew_w_local, skew_v0, m0; + m3x3_skew_symetric( skew_w_local, w_local ); + m3x3_mul( skew_w_local, I, m0 ); + + m3x3_skew_symetric( skew_v0, v0 ); + m3x3_sub( m0, skew_v0, J ); + m3x3_scalef( J, h ); + m3x3_add( I, J, J ); + + /* Single Newton-Raphson update */ + v3f w1; + m3x3_inv( J, iJ ); + m3x3_mulv( iJ, f, w1 ); + v3_sub( w_local, w1, rb->w ); + + m3x3_mulv( rb->to_world, rb->w, rb->w ); +} + /* * Creates relative contact velocity vector */ @@ -215,10 +251,10 @@ static void rb_effect_simple_bouyency( rigidbody *ra, v4f plane, float depth = v3_dot( plane, ra->co ) - plane[3], lambda = vg_clampf( -depth, 0.0f, 1.0f ) * amt; - v3_muladds( ra->v, plane, lambda * k_rb_delta, ra->v ); + v3_muladds( ra->v, plane, lambda * vg.time_fixed_delta, ra->v ); if( depth < 0.0f ) - v3_muls( ra->v, 1.0f-(drag*k_rb_delta), ra->v ); + v3_muls( ra->v, 1.0f-(drag*vg.time_fixed_delta), ra->v ); } /* apply a spring&dampener force to match ra(worldspace) on rigidbody, to