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