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( &regions[ 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  doxygen 1.5.9