From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/water__height__map_8cpp-source.html | 838 +++++++++++++++++++++ 1 file changed, 838 insertions(+) create mode 100644 docs/doxygen/nel/water__height__map_8cpp-source.html (limited to 'docs/doxygen/nel/water__height__map_8cpp-source.html') diff --git a/docs/doxygen/nel/water__height__map_8cpp-source.html b/docs/doxygen/nel/water__height__map_8cpp-source.html new file mode 100644 index 00000000..9ab72b56 --- /dev/null +++ b/docs/doxygen/nel/water__height__map_8cpp-source.html @@ -0,0 +1,838 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

water_height_map.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000, 2001 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "std3d.h"
+00027 
+00028 #include "water_height_map.h"
+00029 #include "nel/misc/common.h"
+00030 #include "nel/misc/debug.h"
+00031 #include "nel/misc/vector_2f.h"
+00032 #include <algorithm>
+00033 #include <math.h>
+00034 
+00035 
+00036 
+00037 namespace NL3D
+00038 {
+00039 
+00040 //===========================================================================================
+00041 
+00042 CWaterHeightMap::CWaterHeightMap() : Date(-1),
+00043                                                                          _WavesEnabled(false),
+00044                                                                          _Damping(0.97f),
+00045                                                                          _FilterWeight(4),
+00046                                                                          _UnitSize(0.6f),
+00047                                                                          _WaveIntensity(0),
+00048                                                                          _WavePeriod(0),
+00049                                                                          _WaveImpulsionRadius(3),
+00050                                                                          _BorderWaves(true),
+00051                                                                          _EmitEllapsedTime(0),
+00052                                                                          _PropagateEllapsedTime(0),
+00053                                                                          _PropagationTime(0.10f),
+00054                                                                          _X(0),
+00055                                                                          _Y(0),
+00056                                                                          _NewX(0),
+00057                                                                          _NewY(0),
+00058                                                                          _CurrMap(0),
+00059                                                                          _Size(0)
+00060 {               
+00061 }
+00062 
+00063 
+00064 //===========================================================================================
+00065 
+00066 void    CWaterHeightMap::setPropagationTime(float time)
+00067 {
+00068         _PropagationTime = time;
+00069         _PropagateEllapsedTime = 0;
+00070         for (uint k = 0; k < NumWaterMap; ++k)
+00071         {       
+00072                 clearArea(k, 0, 0, _Size << 1, _Size << 1);
+00073         }
+00074 }
+00075 
+00076 //===========================================================================================
+00077 
+00078 void CWaterHeightMap::updateUserPos()
+00079 {
+00080         const sint x = _NewX;
+00081         const sint y = _NewY;
+00082 
+00083         nlassert(_Size != 0);
+00084         if ((uint) x == _X && (uint) y == _Y) return;
+00085         if ((uint) abs(x - _X) < _Size && (uint) abs(y - _Y) < _Size) // are there common pixels with the previous location?
+00086         {
+00087                 // compute zone
+00088         
+00089                 sint XDivSize;
+00090                 if ((sint) _X >= 0) XDivSize = (sint) _X / (sint) _Size;
+00091                 else XDivSize = ((sint) (_X + 1) / (sint) _Size) - 1;
+00092 
+00093                 sint YDivSize;
+00094                 if ((sint) _Y >= 0) YDivSize = (sint) _Y / (sint) _Size;
+00095                 else YDivSize = ((sint) (_Y + 1) / (sint) _Size) - 1;
+00096 
+00097                 sint xDivSize;
+00098                 if (x >= 0) xDivSize = (sint) x / (sint) _Size;
+00099                 else xDivSize = ((sint) (x + 1) / (sint) _Size) - 1;
+00100 
+00101                 sint yDivSize;
+00102                 if (y >= 0) yDivSize = (sint) y / (sint) _Size;
+00103                 else yDivSize = ((sint) (y + 1) / (sint) _Size) - 1;
+00104 
+00105                 // different zone -> must decal datas
+00106                 if (xDivSize != XDivSize || yDivSize != YDivSize)
+00107                 {
+00108                         sint left   = std::max(x, (sint) _X);
+00109                         sint top    = std::max(y, (sint) _Y);
+00110                         sint right  = std::min(x + (sint) _Size, (sint) (_X + _Size));
+00111                         sint bottom = std::min(y + (sint) _Size, (sint) (_Y + _Size));
+00112                         sint offsetX, offsetY;
+00113                         if (xDivSize != XDivSize) 
+00114                         {
+00115                                 offsetX = xDivSize < XDivSize ?  _Size : -(sint)_Size;
+00116                         }
+00117                         else
+00118                         {
+00119                                 offsetX = 0;
+00120                         }
+00121 
+00122                         if (yDivSize != YDivSize) 
+00123                         {
+00124                                 offsetY = yDivSize < YDivSize ?  _Size : -(sint)_Size;
+00125                         }
+00126                         else
+00127                         {
+00128                                 offsetY = 0;
+00129                         }
+00130 
+00131                         sint orgX = _Size * XDivSize;
+00132                         sint orgY = _Size * YDivSize;
+00133                         for (uint k = 0; k < NumWaterMap; ++k)
+00134                         {
+00135                                 makeCpy(k, (uint) (left - orgX + offsetX) , (uint) (top - orgY + offsetY),
+00136                                                 (uint) (left - orgX), (uint) (top - orgY),
+00137                                                 (uint) (right - left), (uint) (bottom - top));
+00138                         }
+00139                 }
+00140                 
+00141                 sint newOrgX = _Size * xDivSize;
+00142                 sint newOrgY = _Size * yDivSize;
+00143                 // clear new area
+00144                 if (x == (sint) _X)
+00145                 {
+00146                         if (y < (sint) _Y)
+00147                         {
+00148                                 // x, y, width, height
+00149                                 clearZone(x - newOrgX, y - newOrgY, _Size, _Y - y);
+00150                         }
+00151                         else
+00152                         {
+00153                                 clearZone(x - newOrgX, y + _Size - newOrgY, _Size, y - _Y);
+00154                         }
+00155                 }
+00156                 else
+00157                 {
+00158                         if (x > (sint) _X)
+00159                         {
+00160                                 if (y == (sint) _Y)
+00161                                 {
+00162                                         clearZone(_X + _Size - newOrgX, y - newOrgY, x - _X, _Size);
+00163                                 }
+00164                                 else if (y < (sint) _Y)
+00165                                 {
+00166                                         clearZone(_X + _Size - newOrgX, _Y - newOrgY, x - _X, _Size - (_Y - y));
+00167                                         clearZone(x - newOrgX, y - newOrgY, _Size, _Y - y);
+00168                                 }
+00169                                 else
+00170                                 {
+00171                                         clearZone(_X + _Size - newOrgX, y - newOrgY, x - _X, _Size - (y - _Y));
+00172                                         clearZone(x - newOrgX, _Y + _Size - newOrgY, _Size, y - _Y);
+00173                                 }
+00174                         }
+00175                         else
+00176                         {
+00177                                 if (y == (sint) _Y)
+00178                                 {
+00179                                         clearZone(x - newOrgX, y - newOrgY, _X - x, _Size);
+00180                                 }
+00181                                 else if (y < (sint) _Y)
+00182                                 {
+00183                                         clearZone(x - newOrgX, y - newOrgY, _Size, _Y - y);
+00184                                         clearZone(x - newOrgX, _Y - newOrgY, _X - x, _Size - (_Y - y));
+00185                                 }
+00186                                 else
+00187                                 {
+00188                                         clearZone(x - newOrgX, y - newOrgY, _X - x, _Size - (y -_Y));
+00189                                         clearZone(x - newOrgX, _Y + _Size - newOrgY, _Size, y - _Y);
+00190                                 }
+00191                         }
+00192                 }
+00193                 
+00194         }
+00195         else
+00196         {
+00197                 // the new area has no common pixel's with the previous one
+00198                 // clear the whole new area
+00199                 uint px = _X % _Size;
+00200                 uint py = _Y % _Size;
+00201                 clearZone(px, py, _Size, _Size);
+00202         }
+00203 
+00204         _X = (uint) x;
+00205         _Y = (uint) y;
+00206 }
+00207 
+00208 
+00209 
+00210 //===========================================================================================
+00211 
+00212 void CWaterHeightMap::animatePart(float startTime, float endTime)
+00213 {
+00214         if (endTime < 0.5f * _PropagationTime)
+00215         {
+00216                 // perform propagation
+00217                 propagate((uint) (_Size * 2.f * startTime / _PropagationTime), (uint) (_Size * 2.f * endTime / _PropagationTime));      
+00218         }
+00219         else
+00220         {
+00221                 //  end propagation and start filter
+00222                 if (startTime < 0.5f * _PropagationTime)
+00223                 {
+00224                         propagate((uint) (_Size * 2.f * startTime / _PropagationTime), _Size);  
+00225                         filter(0, (uint) (_Size * 2.f * (endTime / _PropagationTime - 0.5f)));
+00226                 }
+00227                 else
+00228                 {
+00229                         filter((uint) (_Size * 2.f * (startTime  / _PropagationTime - 0.5f)), (uint) (_Size * 2.f * (endTime  / _PropagationTime - 0.5f)));
+00230                 }
+00231         }
+00232 }
+00233 
+00234 //===========================================================================================
+00235 
+00236 void CWaterHeightMap::animate(float deltaT)
+00237 {       
+00238         if (deltaT < 0) deltaT = 0;
+00239         if (deltaT > _PropagationTime)
+00240         {
+00241                 animatePart(0, _PropagationTime);
+00242                 swapBuffers(deltaT);
+00243                 _PropagateEllapsedTime = 0;
+00244         }
+00245         else
+00246         {
+00247                 const float endTime   = _PropagateEllapsedTime + deltaT;                
+00248                 const float startTime = _PropagateEllapsedTime;
+00249 
+00250                 if (endTime < _PropagationTime)
+00251                 {
+00252                         animatePart(startTime, endTime);
+00253                         _PropagateEllapsedTime = endTime;
+00254                 }
+00255                 else
+00256                 {
+00257                         animatePart(startTime, _PropagationTime);
+00258                         swapBuffers(deltaT);
+00259                         //animatePart(0, endTime - _PropagationTime);
+00260 
+00261                         _PropagateEllapsedTime = 0 /*endTime - _PropagationTime*/;
+00262                 }                               
+00263         }
+00264         animateWaves(deltaT);
+00265 }
+00266 
+00267 //===========================================================================================
+00268 
+00269 void            CWaterHeightMap::setSize(uint32 size)
+00270 {
+00271         nlassert(size > 4);
+00272         _Size  = size;  
+00273         for (uint k = 0; k < NumWaterMap; ++k)
+00274         {
+00275                 _Map[k].resize(4 * _Size * _Size);
+00276                 clearArea(k, 0, 0, _Size << 1, _Size << 1);
+00277         }
+00278         //_Grad.resize(4 * _Size * _Size);              
+00279 }
+00280 
+00281 //===========================================================================================
+00282 
+00283 void            CWaterHeightMap::makeCpy(uint buffer, uint dX, uint dY, uint sX, uint sY, uint width, uint height)
+00284 {       
+00285         if (width == 0 || height == 0) return;
+00286         nlassert(dX <= (2 * _Size));
+00287         nlassert(dY <= (2 * _Size));
+00288         nlassert(sX <= (2 * _Size));
+00289         nlassert(sY <= (2 * _Size));
+00290         nlassert(dX + width <= 2 * _Size);
+00291         nlassert(sX + width <= 2 * _Size);
+00292         nlassert(dY + height <= 2 * _Size);
+00293         nlassert(sY + height <= 2 * _Size);
+00294         
+00295         sint stepY;
+00296         float *src, *dest;
+00297 
+00298         const sint stride = _Size << 1;
+00299         if (dY  <= sY)
+00300         {
+00301                 stepY = stride;
+00302                 src   =  &_Map[buffer][sX + sY * stride];
+00303                 dest  =  &_Map[buffer][dX + dY * stride];
+00304         }
+00305         else
+00306         {
+00307                 stepY = -stride;
+00308                 src   =  &_Map[buffer][sX + (sY + height - 1) * stride];
+00309                 dest  =  &_Map[buffer][dX + (dY + height - 1) * stride];
+00310         }
+00311 
+00312         sint k = height;
+00313         do
+00314         {
+00315                 if (dest < src)
+00316                 {
+00317                         std::copy(src, src + width, dest);
+00318                 }
+00319                 else
+00320                 {
+00321                         float *rSrc  = src  + width;
+00322                         float *rDest = dest + width;
+00323                         do
+00324                         {
+00325                                 --rSrc;
+00326                                 --rDest;
+00327                                 *rDest = *rSrc;
+00328                         }
+00329                         while (rSrc != src);
+00330                 }
+00331                 src  += stepY;
+00332                 dest += stepY;
+00333         }
+00334         while (--k);
+00335 }
+00336 
+00337 //===========================================================================================
+00338 
+00339 void            CWaterHeightMap::setUserPos(sint x, sint y)
+00340 {       
+00341         _NewX = x;      
+00342         _NewY = y;      
+00343 }
+00344 
+00345 //===========================================================================================
+00346 
+00347 void            CWaterHeightMap::getUserPos(sint &x, sint &y) const
+00348 {               
+00349         x = (sint) _X; y = (sint) _Y;
+00350 }
+00351 
+00352 
+00353 
+00354 //===========================================================================================
+00355 
+00356 void            CWaterHeightMap::propagate(uint start, uint end)
+00357 {       
+00358         start = std::max(1u, start);
+00359         end   = std::min((uint) (_Size - 1), end);
+00360         const float damping = _Damping;
+00361         clearBorder(0);
+00362         clearBorder(1);
+00363         nlassert(_Size != 0);
+00364         sint x, y;
+00365         uint px = _X % _Size;
+00366         uint py = _Y % _Size;
+00367         sint offset = px + 1 + ((py + start) * (_Size << 1));   
+00368         //nlinfo("%d, %d, %d",  (_CurrMap + (NumWaterMap - 1)) % NumWaterMap,  _CurrMap, 
+00369         float *buf2 = &_Map[ (_CurrMap + (NumWaterMap - 1)) % NumWaterMap][offset];
+00370         float *buf1 = &_Map[_CurrMap][offset];  
+00371         float *dest = &_Map[(_CurrMap + 1) % NumWaterMap][offset];
+00372         
+00373         const sint  sizeX2 = _Size << 1;
+00374         y = end - start;
+00375         if (y <= 0) return;
+00376         do
+00377         {
+00378                 x = _Size - 2;
+00379                 do
+00380                 {
+00381                         *dest   = damping * ( 0.5f * (buf1[1] + buf1[-1] + buf1[sizeX2] + buf1[- sizeX2]) - *buf2);                     
+00382                         ++buf1;
+00383                         ++buf2;
+00384                         ++dest;
+00385                 }
+00386                 while (--x);
+00387                 buf1 = buf1 + _Size + 2;
+00388                 buf2 = buf2 + _Size + 2;
+00389                 dest = dest + _Size + 2;
+00390         }
+00391         while (--y);
+00392         
+00393 }
+00394 
+00395 
+00396 
+00397 //===========================================================================================
+00398 
+00399 void    CWaterHeightMap::filter(uint start, uint end)
+00400 {       
+00401         start = std::max(1u, start);
+00402         end   = std::min((uint) (_Size - 1), end);
+00403         const float blurCoeff = _FilterWeight;
+00404         nlassert(_Size != 0);
+00405         sint x, y;
+00406         uint px = _X % _Size;
+00407         uint py = _Y % _Size;
+00408         sint offset = px + 1 + ((py + start) * (_Size << 1));
+00409         float *buf = &_Map[ (_CurrMap + 1) % NumWaterMap ][offset];
+00410         //NLMISC::CVector2f *ptGrad = &_Grad[offset];
+00411         y = end - start;
+00412         if (y <= 0) return;
+00413         const float totalBlurCoeff = (1.f / (4.f + blurCoeff));
+00414         const sint  sizeX2 = _Size << 1;
+00415         do
+00416         {
+00417                 x = _Size - 2;
+00418                 do
+00419                 {
+00420                         *buf = totalBlurCoeff * (*buf * blurCoeff
+00421                                                                                  + buf[1] 
+00422                                                                                  + buf[-1]
+00423                                                                                  + buf[sizeX2]
+00424                                                                                  + buf[- sizeX2]
+00425                                                                          );     
+00426                         // compute gradient
+00427                         /*ptGrad->x = buf[1]                - buf[- 1];
+00428                         ptGrad->y = buf[sizeX2]     - buf[- sizeX2];*/
+00429 
+00430                         ++buf;
+00431                         //++ptGrad;
+00432                 }
+00433                 while (--x);
+00434                 buf    += _Size + 2;
+00435                 //ptGrad += _Size + 2;
+00436         }
+00437         while (--y);    
+00438 }
+00439 
+00440 //===========================================================================================
+00441 
+00442 void CWaterHeightMap::animateWaves(float deltaT)
+00443 {
+00444         if (_WavesEnabled)
+00445         {
+00446                 uint numWaves;
+00447                 if (_WavePeriod == 0)
+00448                 {
+00449                         numWaves = 1;
+00450                 }
+00451                 else
+00452                 {
+00453                         _EmitEllapsedTime += deltaT;
+00454                         if (_EmitEllapsedTime > _WavePeriod)
+00455                         {
+00456                                 numWaves = (uint) (_EmitEllapsedTime / _WavePeriod);
+00457                                 _EmitEllapsedTime -= numWaves * _WavePeriod;
+00458                                 if (numWaves > 10) numWaves = 10;
+00459                         }
+00460                         else
+00461                         {
+00462                                 numWaves = 0;
+00463                         }
+00464                 }
+00465                 
+00466                 uint k;
+00467                 // generate automatic waves
+00468                 if (!_BorderWaves)
+00469                 {
+00470                         if (_WaveIntensity != 0)
+00471                         {
+00472                                 for (k = 0; k < numWaves; ++k)
+00473                                 {
+00474                                         perturbate(_NewX + rand() % _Size, _NewY + rand() % _Size, _WaveImpulsionRadius, _WaveIntensity);
+00475                                 }
+00476                         }
+00477                 }
+00478                 else
+00479                 {
+00480                         switch(rand() & 3) // choose a random border
+00481                         {
+00482                                 case 0: // top border
+00483                                         for (k = 0; k < numWaves; ++k)
+00484                                         {
+00485                                                 perturbate(_NewX + (uint) rand() % _Size, _NewY, _WaveImpulsionRadius, _WaveIntensity);
+00486                                         }
+00487                                 break;
+00488                                 case 1: // bottom border
+00489                                         for (k = 0; k < numWaves; ++k)
+00490                                         {
+00491                                                 perturbate(_NewX + (uint) rand() % _Size, _NewY + _Size - 1, _WaveImpulsionRadius, _WaveIntensity);
+00492                                         }
+00493                                 break;
+00494                                 case 2: // right border
+00495                                         for (k = 0; k < numWaves; ++k)
+00496                                         {
+00497                                                 perturbate(_NewX + _Size - 1, _NewY + (uint) rand() % _Size, _WaveImpulsionRadius, _WaveIntensity);
+00498                                         }
+00499                                 break;
+00500                                 case 3: // left border
+00501                                         for (k = 0; k < numWaves; ++k)
+00502                                         {
+00503                                                 perturbate(_NewX, _NewY + (uint) rand() % _Size, _WaveImpulsionRadius, _WaveIntensity);
+00504                                         }
+00505                                 break;
+00506                         }
+00507         
+00508                 }
+00509         }
+00510 }
+00511 
+00512 //===========================================================================================
+00513 
+00514 void CWaterHeightMap::swapBuffers(float deltaT)
+00515 {
+00516         updateUserPos();
+00517         _CurrMap = (_CurrMap + 1) % NumWaterMap;
+00518 }
+00519 
+00520 
+00521 //===========================================================================================
+00522 
+00523 void CWaterHeightMap::clearZone(sint x, sint y, sint width, sint height)
+00524 {
+00525         for (uint k = 0; k < NumWaterMap; ++k)
+00526         {
+00527                 clearArea(k, x, y, width, height);
+00528         }
+00529 }
+00530 
+00531 //===========================================================================================
+00532 
+00533 void CWaterHeightMap::clearArea(uint8 currMap, sint x, sint y, sint width, sint height)
+00534 {       
+00535         nlassert(_Size > 1);
+00536         nlassert(width >= 0);
+00537         nlassert(height >= 0);
+00538         uint sizex2 = _Size << 1;
+00539 
+00540         if (x < 0)
+00541         {               
+00542                 width += x;
+00543                 x = 0;
+00544                 if (width <= 0) return;
+00545         }
+00546         if (y < 0)
+00547         {
+00548                 height += y;
+00549                 y = 0;
+00550                 if (height <= 0) return;
+00551         }
+00552         if (x + width > (sint) sizex2)
+00553         {
+00554                 width = width - (x + width - sizex2);
+00555         }
+00556 
+00557         if (y + height > (sint) sizex2)
+00558         {
+00559                 height = height - (y + height - sizex2);
+00560         }
+00561         
+00562         float *dest = &*(_Map[  currMap  ].begin() + x + (_Size << 1) * y);
+00563         do
+00564         {
+00565                 std::fill(dest, dest + width, 0.f);             
+00566                 dest  += (_Size << 1);
+00567         }
+00568         while (-- height);
+00569 }
+00570 
+00571 
+00572 
+00573 //===========================================================================================
+00574 
+00575 void    CWaterHeightMap::perturbate(sint x, sint y, sint radius, float intensity)
+00576 {
+00577                 nlassert(_Size != 0);
+00578                 nlassert(radius > 0);
+00579                 sint orgX = _X - _X % _Size;
+00580                 sint orgY = _Y - _Y % _Size;
+00581                 TFloatVect &map = _Map[(_CurrMap + 1) % NumWaterMap];
+00582                 const uint sizeX2 = _Size << 1;
+00583                 for (sint px = -radius + 1; px < radius; ++px)
+00584                 {
+00585                         for (sint py = -radius + 1; py < radius; ++py)          
+00586                         {       
+00587                                 if ((uint) (x + px - orgX) < sizeX2 
+00588                                         && (uint) (y + py - orgY) < sizeX2)
+00589                                 {                                       
+00590                                 
+00591                                         float dist = ((float) radius - sqrtf((float) (px * px + py * py ))) / (float) radius;
+00592                                         float v = dist < radius ? intensity * cosf(dist * (float) NLMISC::Pi * 0.5f) : 0.f;
+00593                                         map[x + px - orgX + sizeX2 * (y + py - orgY)] = v;
+00594                                 }
+00595                         }
+00596                 }
+00597 }
+00598 
+00599 //===========================================================================================
+00600 
+00601 void    CWaterHeightMap::perturbate(const NLMISC::CVector2f &pos, float strenght, float radius)
+00602 {
+00603         const float invUnitSize = 1.f / _UnitSize;
+00604         perturbate((sint) (pos.x * invUnitSize), (sint) (pos.y * invUnitSize), (sint) radius, strenght);
+00605 }
+00606 
+00607 //===========================================================================================
+00608 
+00609 void CWaterHeightMap::perturbatePoint(sint x, sint y, float intensity)
+00610 {       
+00611         sint orgX = _X - _X % _Size;
+00612         sint orgY = _Y - _Y % _Size;
+00613         uint X = (uint) (x - orgX);
+00614         uint Y = (uint) (y - orgY);     
+00615         if (X < (_Size << 1)
+00616                 && Y < (_Size << 1)
+00617                 )
+00618         {
+00619                 const uint sizex2 = _Size << 1;         
+00620                 TFloatVect &map = _Map[(_CurrMap + 1) % NumWaterMap];
+00621                 map[X + sizex2 * Y] = intensity;                
+00622         }
+00623 }
+00624 
+00625 //===========================================================================================
+00626 
+00627 void    CWaterHeightMap::perturbatePoint(const NLMISC::CVector2f &pos, float strenght)
+00628 {
+00629         const float invUnitSize = 1.f / _UnitSize;
+00630         perturbatePoint((sint) (pos.x * invUnitSize), (sint) (pos.y * invUnitSize), strenght);
+00631 }
+00632 
+00633 //===========================================================================================
+00634 
+00635 void    CWaterHeightMap::clearBorder(uint currMap)
+00636 {
+00637         float *map  = &_Map[currMap][0];
+00638         uint sizex2 = _Size << 1;
+00639 
+00640         // top and bottom
+00641 
+00642         float *up    = &map[(_X % _Size) + sizex2 * (_Y % _Size)];
+00643         float *curr = up;
+00644         const float *endUp = up + _Size;
+00645         const uint  downOff  = (_Size - 1) * sizex2;
+00646         do
+00647         {
+00648                 *curr = curr[downOff] = 0.f;
+00649                 ++curr;
+00650         }
+00651         while (curr != endUp);
+00652 
+00653         // right and left
+00654         curr  = up;
+00655         const float *endLeft = up + downOff;
+00656         const uint  rightOff = _Size - 1;
+00657         do
+00658         {
+00659                 *curr = curr[rightOff] = 0.f;
+00660                 curr += sizex2;
+00661         }
+00662         while (curr != endLeft);
+00663 }
+00664 
+00665 //===========================================================================================
+00666 
+00667 void CWaterHeightMap::setWaves(float intensity, float period, uint radius, bool border)
+00668 {
+00669         _WaveIntensity            = intensity;
+00670         _WavePeriod                       = period;
+00671         _WaveImpulsionRadius  = radius;
+00672         _BorderWaves              = border;
+00673 
+00674 }
+00675 
+00676 
+00677 //===========================================================================================
+00678 
+00679 void CWaterHeightMap::serial(NLMISC::IStream &f)  throw(NLMISC::EStream)
+00680 {
+00681         f.xmlPushBegin("WaterHeightMap");                       
+00682                 f.xmlSetAttrib ("NAME")                                 ;
+00683                 f.serial (_Name);
+00684         f.xmlPushEnd();
+00685         (void)f.serialVersion(0);
+00686         f.xmlSerial(_Size, "SIZE");
+00687         if (f.isReading())
+00688         {
+00689                 setSize(_Size);
+00690         }
+00691         f.xmlSerial(_Damping, "DAMPING");
+00692         f.xmlSerial(_FilterWeight, "FILTER_WEIGHT");
+00693         f.xmlSerial(_UnitSize, "WATER_UNIT_SIZE");      
+00694         f.xmlSerial(_WavesEnabled, "WavesEnabled");
+00695         if (_WavesEnabled)
+00696         {
+00697                 f.xmlPush("WavesParams");
+00698                         f.xmlSerial(_WaveIntensity, "WAVE_INTENSITY");
+00699                         f.xmlSerial(_WavePeriod, "WAVE_PERIOD");
+00700                         f.xmlSerial(_WaveImpulsionRadius, "WAVE_IMPULSION_RADIUS");
+00701                         f.xmlSerial(_BorderWaves, "BORDER_WAVES");
+00702                         f.xmlSerial(_PropagationTime, "PROPAGATION_TIME");
+00703                 f.xmlPop();
+00704         }
+00705         f.xmlPop();
+00706 }
+00707 
+00708 
+00709 
+00710 
+00711 //*** perform a bilinear on 4 values
+00712 //   0---1
+00713 //   |   |
+00714 //   3---2
+00715 static float inline BilinFilter(float v0, float v1, float v2, float v3, float u, float v)
+00716 {
+00717         const float g = v * v3 + (1.f - v) * v0;
+00718         const float h = v * v2 + (1.f - v) * v1;
+00719         return u * h + (1.f - u) * g;
+00720 }
+00721 
+00722 
+00723 
+00724 //===========================================================================================
+00725 
+00726 float   CWaterHeightMap::getHeight(const NLMISC::CVector2f &pos)
+00727 {
+00728         const float invUnitSize = 1.f / _UnitSize;
+00729         
+00730         const float xPos = invUnitSize * pos.x; // position in map space
+00731         const float yPos = invUnitSize * pos.y; // position in map space
+00732 
+00733         
+00734         if ((uint) xPos - _X < _Size - 1
+00735                 && (uint) yPos - _Y < _Size - 1
+00736                 )
+00737 
+00738         {
+00739 
+00740                 const sint orgX = _X - _X % _Size;
+00741                 const sint orgY = _Y - _Y % _Size;
+00742                 const uint sizeX2 = _Size << 1;
+00743 
+00744         
+00745                 const sint  fxPos = (sint) floorf(xPos); 
+00746                 const sint  fyPos = (sint) floorf(yPos); 
+00747 
+00748         
+00749                         
+00750                         const float deltaU        = xPos - fxPos;
+00751                         const float deltaV        = yPos - fyPos;
+00752                         const uint  offset        = (uint) fxPos - orgX + sizeX2 * ( (uint) fyPos - orgY);
+00753                         const float lambda        = getBufferRatio();
+00754                         const float *map1     = getPrevPointer();
+00755                         const float *map2     = getPointer();
+00756 
+00757                         return BilinFilter(lambda * map2[offset]                          + (1.f - lambda) * map1[offset        ],                        // top left
+00758                                                            lambda * map2[offset + 1]              + (1.f - lambda) * map1[offset + 1],            // top right
+00759                                                            lambda * map2[offset + sizeX2 + 1] + (1.f - lambda) * map1[offset + sizeX2 + 1], // bottom right
+00760                                                            lambda * map2[offset + sizeX2 ]    + (1.f - lambda) * map1[offset + sizeX2 ],          // bottom left
+00761                                                            deltaU,
+00762                                                            deltaV
+00763                                                            );
+00764         }                                               
+00765         else return 0;
+00766 
+00767 }
+00768 
+00769 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1