# MCapousek

Member

8

355 Neutral

• Rank
Newbie

• Interests
Programming
1. ## Looking for help with aab/tri collision

Code for "static" case can be found here:http://www.gamedev.net/topic/671401-triangle-aabb-intersection-test/
2. ## Triangle-AABB intersection test

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; } }
3. ## Compute cube edges in screenspace

This approach should be easily extendable (from "vertices-on-outline") to "front-facing-quads" or "front-facing-triangle-strips", etc.
4. ## Compute cube edges in screenspace

I edited my snippet again.... each bit-mask (for given situation) contains number of vertices in outline (4 or 6, stored in lowest 3 bits) followed by corresponding indices (0-7, each again stored in 3 bits).
5. ## Compute cube edges in screenspace

Parameters 'boxMin' and 'boxMax' are "minimum" and "maximum" of axis-aligned box (AABB). "Straightforward" usage would be for AABBs in world-space but if you transform your camera in local space of box then it can be used for oriented boxes (OBB) too. These still can be some bugs in those hex constants... I was testing it at most 2 mins so... :)
6. ## Compute cube edges in screenspace

I fixed my snippet ("front left", "front right" cases) and made it little shorter :).
7. ## Compute cube edges in screenspace

C# snippet: public static class BoxOutline { private static readonly int [] OUTLINE = new int [43] { 0x00000000, // 00 ... inside 0x00003F04, // 01 ... left ................... 0,4,7,3 0x00005C8C, // 02 ... right .................. 1,2,6,5 0x00000000, // 03 0x00004A44, // 04 ... bottom ................. 0,1,5,4 0x000FCA46, // 05 ... bottom, left ........... 0,1,5,4,7,3 0x0012E446, // 06 ... bottom, right .......... 0,1,2,6,5,4 0x00000000, // 07 0x00006ED4, // 08 ... top .................... 2,3,7,6 0x0001ADE6, // 09 ... top, left .............. 4,7,6,2,3,0 0x0006EED6, // 10 ... top, right ............. 2,3,7,6,5,1 0x00000000, // 11 0x00000000, // 12 0x00000000, // 13 0x00000000, // 14 0x00000000, // 15 0x000014C4, // 16 ... front .................. 0,3,2,1 0x000FC056, // 17 ... front, left ............ 2,1,0,4,7,3 0x0006E4C6, // 18 ... front, right ........... 0,3,2,6,5,1 0x00000000, // 19 0x001294C6, // 20 ... front, bottom .......... 0,3,2,1,5,4 0x000FCA56, // 21 ... front, bottom, left .... 2,1,5,4,7,3 0x0012E4C6, // 22 ... front, bottom, right ... 0,3,2,6,5,4 0x00000000, // 23 0x00056EC6, // 24 ... front, top ............. 0,3,7,6,2,1 0x00056F06, // 25 ... front, top, left ....... 0,4,7,6,2,1 0x0006EEC6, // 26 ... front, top, right ...... 0,3,7,6,5,1 0x00000000, // 27 0x00000000, // 28 0x00000000, // 29 0x00000000, // 30 0x00000000, // 31 0x00007D64, // 32 ... back ................... 4,5,6,7 0x0001FD66, // 33 ... back, left ............. 4,5,6,7,3,0 0x00167C8E, // 34 ... back, right ............ 1,2,6,7,4,5 0x00000000, // 35 0x0013EA46, // 36 ... back, bottom ........... 0,1,5,6,7,4 0x000FEA46, // 37 ... back, bottom, left ..... 0,1,5,6,7,3 0x0013E446, // 38 ... back, bottom, right .... 0,1,2,6,7,4 0x00000000, // 39 0x001ACED6, // 40 ... back, top .............. 2,3,7,4,5,6 0x000D6B06, // 41 ... back, top, left ........ 0,4,5,6,2,3 0x0016768E // 42 ... back, top, right ....... 1,2,3,7,4,5 }; private static readonly Vector3 [] m_Corners = new Vector3[8]; //----------------------------------------------------------------------------------------------------------------- static public int GetOutline( Vector3 boxMin, Vector3 boxMax, Vector3 camPos, Vector3 [/*6*/] outline ) { int idx = ( camPos.x < boxMin.x ? 1 : 0 ) // 1 = left + ( camPos.x > boxMax.x ? 2 : 0 ) // 2 = right + ( camPos.y < boxMin.y ? 4 : 0 ) // 4 = bottom + ( camPos.y > boxMax.y ? 8 : 0 ) // 8 = top + ( camPos.z < boxMin.z ? 16 : 0 ) // 16 = front + ( camPos.z > boxMax.z ? 32 : 0 ); // 32 = back if ( idx >= OUTLINE.Length ) return 0; int enc = OUTLINE[ idx ]; if ( enc == 0 ) return 0; GetCorners( boxMin, boxMax, m_Corners ); int num = enc & 7; // decodes count of vertices in outline for ( idx = 0; idx < num; ++idx ) { enc >>= 3; outline[ idx ] = m_Corners[ enc & 7 ]; // decodes outline vertices one by one } return num; } //----------------------------------------------------------------------------------------------------------------- public static void GetCorners( Vector3 boxMin, Vector3 boxMax, Vector3 [/*8*/] corners ) { corners[ 0 ] = new Vector3( boxMin.x, boxMin.y, boxMin.z ); // 3--------------2 corners[ 1 ] = new Vector3( boxMax.x, boxMin.y, boxMin.z ); // | \ / | corners[ 2 ] = new Vector3( boxMax.x, boxMax.y, boxMin.z ); // | 7 ------ 6 | corners[ 3 ] = new Vector3( boxMin.x, boxMax.y, boxMin.z ); // | | | | // | | | | corners[ 4 ] = new Vector3( boxMin.x, boxMin.y, boxMax.z ); // | | | | corners[ 5 ] = new Vector3( boxMax.x, boxMin.y, boxMax.z ); // | 4 ------ 5 | corners[ 6 ] = new Vector3( boxMax.x, boxMax.y, boxMax.z ); // | / \ | corners[ 7 ] = new Vector3( boxMin.x, boxMax.y, boxMax.z ); // 0 -------------1 } } EDIT 2015-07-14 : simplified EDIT 2015-07-17 : added comments so it is clear how it works :)
8. ## Compute cube edges in screenspace

This could help: http://www.cg.tuwien.ac.at/research/publications/1999/Fuhr-1999-Conc/TR-186-2-99-05Paper.pdf