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