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