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 RBITS( 5 ); // regions contain (2^RBITS)^2 pixels 00017 const int32_t SBITS( 5 );// superregions contain (2^SBITS)^2 regions 00018 const int32_t SRBITS( RBITS+SBITS ); 00019 00020 const int32_t REGIONWIDTH( 1<<RBITS ); 00021 const int32_t REGIONSIZE( REGIONWIDTH*REGIONWIDTH ); 00022 00023 const int32_t SUPERREGIONWIDTH( 1<<SBITS ); 00024 const int32_t SUPERREGIONSIZE( SUPERREGIONWIDTH*SUPERREGIONWIDTH ); 00025 00026 const int32_t CELLMASK( ~((~0x00)<< RBITS )); 00027 const int32_t REGIONMASK( ~((~0x00)<< SRBITS )); 00028 00029 inline int32_t GETCELL( const int32_t x ) { return( x & CELLMASK); } 00030 inline int32_t GETREG( const int32_t x ) { return( ( x & REGIONMASK ) >> RBITS); } 00031 inline int32_t GETSREG( const int32_t x ) { return( x >> SRBITS); } 00032 00033 // this is slightly faster than the inline method above, but not as safe 00034 //#define GETREG(X) (( (static_cast<int32_t>(X)) & REGIONMASK ) >> RBITS) 00035 00036 class Cell 00037 { 00038 friend class Region; 00039 friend class SuperRegion; 00040 friend class World; 00041 friend class Block; 00042 00043 private: 00044 Region* region; 00045 std::vector<Block*> blocks; 00046 00047 public: 00048 Cell( Region* reg ) 00049 : region( reg ), 00050 blocks() 00051 { /* nothing to do */ } 00052 }; // class Cell 00053 00054 class Region 00055 { 00056 public: 00057 std::vector<Cell> cells; 00058 00059 SuperRegion* superregion; 00060 unsigned long count; // number of blocks rendered into this region 00061 00062 Region( SuperRegion* sr ); 00063 ~Region(); 00064 00065 Cell* GetCell( int32_t x, int32_t y ) 00066 { 00067 if( cells.empty() ) // lazy population of cells 00068 cells.insert( cells.begin(), REGIONSIZE, Cell( this ) ); 00069 00070 return( (Cell*)&cells[ x + y * REGIONWIDTH ] ); 00071 } 00072 00073 }; // class Region 00074 00075 class SuperRegion 00076 { 00077 friend class World; 00078 friend class Model; 00079 00080 private: 00081 00082 std::vector<Region> regions; 00083 point_int_t origin; 00084 World* world; 00085 00086 public: 00087 00088 SuperRegion( World* world, point_int_t origin ); 00089 ~SuperRegion(); 00090 00091 Region* GetRegion( int32_t x, int32_t y ) 00092 { return( ®ions[ x + y * SUPERREGIONWIDTH ] ); } 00093 00094 void DrawOccupancy(); 00095 void DrawVoxels(); 00096 00097 unsigned long count; // number of blocks rendered into this superregion 00098 }; // class SuperRegion; 00099 00100 }; // namespace Stg