Untested C# snipet:
public class AabbTriTest
{
// CONSTANTS //////////////////////////////////////////////////////////////////////////////////////////////////////
private static readonly Vector3 [] BOX_DIR = new Vector3 [3] { new Vector3( 1.0f, 0.0f, 0.0f ),
new Vector3( 0.0f, 1.0f, 0.0f ),
new Vector3( 0.0f, 0.0f, 1.0f ) };
// FIELDS /////////////////////////////////////////////////////////////////////////////////////////////////////////
private Vector3 m_Center;
private Vector3 m_Extent;
private readonly float [] m_MinMax = new float [6];
// METHODS ////////////////////////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------------------------------------
public void Setup( Vector3 boxCenter, Vector3 boxExtents )
{
m_Center = boxCenter;
m_Extent = boxExtents;
Vector3 min = boxCenter - boxExtents;
Vector3 max = boxCenter + boxExtents;
m_MinMax[0] = min.x;
m_MinMax[1] = max.x;
m_MinMax[2] = min.y;
m_MinMax[3] = max.y;
m_MinMax[4] = min.z;
m_MinMax[5] = max.z;
}
//-----------------------------------------------------------------------------------------------------------------
public bool Test( Vector3 [/*3*/] tri, Vector3 triPlaneN, float triPlaneD )
{
Vector3 dir;
float tMin, tMax, bMin, bMax;
// tri's normal...
tMin = tMax = -triPlaneD;
ProjectBox( triPlaneN, out bMin, out bMax );
if ( tMax < tMin || bMax < tMin )
return false;
// normals of box faces...
ProjectTri( BOX_DIR[0], tri, out tMin, out tMax ); // tMin = min( tri[0].x, ... , tri[2].x )
// tMax = max( tri[0].x, ... , tri[2].x )
if ( tMax < m_MinMax[0] || m_MinMax[1] < tMin )
return false;
ProjectTri( BOX_DIR[1], tri, out tMin, out tMax ); // tMin = min( tri[0].y, ... , tri[2].y )
// tMax = max( tri[0].y, ... , tri[2].y )
if ( tMax < m_MinMax[2] || m_MinMax[3] < tMin )
return false;
ProjectTri( BOX_DIR[2], tri, out tMin, out tMax ); // tMin = min( tri[0].z, ... , tri[2].z )
// tMax = max( tri[0].z, ... , tri[2].z )
if ( tMax < m_MinMax[4] || m_MinMax[5] < tMin )
return false;
// cross-products of tri edges and box axis...
for ( int i = 0, j = 3; i < 3; j = i++ )
{
Vector3 edge = tri[i] - tri[j];
for ( int k = 0; k < 3; ++k )
{
dir = Vector3.Cross( edge, BOX_DIR[k] );
ProjectBox( dir, out bMin, out bMax );
ProjectTri( dir, tri, out tMin, out tMax );
if ( tMax < bMin || bMax < tMin )
return false;
}
}
return true;
}
//-----------------------------------------------------------------------------------------------------------------
private void ProjectBox( Vector3 dir, out float projMin, out float projMax )
{
float c = ( dir.x * m_Center.x ) + ( dir.y * m_Center.y ) + ( dir.z * m_Center.z );
float e = Mathf.Abs( dir.x * m_Extent.x ) + Mathf.Abs( dir.y * m_Extent.y ) + Mathf.Abs( dir.z * m_Extent.z );
projMin = c - e;
projMax = c + e;
}
//-----------------------------------------------------------------------------------------------------------------
private static void ProjectTri( Vector3 dir, Vector3 [] tri, out float projMin, out float projMax )
{
projMin =
projMax = Vector3.Dot( dir, tri[0] );
float p = Vector3.Dot( dir, tri[1] );
if ( p < projMin ) projMin = p; else
if ( p > projMax ) projMax = p;
p = Vector3.Dot( dir, tri[2] );
if ( p < projMin ) projMin = p; else
if ( p > projMax ) projMax = p;
}
}