# 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_shape.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 "3d/water_shape.h"
00029 #include "3d/water_model.h"
00030 #include "3d/vertex_buffer.h"
00031 #include "3d/texture_bump.h"
00032 #include "3d/texture_blend.h"
00033 #include "3d/scene.h"
00034 #include "3d/water_pool_manager.h"
00035 #include "3d/water_height_map.h"
00036 #include <memory>
00037 
00038 
00039 namespace NL3D {
00040 
00041 
00042 
00043 
00044 // globals
00045 
00046 
00047 
00048 // common start for Water vertex programs
00061 const char *WaterVPStartCode =
00062 "!!VP1.0\n\
00063         ADD R1, c[7], -v[0];                    #r1 = eye - vertex                                                      \n\
00064         DP3 R2, R1, R1;                             #r1 = eye - vertex, r2 = (eye - vertex)²    \n\
00065         MAX R2, R2, c[16];              # avoid imprecision around 0                            \n\
00066         RSQ R2, R2.x;                                   #r1 = eye - vertex, r2 = 1/d(eye, vertex)       \n\
00067         RCP R3, R2.x;                                                                                                                           \n\
00068         MAD R3, c[6].xxxx, -R3, c[6].yyyy;                                                                                      \n\
00069         MAX R3, c[5],   R3;                                                                                                                     \n\
00070         MUL R0, R3, v[8];                       #attenuate normal with distance                                 \n\
00071         MUL R4.z,   R3, v[0];                   #attenuate height with distance                         \n\
00072         MOV R4.xyw, v[0];                                                                                                                       \n\
00073         MOV R0.z,  c[4].x;                      #set normal z to 1                                                              \n\
00074         DP3 R3.x, R0, R0;                                                                                                                       \n\
00075         RSQ R3.x,  R3.x;                                #normalize normal in R3                                         \n\
00076         MUL R0,  R0, R3.x;                                                                                                                      \n\
00077         DP4 o[HPOS].x, c[0], R4;        #transform vertex in view space                             \n\
00078         DP4 o[HPOS].y, c[1], R4;                                                                                                    \n\
00079         DP4 o[HPOS].z, c[2], R4;                                                                                                    \n\
00080         DP4 o[HPOS].w, c[3], R4;                                                                                                    \n\
00081         MUL R1, R1, R2.x;                       #normalize r1, r1 = (eye - vertex).normed   \n\
00082         DP4 o[FOGC].x, c[2], R4;            #setup fog                                                              \n\
00083 ";
00084 
00085 /*
00086 const char *WaterVPStartCode =
00087 "!!VP1.0\n\
00088         ADD R1, c[7], -v[0];                    #r1 = eye - vertex                                                      \n\
00089         DP3 R2, R1, R1;                             #r1 = eye - vertex, r2 = (eye - vertex)²    \n\
00090         MAX R2, R2, c[16];              # avoid imprecision around 0                            \n\
00091         RSQ R2, R2.x;                                   #r1 = eye - vertex, r2 = 1/d(eye, vertex)       \n\
00092         RCP R3, R2.x;                                                                                                                           \n\
00093         MUL R3, c[6], R3;                                                           \n\
00094         ADD R3, c[15], -R3;                                                         \n\
00095         MAX R3, c[5],   R3;                                                                                                                     \n\
00096         MUL R0, R3, v[8];                       #attenuate normal with distance                                 \n\
00097         MUL R4.z,   R3, v[0];                   #attenuate height with distance                         \n\
00098         MOV R4.xyw, v[0];                                                                                                                       \n\
00099         MOV R0.z,  c[4].x;                      #set normal z to 1                                                              \n\
00100         DP3 R3.x, R0, R0;                                                                                                                       \n\
00101         RSQ R3.x,  R3.x;                                #normalize normal in R3                                         \n\
00102         MUL R0,  R0, R3.x;                                                                                                                      \n\
00103         DP4 o[HPOS].x, c[0], R4;        #transform vertex in view space                             \n\
00104         DP4 o[HPOS].y, c[1], R4;                                                                                                    \n\
00105         DP4 o[HPOS].z, c[2], R4;                                                                                                    \n\
00106         DP4 o[HPOS].w, c[3], R4;                                                                                                    \n\
00107         MUL R1, R1, R2.x;                       #normalize r1, r1 = (eye - vertex).normed   \n\
00108         DP4 o[FOGC].x, c[2], -R4;           #setup fog                                                              \n\
00109 ";
00110 */
00111 
00114 const char *WaterVpBump2LayersCode = "MUL R3, v[0], c[10];                      #compute bump 0 uv's                    \n\
00115                                                    ADD o[TEX0].xy, R3, c[9];                                                                                            \n\
00116                                                    MUL R3, v[0], c[12];                 #compute bump 1 uv's                                            \n\
00117                                                    ADD o[TEX1].xy, R3, c[11];                                                                                           \n\
00118                                                    DP3 R2.x, R1, R0;                                                                                                            \n\
00119                                                    MUL R0, R0, R2.x;                                                                                                            \n\
00120                                                    ADD R2, R0, R0;                                                                                                                      \n\
00121                                                    ADD R0, R2, -R1;                             #compute reflection vector                                      \n\
00122                                                    MAD o[TEX2].xy, R0, c[8], c[8];                                                                                      \n\
00123                                                    ";
00124 
00127 const char *WaterVpBump1LayersCode = "MUL R3, v[0], c[12];                      #compute bump 1 uv's                            \n\
00128                                                                           ADD o[TEX0].xy, R3, c[11];                                                                            \n\
00129                                                                           DP3 R2.x, R1, R0;                                                                                                     \n\
00130                                                                           MUL R0, R0, R2.x;                                                                                                     \n\
00131                                                                           ADD R2, R0, R0;                                                                                                       \n\
00132                                                                           ADD R0, R2, -R1;                              #compute reflection vector                      \n\
00133                                                                           MAD o[TEX1].xy, R0, c[8], c[8];                                                                       \n\
00134                                                                           ";
00135 
00138 const char *WaterVpDiffuseMapStage3Code = "DP4 o[TEX3].x, R4, c[13]; #compute uv for diffuse texture                                    \n\
00139                                                                                DP4 o[TEX3].y, R4, c[14];                                                                                                        \n\
00140                                                                           ";
00141 
00144 const char *WaterVpDiffuseMapStage2Code = "DP4 o[TEX2].x, R4, c[13]; #compute uv for diffuse texture                                    \n\
00145                                                                                DP4 o[TEX2].y, R4, c[14];                                                                                                        \n\
00146                                                                           ";
00147 
00150 const char *WaterVpDiffuseMapStage1Code = "DP4 o[TEX1].x, R4, c[13]; #compute uv for diffuse texture                                    \n\
00151                                                                                DP4 o[TEX1].y, R4, c[14];                                                                                                        \n\
00152                                                                           ";
00153 
00154 
00155 
00156 // Envmap is setup in texture 0, no bump is used
00157 const char *WaterVpNoBumpCode = "  DP3 R2.x, R1, R0;                            #project view vector on normal for symetry      \n\
00158                                                                                   MUL R0, R0, R2.x;                                                                                                                     \n\
00159                                                                                   ADD R2, R0, R0;                                                                                                                       \n\
00160                                                                                   ADD R0, R2, -R1;                              #compute reflection vector                                      \n\
00161                                                                                   MAD o[TEX0].xy, R0, c[8], c[8];                                                                                       \n\
00162                                                                                   DP4 o[FOGC].x, c[2], -R4;     #setup fog                                                                          \n\
00163                                                                                   ";
00164 
00165 
00166 // static members
00167 
00168 uint32                                                                  CWaterShape::_XScreenGridSize = 40;
00169 uint32                                                                  CWaterShape::_YScreenGridSize = 40;
00170 uint32                                                                  CWaterShape::_XGridBorder = 4;
00171 uint32                                                                  CWaterShape::_YGridBorder = 4;
00172 uint32                                                                  CWaterShape::_MaxGridSize;
00173 CVertexBuffer                                                   CWaterShape::_VB;
00174 std::vector<uint32>                                             CWaterShape::_IBUpDown;
00175 std::vector<uint32>                                             CWaterShape::_IBDownUp;
00176 //NLMISC::CSmartPtr<IDriver>                            CWaterShape::_Driver;
00177 bool                                                                    CWaterShape::_GridSizeTouched = true;
00178 std::auto_ptr<CVertexProgram>                   CWaterShape::_VertexProgramBump1;
00179 std::auto_ptr<CVertexProgram>                   CWaterShape::_VertexProgramBump2;
00180 std::auto_ptr<CVertexProgram>                   CWaterShape::_VertexProgramBump1Diffuse;
00181 std::auto_ptr<CVertexProgram>                   CWaterShape::_VertexProgramBump2Diffuse;
00182 std::auto_ptr<CVertexProgram>                   CWaterShape::_VertexProgramNoBump;
00183 std::auto_ptr<CVertexProgram>                   CWaterShape::_VertexProgramNoBumpDiffuse;
00184 
00185 
00188 static CVertexProgram *BuildWaterVP(bool diffuseMap, bool bumpMap, bool use2BumpMap)
00189 {
00190         std::string vp = WaterVPStartCode;
00191         if (bumpMap && use2BumpMap)
00192         { 
00193                 vp += WaterVpBump2LayersCode;
00194                 if (diffuseMap) vp += WaterVpDiffuseMapStage3Code;
00195         }
00196         else
00197         if (bumpMap)
00198         {
00199                 vp += WaterVpBump2LayersCode;
00200                 if (diffuseMap) vp += WaterVpDiffuseMapStage2Code;
00201         }
00202         else
00203         {
00204                 vp += WaterVpNoBumpCode;
00205                 if (diffuseMap) vp += WaterVpDiffuseMapStage1Code;
00206         }
00207 
00208         vp += "\nEND";
00209         return new CVertexProgram(vp.c_str());
00210 }
00211 
00212 
00213 
00214 //============================================
00215 /*
00216  * Constructor
00217  */
00218 CWaterShape::CWaterShape() :  _WaterPoolID(0), _TransitionRatio(0.6f), _WaveHeightFactor(3), _ComputeLightmap(false)
00219 {
00220         _DefaultPos.setValue(NLMISC::CVector::Null);
00221         _DefaultScale.setValue(NLMISC::CVector(1, 1, 1));
00222         _DefaultRotQuat.setValue(CQuat::Identity);
00223 
00224         for (sint k = 0; k < 2; ++k)
00225         {
00226                 _HeightMapScale[k].set(1, 1);
00227                 _HeightMapSpeed[k].set(0, 0);
00228                 _HeightMapTouch[k] = true;
00229         }
00230         _ColorMapMatColumn0.set(1, 0);
00231         _ColorMapMatColumn1.set(0, 1);
00232         _ColorMapMatPos.set(0, 0);
00233 }
00234 
00235 //============================================
00236 
00237 CWaterShape::~CWaterShape()
00238 {
00239         if (
00240                 (_EnvMap[0] && dynamic_cast<CTextureBlend *>((ITexture *) _EnvMap[0]))
00241                 || (_EnvMap[1] && dynamic_cast<CTextureBlend *>((ITexture *) _EnvMap[1]))
00242                 )
00243         {
00244                 GetWaterPoolManager().unRegisterWaterShape(this);               
00245         }
00246 }
00247 
00248 //============================================
00249 
00250 void CWaterShape::initVertexProgram()
00251 {       
00252         static bool created = false;
00253         if (!created)
00254         {
00255 
00256                 _VertexProgramBump1 = std::auto_ptr<CVertexProgram>(BuildWaterVP(false, true, false));
00257                 _VertexProgramBump2 = std::auto_ptr<CVertexProgram>(BuildWaterVP(false, true, true));
00258 
00259                 _VertexProgramBump1Diffuse = std::auto_ptr<CVertexProgram>(BuildWaterVP(true, true, false));
00260                 _VertexProgramBump2Diffuse = std::auto_ptr<CVertexProgram>(BuildWaterVP(true, true, true));
00261 
00262                 _VertexProgramNoBump = std::auto_ptr<CVertexProgram>(BuildWaterVP(false, false, false));
00263                 _VertexProgramNoBumpDiffuse = std::auto_ptr<CVertexProgram>(BuildWaterVP(true, false, false));
00264                 created = true;
00265         }
00266 }
00267 
00268 
00269 //============================================
00270 
00271 void CWaterShape::setupVertexBuffer()
00272 {
00273         const uint rotLength = (uint) ::ceilf(::sqrtf((float) ((_XScreenGridSize >> 1) * (_XScreenGridSize >> 1)
00274                                                                   + (_YScreenGridSize >> 1) * (_YScreenGridSize >> 1))));
00275         _MaxGridSize = 2 * rotLength;
00276         const uint w =  _MaxGridSize + 2 * _XGridBorder;
00277 
00278         _VB.clearValueEx();
00279         _VB.addValueEx (WATER_VB_POS, CVertexBuffer::Float3);
00280         _VB.addValueEx (WATER_VB_DX, CVertexBuffer::Float2);    
00281 
00282         _VB.initEx();
00283         _VB.setNumVertices((w + 1) * 2);
00284         
00285 
00286         
00287         uint x;
00288 
00289         // setup each index buffer
00290         // We need 2 vb, because, each time 2 lines of the vertex buffer are filled, we start at the beginning again
00291         // So we need 1 vb for triangle drawn up to down, and one other for triangle drawn down to top  
00292 
00293         _IBUpDown.resize(6 * w);        
00294         for (x = 0; x < w; ++x)
00295         {
00296                 _IBUpDown [ 6 * x      ] = x;
00297                 _IBUpDown [ 6 * x  + 1 ] = x + 1 + (w + 1);
00298                 _IBUpDown [ 6 * x  + 2 ] = x + 1;
00299 
00300                 _IBUpDown [ 6 * x  + 3 ] = x;
00301                 _IBUpDown [ 6 * x  + 4 ] = x + 1 + (w + 1);
00302                 _IBUpDown [ 6 * x  + 5 ] = x     + (w + 1);
00303 
00304         }
00305 
00306         _IBDownUp.resize(6 * w);
00307         for (x = 0; x < w; ++x)
00308         {
00309                 _IBDownUp [ 6 * x      ] = x;
00310                 _IBDownUp [ 6 * x  + 1 ] = x + 1;
00311                 _IBDownUp [ 6 * x  + 2 ] = x + 1 + (w + 1);
00312 
00313                 _IBDownUp [ 6 * x  + 3 ] = x;
00314                 _IBDownUp [ 6 * x  + 4 ] = x     + (w + 1);
00315                 _IBDownUp [ 6 * x  + 5 ] = x + 1 + (w + 1);
00316 
00317         }
00318 
00319         _GridSizeTouched = false;
00320 }
00321 
00322 //============================================
00323 
00324 CTransformShape         *CWaterShape::createInstance(CScene &scene)
00325 {
00326         CWaterModel *wm = NLMISC::safe_cast<CWaterModel *>(scene.createModel(WaterModelClassId) );
00327         wm->Shape = this;
00328         // set default pos & scale
00329         wm->ITransformable::setPos( ((CAnimatedValueVector&)_DefaultPos.getValue()).Value  );
00330         wm->ITransformable::setScale( ((CAnimatedValueVector&)_DefaultScale.getValue()).Value  );
00331         wm->ITransformable::setRotQuat( ((CAnimatedValueQuat&)_DefaultRotQuat.getValue()).Value  );
00332         wm->_Scene = &scene;
00333         return wm;
00334 }
00335 
00336 //============================================
00337 
00338 float CWaterShape::getNumTriangles (float distance)
00339 {
00340         // TODO
00341         return 0;
00342 }
00343 
00344 //============================================
00345 
00346 void CWaterShape::flushTextures (IDriver &driver)
00347 {
00348         // Test if bump maps are supported by driver before to flush them.      
00349         if (
00350                 (driver.supportTextureShaders() && driver.isTextureAddrModeSupported(CMaterial::OffsetTexture))
00351                 || driver.supportEMBM()
00352            )
00353         {
00354                 for (uint k = 0; k < 2; ++k)
00355                 {
00356                         if (_BumpMap[k] != NULL)
00357                                 driver.setupTexture(*_BumpMap[k]);
00358                         if (_EnvMap[k] != NULL)
00359                                 driver.setupTexture(*_EnvMap[k]);               
00360                 }
00361         }
00362         if (_ColorMap != NULL)
00363                 driver.setupTexture(*_ColorMap);
00364 }
00365 
00366 //============================================
00367 
00368 void    CWaterShape::setScreenGridSize(uint32 x, uint32 y)
00369 {
00370         nlassert(x > 0 && y > 0);
00371         _XScreenGridSize = x;   
00372         _YScreenGridSize = y;
00373         _GridSizeTouched = true;
00374 }
00375 
00376 //============================================
00377 
00378 void            CWaterShape::setGridBorderSize(uint32 x, uint32 y)
00379 {
00380         _XGridBorder = x;
00381         _YGridBorder = y;
00382         _GridSizeTouched = true;
00383 }
00384 
00385 //============================================
00386 
00387 void CWaterShape::setShape(const NLMISC::CPolygon2D &poly)
00388 {
00389         nlassert(poly.Vertices.size() != 0); // empty poly not allowed
00390         _Poly = poly;
00391         computeBBox();
00392 }
00393 
00394 //============================================
00395 
00396 void CWaterShape::computeBBox()
00397 {
00398         nlassert(_Poly.Vertices.size() != 0);
00399         NLMISC::CVector2f min, max;
00400         min = max = _Poly.Vertices[0];
00401         for (uint k = 1; k < _Poly.Vertices.size(); ++k)
00402         {
00403                 min.minof(min, _Poly.Vertices[k]);
00404                 max.maxof(max, _Poly.Vertices[k]);
00405         }
00406         _BBox.setMinMax(CVector(min.x, min.y, 0), CVector(max.x, max.y, 0));
00407         /* nlinfo("center x = %f, y = %f, z = %f", _BBox.getCenter().x, _BBox.getCenter().y, _BBox.getCenter().z);
00408         nlinfo("halsize x = %f, y = %f, z = %f", _BBox.getHalfSize().x, _BBox.getHalfSize().y, _BBox.getHalfSize().z); */
00409 }
00410 
00411 //============================================
00412 
00413 void                            CWaterShape::setHeightMap(uint k, ITexture *hm)
00414 {
00415         nlassert(k < 2);        
00416         if (!_BumpMap[k])
00417         {
00418                 _BumpMap[k] = new CTextureBump;
00419         }
00420         static_cast<CTextureBump *>( (ITexture *) _BumpMap[k])->forceNormalize(true);
00421         static_cast<CTextureBump *>( (ITexture *) _BumpMap[k])->setHeightMap(hm);
00422         _HeightMapTouch[k] = true; // must recompute normalization factor
00423 }
00424 
00425 //============================================
00426 
00427 ITexture                        *CWaterShape::getHeightMap(uint k)
00428 {
00429         nlassert(k < 2);
00430         return ((CTextureBump *) (ITexture *) _BumpMap[k] )->getHeightMap();
00431 }
00432 
00433 //============================================
00434 
00435 const ITexture          *CWaterShape::getHeightMap(uint k) const
00436 {
00437         nlassert(k < 2);
00438         return ((CTextureBump *) (ITexture *) _BumpMap[k] )->getHeightMap();
00439 }
00440 
00441 //============================================
00442 
00443 void CWaterShape::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00444 {
00445         sint ver = f.serialVersion(2);
00446         // serial 'shape' 
00447         f.serial(_Poly);
00448         // serial heightMap identifier
00449         f.serial(_WaterPoolID);
00450         //serial maps
00451         ITexture *map = NULL;   
00452         if (f.isReading())
00453         {
00454                 f.serialPolyPtr(map); _EnvMap[0] = map;
00455                 f.serialPolyPtr(map); _EnvMap[1] = map;
00456                 f.serialPolyPtr(map); _BumpMap[0] = map;
00457                 f.serialPolyPtr(map); _BumpMap[1] = map;
00458                 f.serialPolyPtr(map); _ColorMap = map;
00459                 computeBBox();
00460         }
00461         else
00462         {
00463                 map = _EnvMap[0]; f.serialPolyPtr(map);
00464                 map = _EnvMap[1]; f.serialPolyPtr(map);
00465                 map = _BumpMap[0]; f.serialPolyPtr(map);
00466                 map = _BumpMap[1]; f.serialPolyPtr(map);
00467                 map = _ColorMap; f.serialPolyPtr(map);  
00468         }
00469 
00470         f.serial(_HeightMapScale[0], _HeightMapScale[1],
00471                          _HeightMapSpeed[0], _HeightMapSpeed[1]);
00472 
00473         f.serial(_ColorMapMatColumn0, _ColorMapMatColumn1, _ColorMapMatPos);    
00474 
00475         // serial default tracks
00476         f.serial(_DefaultPos);
00477         f.serial(_DefaultScale);
00478         f.serial(_DefaultRotQuat);
00479 
00480         f.serial(_TransitionRatio);     
00481 
00482         f.serial(_WaveHeightFactor);
00483 
00484         if (ver >= 1)
00485                 f.serial (_ComputeLightmap);
00486 
00487         if (ver >= 2)
00488                 f.serial (_DistMax);
00489 }
00490 
00491 //============================================
00492 
00493 bool CWaterShape::clip(const std::vector<CPlane>        &pyramid, const CMatrix &worldMatrix)
00494 {       
00495         for (uint k = 0; k < pyramid.size(); ++k)
00496         {
00497                 if (! _BBox.clipBack(pyramid[k] * worldMatrix)) return false;
00498         }
00499         return true;
00500 }
00501 
00502 //============================================
00503 
00504 void                            CWaterShape::setHeightMapScale(uint k, const NLMISC::CVector2f &scale)
00505 {
00506         nlassert(k < 2);
00507         _HeightMapScale[k] = scale;
00508 }
00509 
00510 //============================================
00511 
00512 NLMISC::CVector2f       CWaterShape::getHeightMapScale(uint k) const
00513 {
00514         nlassert(k < 2);
00515         return _HeightMapScale[k];
00516 }
00517 
00518 //============================================
00519 
00520 void                        CWaterShape::setHeightMapSpeed(uint k, const NLMISC::CVector2f &speed)
00521 {
00522         nlassert(k < 2);
00523         _HeightMapSpeed[k] = speed;
00524 }
00525 
00526 //============================================
00527 
00528 NLMISC::CVector2f   CWaterShape::getHeightMapSpeed(uint k) const
00529 {
00530         nlassert(k < 2);
00531         return _HeightMapSpeed[k];
00532 }
00533 
00534 //============================================
00535 
00536 void    CWaterShape::setColorMapMat(const NLMISC::CVector2f &column0, const NLMISC::CVector2f &column1, const NLMISC::CVector2f &pos)
00537 {
00538         _ColorMapMatColumn0 = column0;
00539         _ColorMapMatColumn1 = column1;
00540         _ColorMapMatPos  = pos;
00541 }
00542 
00543 //============================================
00544 
00545 void    CWaterShape::getColorMapMat(NLMISC::CVector2f &column0, NLMISC::CVector2f &column1, NLMISC::CVector2f &pos)
00546 {
00547         column0 = _ColorMapMatColumn0;
00548         column1 = _ColorMapMatColumn1;
00549         pos  = _ColorMapMatPos;
00550 }
00551 
00552 //============================================
00553 
00554 void CWaterShape::envMapUpdate()
00555 {
00556         // if the color map is a blend texture, we MUST be registered to the water pool manager, so that, the
00557         // setBlend message will be routed to this texture.
00558         if (
00559                 (_EnvMap[0] && dynamic_cast<CTextureBlend *>((ITexture *) _EnvMap[0]))
00560                 || (_EnvMap[1] && dynamic_cast<CTextureBlend *>((ITexture *) _EnvMap[1]))
00561                 )
00562         {
00563                 if (!GetWaterPoolManager().isWaterShapeObserver(this))
00564                 {
00565                         GetWaterPoolManager().registerWaterShape(this);
00566                 }
00567         }
00568         else
00569         {
00570                 if (GetWaterPoolManager().isWaterShapeObserver(this))
00571                 {
00572                         GetWaterPoolManager().unRegisterWaterShape(this);
00573                 }
00574         }
00575 }
00576 
00577 //============================================
00578 
00579 void CWaterShape::setColorMap(ITexture *map)
00580 { 
00581         _ColorMap = map; 
00582         //colorMapUpdate();
00583 }
00584 
00585 //============================================
00586 
00587 void CWaterShape::setEnvMap(uint index, ITexture *envMap)
00588 {
00589         nlassert(index < 2);
00590         _EnvMap[index] = envMap;        
00591 }
00592 
00593 //============================================
00594 
00595 void CWaterShape::getShapeInWorldSpace(NLMISC::CPolygon &poly) const
00596 {
00597         poly.Vertices.resize(_Poly.Vertices.size());
00598         // compute the matrix of the object in world space, by using the default tracks
00599         NLMISC::CMatrix objMat;
00600         objMat.identity();              
00601         objMat.translate(((CAnimatedValueVector *) &_DefaultPos.getValue())->Value);
00602         objMat.rotate(((CAnimatedValueQuat *) &_DefaultRotQuat.getValue())->Value);
00603         objMat.scale(((CAnimatedValueVector *) &_DefaultScale.getValue())->Value);
00604         
00605         for (uint k = 0; k < _Poly.Vertices.size(); ++k)
00606         {
00607                 poly.Vertices[k] = objMat * NLMISC::CVector(_Poly.Vertices[k].x, _Poly.Vertices[k].y, 0);
00608         }
00609 }
00610 
00611 
00612 //============================================
00613 void  CWaterShape::updateHeightMapNormalizationFactors()
00614 {
00615         for (uint k = 0; k < 2; ++k)
00616         {
00617                 if (_HeightMapTouch[k])
00618                 {
00619                         if (_BumpMap[k] != NULL)
00620                         {
00621                                 _BumpMap[k]->generate();
00622                                 _HeightMapNormalizationFactor[k] = NLMISC::safe_cast<CTextureBump *>((ITexture *)_BumpMap[k])->getNormalizationFactor();
00623                                 if (_BumpMap[k]->getReleasable())
00624                                 {
00625                                         _BumpMap[k]->release();
00626                                 }
00627                         }
00628                         else
00629                         {
00630                                 _HeightMapNormalizationFactor[k] = 1.f;
00631                         }
00632                         _HeightMapTouch[k] = false;
00633                 }
00634         }
00635 }
00636 
00637 
00638 
00639 //======================================================//
00640 //                                              WaveMakerShape                                  //
00641 //======================================================//
00642 
00643 
00644 //============================================
00645 
00646 CWaveMakerShape::CWaveMakerShape() : _Period(1),
00647                                      _Radius(3),
00648                                      _PoolID(0),
00649                                      _Intensity(1),
00650                                      _ImpulsionMode(true)
00651 {
00652 }
00653 
00654 //============================================
00655 
00656 CWaveMakerShape::~CWaveMakerShape()
00657 {
00658 }
00659 
00660 //============================================
00661 
00662 void CWaveMakerShape::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00663 {
00664         f.serialVersion(0);
00665         f.serial(_Period, _Radius, _Intensity, _PoolID, _ImpulsionMode);
00666 }
00667 
00668 //============================================
00669 
00670 CTransformShape         *CWaveMakerShape::createInstance(CScene &scene)
00671 {
00672         CWaveMakerModel *wmm = NLMISC::safe_cast<CWaveMakerModel *>(scene.createModel(WaveMakerModelClassId) );
00673         wmm->Shape = this;
00674         // set default pos & scale
00675         wmm->ITransformable::setPos( ((CAnimatedValueVector&)_DefaultPos.getValue()).Value  );          
00676         wmm->_Scene = &scene;
00677         return wmm;
00678 }
00679 
00680 //============================================
00681 
00682 bool    CWaveMakerShape::clip(const std::vector<CPlane> &pyramid, const CMatrix &worldMatrix)
00683 {
00684         // we just test if not too far
00685         const CWaterHeightMap &whm = GetWaterPoolManager().getPoolByID(_PoolID);
00686         const float maxDist = 0.5f * whm.getUnitSize() * whm.getSize(); 
00687         const NLMISC::CVector pos = worldMatrix.getPos();
00688         for (std::vector<NLMISC::CPlane>::const_iterator it = pyramid.begin(); it != pyramid.end(); ++it)
00689         {
00690                 if ((*it) * pos > maxDist) return false;
00691         }
00692         return true;
00693 
00694 }
00695 
00696 //============================================
00697 void    CWaveMakerShape::getAABBox(NLMISC::CAABBox &bbox) const
00698 {       
00699         // its just a point
00700         bbox.setCenter(NLMISC::CVector::Null);
00701         bbox.setHalfSize(NLMISC::CVector::Null);
00702 }
00703 
00704 } // NL3D