+/*
+ * Translate existing inertia tensor
+ */
+static void rb_translate_inertia( m3x3f inout_inertia, f32 mass, v3f d ){
+ /*
+ * I = I_0 + m*[(d.d)E_3 - d(X)d]
+ *
+ * I: updated tensor
+ * I_0: original tensor
+ * m: scalar mass
+ * d: translation vector
+ * (X): outer product
+ * E_3: identity matrix
+ */
+ m3x3f t, outer, scale;
+ m3x3_diagonal( t, v3_dot(d,d) );
+ m3x3_outer_product( outer, d, d );
+ m3x3_sub( t, outer, t );
+ m3x3_diagonal( scale, mass );
+ m3x3_mul( scale, t, t );
+ m3x3_add( inout_inertia, t, inout_inertia );
+}
+
+/*
+ * Rotate existing inertia tensor
+ */
+static void rb_rotate_inertia( m3x3f inout_inertia, m3x3f rotation ){
+ /*
+ * I = R I_0 R^T
+ *
+ * I: updated tensor
+ * I_0: original tensor
+ * R: rotation matrix
+ * R^T: tranposed rotation matrix
+ */
+
+ m3x3f Rt;
+ m3x3_transpose( rotation, Rt );
+ m3x3_mul( rotation, inout_inertia, inout_inertia );
+ m3x3_mul( inout_inertia, Rt, inout_inertia );
+}
+/*
+ * Create inertia tensor for box
+ */
+static void rb_box_inertia( boxf box, f32 mass, m3x3f out_inertia ){
+ v3f e, com;
+ v3_sub( box[1], box[0], e );
+ v3_muladds( box[0], e, 0.5f, com );
+
+ f32 ex2 = e[0]*e[0],
+ ey2 = e[1]*e[1],
+ ez2 = e[2]*e[2],
+ ix = (ey2+ez2) * mass * (1.0f/12.0f),
+ iy = (ex2+ez2) * mass * (1.0f/12.0f),
+ iz = (ex2+ey2) * mass * (1.0f/12.0f);
+
+ m3x3_identity( out_inertia );
+ m3x3_setdiagonalv3( out_inertia, (v3f){ ix, iy, iz } );
+ rb_translate_inertia( out_inertia, mass, com );
+}
+
+/*
+ * Create inertia tensor for sphere
+ */
+static void rb_sphere_inertia( f32 r, f32 mass, m3x3f out_inertia ){
+ f32 ixyz = r*r * mass * (2.0f/5.0f);
+
+ m3x3_identity( out_inertia );
+ m3x3_setdiagonalv3( out_inertia, (v3f){ ixyz, ixyz, ixyz } );
+}