"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSPhysicsLib/Src/SpatialPartitions/LSPSolidLeafBspBase.h

00001 
00017 #ifndef __LSP_SOLIDLEAFBSPBASE_H__
00018 #define __LSP_SOLIDLEAFBSPBASE_H__
00019 
00020 #include "../LSPPhysicsLib.h"
00021 #include "../Intersections/LSPClassify.h"
00022 #include "../Intersections/LSPIntersect.h"
00023 #include "../Misc/LSPPhysUtils.h"
00024 #include "Vector/LSTLVector.h"
00025 
00026 #ifdef LSP_TOOL
00027 #include <iostream>
00028 #endif  // #ifdef LSP_TOOL
00029 
00030 namespace lsp {
00031 
00039         template <typename _tType, typename _tVecType, typename _tPlaneType, typename _tPolyType>
00040         class CSolidLeafBspBase {
00041         public :
00042                 // == Various constructors.
00043                 LSE_CALLCTOR                                            CSolidLeafBspBase() {
00044                 }
00045 
00046 
00047                 // == Types.
00051                 typedef struct LSP_NODE {
00055                         LSP_NODE *                                              pnParent;
00056 
00060                         LSP_NODE *                                              pnFront;
00061 
00065                         LSP_NODE *                                              pnBack;
00066 
00070                         CVector<_tPolyType, LSUINT32, 4096UL>
00071                                                                                         vPolies;
00072 
00076                         _tPlaneType                                             tPlane;
00077 
00081                         LSUINTPTR                                               uiptrUser;
00082 
00083 
00084                         // == Various constructors.
00085                         LSE_CALLCTOR                                    LSP_NODE() :
00086                                 pnParent( NULL ),
00087                                 pnFront( NULL ),
00088                                 pnBack( NULL ),
00089                                 uiptrUser( 0UL ) {
00090                         }
00091                         LSE_CALLCTOR                                    ~LSP_NODE() {
00092                                 if ( pnFront ) {
00093                                         pnFront->~LSP_NODE();
00094                                         pnFront = NULL;
00095                                 }
00096                                 if ( pnBack ) {
00097                                         pnBack->~LSP_NODE();
00098                                         pnBack = NULL;
00099                                 }
00100                         }
00101                 } * LPLSP_NODE, * const LPCLSP_NODE;
00102 
00103 
00104                 // == Functions.
00110                 const LSP_NODE * LSE_CALL                       Root() const {
00111                         return &m_nRoot;
00112                 }
00113 
00123                 LSBOOL LSE_CALL                                         CreateBsp( const _tPolyType * _ppPolies, LSUINT32 _ui32Total,
00124                         CStackAllocator * _psaAllocator, _tType _fThickness = static_cast<_tType>(LSM_PLANE_THICKNESS) ) {
00125                         // Make a copy of the polygons.
00126                         CVector<_tPolyType, LSUINT32, 4096UL> vPolyCopy;
00127                         vPolyCopy.Allocate( _ui32Total );
00128                         for ( LSUINT32 I = 0UL; I < _ui32Total; ++I ) {
00129                                 if ( _ppPolies[I].TotalSegments() ) {
00130                                         if ( !vPolyCopy.Push( _tPolyType() ) ) { return false; }
00131                                         if ( !vPolyCopy[vPolyCopy.Length()-1UL].Copy( _ppPolies[I], _psaAllocator ) ) { return false; }
00132                                 }
00133                         }
00134                         vPolyCopy.Snap();
00135 
00136                         return CreateBsp( m_nRoot, vPolyCopy, _psaAllocator, _fThickness );
00137                 }
00138 
00149                 LSBOOL LSE_CALL                                         CreateBspConvex( const _tPolyType * _ppPolies, LSUINT32 _ui32Total,
00150                         CStackAllocator * _psaAllocator, _tType _fThickness = static_cast<_tType>(LSM_PLANE_THICKNESS) ) {
00151                         // Make a copy of the polygons.
00152                         CVector<_tPolyType, LSUINT32, 4096UL> vPolyCopy;
00153                         vPolyCopy.Allocate( _ui32Total );
00154                         for ( LSUINT32 I = 0UL; I < _ui32Total; ++I ) {
00155                                 if ( _ppPolies[I].TotalSegments() ) {
00156                                         if ( !vPolyCopy.Push( _tPolyType() ) ) { return false; }
00157                                         if ( !vPolyCopy[vPolyCopy.Length()-1UL].Copy( _ppPolies[I], _psaAllocator ) ) { return false; }
00158                                 }
00159                         }
00160                         vPolyCopy.Snap();
00161 
00162                         return CreateBspConvex( m_nRoot, vPolyCopy, _psaAllocator, _fThickness );
00163                 }
00164 
00171                 LSBOOL LSE_CALL                                         GetLeafs( CVectorPoD<LSP_NODE *, LSUINT32> &_vArray ) {
00172                         return GetLeafs( &m_nRoot, _vArray );
00173                 }
00174 
00182                 LSBOOL LSE_CALL                                         GetLeafs( CVectorPoD<const LSP_NODE *, LSUINT32> &_vArray, CVectorPoD<const LSP_NODE *, LSUINT32> &_vStack ) const {
00183                         return GetLeafs( &m_nRoot, _vArray, _vStack );
00184                 }
00185 
00193                 LSBOOL LSE_CALL                                         GetLeafs( LSP_NODE * _pnNode, CVectorPoD<LSP_NODE *, LSUINT32> &_vArray ) const {
00194                         // Explicit stacking for stability.
00195                         CVector<LSP_NODE *, LSUINT32, 4096UL> vStack;
00196                         if ( !vStack.Push( _pnNode ) ) { return false; }
00197                         while ( vStack.Length() ) {
00198                                 LSP_NODE * pnThis = vStack[vStack.Length()-1UL];
00199                                 vStack.PopNoDealloc();
00200                                 if ( !_vArray.Push( pnThis ) ) { return false; }
00201 
00202                                 if ( pnThis->pnFront ) {
00203                                         if ( !vStack.Push( pnThis->pnFront ) ) { return false; }
00204                                 }
00205                                 if ( pnThis->pnBack ) {
00206                                         if ( !vStack.Push( pnThis->pnBack ) ) { return false; }
00207                                 }
00208                         }
00209                         return true;
00210                 }
00211 
00220                 LSBOOL LSE_CALL                                         GetLeafs( const LSP_NODE * _pnNode, CVectorPoD<const LSP_NODE *, LSUINT32> &_vArray,
00221                         CVectorPoD<const LSP_NODE *, LSUINT32> &_vStack ) const {
00222                         // Explicit stacking for stability.
00223                         _vStack.ResetNoDealloc();
00224                         if ( !_vStack.Push( _pnNode ) ) { return false; }
00225                         while ( _vStack.Length() ) {
00226                                 const LSP_NODE * pnThis = _vStack[_vStack.Length()-1UL];
00227                                 _vStack.PopNoDealloc();
00228                                 if ( !_vArray.Push( pnThis ) ) { return false; }
00229 
00230                                 if ( pnThis->pnFront ) {
00231                                         if ( !_vStack.Push( pnThis->pnFront ) ) { return false; }
00232                                 }
00233                                 if ( pnThis->pnBack ) {
00234                                         if ( !_vStack.Push( pnThis->pnBack ) ) { return false; }
00235                                 }
00236                         }
00237                         return true;
00238                 }
00239 
00247                 static LSBOOL LSE_CALL                          GetParents( const LSP_NODE * _pnNode, CVectorPoD<LSP_NODE *, LSUINT32> &_vArray ) {
00248                         _vArray.ResetNoDealloc();
00249                         for ( LSP_NODE * pnParent = _pnNode->pnParent; pnParent; pnParent = pnParent->pnParent ) {
00250                                 if ( !_vArray.Push( pnParent ) ) { return false; }
00251                         }
00252                         return true;
00253                 }
00254 
00255 
00256         protected :
00257                 // == Types.
00261                 typedef struct LSP_STACK {
00265                         LSP_NODE *                                              pnNode;
00266 
00270                         CVector<_tPolyType, LSUINT32, 4096UL>
00271                                                                                         vPolies;
00272                 } * LPLSP_STACK, * const LPCLSP_STACK;
00273 
00274 
00275                 // == Members.
00279                 LSP_NODE                                                        m_nRoot;
00280 
00281 
00282                 // == Functions
00292                 LSBOOL LSE_CALL                                         CreateBsp( LSP_NODE &_nNode, const CVector<_tPolyType, LSUINT32, 4096UL> &_vPolies,
00293                         CStackAllocator * _psaAllocator, _tType _fThickness = static_cast<_tType>(LSM_PLANE_THICKNESS) ) {
00294                         // Explicit stacking is used for stability.  Stack overflow on large/complicated next-generation maps is not
00295                         //      a problem for this algorithm.
00296                         CVector<LSP_STACK, LSUINT32, 4096UL> vStack;
00297                         vStack.Allocate( _vPolies.Length() );   // The number of polygons should be sufficient stack size.
00298 
00299                         // Start it off with the first node.
00300                         if ( !vStack.Push( LSP_STACK() ) ) { return false; }
00301                         vStack[0].pnNode = &_nNode;
00302                         vStack[0].vPolies = _vPolies;
00303 
00304                         CVector<_tPolyType, LSUINT32, 4096UL> vFrontPolies, vBackPolies;
00305 
00306                         while ( vStack.Length() ) {
00307                                 LSP_STACK sThis = vStack[vStack.Length()-1UL];
00308                                 vStack.PopNoDealloc();
00309                                 if ( sThis.vPolies.Length() == 0UL ) { continue; }
00310                                 vFrontPolies.ResetNoDealloc();
00311                                 vBackPolies.ResetNoDealloc();
00312                                 LSUINT32 ui32Index;
00313                                 sThis.pnNode->tPlane = BestSplittingPlane( sThis.vPolies, ui32Index, _fThickness );
00314 #ifdef LSP_TOOL
00315                                 ::printf( "." );
00316 #endif  // #ifdef LSP_TOOL
00317 
00318                                 for ( LSUINT32 I = 0UL; I < sThis.vPolies.Length(); ++I ) {
00319                                         if ( I == ui32Index ) {
00320                                                 if ( !sThis.pnNode->vPolies.Push( sThis.vPolies[I] ) ) {
00321                                                         return false;
00322                                                 }
00323                                                 continue;
00324                                         }
00325                                         switch ( CClassify::Polygon( sThis.vPolies[I], sThis.pnNode->tPlane, _fThickness ) ) {
00326                                                 case LSM_PI_FRONT : {
00327                                                         if ( !vFrontPolies.Push( sThis.vPolies[I] ) ) { return false; }
00328                                                         break;
00329                                                 }
00330                                                 case LSM_PI_BACK : {
00331                                                         if ( !vBackPolies.Push( sThis.vPolies[I] ) ) { return false; }
00332                                                         break;
00333                                                 }
00334                                                 case LSM_PI_COPLANAR : {
00335                                                         if ( !sThis.pnNode->vPolies.Push( sThis.vPolies[I] ) ) {
00336                                                                 return false;
00337                                                         }
00338                                                         break;
00339                                                 }
00340                                                 case LSM_PI_INTERSECT : {
00341                                                         LSUINT32 ui32Left, ui32Right;
00342                                                         CPhysUtils::Split<_tType, _tVecType, _tPolyType, _tPlaneType>( sThis.vPolies[I], sThis.pnNode->tPlane, &ui32Left, NULL, &ui32Right, NULL,
00343                                                                 _fThickness );
00344                                                         _tPolyType tLeft, tRight;
00345                                                         if ( !tLeft.SetTotalSides( ui32Left, _psaAllocator ) ) {
00346                                                                 return false;
00347                                                         }
00348                                                         if ( !tRight.SetTotalSides( ui32Right, _psaAllocator ) ) {
00349                                                                 return false;
00350                                                         }
00351                                                         CPhysUtils::Split<_tType, _tVecType, _tPolyType, _tPlaneType>( sThis.vPolies[I], sThis.pnNode->tPlane, NULL, &tLeft, NULL, &tRight,
00352                                                                 _fThickness );
00353                                                         if ( !vFrontPolies.Push( tLeft ) ) { return false; }
00354                                                         if ( !vBackPolies.Push( tRight ) ) { return false; }
00355                                                         break;
00356                                                 }
00357                                         }
00358                                 }
00359 
00360                                 sThis.pnNode->vPolies.Snap();
00361                                 if ( vFrontPolies.Length() ) {
00362                                         sThis.pnNode->pnFront = static_cast<LSP_NODE *>(_psaAllocator->Alloc( sizeof( LSP_NODE ), 4UL ));
00363                                         if ( !sThis.pnNode->pnFront ) {
00364                                                 return false;
00365                                         }
00366                                         new( sThis.pnNode->pnFront ) LSP_NODE();
00367                                         if ( !vStack.Push( LSP_STACK() ) ) {
00368                                                 return false;
00369                                         }
00370                                         sThis.pnNode->pnFront->pnParent = sThis.pnNode;
00371                                         vStack[vStack.Length()-1].pnNode = sThis.pnNode->pnFront;
00372                                         vStack[vStack.Length()-1].vPolies = vFrontPolies;
00373                                 }
00374                                 if ( vBackPolies.Length() ) {
00375                                         sThis.pnNode->pnBack = static_cast<LSP_NODE *>(_psaAllocator->Alloc( sizeof( LSP_NODE ), 4UL ));
00376                                         if ( !sThis.pnNode->pnBack ) {
00377                                                 return false;
00378                                         }
00379                                         new( sThis.pnNode->pnBack ) LSP_NODE();
00380                                         if ( !vStack.Push( LSP_STACK() ) ) {
00381                                                 return false;
00382                                         }
00383                                         sThis.pnNode->pnBack->pnParent = sThis.pnNode;
00384                                         vStack[vStack.Length()-1].pnNode = sThis.pnNode->pnBack;
00385                                         vStack[vStack.Length()-1].vPolies = vBackPolies;
00386                                 }
00387                         }
00388 
00389                         return true;
00390                 }
00391 
00401                 LSBOOL LSE_CALL                                         CreateBspConvex( LSP_NODE &_nNode, const CVector<_tPolyType, LSUINT32, 4096UL> &_vPolies,
00402                         CStackAllocator * _psaAllocator, _tType _fThickness = static_cast<_tType>(LSM_PLANE_THICKNESS) ) {
00403                         // Explicit stacking is used for stability.  Stack overflow on large/complicated next-generation maps is not
00404                         //      a problem for this algorithm.
00405                         CVector<LSP_STACK, LSUINT32, 4096UL> vStack;
00406                         vStack.Allocate( _vPolies.Length() );   // The number of polygons should be sufficient stack size.
00407 
00408                         // Start it off with the first node.
00409                         if ( !vStack.Push( LSP_STACK() ) ) { return false; }
00410                         vStack[0].pnNode = &_nNode;
00411                         vStack[0].vPolies = _vPolies;
00412 
00413                         CVector<_tPolyType, LSUINT32, 4096UL> vFrontPolies, vBackPolies;
00414 #ifdef LSP_TOOL
00415                         LSUINT32 ui32Max = 0UL;
00416 #endif  // #ifdef LSP_TOOL
00417                         while ( vStack.Length() ) {
00418                                 LSP_STACK sThis = vStack[vStack.Length()-1UL];
00419                                 vStack.PopNoDealloc();
00420                                 if ( sThis.vPolies.Length() == 0UL ) { continue; }
00421                                 if ( sThis.vPolies.Length() == 1UL ) {
00422                                         // Only one polygon.  This is a leaf.
00423                                         sThis.pnNode->tPlane = sThis.vPolies[0].Plane();
00424                                         if ( !sThis.pnNode->vPolies.Push( sThis.vPolies[0] ) ) {
00425                                                 return false;
00426                                         }
00427                                         sThis.pnNode->vPolies.Snap();
00428                                         continue;
00429                                 }
00430                                 vFrontPolies.ResetNoDealloc();
00431                                 vBackPolies.ResetNoDealloc();
00432                                 LSUINT32 ui32Index;
00433                                 sThis.pnNode->tPlane = BestSplittingPlane( sThis.vPolies, ui32Index, _fThickness );
00434 #ifdef LSP_TOOL
00435                                 ::printf( "." );
00436 #endif  // #ifdef LSP_TOOL
00437 
00438                                 for ( LSUINT32 I = 0UL; I < sThis.vPolies.Length(); ++I ) {
00439                                         if ( I == ui32Index ) {
00440                                                 //if ( !sThis.pnNode->vPolies.Push( sThis.vPolies[I] ) ) {
00441                                                 sThis.vPolies[I].SetAsSplitter( true );
00442                                                 if ( !vFrontPolies.Push( sThis.vPolies[I] ) ) {
00443                                                         return false;
00444                                                 }
00445                                                 continue;
00446                                         }
00447                                         switch ( CClassify::Polygon( sThis.vPolies[I], sThis.pnNode->tPlane, _fThickness ) ) {
00448                                                 case LSM_PI_FRONT : {
00449                                                         if ( !vFrontPolies.Push( sThis.vPolies[I] ) ) { return false; }
00450                                                         break;
00451                                                 }
00452                                                 case LSM_PI_BACK : {
00453                                                         sThis.vPolies[I].SetAsSplitter( false );
00454                                                         if ( !vBackPolies.Push( sThis.vPolies[I] ) ) { return false; }
00455                                                         break;
00456                                                 }
00457                                                 case LSM_PI_COPLANAR : {
00458                                                         if ( sThis.vPolies[I].Plane().n * sThis.pnNode->tPlane.n > _tType( 0 ) ) {
00459                                                                 //if ( !sThis.pnNode->vPolies.Push( sThis.vPolies[I] ) ) {
00460                                                                 sThis.vPolies[I].SetAsSplitter( true );
00461                                                                 if ( !vFrontPolies.Push( sThis.vPolies[I] ) ) {
00462                                                                         return false;
00463                                                                 }
00464                                                         }
00465                                                         else {
00466                                                                 sThis.vPolies[I].SetAsSplitter( false );
00467                                                                 if ( !vBackPolies.Push( sThis.vPolies[I] ) ) {
00468                                                                         return false;
00469                                                                 }
00470                                                         }
00471 
00472                                                         break;
00473                                                 }
00474                                                 case LSM_PI_INTERSECT : {
00475                                                         LSUINT32 ui32Left, ui32Right;
00476                                                         CPhysUtils::Split<_tType, _tVecType, _tPolyType, _tPlaneType>( sThis.vPolies[I], sThis.pnNode->tPlane, &ui32Left, NULL, &ui32Right, NULL,
00477                                                                 _fThickness );
00478                                                         _tPolyType tLeft, tRight;
00479                                                         if ( !tLeft.SetTotalSides( ui32Left, _psaAllocator ) ) {
00480                                                                 return false;
00481                                                         }
00482                                                         if ( !tRight.SetTotalSides( ui32Right, _psaAllocator ) ) {
00483                                                                 return false;
00484                                                         }
00485                                                         CPhysUtils::Split<_tType, _tVecType, _tPolyType, _tPlaneType>( sThis.vPolies[I], sThis.pnNode->tPlane, NULL, &tLeft, NULL, &tRight,
00486                                                                 _fThickness );
00487                                                         if ( sThis.vPolies[I].IsSplitter() ) {
00488                                                                 tLeft.SetAsSplitter( true );
00489                                                                 //tRight.SetAsSplitter( true );
00490                                                         }
00491                                                         if ( !vFrontPolies.Push( tLeft ) ) { return false; }
00492                                                         if ( !vBackPolies.Push( tRight ) ) { return false; }
00493                                                         break;
00494                                                 }
00495                                         }
00496                                 }
00497                                 if ( vFrontPolies.Length() && (AllAreSplitters( vFrontPolies ) || AllAreConvex( sThis.pnNode->vPolies, vFrontPolies, _fThickness )) ) {
00498                                         // Add them to the front node.
00499                                         if ( !sThis.pnNode->vPolies.Append( &vFrontPolies[0], vFrontPolies.Length() ) ) {
00500                                                 return false;
00501                                         }
00502 
00503                                         /*sThis.pnNode->pnFront = static_cast<LSP_NODE *>(_psaAllocator->Alloc( sizeof( LSP_NODE ), 4UL ));
00504                                         if ( !sThis.pnNode->pnFront ) {
00505                                                 return false;
00506                                         }
00507                                         new( sThis.pnNode->pnFront ) LSP_NODE();
00508                                         sThis.pnNode->pnFront->pnParent = sThis.pnNode;
00509                                         if ( !sThis.pnNode->pnFront->vPolies.Append( &vFrontPolies[0], vFrontPolies.Length() ) ) {
00510                                                 sThis.pnNode->pnFront->vPolies.Append( &vFrontPolies[0], vFrontPolies.Length() );
00511                                                 return false;
00512                                         }
00513                                         sThis.pnNode->pnFront->vPolies.Snap();*/
00514 
00515 #ifdef LSP_TOOL
00516                                         ::printf( "%u ", sThis.pnNode->vPolies.Length() );
00517                                         ui32Max = CStd::Max( ui32Max, sThis.pnNode->vPolies.Length() );
00518                                         /*::printf( "%u ", sThis.pnNode->pnFront->vPolies.Length() );
00519                                         ui32Max = CStd::Max( ui32Max, sThis.pnNode->pnFront->vPolies.Length() );*/
00520 #endif  // #ifdef LSP_TOOL
00521                                         vFrontPolies.ResetNoDealloc();
00522                                 }
00523 
00524                                 sThis.pnNode->vPolies.Snap();
00525                                 if ( vFrontPolies.Length() ) {
00526                                         sThis.pnNode->pnFront = static_cast<LSP_NODE *>(_psaAllocator->Alloc( sizeof( LSP_NODE ), 4UL ));
00527                                         if ( !sThis.pnNode->pnFront ) {
00528                                                 return false;
00529                                         }
00530                                         new( sThis.pnNode->pnFront ) LSP_NODE();
00531                                         if ( !vStack.Push( LSP_STACK() ) ) {
00532                                                 return false;
00533                                         }
00534                                         sThis.pnNode->pnFront->pnParent = sThis.pnNode;
00535                                         vStack[vStack.Length()-1].pnNode = sThis.pnNode->pnFront;
00536                                         vStack[vStack.Length()-1].vPolies = vFrontPolies;
00537                                 }
00538                                 if ( vBackPolies.Length() ) {
00539                                         sThis.pnNode->pnBack = static_cast<LSP_NODE *>(_psaAllocator->Alloc( sizeof( LSP_NODE ), 4UL ));
00540                                         if ( !sThis.pnNode->pnBack ) {
00541                                                 return false;
00542                                         }
00543                                         new( sThis.pnNode->pnBack ) LSP_NODE();
00544                                         if ( !vStack.Push( LSP_STACK() ) ) {
00545                                                 return false;
00546                                         }
00547                                         sThis.pnNode->pnBack->pnParent = sThis.pnNode;
00548                                         vStack[vStack.Length()-1].pnNode = sThis.pnNode->pnBack;
00549                                         vStack[vStack.Length()-1].vPolies = vBackPolies;
00550                                 }
00551                         }
00552 #ifdef LSP_TOOL
00553                         ::printf( "\r\nMax: %u.\r\n", ui32Max );
00554 #endif  // #ifdef LSP_TOOL
00555                         return true;
00556                 }
00557 
00566                 _tPlaneType LSE_CALL                            BestSplittingPlane( const CVector<_tPolyType, LSUINT32, 4096UL> &_vPolies, LSUINT32 &_ui32Index, _tType _fThickness = static_cast<_tType>(LSM_PLANE_THICKNESS) ) {
00567                         // Blend factor for optimizing for balancing splits (to be tweaked).
00568                         _tType fK = static_cast<_tType>(0.95);
00569 
00570                         // Variables for tracking the best plane seen so far.
00571                         _tPlaneType pBest;
00572                         _tType fBestScore = static_cast<_tType>(LSM_INFINITY);  // Lower score = better.
00573                         LSBOOL bFoundOneBest = false;
00574 
00575                         // Compare every plane against every other plane.
00576                         for ( LSUINT32 I = 0UL; I < _vPolies.Length(); ++I ) {
00577                                 if ( _vPolies[I].IsSplitter() ) { continue; }
00578                                 LSUINT32 ui32Front = 0, ui32Behind = 0, ui32Straddling = 0;
00579                                 const _tPlaneType & pPlane = _vPolies[I].Plane();
00580                                 if ( bFoundOneBest && pBest == pPlane ) { continue; }
00581 
00582                                 // Check against all other polygons.  See how many are in front,
00583                                 //      behind, or straddling.
00584                                 for ( LSUINT32 J = 0UL; J < _vPolies.Length(); ++J ) {
00585                                         if ( I == J ) { continue; }
00586 
00587                                         switch ( CClassify::Polygon( _vPolies[J], pPlane, _fThickness ) ) {
00588                                                 case LSM_PI_COPLANAR : {
00589                                                         // Send these down the front by falling through.
00590                                                 }
00591                                                 case LSM_PI_FRONT : {
00592                                                         ++ui32Front;
00593                                                         break;
00594                                                 }
00595                                                 case LSM_PI_BACK : {
00596                                                         ++ui32Behind;
00597                                                         break;
00598                                                 }
00599                                                 case LSM_PI_INTERSECT : {
00600                                                         ++ui32Straddling;
00601                                                         break;
00602                                                 }
00603                                         }
00604                                 }
00605 
00606                                 // Get the score for this plane.
00607                                 _tType fScore = fK * ui32Straddling + (static_cast<_tType>(1.0) - fK) * CMathLib::AbsT<_tType>( static_cast<_tType>(ui32Front - ui32Behind) );
00608                                 if ( fScore < fBestScore ) {
00609                                         fBestScore = fScore;
00610                                         pBest = pPlane;
00611                                         bFoundOneBest = true;
00612                                         _ui32Index = I;
00613                                 }
00614                         }
00615                         if ( !bFoundOneBest ) {
00616                                 // Just find one that is not a splitter.
00617                                 for ( LSUINT32 I = 0UL; I < _vPolies.Length(); ++I ) {
00618                                         if ( !_vPolies[I].IsSplitter() ) {
00619                                                 pBest = _vPolies[I].Plane();
00620                                                 _ui32Index = I;
00621                                                 break;
00622                                         }
00623                                 }
00624                         }
00625                         return pBest;
00626                 }
00627 
00636                 LSBOOL LSE_CALL                                         AllAreConvex( const CVector<_tPolyType, LSUINT32, 4096UL> &_vPlanePolies, const CVector<_tPolyType, LSUINT32, 4096UL> &_vPolies, _tType _fThickness = static_cast<_tType>(LSM_PLANE_THICKNESS) ) {
00637                         for ( LSUINT32 I = 0UL; I < _vPolies.Length(); ++I ) {
00638                                 // If any other polygons are behind this one's plane, it is not convex.
00639                                 // Check here first since it is more likely to exit early.
00640                                 for ( LSUINT32 J = I + 1UL; J < _vPolies.Length(); ++J ) {
00641                                         if ( CClassify::Polygon( _vPolies[J], _vPolies[I].Plane(), _fThickness ) == LSM_PI_BACK ) {
00642                                                 return false;
00643                                         }
00644                                         // Check against the plane polygons too.
00645                                         for ( LSUINT32 J = _vPlanePolies.Length(); J--; ) {
00646                                                 if ( CClassify::Polygon( _vPlanePolies[J], _vPolies[I].Plane(), _fThickness ) == LSM_PI_BACK ) { return false; }
00647                                         }
00648                                 }
00649                         }
00650                         return true;
00651                 }
00652 
00659                 LSBOOL LSE_CALL                                         AllAreSplitters( const CVector<_tPolyType, LSUINT32, 4096UL> &_vPolies ) {
00660                         for ( LSUINT32 I = _vPolies.Length(); I--; ) {
00661                                 if ( !_vPolies[I].IsSplitter() ) { return false; }
00662                         }
00663                         return true;
00664                 }
00665 
00666         };
00667 
00668 }       // namespace lsp
00669 
00670 #endif  // __LSP_SOLIDLEAFBSPBASE_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator