00001 #ifndef __SQUARETEMPLATE
00002 #define __SQUARETEMPLATE
00003 
00004 
00005 #include "GXStandardDefines.h"
00006 #include "GXStreamFunctions.h"
00007 
00008 #define LEFT_SIDE 0
00009 #define RIGHT_SIDE 1
00010 #define UP_SIDE 2
00011 #define DOWN_SIDE 3
00012 
00013 
00014 
00015 template<typename type>
00016 class CGXSquare
00017 {
00018 public:
00019         CGXSquare()
00020         {
00021                 m_uSideSize=0;
00022                 m_pArray=NULL;
00023         }
00024 
00025 
00026         ~CGXSquare()
00027         {
00028                 Cleanup();
00029         }
00030 
00031         bool Fill(type& Val)
00032         {
00033                 for(UINT x=0;x<m_uSideSize;x++)
00034                 {
00035                         for(UINT y=0;y<m_uSideSize;y++)
00036                         {
00037                                 SetVal(Val,x,y);
00038                         }
00039                 }
00040 
00041                 return true;
00042         }
00043 
00044         
00045         
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072         void Cleanup()
00073         {
00074                 SAFE_ARRAY_DELETE(m_pArray);
00075                 m_uSideSize=0;
00076         }
00077 
00078 
00079         bool Init(UINT uSideSize, type* pInitialValue)
00080         {
00081                 if(0==uSideSize)
00082                 {
00083                         return false;
00084                 }
00085 
00086                 Cleanup();
00087                 
00088                 m_pArray=new type[uSideSize*uSideSize];
00089                 if(!m_pArray)
00090                 {
00091                         return false;
00092                 }
00093                 m_uSideSize=uSideSize;
00094 
00095                 if(pInitialValue)
00096                 {
00097                         for(UINT xctr=0;xctr<m_uSideSize;xctr++)
00098                         {
00099                                 for(UINT yctr=0;yctr<m_uSideSize;yctr++)
00100                                 {
00101                                         m_pArray[GetIndex(xctr,yctr)]=*pInitialValue;
00102                                 }
00103                         }
00104                 }
00105 
00106                 return true;
00107         }
00108 
00109         bool Smooth(float fAmt, bool bSmoothEdges)
00110         {
00111                 UINT uArea=m_uSideSize*m_uSideSize;
00112 
00113                 CGXAutoArray<type> TempType;
00114                 if(!TempType.Init(uArea))
00115                 {
00116                         return false;
00117                 }
00118 
00119                 
00120 
00121 
00122 
00123                 memcpy(TempType,m_pArray,sizeof(type)*uArea);
00124 
00125                 for(UINT xctr=1;xctr<m_uSideSize-1;xctr++)
00126                 {
00127                         for(UINT yctr=1;yctr<m_uSideSize-1;yctr++)
00128                         {
00129                                 type Total=TempType[GetIndex(xctr-1,yctr-1)];
00130                                 Total+=TempType[GetIndex(xctr-1,yctr)];
00131                                 Total+=TempType[GetIndex(xctr-1,yctr+1)];
00132 
00133                                 Total+=TempType[GetIndex(xctr,yctr-1)];
00134                                 Total+=TempType[GetIndex(xctr,yctr)];
00135                                 Total+=TempType[GetIndex(xctr,yctr+1)];
00136 
00137                                 Total+=TempType[GetIndex(xctr+1,yctr-1)];
00138                                 Total+=TempType[GetIndex(xctr+1,yctr)];
00139                                 Total+=TempType[GetIndex(xctr+1,yctr+1)];
00140 
00141                                 Total/=9;
00142                                 BlakeUtilLerp(fAmt,&(TempType[GetIndex(xctr,yctr)]),&(Total),&(m_pArray[GetIndex(xctr,yctr)]));
00143 
00144                         }
00145                 }
00146 
00147 
00148                 if(bSmoothEdges)
00149                 {
00150                         
00151                         UINT ctr;
00152                         for(ctr=0;ctr<m_uSideSize;ctr++)
00153                         {
00154                                 
00155                                 m_pArray[GetIndex(0,ctr)]=m_pArray[GetIndex(1,ctr)];
00156                                 
00157                                 
00158                                 m_pArray[GetIndex(m_uSideSize-1,ctr)]=m_pArray[GetIndex(m_uSideSize-2,ctr)];
00159                         
00160                                 
00161                                 m_pArray[GetIndex(ctr,0)]=m_pArray[GetIndex(ctr,1)];
00162 
00163                                 
00164                                 m_pArray[GetIndex(ctr,m_uSideSize-1)]=m_pArray[GetIndex(ctr,m_uSideSize-2)];
00165                                 
00166                         }
00167                 }
00168 
00169 
00170                 
00171                 return true;
00172         }
00173 
00174 
00175         inline void GetVal(type& Out, UINT x, UINT y)
00176         {
00177                 Out=m_pArray[GetIndex(x,y)];
00178         }
00179 
00180         inline void SetVal(type& In, UINT x, UINT y)
00181         {
00182                 m_pArray[GetIndex(x,y)]=In;
00183         }
00184 
00185         inline void SetVal(type& In, UINT index)
00186         {
00187                 m_pArray[index]=In;
00188         }
00189 
00190         void SetBigVal(type& In,UINT x, UINT y, UINT uRadius)
00191         {
00192                 for(UINT xctr=0;xctr<uRadius;xctr++)
00193                 {
00194                         for(UINT yctr=0;yctr<uRadius;yctr++)
00195                         {
00196                                 if(x>=xctr)
00197                                 {
00198                                         if(y>=yctr)
00199                                         {
00200                                                 SetVal(In,x-xctr,y-yctr);
00201                                         }
00202                                 }
00203 
00204                                 if(m_uSideSize>(x+xctr))
00205                                 {
00206                                         if(m_uSideSize>(y+yctr))
00207                                         {
00208                                                 SetVal(In,x+xctr,y+yctr);
00209                                         }
00210                                 }
00211                         }
00212                 }
00213         }
00214 
00215 
00216 
00217 
00218 
00219 
00220         inline UINT GetIndex(UINT x, UINT y)
00221         {
00222                 return ((m_uSideSize*y)+x);
00223         }
00224 
00225         inline UINT GetSideSize()
00226         {
00227                 return m_uSideSize;
00228         }
00229 
00230         inline type* GetArrayPointer()
00231         {
00232                 return m_pArray;
00233         }
00234 
00235         inline bool IsNull()
00236         {
00237                 return (NULL==m_pArray);
00238         }
00239 
00240         
00241         void Lerp(float fAmt, CGXSquare<type> One, CGXSquare<type> Two)
00242         {
00243                 if(One.GetSideSize()!=Two.GetSideSize())
00244                 {
00245                         return;
00246                 }
00247 
00248                 if(One.GetSideSize()!=m_uSideSize)
00249                 {
00250                         return;
00251                 }
00252 
00253                 for(UINT xctr=0;xctr<m_uSideSize;xctr++)
00254                 {
00255                         for(UINT yctr=0;yctr<m_uSideSize;yctr++)
00256                         {
00257                                 type ValOne, ValTwo, Result;
00258                                 One.GetVal(ValOne,xctr,yctr);
00259                                 Two.GetVal(ValTwo,xctr,yctr);
00260 
00261                                 BlakeUtilLerp(fAmt,&ValOne,&ValTwo,&Result);
00262                                 SetVal(Result,xctr,yctr);
00263                         }
00264                 }
00265         }
00266 
00267 
00268         
00269         void MakeSideSimilarTo(CGXSquare<type>& Target, UINT uSide)
00270         {
00271                 if(Target.GetSideSize()!=m_uSideSize)
00272                 {
00273                         return;
00274                 }
00275 
00276                 for(UINT ctr=0;ctr<m_uSideSize;ctr++)
00277                 {
00278                         type TargetVal;
00279                         switch(uSide)
00280                         {
00281                         case LEFT_SIDE:
00282                                 Target.GetVal(TargetVal,0,ctr);
00283                                 m_pArray[GetIndex(m_uSideSize-1,ctr)]=TargetVal;
00284                                 break;
00285                         
00286                         case RIGHT_SIDE:
00287                                 Target.GetVal(TargetVal,m_uSideSize-1,ctr);
00288                                 m_pArray[GetIndex(0,ctr)]=TargetVal;
00289                                 break;
00290 
00291                         case UP_SIDE:
00292                                 Target.GetVal(TargetVal,ctr,0);
00293                                 m_pArray[GetIndex(ctr,m_uSideSize-1)]=TargetVal;
00294                                 break;
00295 
00296 
00297                         case DOWN_SIDE:
00298                                 Target.GetVal(TargetVal,ctr,m_uSideSize-1);
00299                                 m_pArray[GetIndex(ctr,0)]=TargetVal;
00300                                 break;
00301                         }
00302                 }
00303 
00304         }
00305 
00306 
00307 
00308 
00309 
00310 
00311         void operator+=(CGXSquare<type>& Target)
00312         {
00313                 for(UINT x=0;x<m_uSideSize;x++)
00314                 {
00315                         for(UINT y=0;y<m_uSideSize;y++)
00316                         {
00317                                 float fTargetX, fTargetY;
00318 
00319                                 fTargetX= x/((float)m_uSideSize);
00320                                 fTargetY= y/((float)m_uSideSize);
00321 
00322 
00323                                 type Add;
00324                                 Target.GetFilteredVal(Add,fTargetX,fTargetY);
00325                                 m_pArray[GetIndex(x,y)]+=Add;
00326                         }
00327                 }
00328         }
00329 
00330 
00331 
00332 
00333         void GetFilteredVal(type& Out, float fX, float fY)
00334         {
00335 
00336                 fX*=m_uSideSize;
00337                 fY*=m_uSideSize;
00338 
00339                 type UpperLeft;
00340                 type UpperRight;
00341                 type LowerLeft;
00342                 type LowerRight;
00343 
00344                 
00345 
00346 
00347 
00348 
00349                 UINT uFloorX;
00350                 UINT uCeilX;
00351                 UINT uFloorY;
00352                 UINT uCeilY;
00353 
00354                 float fFloorX=(float)floor(fX);
00355                 float fCeilX=(float)ceil(fX);
00356                 float fFloorY=(float)floor(fY);
00357                 float fCeilY=(float)ceil(fY);
00358 
00359                 FloatToInt((int*)&uFloorX, fFloorX);
00360                 FloatToInt((int*)&uCeilX, fCeilX);
00361                 FloatToInt((int*)&uFloorY, fFloorY);
00362                 FloatToInt((int*)&uCeilY, fCeilY);
00363 
00364 
00365                 if(uCeilY>=GetSideSize())
00366                 {
00367                         if(uFloorY>=GetSideSize())
00368                         {
00369                                 uFloorY=GetSideSize()-1;
00370                         }
00371                         uCeilY=uFloorY;
00372                 }
00373 
00374                 
00375                 if(uCeilX>=GetSideSize())
00376                 {
00377                         if(uFloorX>=GetSideSize())
00378                         {
00379                                 uFloorX=GetSideSize()-1;
00380                         }
00381                         uCeilX=uFloorX;
00382                 }
00383 
00384                 GetVal(UpperLeft, uFloorX, uFloorY);
00385                 GetVal(UpperRight, uCeilX, uFloorY);
00386                 GetVal(LowerLeft, uFloorX, uCeilY);
00387                 GetVal(LowerRight, uCeilX, uCeilY);
00388 
00389                 
00390                 float fU=(fX-uFloorX);
00391                 float fV=(fY-uFloorY);
00392 
00393                 float fOneMinusU=1-fU;
00394                 float fOneMinusV=1-fV;
00395 
00396                 UpperLeft*=(fOneMinusU*fOneMinusV);
00397                 UpperRight*=(fU*fOneMinusV);
00398                 LowerLeft*=(fOneMinusU*fV);
00399                 LowerRight*=(fU*fV);
00400 
00401 
00402                 UpperLeft+=UpperRight;
00403                 UpperLeft+=LowerLeft;
00404                 UpperLeft+=LowerRight;
00405 
00406                 Out=UpperLeft;
00407         }
00408 
00409 
00410         void operator+=(float fAmt)
00411         {
00412                 for(UINT x=0;x<m_uSideSize;x++)
00413                 {
00414                         for(UINT y=0;y<m_uSideSize;y++)
00415                         {
00416                                 m_pArray[GetIndex(x,y)]+=fAmt;
00417                         }
00418                 }
00419         }
00420 
00421 
00422         void operator*=(float fAmt)
00423         {
00424                 for(UINT x=0;x<m_uSideSize;x++)
00425                 {
00426                         for(UINT y=0;y<m_uSideSize;y++)
00427                         {
00428                                 m_pArray[GetIndex(x,y)]*=fAmt;
00429                         }
00430                 }
00431         }
00432 
00433 
00434 
00435         bool WriteToStream(IStream* pStream)
00436         {
00437                 if(!pStream)
00438                 {
00439                         return false;
00440                 }
00441 
00442 
00443                 if(!GXWriteToStream(pStream, &m_uSideSize, sizeof(m_uSideSize)))
00444                 {
00445                         return false;
00446                 }
00447 
00448                 for(UINT xctr=0;xctr<m_uSideSize;xctr++)
00449                 {
00450                         for(UINT yctr=0;yctr<m_uSideSize;yctr++)
00451                         {
00452 
00453                                 if(!GXWriteToStream(pStream, 
00454                                                                         &m_pArray[GetIndex(xctr,yctr)], 
00455                                                                         sizeof(type)))
00456                                 {
00457                                         return false;
00458                                 }
00459                         }
00460                 }
00461 
00462                 return true;
00463         }
00464         
00465 
00466 
00467 
00468         bool ReadFromStream(IStream* pStream)
00469         {
00470                 Cleanup();
00471 
00472                 if(!GXReadFromStream(pStream, 
00473                                                         &m_uSideSize, 
00474                                                         sizeof(m_uSideSize)))
00475                 {
00476                         return false;
00477                 }
00478 
00479                 m_pArray=new type[m_uSideSize*m_uSideSize];
00480 
00481                 if(!m_pArray)
00482                 {
00483                         return false;
00484                 }
00485 
00486                 for(UINT xctr=0;xctr<m_uSideSize;xctr++)
00487                 {
00488                         for(UINT yctr=0;yctr<m_uSideSize;yctr++)
00489                         {
00490                                 UINT uIndex=GetIndex(xctr,yctr);
00491 
00492                                 if(!GXReadFromStream(pStream, 
00493                                                                         &(m_pArray[uIndex]), 
00494                                                                         sizeof(type)))
00495                                 {
00496                                         SAFE_DELETE(m_pArray);
00497                                         return false;
00498                                 }
00499                         }
00500                 }
00501 
00502                 return true;
00503         }
00504 
00505 
00506                 
00507 
00508 
00509 
00510 
00511 
00512 
00513 private:
00514         UINT m_uSideSize;
00515         type* m_pArray;
00516 };
00517 
00518 #endif