+VG_STATIC int rb_capsule__triangle( m4x3f mtxA, rb_capsule *c,
+ v3f tri[3], rb_ct *buf )
+{
+ v3f pc, p0w, p1w;
+ v3_muladds( mtxA[3], mtxA[1], -c->height*0.5f+c->radius, p0w );
+ v3_muladds( mtxA[3], mtxA[1], c->height*0.5f-c->radius, p1w );
+
+ capsule_manifold manifold;
+ rb_capsule_manifold_init( &manifold );
+
+ v3f c0, c1;
+ closest_on_triangle_1( p0w, tri, c0 );
+ closest_on_triangle_1( p1w, tri, c1 );
+
+ v3f d0, d1, da;
+ v3_sub( c0, p0w, d0 );
+ v3_sub( c1, p1w, d1 );
+ v3_sub( p1w, p0w, da );
+
+ v3_normalize(d0);
+ v3_normalize(d1);
+ v3_normalize(da);
+
+ if( v3_dot( da, d0 ) <= 0.01f )
+ rb_capsule_manifold( p0w, c0, 0.0f, c->radius, &manifold );
+
+ if( v3_dot( da, d1 ) >= -0.01f )
+ rb_capsule_manifold( p1w, c1, 1.0f, c->radius, &manifold );
+
+ for( int i=0; i<3; i++ )
+ {
+ int i0 = i,
+ i1 = (i+1)%3;
+
+ v3f ca, cb;
+ float ta, tb;
+ closest_segment_segment( p0w, p1w, tri[i0], tri[i1], &ta, &tb, ca, cb );
+ rb_capsule_manifold( ca, cb, ta, c->radius, &manifold );
+ }
+
+ v3f v0, v1, n;
+ v3_sub( tri[1], tri[0], v0 );
+ v3_sub( tri[2], tri[0], v1 );
+ v3_cross( v0, v1, n );
+ v3_normalize( n );
+
+ int count = rb_capsule__manifold_done( mtxA, c, &manifold, buf );
+ for( int i=0; i<count; i++ )
+ v3_copy( n, buf[i].n );
+
+ return count;
+}
+