"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSPhysicsLib/Src/Intersections/LSPClassify.h

00001 
00017 #ifndef __LSP_CLASSIFY_H__
00018 #define __LSP_CLASSIFY_H__
00019 
00020 #include "../LSPPhysicsLib.h"
00021 #include "../BoundingBoxes/LSPAabb.h"
00022 #include "Plane/LSMPlane3.h"
00023 
00024 namespace lsp {
00025 
00033         class CClassify {
00034                 // All is public.  This class has no secrets.
00035         public :
00036                 // == Functions.
00044                 static LSE_INLINE LSM_PLANE_INTERSECT LSE_CALL                          Aabb( const CAabb &_aAabb, const CPlane3 &_pPlane );
00045 
00054                 template <typename _tType, typename _tVec3Type, typename _tPlane3Type>
00055                 static LSE_INLINE LSM_PLANE_INTERSECT LSE_CALL                          Point( const _tVec3Type &_vPoint, const _tPlane3Type &_pPlane, _tType _fThickness = static_cast<_tType>(LSM_PLANE_THICKNESS) ) {
00056                         _tType fDist = (_pPlane.n * _vPoint) - _pPlane.dist;
00057                         if ( fDist > _fThickness ) { return LSM_PI_FRONT; }
00058                         if ( fDist < -_fThickness ) { return LSM_PI_BACK; }
00059                         return LSM_PI_COPLANAR;
00060                 }
00061 
00070                 template <typename _tType, typename _tPoly3Type, typename _tPlane3Type>
00071                 static LSE_INLINE LSM_PLANE_INTERSECT LSE_CALL                          Polygon( const _tPoly3Type &_pPoly, const _tPlane3Type &_pPlane, _tType _fThickness = static_cast<_tType>(LSM_PLANE_THICKNESS) ) {
00072                         LSUINT32 ui32Front = 0UL, ui32Back = 0UL;
00073 
00074                         // Easy as pie.  Loop over vertices and determine if all are on one side or not.
00075                         for ( LSUINT32 I = _pPoly.TotalSegments(); I--; ) {
00076                                 switch ( Point<_tType>( _pPoly[I]->p, _pPlane, _fThickness ) ) {
00077                                         case LSM_PI_FRONT : {
00078                                                 // This one is in front.  If any are in back then we are straddling.
00079                                                 if ( ui32Back ) { return LSM_PI_INTERSECT; }
00080                                                 ++ui32Front;
00081                                                 break;
00082                                         }
00083                                         case LSM_PI_BACK : {
00084                                                 // This one is in back.  If any are in front then we are straddling.
00085                                                 if ( ui32Front ) { return LSM_PI_INTERSECT; }
00086                                                 ++ui32Back;
00087                                                 break;
00088                                         }
00089                                 }
00090                         }
00091                         // We are not straddling.  Then we must be fully in front, fully behind, or coplanar.
00092                         if ( ui32Front ) { return LSM_PI_FRONT; }
00093                         return ui32Back ? LSM_PI_BACK : LSM_PI_COPLANAR;
00094                 }
00095 
00096         };
00097 
00098 
00099         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00100         // DEFINITIONS
00101         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00102         // == Functions.
00110         LSE_INLINE LSM_PLANE_INTERSECT LSE_CALL CClassify::Aabb( const CAabb &_aAabb, const CPlane3 &_pPlane ) {
00111                 // Center of the AABB.
00112                 CVector3 vC = (_aAabb.m_vMax + _aAabb.m_vMin) * LSM_HALF;
00113                 // Positive extents.
00114                 CVector3 vE = _aAabb.m_vMax - vC;
00115 
00116                 // Compute the projected interval radius of _aAabb onto L(t) = _aAabb.c + t * _pPlane.n.
00117                 LSREAL fR = vE[0] * CMathLib::Abs( _pPlane.n[0] ) +
00118                         vE[1] * CMathLib::Abs( _pPlane.n[1] ) +
00119                         vE[2] * CMathLib::Abs( _pPlane.n[2] );
00120 
00121                 // Distance from box center to plane.
00122                 LSREAL fS = _pPlane.n.Dot( vC ) - _pPlane.dist;
00123 
00124                 // If less than R, return overlap.
00125                 if ( CMathLib::Abs( fS ) <= fR ) { return LSM_PI_INTERSECT; }
00126                 // Otherwise it is in front or back of the plane.
00127                 return fS > fR ? LSM_PI_FRONT : LSM_PI_BACK;
00128         }
00129 
00130 }       // namespace lsp
00131 
00132 #endif  // __LSP_CLASSIFY_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator