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 #include <algorithm> 00011 #include <vector> 00012 00013 namespace Stg 00014 { 00015 00016 // a bit of experimenting suggests that these values are fast. YMMV. 00017 const int32_t RBITS( 5 ); // regions contain (2^RBITS)^2 pixels 00018 const int32_t SBITS( 5 );// superregions contain (2^SBITS)^2 regions 00019 const int32_t SRBITS( RBITS+SBITS ); 00020 00021 const int32_t REGIONWIDTH( 1<<RBITS ); 00022 const int32_t REGIONSIZE( REGIONWIDTH*REGIONWIDTH ); 00023 00024 const int32_t SUPERREGIONWIDTH( 1<<SBITS ); 00025 const int32_t SUPERREGIONSIZE( SUPERREGIONWIDTH*SUPERREGIONWIDTH ); 00026 00027 const int32_t CELLMASK( ~((~0x00)<< RBITS )); 00028 const int32_t REGIONMASK( ~((~0x00)<< SRBITS )); 00029 00030 inline int32_t GETCELL( const int32_t x ) { return( x & CELLMASK); } 00031 inline int32_t GETREG( const int32_t x ) { return( ( x & REGIONMASK ) >> RBITS); } 00032 inline int32_t GETSREG( const int32_t x ) { return( x >> SRBITS); } 00033 00034 // this is slightly faster than the inline method above, but not as safe 00035 //#define GETREG(X) (( (static_cast<int32_t>(X)) & REGIONMASK ) >> RBITS) 00036 00037 00038 class Cell 00039 { 00040 friend class Region; 00041 friend class SuperRegion; 00042 friend class World; 00043 friend class Block; 00044 00045 private: 00046 Region* region; 00047 std::vector<Block*> blocks; 00048 bool boundary; 00049 00050 public: 00051 Cell() 00052 : region( NULL), 00053 blocks() 00054 { 00055 } 00056 00057 inline void RemoveBlock( Block* b ); 00058 inline void AddBlock( Block* b ); 00059 inline void AddBlockNoRecord( Block* b ); 00060 }; 00061 00062 class Region 00063 { 00064 public: 00065 00066 Cell* cells; 00067 SuperRegion* superregion; 00068 unsigned long count; // number of blocks rendered into this region 00069 00070 Region(); 00071 ~Region(); 00072 00073 Cell* GetCell( int32_t x, int32_t y ) 00074 { 00075 if( ! cells ) 00076 { 00077 cells = new Cell[REGIONSIZE]; 00078 00079 for( int i=0; i<REGIONSIZE; ++i ) 00080 cells[i].region = this; 00081 } 00082 00083 return( (Cell*)&cells[ x + y * REGIONWIDTH ] ); 00084 } 00085 00086 00089 //static Region* GetRegion( SuperRegion* superregion ); 00090 // static std::stack<Region*> recycled_regions; 00091 00092 // static std::set<Region*> empty_regions; 00093 00094 // static void GarbageCollect() 00095 // { 00096 // FOR_EACH( it, empty_regions ) 00097 // { 00098 // Region* reg = *it; 00099 // //delete reg; 00100 00101 // printf( "Garbage collecting region %p\n", reg ); 00102 // } 00103 00104 // empty_regions.clear(); 00105 // } 00106 00107 }; 00108 00109 class SuperRegion 00110 { 00111 friend class World; 00112 friend class Model; 00113 00114 private: 00115 00116 Region* regions; 00117 stg_point_int_t origin; 00118 World* world; 00119 00120 public: 00121 00122 SuperRegion( World* world, stg_point_int_t origin ); 00123 ~SuperRegion(); 00124 00125 Region* GetRegion( int32_t x, int32_t y ) 00126 { return( ®ions[ x + y * SUPERREGIONWIDTH ] ); } 00127 00128 void Draw( bool drawall ); 00129 void Floor(); 00130 00131 unsigned long count; // number of blocks rendered into this superregion 00132 }; 00133 00134 00135 // inline void printvec( std::vector<Block*>& vec ) 00136 // { 00137 // printf( "Vec: "); 00138 // for( size_t i=0; i<vec.size(); i++ ) 00139 // printf( "%p ", vec[i] ); 00140 // puts( "" ); 00141 // } 00142 00143 void Cell::RemoveBlock( Block* b ) 00144 { 00145 // linear time removal, but these vectors are very short, usually 1 00146 // or 2 elements. Fast removal - our strategy is to copy the last 00147 // item in the vector over the item we want to remove, then pop off 00148 // the tail. This avoids moving the other items in the vector. Saves 00149 // maybe 1 or 2% run time in my tests. 00150 00151 // find the value in the vector 00152 // printf( "\nremoving %p\n", b ); 00153 // puts( "before" ); 00154 // printvec( blocks ); 00155 00156 // copy the last item in the vector to overwrite this one 00157 copy_backward( blocks.end(), blocks.end(), std::find( blocks.begin(), blocks.end(), b )); 00158 blocks.pop_back(); // and remove the redundant copy at the end of 00159 // the vector 00160 00161 --region->count; 00162 --region->superregion->count; 00163 00164 // if( region->count == 0 && region->candidate_count == 0 ) 00165 // Region::empty_regions.insert( region ); 00166 } 00167 00168 void Cell::AddBlock( Block* b ) 00169 { 00170 blocks.push_back( b ); 00171 b->RecordRendering( this ); 00172 00173 ++region->count; 00174 ++region->superregion->count; 00175 } 00176 00177 00178 }; // namespace Stg
Generated on Wed Jul 22 11:51:03 2009 for Stage by
