eng_bsp.hh

Go to the documentation of this file.
00001 /*
00008  * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
00009  *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
00010  *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
00011  *****************************************************************************/
00012 
00013 #ifndef ENG_BSP_HH
00014 #define ENG_BSP_HH 1
00015 
00016 namespace eng {
00017 
00018 class Object;
00019 
00023 class BSP
00024 {
00025 
00026 friend class Quadrant;
00027 friend class World;
00028 
00029 public:
00031     enum ePolicy
00032     {
00033         ePolicy_FORCE,  
00034         ePolicy_THROW_EXCEPTION
00035     };
00036 
00037 //------------------------------------------------------------------------------
00038 // Functor:
00039 public:
00047     class ForEachObjectFunctor
00048     {
00049     public:
00050                         ForEachObjectFunctor( void ) { }
00051         virtual         ~ForEachObjectFunctor() { }
00052         virtual void    operator()( SharedPtr<Object> obj ) = 0;
00053     };
00054 
00055     void        ForEachObject( ForEachObjectFunctor& functor ); 
00056 
00057 //------------------------------------------------------------------------------
00058 // Viewpoint (defined appropriately for recursing a BSP tree).
00059 private:
00067     class Viewpoint
00068     {
00069     public:
00070                     Viewpoint( void );
00071                     ~Viewpoint();
00073         fp Distance( const BoxVolume& boxVolume ) const
00074         {
00075             return gfx::Distance<WorldVertex,Vector3>( mPos, boxVolume.GetCenter() );
00076         }
00077 
00078     private:
00079         WorldVertex     mPos;  
00080     };
00081 
00082 //------------------------------------------------------------------------------
00083 // BSP Node:
00084 private:
00092     class Node
00093     {
00094     
00095     public:
00096         typedef list< shptr<Object> > ObjectList;  // Dlist incompatible with SharedPtr
00097         typedef Node* Ptr;
00098     public:
00099                     Node( const BoxVolume& boxVolume );
00100                     ~Node();
00101         bool        IfInside( const WorldVertex& viewpoint ) const { return mBoxVolume.IfInside( viewpoint ); }
00102         bool        IfInside( const Volume& volume ) const { return mBoxVolume.IfInside( volume ); }
00103         bool        IfInside( const BoxVolume& boxVolume ) const { return mBoxVolume.IfInside( boxVolume ); }
00104         eAttached   Attach( SharedPtr<Object> object );
00105         eAttached   Detach( SharedPtr<Object> object );
00106         void        Draw( const BSP::Viewpoint& viewpoint );
00107         void        ForEachObject( BSP::ForEachObjectFunctor& functor );
00108         // Saves memory by lazy-allocation.  Not for use in testing if a node exists.
00109         ObjectList* GetOrNewObjectList( void )
00110         {
00111             return (mObjectList != NULL) ? mObjectList : (mObjectList = new ObjectList);
00112         }
00113     private:
00114         void        DrawVisit( void );
00115 
00116     public:
00117         BoxVolume       mBoxVolume;     
00118         Node::Ptr       mLeft;          
00119         Node::Ptr       mRight;         
00120     private:
00121         ObjectList*     mObjectList;    
00122         struct Bits                     
00123         {
00124             uint mObjectCnt            : 16;
00125             uint mObjectCntTranslucent : 16;
00126         };
00127         Bits            mBits;
00128         CLASS_CONST uint NODE_OBJECT_LIMIT = 0x7fff;  // 16 bits
00129     public:
00130         
00131     };
00132 
00133 //------------------------------------------------------------------------------
00134 // BSP interface:
00135 public:
00136                 BSP( const BoxVolume& boxVolume );
00137                 ~BSP();
00138     CLASS_METHOD void SetPolicy( const ePolicy policy );
00139     // BoxVolume::IfInside() is faster than absract Volume::IfInside().
00140     bool        IfInside( const Volume& volume ) { return mRoot->IfInside( volume ); }
00141     bool        IfInside( const BoxVolume& boxVolume ) { return mRoot->IfInside( boxVolume ); }
00142     const BoxVolume& GetBoxVolume( void ) { return mRoot->mBoxVolume; }
00143     eAttached   Attach( SharedPtr<Object> object );
00144     eAttached   Detach( SharedPtr<Object> object );
00145     void        Draw( void );
00146 
00147 //------------------------------------------------------------------------------
00148 // BSP private methods:
00149 private:
00150     BSP::Node::Ptr  FindFit( SharedPtr<Object> object );
00151     BSP::Node::Ptr  FindFit( const BoxVolume& objectVolume );
00152 
00155     bool IfContinueRecursion( const uint level )
00156     {
00157         return (level < msRecursionLimit) && (mNodeCnt < msNodeLimit);
00158     }
00159 
00160 //------------------------------------------------------------------------------
00161 // BSP data members:
00162 public:
00163 #if DEBUG
00164     CLASS_VAR uint      msDebugRecursionLevel;  // for testing
00165     CLASS_VAR bool      msDebugDrawBox;
00166 #endif
00167 private:
00168     CLASS_VAR uint      msRecursionLimit;   
00169     CLASS_VAR int       msNodeLimit;        
00170     CLASS_VAR ePolicy   msPolicy;
00171     Node::Ptr           mRoot;              
00172     int                 mNodeCnt;
00173 };
00174 
00175 //==============================================================================
00176 
00180 class PolygonBSP
00181 {
00182 // STUB
00183 };
00184 
00185 //==============================================================================
00186 
00190 class ExceptionBSP : public Exception
00191 {
00192 public:
00193     string  GetText( void ) const { return "BSP exception"; }
00194 };
00195 
00196 } // namespace eng
00197 
00198 #endif // ENG_BSP_HH
Palomino 3D Engine documents generated by doxygen 1.5.3 on Fri Nov 23 11:26:07 2007