"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSPhysicsLib/Src/Misc/LSPPhysUtils.h

00001 
00016 #ifndef __LSP_PHYSUTILS_H__
00017 #define __LSP_PHYSUTILS_H__
00018 
00019 #include "../LSPPhysicsLib.h"
00020 #include "../BoundingBoxes/LSPObb.h"
00021 #include "../Intersections/LSPClassify.h"
00022 #include "../Intersections/LSPIntersect.h"
00023 #include "Frustum/LSMFrustum.h"
00024 #include "Matrix/LSMMatrix3x3.h"
00025 #include "Plane/LSMPlane3.h"
00026 #include "Sphere/LSMSphere.h"
00027 #include "Vector/LSMVector3.h"
00028 #include "Vector/LSTLVector.h"
00029 
00030 namespace lsp {
00031 
00038         class CPhysUtils {
00039                 // All is public.  This class has no secrets.
00040         public :
00041                 // == Functions.
00052                 static LSVOID LSE_CALL                          ExtremePointsAlongDirection( const CVector3 &_vDir, const CVector3 * _pvPoints,
00053                         LSUINT32 _ui32TotalPoints, LSUINT32 &_ui32Min, LSUINT32 &_ui32Max );
00054 
00065                 static LSVOID LSE_CALL                          ExtremeValuesAlongDirection( const CVector3 &_vDir, const CVector3 * _pvPoints,
00066                         LSUINT32 _ui32TotalPoints, LSREAL &_fMin, LSREAL &_fMax );
00067 
00078                 static CSphere & LSE_CALL                       SphereOfSphereAndPoint( CSphere &_sSphere, const CVector3 &_vPoint );
00079 
00091                 static LSVOID LSE_CALL                          SymSchur2( const CMatrix3x3 &_mMat, LSINT32 _i32P, LSINT32 _i32Q,
00092                         LSREALHP &_fCos, LSREALHP &_fSin );
00093 
00104                 static LSVOID LSE_CALL                          Jacobi( CMatrix3x3 &_mA, CMatrix3x3 &_mV );
00105 
00114                 static CSphere LSE_CALL                         EigenSphere( const CVector3 * _pvPoints, LSUINT32 _ui32TotalPoints );
00115 
00124                 static CSphere LSE_CALL                         RitterEigenSphere( const CVector3 * _pvPoints, LSUINT32 _ui32TotalPoints );
00125 
00132                 static LSVOID LSE_CALL                          FrustumCorners( const CFrustum &_fFrustum, CVector3 _vRet[8] );
00133 
00141                 static CVector3 LSE_CALL                        MajorAxis( const CVector3 &_vVector );
00142 
00154                 template <typename _tType, typename _tVecType, typename _tPolyType, typename _tPlaneType>
00155                 static LSVOID LSE_CALL                          Split( const _tPolyType &_pPoly, const _tPlaneType &_pPlane,
00156                         LSUINT32 * _pui32LeftSides, _tPolyType * _ppLeftRet,
00157                         LSUINT32 * _pui32RightSides, _tPolyType * _ppRightRet,
00158                         _tType _fThickness = static_cast<_tType>(LSM_PLANE_THICKNESS) ) {
00159                         // No way to split a polygon with fewer than 3 vertices.
00160                         assert( _pPoly.TotalSegments() >= 3UL );
00161 
00162                         LSUINT32 ui32FrontCount = 0UL;
00163                         LSUINT32 ui32BackCount = 0UL;
00164 
00165                         _tVecType vA = _pPoly[_pPoly.TotalSegments()-1]->p;
00166                         LSM_PLANE_INTERSECT piSide = CClassify::Point<_tType, _tVecType, _tPlaneType>( vA, _pPlane, _fThickness );
00167                         LSUINT32 ui32Total = _pPoly.TotalSegments();
00168 
00169                         _tVecType vSplitPoint;
00170 #define LSP_PUSHFRONT( VEC )    if ( _ppLeftRet ) { (*_ppLeftRet).Segments()[ui32FrontCount].p = VEC; } ++ui32FrontCount
00171 #define LSP_PUSHBACK( VEC )             if ( _ppRightRet ) { (*_ppRightRet).Segments()[ui32BackCount].p = VEC; } ++ui32BackCount
00172 
00173                         // Run over all edges of the polygon.
00174                         for ( LSUINT32 N = 0; N < ui32Total; ++N ) {
00175                                 _tVecType vB = _pPoly[N]->p;
00176                                 LSM_PLANE_INTERSECT piSide2 = CClassify::Point<_tType>( vB, _pPlane, _fThickness );
00177                                 switch ( piSide2 ) {
00178                                         case LSM_PI_FRONT : {
00179                                                 if ( piSide == LSM_PI_BACK ) {
00180                                                         // Edge (A, B) crosses plane.
00181                                                         CIntersect::LineSegPlaneFast<_tType, _tVecType, _tPlaneType>( vB, vA, _pPlane, vSplitPoint );
00182                                                         LSP_PUSHFRONT( vSplitPoint );
00183                                                         //if ( !vFrontVerts.Push( vSplitPoint ) ) { return false; }
00184 
00185                                                         LSP_PUSHBACK( vSplitPoint );
00186                                                         //if ( !vBackVerts.Push( vSplitPoint ) ) { return false; }
00187                                                 }
00188                                                 // Always put B on the front side.
00189                                                 LSP_PUSHFRONT( vB );
00190                                                 //if ( !vFrontVerts.Push( vB ) ) { return false; }
00191                                                 break;
00192                                         }
00193                                         case LSM_PI_BACK : {
00194                                                 if ( piSide == LSM_PI_FRONT ) {
00195                                                         // Edge (A, B) crosses plane.
00196                                                         CIntersect::LineSegPlaneFast<_tType, _tVecType, _tPlaneType>( vA, vB, _pPlane, vSplitPoint );
00197                                                         LSP_PUSHFRONT( vSplitPoint );
00198                                                         //if ( !vFrontVerts.Push( vSplitPoint ) ) { return false; }
00199 
00200                                                         LSP_PUSHBACK( vSplitPoint );
00201                                                         //if ( !vBackVerts.Push( vSplitPoint ) ) { return false; }
00202                                                 }
00203                                                 else if ( piSide == LSM_PI_COPLANAR ) {
00204                                                         // Output A when edge goes from on to behind the plane.
00205                                                         LSP_PUSHBACK( vA );
00206                                                         //if ( !vBackVerts.Push( vA ) ) { return false; }
00207                                                 }
00208                                                 // Always put B on the back side.
00209                                                 LSP_PUSHBACK( vB );
00210                                                 //if ( !vBackVerts.Push( vB ) ) { return false; }
00211                                                 break;
00212                                         }
00213                                         default : {
00214                                                 // B is on the plane.  Always pass it to the front side.
00215                                                 LSP_PUSHFRONT( vB );
00216                                                 //if ( !vFrontVerts.Push( vB ) ) { return false; }
00217                                                 // If A is behind the plane, also put B on the back side.
00218                                                 if ( piSide == LSM_PI_BACK ) {
00219                                                         LSP_PUSHBACK( vB );
00220                                                         //if ( !vBackVerts.Push( vB ) ) { return false; }
00221                                                 }
00222                                         }
00223                                 }
00224 
00225                                 // Next edge will be from B to the next.
00226                                 vA = vB;
00227                                 piSide = piSide2;
00228                         }
00229 #undef LSP_PUSHBACK
00230 #undef LSP_PUSHFRONT
00231 
00232                         if ( _pui32LeftSides ) {
00233                                 (*_pui32LeftSides) = ui32FrontCount;
00234                         }
00235                         if ( _pui32RightSides ) {
00236                                 (*_pui32RightSides) = ui32BackCount;
00237                         }
00238                         if ( _ppLeftRet ) {
00239                                 for ( LSUINT32 I = ui32FrontCount; I--; ) {
00240                                         (*_ppLeftRet)[I]->q = (*_ppLeftRet)[(I+1)%ui32FrontCount]->p;
00241                                 }
00242                                 (*_ppLeftRet).Plane() = _pPoly.Plane();
00243                                 (*_ppLeftRet).SetUser( _pPoly.GetUser() );
00244                         }
00245                         if ( _ppRightRet ) {
00246                                 for ( LSUINT32 I = ui32BackCount; I--; ) {
00247                                         (*_ppRightRet)[I]->q = (*_ppRightRet)[(I+1)%ui32BackCount]->p;
00248                                 }
00249                                 (*_ppRightRet).Plane() = _pPoly.Plane();
00250                                 (*_ppRightRet).SetUser( _pPoly.GetUser() );
00251                         }
00252                 }
00253 
00265                 /*template <typename _tType, typename _tVecType, typename _tPolyType, typename _tPlaneType>
00266                 static LSVOID LSE_CALL                          Carve( const _tPolyType &_pPoly, const _tPolyType &_pSplitterPoly,
00267                         LSUINT32 * _pui32LeftSides, _tPolyType * _ppLeftRet,
00268                         _tType _fThickness = static_cast<_tType>(LSM_PLANE_THICKNESS) ) {
00269                 }*/
00270 
00271 
00272         protected :
00273                 // == Members.
00274         };
00275 
00276 
00277         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00278         // DEFINITIONS
00279         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00280 
00281 }       // namespace lsp
00282 
00283 #endif  // __LSP_PHYSUTILS_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator