"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSPhysicsLib/Src/Polygon/LSPPolygon3Base.h

00001 
00016 #ifndef __LSP_POLYGON3BASE_H__
00017 #define __LSP_POLYGON3BASE_H__
00018 
00019 #include "../LSPPhysicsLib.h"
00020 #include "Allocators/LSAStackAllocator.h"
00021 
00022 #include <cassert>
00023 
00024 namespace lsp {
00025 
00032         template <typename _tType, typename _tSeg3Type, typename _tPlane3Type>
00033         class CPolygon3Base {
00034         public :
00035                 // == Various constructors.
00036                 LSE_CALLCTOR                                                    CPolygon3Base() :
00037                         m_ptSegs( NULL ),
00038                         m_psaAllocator( NULL ),
00039                         m_uiptrUser( 0UL ),
00040                         m_ui32Total( 0UL ),
00041                         m_bSplitter( false ) {
00042                 }
00043                 LSE_CALLCTOR                                                    ~CPolygon3Base() {
00044                         Reset();
00045                 }
00046 
00047 
00048                 // == Operators.
00055                 _tSeg3Type * LSE_CALL                                   operator [] ( LSUINT32 _ui32Index ) {
00056                         return &Segments()[_ui32Index];
00057                 }
00058 
00065                 const _tSeg3Type * LSE_CALL                             operator [] ( LSUINT32 _ui32Index ) const {
00066                         return &Segments()[_ui32Index];
00067                 }
00068 
00075                 CPolygon3Base<_tType, _tSeg3Type, _tPlane3Type> & LSE_CALL
00076                                                                                                 operator = ( const CPolygon3Base<_tType, _tSeg3Type, _tPlane3Type> &_pSrc ) {
00077                         Reset();
00078                         Copy( _pSrc, _pSrc.m_psaAllocator );
00079                         return (*this);
00080                 }
00081 
00082 
00083                 // == Functions.
00087                 LSVOID LSE_CALL                                                 Reset() {
00088                         for ( ; m_ui32Total--; ) {
00089                                 m_ptSegs[m_ui32Total].~_tSeg3Type();    // Destroy, don't delete.
00090                         }
00091                         m_ptSegs = NULL;
00092                         m_ui32Total = 0UL;
00093                         m_psaAllocator = NULL;
00094                         m_uiptrUser = 0UL;
00095                         m_bSplitter = false;
00096                 }
00097 
00105                 LSBOOL LSE_CALL                                                 Copy( const CPolygon3Base<_tType, _tSeg3Type, _tPlane3Type> &_p3bSrc, CStackAllocator * _psaAllocator ) {
00106                         Reset();
00107                         if ( !SetTotalSides( _p3bSrc.TotalSegments(), _psaAllocator ) ) { return false; }
00108                         for ( LSUINT32 I = _p3bSrc.TotalSegments(); I--; ) {
00109                                 m_ptSegs[I] = _p3bSrc.Segments()[I];
00110                         }
00111                         m_pPlane = _p3bSrc.m_pPlane;
00112                         m_uiptrUser = _p3bSrc.m_uiptrUser;
00113                         m_bSplitter = _p3bSrc.m_bSplitter;
00114                         return true;
00115                 }
00116 
00124                 LSBOOL LSE_CALL                                                 SetTotalSides( LSUINT32 _ui32Total, CStackAllocator * _psaAllocator ) {
00125                         Reset();
00126                         m_psaAllocator = _psaAllocator;
00127                         if ( _ui32Total < 3UL ) { return false; }
00128                         if ( (m_ptSegs = static_cast<_tSeg3Type *>(_psaAllocator->Alloc( sizeof( _tSeg3Type ) * _ui32Total, 4UL ))) ) {
00129                                 m_ui32Total = _ui32Total;
00130                                 for ( ; _ui32Total--; ) {
00131                                         new( &m_ptSegs[_ui32Total] ) _tSeg3Type();
00132                                 }
00133                                 return true;
00134                         }
00135                         return false;
00136                 }
00137 
00143                 LSUINT32 LSE_CALL                                               TotalSegments() const {
00144                         return m_ui32Total;
00145                 }
00146 
00152                 _tSeg3Type * LSE_CALL                                   Segments() {
00153                         return m_ptSegs;
00154                 }
00155 
00161                 const _tSeg3Type * LSE_CALL                             Segments() const {
00162                         return m_ptSegs;
00163                 }
00164 
00170                 const _tPlane3Type & LSE_CALL                   Plane() const {
00171                         return m_pPlane;
00172                 }
00173 
00179                 _tPlane3Type & LSE_CALL                                 Plane() {
00180                         return m_pPlane;
00181                 }
00182 
00188                 LSVOID LSE_CALL                                                 SetUser( LSUINTPTR _uiptrValue ) {
00189                         m_uiptrUser = _uiptrValue;
00190                 }
00191 
00197                 LSUINTPTR LSE_CALL                                              GetUser() const {
00198                         return m_uiptrUser;
00199                 }
00200 
00208                 LSBOOL LSE_CALL                                                 Finalize( _tType _tEpsilon ) {
00209                         assert( m_ui32Total >= 3UL );
00210                         _tSeg3Type tTemp;
00211                         // Remove any segments that have any missing connections.
00212                         for ( LSUINT32 I = 0UL; I < m_ui32Total; ) {
00213                                 // Check P against Q.
00214                                 LSBOOL bHasP = false, bHasQ = false;
00215                                 _tType tLen = (m_ptSegs[I].q - m_ptSegs[I].p).LenSq();
00216                                 if ( tLen >= _tEpsilon * _tEpsilon ) {
00217                                         for ( LSUINT32 J = 0UL; J < m_ui32Total; ++J ) {
00218                                                 if ( J == I ) { continue; }
00219                                                 _tType tDist = (m_ptSegs[I].p - m_ptSegs[J].q).Len();
00220                                                 if ( tDist <= _tEpsilon ) {
00221                                                         bHasP = true;
00222                                                         break;
00223                                                 }
00224                                         }
00225                                         if ( bHasP ) {
00226                                                 // Check its Q.
00227                                                 for ( LSUINT32 J = 0UL; J < m_ui32Total; ++J ) {
00228                                                         if ( J == I ) { continue; }
00229                                                         _tType tDist = (m_ptSegs[I].q - m_ptSegs[J].p).Len();
00230                                                         if ( tDist <= _tEpsilon ) {
00231                                                                 bHasQ = true;
00232                                                                 break;
00233                                                         }
00234                                                 }
00235                                         }
00236                                 }
00237 
00238                                 if ( !bHasP || !bHasQ ) {
00239                                         Remove( I );
00240                                         if ( m_ui32Total <= 2UL ) {
00241                                                 return false;
00242                                         }
00243                                 }
00244                                 else {
00245                                         ++I;
00246                                 }
00247                         }
00248                         for ( LSUINT32 I = 0UL; I < m_ui32Total; ++I ) {
00249                                 // Find the starting point that connects to the end point of the Ith edge.
00250                                 for ( LSUINT32 J = I + 1UL; J < m_ui32Total; ++J ) {
00251                                         _tType tDist = (m_ptSegs[J].p - m_ptSegs[I].q).Len();
00252                                         if ( tDist <= _tEpsilon ) {
00253                                                 if ( J != I + 1UL ) {   // No need to swap here.
00254                                                         tTemp = m_ptSegs[I+1];
00255                                                         m_ptSegs[I+1] = m_ptSegs[J];
00256                                                         m_ptSegs[J] = tTemp;
00257                                                 }
00258                                                 break;
00259                                         }
00260                                 }
00261                         }
00262 
00263                         // Return true if we came full circle.
00264                         return (m_ptSegs[0].p - m_ptSegs[m_ui32Total-1].q).Len() <= _tEpsilon;
00265                 }
00266 
00272                 LSVOID LSE_CALL                                                 Remove( LSUINT32 _ui32Index ) {
00273                         if ( _ui32Index < m_ui32Total ) {
00274                                 m_ptSegs[_ui32Index].~_tSeg3Type();             // Destroy, don't delete.
00275                                 for ( LSUINT32 J = _ui32Index + 1UL; J < m_ui32Total; ++J ) {
00276                                         m_ptSegs[J-1] = m_ptSegs[J];
00277                                 }
00278                                 --m_ui32Total;
00279                         }
00280                 }
00281 
00287                 LSBOOL LSE_CALL                                                 IsSplitter() const {
00288                         return m_bSplitter;
00289                 }
00290 
00296                 LSVOID LSE_CALL                                                 SetAsSplitter( LSBOOL _bVal ) {
00297                         m_bSplitter = _bVal;
00298                 }
00299 
00300 
00301         protected :
00302                 // == Members.
00306                 _tSeg3Type *                                                    m_ptSegs;
00307 
00311                 CStackAllocator *                                               m_psaAllocator;
00312 
00316                 LSUINTPTR                                                               m_uiptrUser;
00317 
00321                 LSUINT32                                                                m_ui32Total;
00322 
00326                 _tPlane3Type                                                    m_pPlane;
00327 
00331                 LSBOOL                                                                  m_bSplitter;
00332 
00333         };
00334 
00335 }       // namespace lsp
00336 
00337 #endif  // __LSP_POLYGON3BASE_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator