region.hh
Go to the documentation of this file.
00001 #pragma once
00002 /*
00003   region.hh
00004   data structures supporting multi-resolution ray tracing in world class.
00005   Copyright Richard Vaughan 2008
00006 */
00007 
00008 #include "stage.hh"
00009 
00010 namespace Stg 
00011 {
00012 
00013   // a bit of experimenting suggests that these values are fast. YMMV.
00014   const int32_t RBITS( 5 ); // regions contain (2^RBITS)^2 pixels
00015   const int32_t SBITS( 5 );// superregions contain (2^SBITS)^2 regions
00016   const int32_t SRBITS( RBITS+SBITS );
00017         
00018   const int32_t REGIONWIDTH( 1<<RBITS );
00019   const int32_t REGIONSIZE( REGIONWIDTH*REGIONWIDTH );
00020 
00021   const int32_t SUPERREGIONWIDTH( 1<<SBITS );
00022   const int32_t SUPERREGIONSIZE( SUPERREGIONWIDTH*SUPERREGIONWIDTH );
00023         
00024   const int32_t CELLMASK( ~((~0x00)<< RBITS ));
00025   const int32_t REGIONMASK( ~((~0x00)<< SRBITS ));
00026         
00027   inline int32_t GETCELL( const int32_t x ) { return( x & CELLMASK); }
00028   inline int32_t GETREG(  const int32_t x ) { return( ( x & REGIONMASK ) >> RBITS); }
00029   inline int32_t GETSREG( const int32_t x ) { return( x >> SRBITS); }
00030 
00031   // this is slightly faster than the inline method above, but not as safe
00032   //#define GETREG(X) (( (static_cast<int32_t>(X)) & REGIONMASK ) >> RBITS)
00033     
00034   class Cell 
00035   {
00036     friend class SuperRegion;
00037     friend class World;
00038      
00039   private:
00040     std::vector<Block*> blocks[2];      
00041      
00042   public:
00043     Cell() 
00044       : blocks(), 
00045     region(NULL)
00046     { /* nothing to do */ }                 
00047      
00048     void RemoveBlock( Block* b, unsigned int index );
00049     void AddBlock( Block* b, unsigned int index );
00050     
00051     inline const std::vector<Block*>& GetBlocks( unsigned int index )
00052     { return blocks[index]; }
00053      
00054     Region* region;  
00055   };  // class Cell
00056   
00057   class Region
00058   {
00059     friend class SuperRegion;
00060     friend class World; // for raytracing
00061      
00062   private:
00063     std::vector<Cell> cells;
00064     unsigned long count; // number of blocks rendered into this region
00065      
00066   public:
00067     Region();
00068     ~Region();
00069      
00070     inline Cell* GetCell( int32_t x, int32_t y ) 
00071     {   
00072       if( cells.size() == 0 )
00073     {
00074       assert(count == 0 );
00075       
00076       cells.resize( REGIONSIZE );
00077       
00078       for( int32_t c=0; c<REGIONSIZE;++c)
00079         cells[c].region = this;
00080     } 
00081       
00082       return( &cells[ x + y * REGIONWIDTH ] );
00083     }
00084          
00085     inline void AddBlock();
00086     inline void RemoveBlock(); 
00087      
00088     SuperRegion* superregion;   
00089      
00090   }; // class Region
00091   
00092   class SuperRegion
00093   {
00094   private:
00095     unsigned long count; // number of blocks rendered into this superregion
00096     point_int_t origin;
00097     Region regions[SUPERREGIONSIZE];
00098     World* world;
00099      
00100   public:    
00101     SuperRegion( World* world, point_int_t origin );
00102     ~SuperRegion();
00103      
00104     inline Region* GetRegion( int32_t x, int32_t y )
00105     { 
00106       return( &regions[ x + y * SUPERREGIONWIDTH ]);
00107     }
00108      
00109     void DrawOccupancy(void) const;
00110     void DrawVoxels(unsigned int layer) const;
00111          
00112     inline void AddBlock();
00113     inline void RemoveBlock();      
00114      
00115     const point_int_t& GetOrigin() const { return origin; }
00116   }; // class SuperRegion;
00117   
00118         
00119 }; // namespace Stg