+
+ f32 mass = 0.0f,
+ k_density = 8.0f,
+ k_inertia_scale = 1.0f;
+ m3x3f I;
+ m3x3_zero( I );
+
+ for( u32 i=0; i<vg_list_size(player_glide.parts); i ++ ){
+ /* create part transform matrix */
+ v4f qp, qy, qr, q;
+ q_axis_angle( qp, (v3f){1,0,0}, player_glide.parts[i].euler[0] );
+ q_axis_angle( qy, (v3f){0,1,0}, player_glide.parts[i].euler[1] );
+ q_axis_angle( qr, (v3f){0,0,1}, player_glide.parts[i].euler[2] );
+
+ q_mul( qr, qy, q );
+ q_mul( q, qp, q );
+
+ q_m3x3( q, player_glide.parts[i].mdl );
+ v3_copy( player_glide.parts[i].co, player_glide.parts[i].mdl[3] );
+
+ /* add it to inertia model */
+
+ if( player_glide.parts[i].shape == k_rb_shape_capsule ){
+ f32 r = player_glide.parts[i].inf.r,
+ h = player_glide.parts[i].inf.h,
+ pv = vg_capsule_volume( r, h ),
+ pm = pv * k_density;
+
+ mass += pm;
+
+ m3x3f pI;
+ rb_capsule_inertia( r, h, pm, pI );
+ rb_rotate_inertia( pI, player_glide.parts[i].mdl );
+ rb_translate_inertia( pI, pm, player_glide.parts[i].co );
+ m3x3_add( I, pI, I );
+ }
+ else if( player_glide.parts[i].shape == k_rb_shape_sphere ){
+ f32 r = player_glide.parts[i].r,
+ pv = vg_sphere_volume( r ),
+ pm = pv * k_density;
+
+ mass += pm;
+ m3x3f pI;
+ rb_sphere_inertia( r, pm, pI );
+ rb_translate_inertia( pI, pm, player_glide.parts[i].co );
+ m3x3_add( I, pI, I );
+ }
+ }
+
+ /* set inverses */
+ m3x3_inv( I, player_glide.rb.iI );
+ player_glide.rb.inv_mass = 1.0f / mass;