eng_world.hh

Go to the documentation of this file.
00001 /*
00008  * LEGAL:   COPYRIGHT (C) 2004 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_WORLD_HH
00014 #define ENG_WORLD_HH 1
00015 
00016 namespace eng {
00017 
00018 class Object;
00019 #define QuadrantPtr SafePtr<World::Quadrant>
00020 
00021 // Symbolic names for world axises (N/A to matrix axises).
00022 // World axises vs. eye matrix axises:
00023 // In terms of depth, Z defines depth in both world and eye space.
00024 // But in terms of altitude (up/down), Y is up/down in eye space
00025 // while Z is up/down in world space.
00026 enum { AXIS_LAT = AXIS_X, LAT = AXIS_LAT,    // latitude
00027        AXIS_LON = AXIS_Y, LON = AXIS_LON,    // longitude
00028        AXIS_ALT = AXIS_Z, ALT = AXIS_ALT };  // altitude
00029 #define AXIS_LAT_ x
00030 #define AXIS_LON_ y
00031 #define AXIS_ALT_ z
00032 #define LAT_ AXIS_LAT_
00033 #define LON_ AXIS_LON_
00034 #define ALT_ AXIS_ALT_
00035 
00036 // Macro for constructing a Vector3 independent of definition of axises.
00037 // (For future, this may help to facilitate changing order of axises.)
00038 // WorldVertex pos( LAT_LON_ALT( lat, lon, alt ) );
00039 #define LAT_LON_ALT( LAT, LON, ALT )  (LAT), (LON), (ALT)
00040 
00049 class World : public Threadable
00050 {
00051 
00052 protected:
00053 class Quadrant;
00054 class Locus;
00055 friend class Locus;
00056 friend class Quadrant;
00057 friend void ThreadQuadrantPopulate( long quadrant );
00058 
00059 // Macro also used by friend classes.
00060 #define WORLD_AUTO_LOCK() THREAD_CODE( AutoLock<SlowLock> lock( &gWorld.mLock ); )
00061 #define LOCUS_AUTO_LOCK() THREAD_CODE( AutoLock<SlowLock> lock( &mLock ); )
00062 #define ASSERT_WORLD() 
00063 
00064 public:
00065     FN_MAIN_THREAD virtual void Make( void ) = 0;
00066     FN_REENTRANT virtual bool   IfMade( void ) = 0;  
00067     FN_REENTRANT eAttached      Attach( SharedPtr<Object> object );
00068     FN_REENTRANT eAttached      Detach( SharedPtr<Object> object );
00069     FN_REENTRANT WorldVertex    CorrectPosition( const WorldVertex& pos );
00070     FN_MAIN_THREAD void         Draw( void );
00071     FN_REENTRANT void           EyePositionChanged( void );  // Locus might need updating
00072     FN_REENTRANT uint           GetObjectCnt( void );
00073     FN_REENTRANT const BoxVolume& GetBoxVolume( void ) { ASSERT(IfMade()); return mBoxVolume; }
00074     FN_REENTRANT fp             GetLatWidth( void ) { ASSERT(IfMade()); return mBoxVolume.mMax.LAT_ - mBoxVolume.mMin.LAT_; }
00075     FN_REENTRANT fp             GetLonWidth( void ) { ASSERT(IfMade()); return mBoxVolume.mMax.LON_ - mBoxVolume.mMin.LON_; }
00076     FN_REENTRANT fp             GetAltWidth( void ) { ASSERT(IfMade()); return mBoxVolume.mMax.ALT_ - mBoxVolume.mMin.ALT_; }
00077     FN_REENTRANT WorldVertex    GetCenter( void );
00078 
00079     // Locus:
00080     FN_REENTRANT fp             GetLocusEdge( uint dim );
00081     FN_LOCKED uint              GetLocusObjectCnt( void );
00082 
00083     // Quadrant (limited exposure):
00084     FN_REENTRANT fp             GetQuadrantEdge( void ) { ASSERT(IfMade()); return mQuadrantEdge; }
00085     FN_REENTRANT uint           GetQuadrantDim( uint dim ) { ASSERT(IfMade()); return mQuadrantDim[dim]; }
00086 
00087 #if DEBUG
00088     void                Check( void );
00089 #endif
00090 
00091 protected:
00092     typedef uint Qidx;  
00093     enum eSim { eSim_FLIGHT, eSim_SPACE };
00094     enum eOutsidePolicy { eOutsidePolicy_CLAMP, eOutsidePolicy_WRAP };
00095 
00096 protected:
00097                                 World( void ) { }  // Make() substitutes for ctor
00098     virtual                     ~World() { }
00099     void                        Make( const eSim sim, const Int3& quadrantDim, const fp quadrantEdge, const Int3& locusDim );
00100     FN_LOCKED virtual void      Populate( QuadrantPtr quadrant ) = 0;  // part of Template Method
00101     FN_LOCKED QuadrantPtr       GetQuadrant( const Int3& triplet );
00102     FN_REENTRANT QuadrantPtr    GetQuadrant( const WorldVertex& pos );
00103     FN_REENTRANT Qidx           GetQuadrantIdx( const Int3& triplet );
00104     FN_REENTRANT Qidx           GetQuadrantIdx( const WorldVertex& pos );
00105     FN_REENTRANT Int3           GetQuadrantTriplet( const WorldVertex& pos );
00106     FN_REENTRANT Int3           WrapQuadrantTriplet( const Int3& triplet );
00107     FN_MAIN_THREAD void         DeleteQuadrant( QuadrantPtr quadrant );
00108     FN_REENTRANT WorldVertex    CorrectPositionClamp( const WorldVertex& pos );
00109     FN_REENTRANT WorldVertex    CorrectPositionWrap( const WorldVertex& pos );
00110 
00111 // Quadrant:
00112 protected:
00120     class Quadrant : public Threadable
00121     {
00122     
00123     friend void ThreadQuadrantPopulate( long quadrant );
00124     public:
00125         enum eState { EMPTY, SHRUNK, POPULATING, POPULATED };
00126                     Quadrant( const Int3& triplet, const fp edge, const uint seed );
00127                     ~Quadrant();
00128         FN_LOCKED void          Populate( void );
00129         FN_LOCKED uint          Shrink( void );
00130         FN_LOCKED eAttached     Attach( SharedPtr<Object> object );
00131         FN_LOCKED eAttached     Detach( SharedPtr<Object> object );
00132         FN_REENTRANT void       Draw( void );
00133         FN_LOCKED const BoxVolume& GetBoxVolume( void );
00134         FN_LOCKED WorldVertex   GetCenter( void );
00135         FN_LOCKED Int3          GetTriplet( void );
00136         FN_REENTRANT eState     GetState( void );
00137         FN_LOCKED void          SetState( eState state );
00138         FN_LOCKED uint          GetSeed( void );
00139         FN_REENTRANT uint       GetObjectCnt( void );  // NOTE: shrunk Objects are counted
00140 
00141     private:
00142         BoxVolume   ComputeBoxVolume( const Int3& triplet, const fp edge );
00143         class ShrinkEachObjectFunctor : public BSP::ForEachObjectFunctor
00144         {
00145         public:
00146             ShrinkEachObjectFunctor( void ) : mObjectCnt(0) { }
00147             void operator()( SharedPtr<Object> object );
00148             uint mObjectCnt;  // count of objects that were shrunk
00149         };
00150 
00151     public:
00152         SlowLock        mLock;          
00153     private:
00154         Int3            mTriplet;       
00155         eState          mState;         
00156         uint            mSeed;          
00157         BSP             mBSP;           
00158         int             mObjectCnt;     
00159         CLASS_VAR fp    msEdge;         
00160     public:
00161         
00162     };
00163 
00164 // Locus:
00165 protected:
00169     class Locus
00170     {
00171     
00172     public:
00173         typedef World::Qidx Qidx;
00174         typedef vector<QuadrantPtr> PopulateQueue;
00175                                 Locus( void );  // Init() is actual ctor
00176                                 ~Locus();
00177         FN_MAIN_THREAD void     Init( const Int3& dim );
00178         FN_MAIN_THREAD void     Update( void );
00179         FN_MAIN_THREAD void     Draw( void );
00180         FN_LOCKED uint          GetObjectCnt( void );
00181 
00182     private:
00183         FN_MAIN_THREAD void     Move( QuadrantPtr centerQuadrant );
00184         FN_MAIN_THREAD uint     MakeQuadrant( const Int3 t, vector<PopulateQueue*>& populateQueues, uint populateQueueIdx );
00185         FN_MAIN_THREAD void     DestroyZombieQuadrants( void );
00186         FN_MAIN_THREAD bool     ShrinkQuadrant( QuadrantPtr quadrant );
00187 #if DEBUG
00188         FN_LOCKED QuadrantPtr   GetCenterQuadrant( void );
00189         FN_LOCKED World::Qidx   GetQuadrantIdx( const Int3& triplet );
00190 #endif
00191 
00192     private:
00194         class LocusIdleFunctor : public Event<>::ListenerFunctor
00195         {
00196         public:
00197             LocusIdleFunctor( Locus& locus ) : mLocus(locus) { }
00198             void operator()( Void nothing );
00199             Locus& mLocus;
00200         };
00201         friend class LocusIdleFunctor;
00202 
00203     private:
00204         typedef vector<Qidx> QuadrantContainer;  // flat idx to World::mQuadrants[]
00205         typedef QuadrantContainer::iterator QuadrantIterator;
00206 
00207         SlowLock            mLock;
00208         QuadrantContainer   mQuadrants;
00209         Int3                mDim;                   // locus <= world
00210         Int3                mDimHalf;               // pre-computed by constructor
00211         Int3                mCenterTriplet;         // pre-computed by constructor, center's triplet is constant
00212         Int3                mPrevQuadrantTriplet;   // singular, N/A if mPrevQuadrants empty
00213         QuadrantContainer   mPrevQuadrants;         // plural
00214         set<Qidx>           mZombieQuadrants;       // flat idx to World::mQuadrants[]
00215     };
00216 
00217 private:
00219     struct QuadrantSeed
00220     {
00221         QuadrantSeed( Quadrant* q, uint seed ) : mQuadrant(q), mSeed(seed) { }
00222         Quadrant*   mQuadrant;
00223         uint        mSeed;
00224     };
00225 
00226 // World data:
00227 protected:
00228     SlowLock                mLock;
00229     eSim                    mSim;               
00230     eOutsidePolicy          mOutsidePolicy;     
00231     BoxVolume               mBoxVolume;         
00232     fp                      mQuadrantEdge;      
00233     Int3                    mQuadrantDim;       
00234     Int3                    mLocusDim;          
00235     vector<QuadrantSeed>    mQuadrants;         
00236     Locus                   mLocus;             
00237     fp                      mMargin;            
00238 };
00239 
00240 } // namespace eng
00241 
00242 #endif // ENG_WORLD_HH
Palomino 3D Engine documents generated by doxygen 1.5.3 on Fri Nov 23 11:26:10 2007