"L. Spiro Engine"
|
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__