+static int rb_box_triangle_interval( v3f extent, v3f axis, v3f tri[3] )
+{
+ float
+
+ r = extent[0] * fabsf(axis[0]) +
+ extent[1] * fabsf(axis[1]) +
+ extent[2] * fabsf(axis[2]),
+
+ p0 = v3_dot( axis, tri[0] ),
+ p1 = v3_dot( axis, tri[1] ),
+ p2 = v3_dot( axis, tri[2] ),
+
+ e = vg_maxf(-vg_maxf(p0,vg_maxf(p1,p2)), vg_minf(p0,vg_minf(p1,p2)));
+
+ if( e > r ) return 0;
+ else return 1;
+}
+
+static int rb_box_triangle_sat( rigidbody *rba, v3f tri_src[3] )
+{
+ v3f tri[3];
+
+ v3f extent, c;
+ v3_sub( rba->bbx[1], rba->bbx[0], extent );
+ v3_muls( extent, 0.5f, extent );
+ v3_add( rba->bbx[0], extent, c );
+
+ for( int i=0; i<3; i++ )
+ {
+ m4x3_mulv( rba->to_local, tri_src[i], tri[i] );
+ v3_sub( tri[i], c, tri[i] );
+ }
+
+ /* u0, u1, u2 */
+ if(!rb_box_triangle_interval( extent, (v3f){1.0f,0.0f,0.0f}, tri )) return 0;
+ if(!rb_box_triangle_interval( extent, (v3f){0.0f,1.0f,0.0f}, tri )) return 0;
+ if(!rb_box_triangle_interval( extent, (v3f){0.0f,0.0f,1.0f}, tri )) return 0;
+
+ v3f v0,v1,v2,n, e0,e1,e2;
+ v3_sub( tri[1], tri[0], v0 );
+ v3_sub( tri[2], tri[0], v1 );
+ v3_sub( tri[2], tri[1], v2 );
+ v3_normalize( v0 );
+ v3_normalize( v1 );
+ v3_normalize( v2 );
+ v3_cross( v0, v1, n );
+ v3_cross( v0, n, e0 );
+ v3_cross( n, v1, e1 );
+ v3_cross( v2, n, e2 );
+
+ /* normal */
+ if(!rb_box_triangle_interval( extent, n, tri )) return 0;
+
+ v3f axis[9];
+ v3_cross( e0, (v3f){1.0f,0.0f,0.0f}, axis[0] );
+ v3_cross( e0, (v3f){0.0f,1.0f,0.0f}, axis[1] );
+ v3_cross( e0, (v3f){0.0f,0.0f,1.0f}, axis[2] );
+ v3_cross( e1, (v3f){1.0f,0.0f,0.0f}, axis[3] );
+ v3_cross( e1, (v3f){0.0f,1.0f,0.0f}, axis[4] );
+ v3_cross( e1, (v3f){0.0f,0.0f,1.0f}, axis[5] );
+ v3_cross( e2, (v3f){1.0f,0.0f,0.0f}, axis[6] );
+ v3_cross( e2, (v3f){0.0f,1.0f,0.0f}, axis[7] );
+ v3_cross( e2, (v3f){0.0f,0.0f,1.0f}, axis[8] );
+
+ for( int i=0; i<9; i++ )
+ if(!rb_box_triangle_interval( extent, axis[i], tri )) return 0;
+
+ return 1;
+}
+