#pragma once #include // assert() #include "SimpleTriangleRasterizer.h" // CSimpleTriangleRasterizer // This class is to speed up raycasting queries. // each element in a 2D raster has a pointer (or zero) to a few elements in a second memory(elemets: void *) (0 teminated) // The raster can be used to query elements on a 3D line - if you project the 3D World down to that raster from one side. // To get the maximum speedup you shoudl do this from 3 sides. template class CRasterTable { public: //! constructor CRasterTable( void ); //! destructor virtual ~CRasterTable( void ); //! alloc raster, after that Phase 1 has started //! /param indwXSize 1.. //! /param indwYSize 1.. //! /return true=success, false otherwise bool Init( const DWORD indwXSize, const DWORD indwYSize ); //! //! free data void DeInit( void ); //! Has to be called in Phase 1, after Phase 2 has started //! /return true=success, false otherwise bool PreProcess( void ); //! call this per triangle after Init and before PreProcess //! after PreProcess call it again for every triangle //! /param infX[3] x coordiantes of the 3 vertices in raster units //! /param infX[3] y coordiantes of the 3 vertices in raster units //! /param inElement element you want to store void PutInTriangle( float infX[3], float infY[3], T &inElement ); //! returns pointer to zero terminated array of pointers //! /param iniX 0..m_dwXSize-1 //! /param iniY 0..m_dwYSize-1 //! /return T *GetElementsAt( int iniX, int iniY ); //! //! /return memory consumption in bytes O(1) DWORD CalcMemoryConsumption( void ); //! //! /param inPathFileName filename with path and extension void Debug( const char *inPathFileName ) const; //! //! /param outPitchInBytes //! /return DWORD *GetDebugData( DWORD &outPitchInBytes ) const; //! //! /return width in raster elements DWORD GetWidth( void ); //! //! /return height in raster elements DWORD GetHeight( void ); //! to save memory and make it faster - less cache misses) // IF YOU WANNA USE THIS FUNCTION, CLEAR IT FIRST BECAUSE IT SIMPLY DOES NOT WORK void Compress( void ); // ************************************************************** union { DWORD * m_pDataCounter; //!< used in Phase 1 [m_dwXSize*m_dwYSize] T ** m_pDataPtr; //!< used in Phase 2 [m_dwXSize*m_dwYSize] }; private: T * m_pExtraMemoryPool; //!< for the pointers to store (zero terminated) (sorted in ascending order) [m_ExtraMemorySize] DWORD m_ExtraMemorySize; //!< extra memroy pool size in StoredElementPtr elements DWORD m_dwXSize; //!< width of the buffer 1.. if allocated, otherwise 0 DWORD m_dwYSize; //!< height of the buffer 1.. if allocated, otherwise 0 //! callback function class CPixelIncrement: public CSimpleTriangleRasterizer::IRasterizeSink { public: //! constructor CPixelIncrement( DWORD *inpBuffer, DWORD indwWidth, DWORD indwHeight ) { m_pBuffer=inpBuffer; m_dwWidth=indwWidth; m_dwHeight=indwHeight; } //! virtual void Line( const float infXLeft, const float infXRight, const int iniLeft, const int iniRight, const int iniY ) { assert(iniLeft>=0); assert(iniY>=0); assert(iniRight<=(int)m_dwWidth); assert(iniY<(int)m_dwHeight); DWORD *pMem=&m_pBuffer[iniLeft+iniY*m_dwWidth]; for(int x=iniLeft;x class CPixelAddArrayElement: public CSimpleTriangleRasterizer::IRasterizeSink { public: //! constructor CPixelAddArrayElement( T **inpBuffer, DWORD indwWidth, T *inElementPtr ) { m_pBuffer=inpBuffer; m_dwWidth=indwWidth; m_ElementPtr=inElementPtr; } //! __forceinline void ReturnPixel( T * &rPtr ) { --rPtr; *rPtr=*m_ElementPtr; } //! virtual void Line( const float infXLeft, const float infXRight, const int iniLeft, const int iniRight, const int iniY ) { T **pMem=&m_pBuffer[iniLeft+iniY*m_dwWidth]; for(int x=iniLeft;x CRasterTable::CRasterTable( void ) { assert(sizeof(DWORD)==sizeof(DWORD *)); // only for 32 Bit compiler m_pDataPtr=0; m_pExtraMemoryPool=0; m_ExtraMemorySize=0; } // destructor template CRasterTable::~CRasterTable( void ) { DeInit(); } // free data template void CRasterTable::DeInit( void ) { delete [] m_pDataCounter;m_pDataCounter=0; delete [] m_pExtraMemoryPool;m_pExtraMemoryPool=0; m_ExtraMemorySize=0; m_dwXSize=0; m_dwYSize=0; } // alloc raster, after that Phase 1 has started template bool CRasterTable::Init( const DWORD indwXSize, const DWORD indwYSize ) { assert(!m_pDataCounter); assert(!m_pExtraMemoryPool); DeInit(); assert(indwXSize); assert(indwYSize); m_dwXSize=indwXSize; m_dwYSize=indwYSize; assert(sizeof(DWORD)==sizeof(T *)); m_pDataCounter=new DWORD[m_dwXSize*m_dwYSize]; if(m_pDataCounter) memset(m_pDataCounter,0,m_dwXSize*m_dwYSize*sizeof(DWORD)); return(m_pDataPtr!=0); } // Has to be called in Phase1, after that Phase 2 has started template bool CRasterTable::PreProcess( void ) { assert(m_pDataCounter); assert(!m_pExtraMemoryPool); assert(!m_ExtraMemorySize); DWORD dwSum=0; // extra memroy pool size in StoredElementPtr elements { DWORD *ptr=m_pDataCounter; for(DWORD i=0;i void CRasterTable::PutInTriangle( float infX[3], float infY[3], T &inElement ) { float fU[3],fV[3]; for(int i=0;i<3;i++) { fU[i]=infX[i];fV[i]=infY[i]; } CSimpleTriangleRasterizer Rasterizer(m_dwXSize,m_dwYSize); if(m_pExtraMemoryPool==0) // Phase 1 { CPixelIncrement pix(m_pDataCounter,m_dwXSize,m_dwYSize); Rasterizer.CallbackFillConservative(fU,fV,&pix); } else // Phase 2 { CPixelAddArrayElement pix(m_pDataPtr,m_dwXSize,&inElement); Rasterizer.CallbackFillConservative(fU,fV,&pix); } } // returns pointer to zero terminated array of pointers template T *CRasterTable::GetElementsAt( int iniX, int iniY ) { assert(iniX>=0); assert(iniX<(int)m_dwXSize); assert(iniY>=0); assert(iniY<(int)m_dwYSize); T *pRet=m_pDataPtr[iniY*m_dwXSize+iniX]; if(pRet) assert(*pRet); // no pointer in the raster should point to empty list return(pRet); } // returns pointer to zero terminated array of pointers // IF YOU WANNA USE THIS FUNCTION, CLEAR IT FIRST BECAUSE IT SIMPLY DOES NOT WORK template void CRasterTable::Compress( void ) { if(!m_pExtraMemoryPool)return; T *pDestStart=0; DWORD dwNewMemorySize=0; for(DWORD i=0;i DWORD CRasterTable::CalcMemoryConsumption( void ) { return(m_dwXSize*m_dwYSize*sizeof(m_pDataCounter)+m_ExtraMemorySize*sizeof(T)); } template void CRasterTable::Debug( const char *inPathFileName ) const { #ifdef _TGA_LOADER_INCLUDED for(DWORD i=0;i DWORD *CRasterTable::GetDebugData( DWORD &outPitchInBytes ) const { outPitchInBytes=m_dwXSize*sizeof(DWORD); return(m_pDataCounter); } template DWORD CRasterTable::GetWidth( void ) { return(m_dwXSize); } template DWORD CRasterTable::GetHeight( void ) { return(m_dwYSize); }