Advertisement
vexator

AABB/frustum intersection

Oct 9th, 2011
2,003
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.94 KB | None | 0 0
  1. // DECLARATION:
  2.  
  3. class BoundingVolume
  4. {
  5.     public:
  6.  
  7.         enum TestResult
  8.         {
  9.             TEST_OUTSIDE,
  10.             TEST_INTERSECT,
  11.             TEST_INSIDE
  12.         };
  13.  
  14.     public:
  15.    
  16.         virtual TestResult testIntersection( const vec3 &point ) const = 0;
  17.         virtual TestResult testIntersection( shared_ptr<const BoundingBox> box ) const = 0;
  18.         virtual TestResult testIntersection( shared_ptr<const BoundingSphere> sphere ) const = 0;
  19. };
  20.  
  21. class BoundingBox : public BoundingVolume
  22. {
  23.     public:
  24.    
  25.         vec3 minimum;
  26.         vec3 maximum;
  27.        
  28.         vec3 position;
  29.  
  30.     public:
  31.  
  32.         BoundingBox( vec3 minimum, vec3 maximum, vec3 position = vec3(0.0f) ) : BoundingVolume()
  33.         {
  34.             this->minimum = minimum;
  35.             this->maximum = maximum;
  36.            
  37.             this->position = position;
  38.         }
  39.  
  40.         virtual vec3 getPositiveVertex( const vec3 &normal ) const;
  41.         virtual vec3 getNegativeVertex( const vec3 &normal ) const;
  42.  
  43.         TestResult testIntersection( const vec3 &point ) const;
  44.         TestResult testIntersection( shared_ptr<const BoundingBox> box ) const;
  45.         TestResult testIntersection( shared_ptr<const BoundingSphere> sphere ) const;
  46. };
  47.  
  48. class Frustum : public BoundingVolume
  49. {
  50.     public:
  51.  
  52.         enum Plane
  53.         {
  54.             PLANE_BACK,
  55.             PLANE_FRONT,
  56.             PLANE_RIGHT,
  57.             PLANE_LEFT,
  58.             PLANE_TOP,
  59.             PLANE_BOTTOM
  60.         };
  61.  
  62.     public:
  63.  
  64.         Frustum( const mat4 &viewMatrix, const mat4 &projectionMatrix );
  65.  
  66.         const vec4 &getPlane( const int plane ) const;
  67.        
  68.         TestResult testIntersection( const vec3 &point ) const;
  69.         TestResult testIntersection( shared_ptr<const BoundingBox> box ) const;
  70.         TestResult testIntersection( shared_ptr<const BoundingSphere> sphere ) const;
  71.  
  72.     protected:
  73.  
  74.         vec4 m_planes[6];
  75. };
  76.  
  77.  
  78.  
  79. // RELEVANT IMPLEMENTATION:
  80.  
  81. // compute frustum planes from view and projection matrices
  82. Frustum::Frustum( const mat4 &viewMatrix, const mat4 &projectionMatrix ) : BoundingVolume()
  83. {
  84.     const mat4 &v = viewMatrix;
  85.     const mat4 &p = projectionMatrix;
  86.  
  87.     mat4 clipMatrix;
  88.  
  89.     clipMatrix[0][0] = v[0][0 ]*p[0][0]+v[0][1]*p[1][0]+v[0][2]*p[2][0]+v[0][3]*p[3][0];
  90.     clipMatrix[1][0] = v[0][0]*p[0][1]+v[0][1]*p[1][1]+v[0][2]*p[2][1]+v[0][3]*p[3][1];
  91.     clipMatrix[2][0] = v[0][0]*p[0][2]+v[0][1]*p[1][2]+v[0][2]*p[2][2]+v[0][3]*p[3][2];
  92.     clipMatrix[3][0] = v[0][0]*p[0][3]+v[0][1]*p[1][3]+v[0][2]*p[2][3]+v[0][3]*p[3][3];
  93.     clipMatrix[0][1] = v[1][0]*p[0][0]+v[1][1]*p[1][0]+v[1][2]*p[2][0]+v[1][3]*p[3][0];
  94.     clipMatrix[1][1] = v[1][0]*p[0][1]+v[1][1]*p[1][1]+v[1][2]*p[2][1]+v[1][3]*p[3][1];
  95.     clipMatrix[2][1] = v[1][0]*p[0][2]+v[1][1]*p[1][2]+v[1][2]*p[2][2]+v[1][3]*p[3][2];
  96.     clipMatrix[3][1] = v[1][0]*p[0][3]+v[1][1]*p[1][3]+v[1][2]*p[2][3]+v[1][3]*p[3][3];
  97.     clipMatrix[0][2] = v[2][0]*p[0][0]+v[2][1]*p[1][0]+v[2][2]*p[2][0]+v[2][3]*p[3][0];
  98.     clipMatrix[1][2] = v[2][0]*p[0][1]+v[2][1]*p[1][1]+v[2][2]*p[2][1]+v[2][3]*p[3][1];
  99.     clipMatrix[2][2] = v[2][0]*p[0][2]+v[2][1]*p[1][2]+v[2][2]*p[2][2]+v[2][3]*p[3][2];
  100.     clipMatrix[3][2] = v[2][0]*p[0][3]+v[2][1]*p[1][3]+v[2][2]*p[2][3]+v[2][3]*p[3][3];
  101.     clipMatrix[0][3] = v[3][0]*p[0][0]+v[3][1]*p[1][0]+v[3][2]*p[2][0]+v[3][3]*p[3][0];
  102.     clipMatrix[1][3] = v[3][0]*p[0][1]+v[3][1]*p[1][1]+v[3][2]*p[2][1]+v[3][3]*p[3][1];
  103.     clipMatrix[2][3] = v[3][0]*p[0][2]+v[3][1]*p[1][2]+v[3][2]*p[2][2]+v[3][3]*p[3][2];
  104.     clipMatrix[3][3] = v[3][0]*p[0][3]+v[3][1]*p[1][3]+v[3][2]*p[2][3]+v[3][3]*p[3][3];
  105.  
  106.     m_planes[PLANE_RIGHT].x = clipMatrix[3][0]-clipMatrix[0][0];
  107.     m_planes[PLANE_RIGHT].y = clipMatrix[3][1]-clipMatrix[0][1];
  108.     m_planes[PLANE_RIGHT].z = clipMatrix[3][2]-clipMatrix[0][2];
  109.     m_planes[PLANE_RIGHT].w = clipMatrix[3][3]-clipMatrix[0][3];
  110.  
  111.     m_planes[PLANE_LEFT].x = clipMatrix[3][0]+clipMatrix[0][0];
  112.     m_planes[PLANE_LEFT].y = clipMatrix[3][1]+clipMatrix[0][1];
  113.     m_planes[PLANE_LEFT].z = clipMatrix[3][2]+clipMatrix[0][2];
  114.     m_planes[PLANE_LEFT].w = clipMatrix[3][3]+clipMatrix[0][3];
  115.  
  116.     m_planes[PLANE_BOTTOM].x = clipMatrix[3][0]+clipMatrix[1][0];
  117.     m_planes[PLANE_BOTTOM].y = clipMatrix[3][1]+clipMatrix[1][1];
  118.     m_planes[PLANE_BOTTOM].z = clipMatrix[3][2]+clipMatrix[1][2];
  119.     m_planes[PLANE_BOTTOM].w = clipMatrix[3][3]+clipMatrix[1][3];
  120.  
  121.     m_planes[PLANE_TOP].x = clipMatrix[3][0]-clipMatrix[1][0];
  122.     m_planes[PLANE_TOP].y = clipMatrix[3][1]-clipMatrix[1][1];
  123.     m_planes[PLANE_TOP].z = clipMatrix[3][2]-clipMatrix[1][2];
  124.     m_planes[PLANE_TOP].w = clipMatrix[3][3]-clipMatrix[1][3];
  125.  
  126.     m_planes[PLANE_BACK].x = clipMatrix[3][0]-clipMatrix[2][0];
  127.     m_planes[PLANE_BACK].y = clipMatrix[3][1]-clipMatrix[2][1];
  128.     m_planes[PLANE_BACK].z = clipMatrix[3][2]-clipMatrix[2][2];
  129.     m_planes[PLANE_BACK].w = clipMatrix[3][3]-clipMatrix[2][3];
  130.  
  131.     m_planes[PLANE_FRONT].x = clipMatrix[3][0]+clipMatrix[2][0];
  132.     m_planes[PLANE_FRONT].y = clipMatrix[3][1]+clipMatrix[2][1];
  133.     m_planes[PLANE_FRONT].z = clipMatrix[3][2]+clipMatrix[2][2];
  134.     m_planes[PLANE_FRONT].w = clipMatrix[3][3]+clipMatrix[2][3];
  135.  
  136.     for( int i = 0; i < 6; i++ )
  137.     {
  138.         m_planes[i] = glm::normalize( m_planes[i] );
  139.     }
  140. }
  141.  
  142. // check whether an AABB intersects the frustum
  143. BoundingVolume::TestResult Frustum::testIntersection( shared_ptr<const BoundingBox> box ) const
  144. {
  145.     TestResult result = TEST_INSIDE;
  146.  
  147.     for( uint i = 0; i < 6; i++ )
  148.     {
  149.         const float pos = m_planes[i].w;
  150.         const vec3 normal = vec3(m_planes[i]);
  151.  
  152.         if( glm::dot(normal, box->getPositiveVertex(normal))+pos < 0.0f )
  153.         {
  154.             return TEST_OUTSIDE;
  155.         }
  156.  
  157.         if( glm::dot(normal, box->getNegativeVertex(normal))+pos < 0.0f )
  158.         {
  159.             result = TEST_INTERSECT;
  160.         }
  161.     }
  162.  
  163.     return result;
  164. }
  165.  
  166. vec3 BoundingBox::getPositiveVertex( const vec3 &normal ) const
  167. {
  168.     vec3 positiveVertex = minimum;
  169.  
  170.     if( normal.x >= 0.0f ) positiveVertex.x = maximum.x;
  171.     if( normal.y >= 0.0f ) positiveVertex.y = maximum.y;
  172.     if( normal.z >= 0.0f ) positiveVertex.z = maximum.z;
  173.  
  174.     return position+positiveVertex;
  175. }
  176.  
  177. vec3 BoundingBox::getNegativeVertex( const vec3 &normal ) const
  178. {
  179.     vec3 negativeVertex = maximum;
  180.  
  181.     if( normal.x >= 0.0f ) negativeVertex.x = minimum.x;
  182.     if( normal.y >= 0.0f ) negativeVertex.y = minimum.y;
  183.     if( normal.z >= 0.0f ) negativeVertex.z = minimum.z;
  184.  
  185.     return position+negativeVertex;
  186. }
  187.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement