From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/water__model_8cpp-source.html | 1144 ++++++++++++++++++++++++ 1 file changed, 1144 insertions(+) create mode 100644 docs/doxygen/nel/water__model_8cpp-source.html (limited to 'docs/doxygen/nel/water__model_8cpp-source.html') diff --git a/docs/doxygen/nel/water__model_8cpp-source.html b/docs/doxygen/nel/water__model_8cpp-source.html new file mode 100644 index 00000000..c76d275d --- /dev/null +++ b/docs/doxygen/nel/water__model_8cpp-source.html @@ -0,0 +1,1144 @@ + + + + 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_model.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 "nel/misc/vector_2d.h"
+00029 #include "nel/misc/vector_h.h"
+00030 #include "nel/misc/hierarchical_timer.h"
+00031 #include "nel/3d/animation_time.h"
+00032 #include "3d/water_model.h"
+00033 #include "3d/water_shape.h"
+00034 #include "3d/water_pool_manager.h"
+00035 #include "3d/water_height_map.h"
+00036 #include "3d/dru.h"
+00037 #include "3d/scene.h"
+00038 #include "3d/driver.h"
+00039 #include "3d/render_trav.h"
+00040 #include "3d/anim_detail_trav.h"
+00041 
+00042 
+00043 
+00044 
+00045 namespace NL3D {
+00046 
+00047 
+00048 //=======================================================================
+00049 
+00050 CWaterModel::CWaterModel() : _Scene(NULL)
+00051 {
+00052         setOpacity(false);
+00053         setTransparency(true);
+00054         setOrderingLayer(1);
+00055 }
+00056 
+00057 //=======================================================================
+00058 
+00059 void CWaterModel::registerBasic()
+00060 {
+00061         CMOT::registerModel(WaterModelClassId, TransformShapeId, CWaterModel::creator); 
+00062         CMOT::registerObs(RenderTravId, WaterModelClassId, CWaterRenderObs::creator);   
+00063 }
+00064 
+00065 
+00066 //=======================================================================
+00067 
+00068 ITrack* CWaterModel::getDefaultTrack (uint valueId)
+00069 {
+00070         nlassert(Shape);
+00071         CWaterShape *ws = NLMISC::safe_cast<CWaterShape *>((IShape *) Shape);
+00072         switch (valueId)
+00073         {
+00074                 case PosValue:                  return ws->getDefaultPos(); break;              
+00075                 case ScaleValue:                return ws->getDefaultScale(); break;
+00076                 case RotQuatValue:              return ws->getDefaultRotQuat(); break;
+00077                 default: // delegate to parent
+00078                         return CTransformShape::getDefaultTrack(valueId);
+00079                 break;
+00080         }
+00081 }
+00082 
+00083 //=======================================================================
+00084 
+00085 uint32  CWaterModel::getWaterHeightMapID() const
+00086 {
+00087         CWaterShape *ws = NLMISC::safe_cast<CWaterShape *>((IShape *) Shape);
+00088         return ws->_WaterPoolID;
+00089 }
+00090 
+00091 //=======================================================================
+00092 
+00093 float   CWaterModel::getHeightFactor() const
+00094 {
+00095         CWaterShape *ws = NLMISC::safe_cast<CWaterShape *>((IShape *) Shape);
+00096         return ws->_WaveHeightFactor;
+00097 }
+00098 
+00099 
+00100 //=======================================================================
+00101 
+00102 float   CWaterModel::getHeight(const NLMISC::CVector2f &pos)
+00103 {
+00104         CWaterShape *ws          = NLMISC::safe_cast<CWaterShape *>((IShape *) Shape);  
+00105         CWaterHeightMap &whm = GetWaterPoolManager().getPoolByID(ws->_WaterPoolID);
+00106         const float height   = whm.getHeight(pos);
+00107         return height * ws->_WaveHeightFactor + this->getPos().z;
+00108 }
+00109 
+00110 //=======================================================================
+00111 
+00112 float   CWaterModel::getAttenuatedHeight(const NLMISC::CVector2f &pos, const NLMISC::CVector &viewer)
+00113 {       
+00114         CWaterShape *ws          = NLMISC::safe_cast<CWaterShape *>((IShape *) Shape);                  
+00115         CWaterHeightMap &whm = GetWaterPoolManager().getPoolByID(ws->_WaterPoolID);
+00116         const float maxDist = whm.getUnitSize() * (whm.getSize() >> 1); 
+00117         const NLMISC::CVector planePos(pos.x, pos.y, this->getPos().z);
+00118         const float userDist = (planePos - viewer).norm();
+00119 
+00120         if (userDist > maxDist)
+00121         {
+00122                 return this->getPos().z;
+00123         }
+00124         else
+00125         {
+00126                 const float height   = whm.getHeight(pos);
+00127                 return ws->_WaveHeightFactor * height * (1.f - userDist / maxDist) + this->getPos().z;
+00128         }
+00129 }
+00130 
+00131 
+00132 //=======================================================================
+00133 
+00134 // perform a bilinear on 4 values
+00135 //   0---1
+00136 //   |   |
+00137 //   3---2
+00138 static float inline BilinFilter(float v0, float v1, float v2, float v3, float u, float v)
+00139 {
+00140         float g = v * v3 + (1.f - v) * v0;
+00141         float h = v * v2 + (1.f - v) * v1;
+00142         return u * h + (1.f - u) * g;
+00143 }
+00144 
+00145 
+00146 
+00147 //=======================================================================
+00148 
+00150 static void inline FillWaterVB(uint8 *&vbPointer, float x, float y, float z, float nx, float ny)
+00151 {
+00152         * (float *) vbPointer = x;
+00153         ((float *) vbPointer)[1] = y;
+00154         ((float *) vbPointer)[2] = z;
+00155         *((float *) (vbPointer + 3 * sizeof(float))) = nx;
+00156         *((float *) (vbPointer + 4 * sizeof(float))) = ny;
+00157         vbPointer += 5 * sizeof(float);
+00158 }
+00159 
+00160 //***************************************************************************************************************
+00161 
+00162 
+00164 #ifdef NL_OS_WINDOWS
+00165         __forceinline
+00166 #endif
+00167 static void SetupWaterVertex(  sint  qLeft,
+00168                                                            sint  qRight,
+00169                                                            sint  qUp,
+00170                                                            sint  qDown,
+00171                                                            sint  qSubLeft,
+00172                                                            sint  qSubDown,
+00173                                                            const NLMISC::CVector &inter,                                                           
+00174                                                            float invWaterRatio,                                                    
+00175                                                            sint  doubleWaterHeightMapSize,
+00176                                                            CWaterHeightMap &whm,
+00177                                                            uint8 *&vbPointer,
+00178                                                            float offsetX,
+00179                                                            float offsetY
+00180                                                            )
+00181 {
+00182         const float wXf = invWaterRatio * (inter.x + offsetX);
+00183         const float wYf = invWaterRatio * (inter.y + offsetY);
+00184 
+00185         sint wx = (sint) floorf(wXf);
+00186         sint wy = (sint) floorf(wYf);
+00187 
+00188         
+00189 
+00190         if (!
+00191                  (wx >= qLeft && wx < qRight && wy < qUp &&  wy >= qDown)
+00192            )
+00193         {       
+00194                 // no perturbation is visible
+00195                 FillWaterVB(vbPointer, inter.x, inter.y, 0, 0, 0);              
+00196         }
+00197         else
+00198         {
+00199                 
+00200 
+00201                 // filter height and gradient at the given point
+00202                 const sint stride = doubleWaterHeightMapSize;
+00203 
+00204                 
+00205                 const uint xm     = (uint) (wx - qSubLeft);
+00206                 const uint ym     = (uint) (wy - qSubDown);
+00207                 const sint offset = xm + stride * ym;
+00208                 const float                       *ptWater     = whm.getPointer()         + offset;
+00209 
+00210         /*      float epsilon = 10E-5f;
+00211                 if (ptWater[0] > epsilon                         || ptWater[0] < epsilon 
+00212                         || ptWater[1] > epsilon                  || ptWater[1] < epsilon 
+00213                         || ptWater[stride] > epsilon     || ptWater[stride] < epsilon
+00214                         || ptWater[stride + 1] > epsilon || ptWater[stride + 1] < epsilon
+00215                         )
+00216                 {*/
+00217 
+00218                         float deltaU = wXf - wx;
+00219                         float deltaV = wYf - wy;
+00220                         nlassert(deltaU >= 0.f && deltaU <= 1.f  && deltaV >= 0.f && deltaV <= 1.f);
+00221                         const float                       *ptWaterPrev = whm.getPrevPointer()  + offset;
+00222 
+00223 
+00224 
+00225                         float g0x, g1x, g2x, g3x;  // x gradient for current 
+00226                         float g0xp, g1xp, g2xp, g3xp;
+00227 
+00228                         float gradCurrX, gradCurrY;
+00229 
+00230                         float g0y, g1y, g2y, g3y; // y gradient for previous map
+00231                         float g0yp, g1yp, g2yp, g3yp;
+00232 
+00233                         float gradPrevX, gradPrevY;
+00234 
+00236 
+00237                         g0x = ptWater[ 1] - ptWater[ - 1];
+00238                         g1x = ptWater[ 2] - ptWater[ 0 ];
+00239                         g2x = ptWater[ 2 + stride] - ptWater[ stride];
+00240                         g3x = ptWater[ 1 + stride] - ptWater[ - 1 + stride];
+00241 
+00242                         gradCurrX = BilinFilter(g0x, g1x, g2x, g3x, deltaU, deltaV);
+00243 
+00244 
+00245                         g0y = ptWater[ stride] - ptWater[ - stride];
+00246                         g1y = ptWater[ stride + 1] - ptWater[ - stride + 1];
+00247                         g2y = ptWater[ (stride << 1) + 1] - ptWater[ 1];
+00248                         g3y = ptWater[ (stride << 1)] - ptWater[0];
+00249 
+00250                         gradCurrY = BilinFilter(g0y, g1y, g2y, g3y, deltaU, deltaV);
+00251 
+00253 
+00254                         g0xp = ptWaterPrev[ 1] - ptWaterPrev[ - 1];
+00255                         g1xp = ptWaterPrev[ 2] - ptWaterPrev[ 0  ];
+00256                         g2xp = ptWaterPrev[ 2 + stride] - ptWaterPrev[ + stride];
+00257                         g3xp = ptWaterPrev[ 1 + stride] - ptWaterPrev[ - 1 + stride];
+00258 
+00259                         gradPrevX = BilinFilter(g0xp, g1xp, g2xp, g3xp, deltaU, deltaV);
+00260 
+00261 
+00262                         g0yp = ptWaterPrev[ stride] - ptWaterPrev[ - stride];
+00263                         g1yp = ptWaterPrev[ stride + 1] - ptWaterPrev[ - stride + 1];
+00264                         g2yp = ptWaterPrev[ (stride << 1) + 1] - ptWaterPrev[ 1 ];
+00265                         g3yp = ptWaterPrev[ (stride << 1)] - ptWaterPrev[ 0 ];
+00266 
+00267                         gradPrevY = BilinFilter(g0yp, g1yp, g2yp, g3yp, deltaU, deltaV);
+00268 
+00269 
+00271                         float h = BilinFilter(ptWater[ 0 ], ptWater[ + 1], ptWater[ 1 + stride], ptWater[stride], deltaU, deltaV);
+00272 
+00274                         float hPrev = BilinFilter(ptWaterPrev[ 0 ], ptWaterPrev[ 1], ptWaterPrev[ 1 + stride], ptWaterPrev[stride], deltaU, deltaV);
+00275                         
+00276 
+00277                         float timeRatio = whm.getBufferRatio();
+00278 
+00279 
+00280                         FillWaterVB(vbPointer, inter.x, inter.y, timeRatio * h + (1.f - timeRatio) * hPrev,
+00281                                                 4.5f * (timeRatio * gradCurrX + (1.f - timeRatio) * gradPrevX),
+00282                                                 4.5f * (timeRatio * gradCurrY + (1.f - timeRatio) * gradPrevY)
+00283                                            );
+00284 
+00285 
+00286 
+00287                         //NLMISC::CVector2f *ptGrad  = whm.getGradPointer() + offset;
+00288 
+00289 
+00290 
+00291 
+00292 
+00293                 /*      float dh1 = deltaV * ptWater[stride] + (1.f - deltaV) *  ptWater[0];
+00294                         float dh2 = deltaV * ptWater[stride + 1] + (1.f - deltaV) *  ptWater[1];
+00295                         float h = deltaU * dh2 + (1.f - deltaU ) * dh1;
+00296 
+00297                         
+00298                         float gR = deltaV * ptGrad[stride + 1].x + (1.f - deltaV) * ptGrad[1].x;
+00299                         float gL = deltaV * ptGrad[stride].x + (1.f - deltaV) * ptGrad[0].x;
+00300 
+00301                         float grU = 4.5f * (deltaU *  gR + (1.f - deltaU) * gL);
+00302 
+00303                         gR = deltaV * ptGrad[stride + 1].y + (1.f - deltaV) * ptGrad[1].y;
+00304                         gL = deltaV * ptGrad[stride].y + (1.f - deltaV) * ptGrad[0].y;
+00305 
+00306                         float grV = 4.5f * (deltaU *  gR + (1.f - deltaU) * gL);
+00307 
+00308                         vb.setValueFloat3Ex (Water_VB_POS, vbIndex, inter.x, inter.y, h);
+00309                         vb.setValueFloat2Ex (Water_VB_DX, vbIndex, grU, grV);
+00310                         */
+00311                 /*}
+00312                 else
+00313                 {
+00314                         // no perturbation is visible
+00315                         FillWaterVB(vbPointer, inter.x, inter.y, 0, 0, 0);              
+00316                 }*/
+00317         }
+00318 }
+00319 
+00320 //*********************************************************
+00321 // compute a rotation matrix from the K and the up vector
+00322 static void ComputeUpMatrix(const NLMISC::CVector &J, NLMISC::CMatrix &dest, const NLMISC::CMatrix &defaultMat)
+00323 {
+00324         // if the J vector is oriented toward K, we must use another vector to compute the matrix
+00325         const float JdotK = J.z;
+00326         if ( (1.0f - fabsf(J.z)) < 10E-6)
+00327         {       
+00328                 dest.setRot(defaultMat.getRot());               
+00329         }
+00330         else
+00331         {
+00332                 NLMISC::CVector up        = (NLMISC::CVector::K - JdotK * J).normed();
+00333                 NLMISC::CVector right = J ^ up;
+00334                 dest.setRot(right, J, up);
+00335         }
+00336 }
+00337 
+00338 //*************************************************************
+00339 // draw a 2d polygon after a transformation
+00340 static void DrawPoly2D(CVertexBuffer &vb, IDriver *drv, const NLMISC::CMatrix &mat, const NLMISC::CPolygon &p)
+00341 {
+00342         uint k;
+00343 
+00344         for (k = 0; k < p.Vertices.size(); ++k)
+00345         {
+00346                 NLMISC::CVector tPos = mat * NLMISC::CVector(p.Vertices[k].x, p.Vertices[k].y, 0);
+00347                 vb.setValueFloat3Ex (WATER_VB_POS, k, tPos.x, tPos.y, tPos.z);                                                                                  
+00348                 vb.setValueFloat2Ex (WATER_VB_DX,  k, 0, 0);                    
+00349         }
+00350         static std::vector<uint32> ib;
+00351         ib.resize(3 * p.Vertices.size());
+00352 
+00353         for (k = 0; k < p.Vertices.size() - 2; ++k)
+00354         {
+00355                 ib[ k * 3      ] = 0;
+00356                 ib[ k * 3  + 1 ] = k + 1;
+00357                 ib[ k * 3  + 2 ] = k + 2;
+00358         }       
+00359         drv->renderSimpleTriangles(&ib[0], p.Vertices.size() - 2);      
+00360 }
+00361 
+00362 //***************************************************************************************************************
+00363 
+00364 void    CWaterRenderObs::traverse(IObs *caller)
+00365 {                       
+00366         H_AUTO( NL3D_Water_Render );
+00367 
+00368         CRenderTrav                                     *trav                   = NLMISC::safe_cast<CRenderTrav *>(Trav);
+00369         CWaterModel                                     *m                              = NLMISC::safe_cast<CWaterModel *>(Model);
+00370         CWaterShape                                     *shape                  = NLMISC::safe_cast<CWaterShape *>((IShape *) m->Shape);
+00371         IDriver                                         *drv                    = trav->getDriver();
+00372         const std::vector<CPlane>       &worldPyramid   = ((NLMISC::safe_cast<CClipTrav *>(ClipObs->Trav))->WorldFrustumPyramid);       
+00373 
+00374         if (shape->_GridSizeTouched)
+00375         {
+00376                 shape->setupVertexBuffer();
+00377         }
+00378 
+00379 
+00380         // inverted object world matrix
+00381         //NLMISC::CMatrix invObjMat = HrcObs->WorldMatrix.inverted();
+00382 
+00383         // viewer pos in world space
+00384         const NLMISC::CVector &obsPos = /*invObjMat **/ trav->CamPos;
+00385 
+00386         // camera matrix in world space
+00387         const NLMISC::CMatrix &camMat = trav->CamMatrix;
+00388 
+00389         // view matrix (inverted cam matrix)
+00390         const NLMISC::CMatrix &viewMat = trav->ViewMatrix;
+00391 
+00392         // compute the camera matrix such as there is no rotation around the y axis
+00393         NLMISC::CMatrix camMatUp;
+00394         ComputeUpMatrix(camMat.getJ(), camMatUp, camMat);
+00395         camMatUp.setPos(camMat.getPos());
+00396 
+00397         const NLMISC::CMatrix matViewUp = camMatUp.inverted();
+00398 
+00399         // plane z pos in world
+00400         const float zHeight =  HrcObs->WorldMatrix.getPos().z;
+00401 
+00402         const sint numStepX = CWaterShape::getScreenXGridSize();
+00403         const sint numStepY = CWaterShape::getScreenYGridSize();
+00404 
+00405         const float invNumStepX = 1.f / numStepX;
+00406         const float invNumStepY = 1.f / numStepY;
+00407 
+00408         const uint rotBorderSize = (shape->_MaxGridSize + (shape->_XGridBorder << 1) - numStepX) >> 1;
+00409         
+00410         const sint isAbove = obsPos.z > zHeight ? 1 : 0;
+00411 
+00412                 
+00413 
+00414         //==================//
+00415         // polygon clipping //
+00416         //==================//
+00417 
+00418         uint k;
+00419         static NLMISC::CPolygon clippedPoly, endClippedPoly;    
+00420         clippedPoly.Vertices.resize(shape->_Poly.Vertices.size());
+00421         for (k = 0; k < shape->_Poly.Vertices.size(); ++k)
+00422         {
+00423                 clippedPoly.Vertices[k].set(shape->_Poly.Vertices[k].x, 
+00424                                                                         shape->_Poly.Vertices[k].y,
+00425                                                                         0
+00426                                                                    );
+00427         }
+00428         
+00429         endClippedPoly = clippedPoly;
+00430 
+00431 
+00432         // Build the view pyramid. We need to rebuild it because we use a wider one to avoid holes on the border of the screen
+00433 
+00434         static NLMISC::CPlane plvect[6];
+00435 
+00436         const float borderFactor = 0.67f; // we must avoid numerical imprecision as well as the rotation case (must divide by sqrt(2))
+00437         const float fRight = trav->Right * (2.f * borderFactor * (float) CWaterShape::_XGridBorder +  (float) numStepX) / numStepX;
+00438         const float fTop   = trav->Top   * (2.f * borderFactor * (float) CWaterShape::_YGridBorder +  (float) numStepY) / numStepY;
+00439 
+00440         // build pyramid corners
+00441         const float nearDist        = trav->Near;
+00442         const float farDist                     = trav->Far;    
+00443         const float transitionDist      = shape->_TransitionRatio   * farDist;
+00444 
+00445         const NLMISC::CVector           pfoc(0,0,0);
+00446         const NLMISC::CVector           lb(-fRight,  nearDist, - fTop );
+00447         const NLMISC::CVector           lt(-fRight,  nearDist, fTop  );
+00448         const NLMISC::CVector           rb( fRight,  nearDist, -fTop );
+00449         const NLMISC::CVector           rt(fRight,      nearDist, fTop  );
+00450 
+00451         const NLMISC::CVector           lbfarDist(-fRight, transitionDist, -fTop);
+00452         const NLMISC::CVector           ltfarDist(-fRight, transitionDist, fTop );
+00453         const NLMISC::CVector           rtfarDist(fRight , transitionDist, fTop  );
+00454 
+00455         
+00456         plvect[0].make(lt, lb, rt);                                                     // near plane
+00457         plvect[1].make(lbfarDist, ltfarDist, rtfarDist);    // far plane
+00458 
+00459         plvect[2].make(pfoc, lt, lb);
+00460         plvect[3].make(pfoc, rt, lt);
+00461         plvect[4].make(pfoc, rb, rt);
+00462         plvect[5].make(pfoc, lb, rb);
+00463 
+00464                 
+00465         const NLMISC::CMatrix pyramidMat = viewMat * HrcObs->WorldMatrix;
+00466         for (k = 0; k < worldPyramid.size(); ++k)
+00467         {
+00468                 plvect[k] = plvect[k] * pyramidMat; // put the plane in object space
+00469         }
+00470 
+00471         clippedPoly.clip(plvect, 6);    // get the tesselated part of the poly 
+00472 
+00473         // modify the pyramid to get the transition part of the poly (no tesselated)
+00474         plvect[0].d   += (transitionDist - nearDist);
+00475         // plvect[1].d   -= (farDist - transitionDist);
+00476         // dont clip by far plane (done by driver)
+00477         endClippedPoly.clip(plvect, 1);
+00478         endClippedPoly.clip(plvect + 2, 4);
+00479 
+00480 
+00481 
+00483         if (clippedPoly.Vertices.size() == 0 && endClippedPoly.Vertices.size() == 0)
+00484         {
+00485                 return; 
+00486         }
+00487 
+00488         
+00489         NLMISC::CMatrix modelMat;
+00490         modelMat.setPos(NLMISC::CVector(obsPos.x, obsPos.y, zHeight));
+00491         drv->setupModelMatrix(modelMat);
+00492         
+00493 
+00494         //==================//
+00495         // material setup   //
+00496         //==================//
+00497 
+00498         CWaterHeightMap &whm = GetWaterPoolManager().getPoolByID(shape->_WaterPoolID);
+00499         setupMaterialNVertexShader(drv, shape, obsPos, isAbove > 0, whm.getUnitSize() * (whm.getSize() >> 1), zHeight);
+00500 
+00501         //setAttenuationFactor(drv, false, obsPos, camMat.getJ(), farDist);
+00502         //disableAttenuation(drv);
+00503 
+00504         
+00505         //================================//
+00506         //      Vertex buffer setup           //
+00507         //================================//
+00508                 
+00509         drv->activeVertexBuffer(shape->_VB);
+00510 
+00511         //================================//
+00512         //      tesselated part of the poly   //
+00513         //================================//
+00514 
+00515         if (clippedPoly.Vertices.size())
+00516         {
+00517                 
+00518                 //======================================//
+00519                 // Polygon projection on the near plane //
+00520                 //======================================//
+00521 
+00522                 static NLMISC::CPolygon2D projPoly; // projected poly
+00523                 projPoly.Vertices.resize(clippedPoly.Vertices.size());
+00524                 const float Near = trav->Near;
+00525                 const float xFactor = (numStepX >> 1) * Near  / trav->Right;
+00526                 const float xOffset = (float) (numStepX >> 1) + 0.5f;
+00527                 const float yFactor = - (numStepX >> 1) * Near  / trav->Top;
+00528                 const float yOffset = (float) (numStepY >> 1) - 0.5f * isAbove;
+00529                 
+00530                 const NLMISC::CMatrix projMat =  matViewUp * HrcObs->WorldMatrix;
+00531                 for (k = 0; k < clippedPoly.Vertices.size(); ++k)
+00532                 {
+00533                         // project points in the view
+00534                         NLMISC::CVector t = projMat * clippedPoly.Vertices[k];
+00535                         float invY = 1.f / t.y;
+00536                         projPoly.Vertices[k].set(xFactor * t.x * invY + xOffset, yFactor * t.z * invY + yOffset);
+00537                 }
+00538 
+00539 
+00540 
+00541                 //=============================================//
+00542                 // compute borders of poly at a low resolution //
+00543                 //=============================================//
+00544 
+00545                 NLMISC::CPolygon2D::TRasterVect rasters;                
+00546                 sint startY;
+00547                 projPoly.computeBorders(rasters, startY);
+00548 
+00549                 if (rasters.size())
+00550                 {
+00551                         //===========================//
+00552                         // perform Water animation   //
+00553                         //===========================//                 
+00554 
+00555                         const float WaterRatio = whm.getUnitSize();
+00556                         const float invWaterRatio = 1.f / WaterRatio;
+00557                         const uint  WaterHeightMapSize = whm.getSize();
+00558                         const uint  doubleWaterHeightMapSize = (WaterHeightMapSize << 1);
+00559                                                 
+00560 
+00561                         sint64 idate = (NLMISC::safe_cast<CHrcTrav *>(HrcObs->Trav))->CurrentDate;
+00562 
+00563 
+00564                         
+00565                         if (idate != whm.Date)
+00566                         {
+00567                                 whm.setUserPos((sint) (obsPos.x * invWaterRatio) - (WaterHeightMapSize >> 1),
+00568                                            (sint) (obsPos.y * invWaterRatio) - (WaterHeightMapSize >> 1)
+00569                                           );
+00570                                 nlassert(m->_Scene); // this object should have been created from a CWaterShape!
+00571                                 whm.animate((float) (m->_Scene->getEllapsedTime()));                                                                                            
+00572                                 whm.Date = idate;
+00573                         }
+00574                         
+00575                         //float startDate = (float) (1000.f * NLMISC::CTime::ticksToSecond(NLMISC::CTime::getPerformanceTime()));
+00576 
+00577                         //=====================================//
+00578                         //      compute heightmap useful area      //
+00579                         //=====================================//
+00580 
+00588                         sint mapPosX, mapPosY;
+00589 
+00592                         whm.getUserPos(mapPosX, mapPosY);
+00593 
+00594                         const uint mapBorder = 3;
+00595                         /*const sint qRight = (sint) mapPosX + (WaterHeightMapSize >> 1) - mapBorder;
+00596                                   sint qLeft  = (sint) mapPosX - (WaterHeightMapSize >> 1);
+00597                         const sint qUp    = (sint) mapPosY + (WaterHeightMapSize >> 1) - mapBorder;
+00598                                   sint qDown  = (sint) mapPosY - (WaterHeightMapSize >> 1); */
+00599 
+00600 
+00601                         const sint qRight = (sint) mapPosX + WaterHeightMapSize - mapBorder;
+00602                                   sint qLeft  = (sint) mapPosX;
+00603                         const sint qUp    = (sint) mapPosY + WaterHeightMapSize - mapBorder;
+00604                                   sint qDown  = (sint) mapPosY;
+00605 
+00607                         const sint qSubLeft = qLeft - (uint)  qLeft % WaterHeightMapSize;
+00608                         const sint qSubDown = qDown - (uint)  qDown % WaterHeightMapSize;
+00609 
+00610                         qLeft += mapBorder;
+00611                         qDown += mapBorder;
+00612 
+00613                 
+00614 
+00615                         
+00616                         //==============================================//
+00617                         // setup rays to be traced, and their increment //
+00618                         //==============================================//
+00619                         
+00620 
+00621                         // compute  camera rays in world space
+00622                         CVector currHV = trav->Left * camMatUp.getI() + trav->Near * camMatUp.getJ() + trav->Top * camMatUp.getK(); // current border vector, incremented at each line
+00623                         CVector currV; // current ray vector
+00624                         CVector xStep = (trav->Right - trav->Left) * invNumStepX * camMatUp.getI();        // xStep for the ray vector
+00625                         CVector yStep = (trav->Bottom - trav->Top) * invNumStepY * camMatUp.getK();    // yStep for the ray vector
+00626                         
+00627 
+00628 
+00629                         //===============================================//
+00630                         //                              perform display                  //
+00631                         //===============================================//
+00632 
+00633                         // scale currHV at the top of the poly
+00634                         currHV += (startY - 0.5f  * isAbove) * yStep;
+00635 
+00636                         // current index buffer used. We swap each time a row has been drawn
+00637                         std::vector<uint32> *currIB = &CWaterShape::_IBUpDown, *otherIB = &CWaterShape::_IBDownUp;
+00638 
+00639                                         
+00640                         sint vIndex = 0; // index in vertices   
+00641 
+00642                         // current raster position
+00643                         sint oldStartX, oldEndX, realStartX, realEndX;  
+00644                         //float invNearWidth = numStepX / (trav->Right - trav->Left);
+00645 
+00646                                 //nlinfo("size = %d, maxSize = ", rasters.size(), numStepY);
+00647 
+00648 
+00649                         const uint wqHeight = rasters.size();
+00650                         if (wqHeight)
+00651                         {
+00652                                 // denominator of the intersection equation
+00653                                 const float denom = - obsPos.z + zHeight; 
+00654                                 // test the upper raster
+00655                                 // if it is above the horizon, we modify it to reach the correct location
+00656                                 const float horizonEpsilon = 10E-4f; // we must be a little below the horizon
+00657 
+00658                                 // distance from the viewer along the traced ray
+00659                                 float t;
+00660 
+00661                                 
+00662 
+00663 
+00664                                  NLMISC::CPolygon2D::TRasterVect::const_iterator it = rasters.begin();
+00665                                 for (uint l = 0; l <= wqHeight; ++l)
+00666                                 {               
+00667                                         //nlinfo("start = %d, end = %d", it->first, it->second);                                
+00668                                         const sint startX = it->first;
+00669                                         const sint endX   = (it->second + 1);
+00670 
+00671                                         nlassert(startX >= - (sint) rotBorderSize);
+00672                                         nlassert(endX  <= (sint) (numStepX + rotBorderSize));
+00673 
+00674                                         if (l != 0)
+00675                                         {
+00676                                                 realStartX = std::min(startX, oldStartX);
+00677                                                 realEndX = std::max(endX, oldEndX);
+00678                                         }
+00679                                         else
+00680                                         {
+00681                                                 realStartX = startX;
+00682                                                 realEndX =   endX;
+00683                                         }
+00684 
+00685                                         
+00686                                         // current view vector
+00687                                         currV   = currHV + (realStartX - 0.5f) * xStep;
+00688                                         
+00689                                         if (l == 0)
+00690                                         {
+00691                                                 if (isAbove)
+00692                                                 {
+00693                                                         // test wether the first row is out of horizon.
+00694                                                         // if this is the case, we make a correction
+00695                                                         if (denom * currV.z <= 0)
+00696                                                         {                                       
+00697                                                                 // correct for the first line only by adding a y offset
+00698                                                                 currV += yStep * ((denom > 0 ? horizonEpsilon : - horizonEpsilon)   - currV.z) / yStep.z;
+00699                                                         }
+00700 
+00701                                                         // now, for the transition, check wether the first raster does not go over the transition dist
+00702                                                 
+00703                                                         t = denom / currV.z;
+00704                                                         const float VJ = camMat.getJ() * currV;
+00705                                                         if ( t * VJ >  transitionDist)
+00706                                                         {                                                       
+00707                                                                 float delta = (1.f / yStep.z) * ( denom * VJ / transitionDist - currV.z);
+00708                                                                 // correct the first line to reach that position
+00709                                                                 currV += delta * yStep;
+00710                                                         }
+00711                                                 }
+00712                                         }
+00713 
+00714                                         
+00715                                         uint8 *vbPointer = (uint8 *) shape->_VB.getVertexCoordPointer() + shape->_VB.getVertexSize() * (vIndex + realStartX + rotBorderSize);                                                                                           
+00716                                                 
+00717 
+00718                                         for (sint k = realStartX; k <= realEndX; ++k)
+00719                                         {       
+00720                                                 t =   denom / currV.z;                                          
+00721                                                 // compute intersection with plane                                                                                      
+00722                                                 CVector inter = t * currV;
+00723                                                 inter.z += obsPos.z;
+00724                                                 SetupWaterVertex(qLeft, qRight, qUp, qDown, qSubLeft, qSubDown, inter, invWaterRatio, doubleWaterHeightMapSize, whm, vbPointer, obsPos.x, obsPos.y);
+00725                                                 currV += xStep;                                         
+00726                                         }
+00727 
+00728                                         if (l != 0) // 2 line of the ib done ?
+00729                                         {                                               
+00730                                                 sint count = oldEndX - oldStartX;
+00731                                                 if (count > 0)
+00732                                                 {                                                                                               
+00733                                                         drv->renderSimpleTriangles(&((*currIB)[(oldStartX + rotBorderSize) * 6]),
+00734                                                                                                  2 * count );                           
+00735                                                 }               
+00736                                         }
+00737 
+00738                                         oldStartX = startX;
+00739                                         oldEndX   = endX;
+00740                                         currHV    += yStep;
+00741                                         vIndex    = (numStepX + 2 * rotBorderSize + 1) - vIndex; // swap first row and second row
+00742                                         std::swap(currIB, otherIB);
+00743                                         if (l < (wqHeight - 1))
+00744                                         {
+00745                                                 ++it;
+00746                                         }
+00747                                         else
+00748                                         {
+00749                                                 if (!isAbove)
+00750                                                 {
+00751                                                         // last line
+00752                                                         // test wether we are out of horizon
+00753                                                         if (denom * currHV.z <= 0)
+00754                                                         {                                               
+00755                                                                 // correct for the first line only by adding a y offset
+00756                                                                 currHV += yStep * ((denom > 0 ? horizonEpsilon : - horizonEpsilon)  - currHV.z) / yStep.z;
+00757                                                         }
+00758 
+00759                                                         // now, for the transition, check wether the first raster does not go over the transition dist
+00760                                                 
+00761                                                         t = denom / currHV.z;
+00762                                                         const float VJ = camMat.getJ() * currHV;
+00763                                                         if ( t * VJ >  transitionDist)
+00764                                                         {                                                       
+00765                                                                 float delta = (1.f / yStep.z) * ( denom * VJ / transitionDist - currHV.z);
+00766                                                                 // correct the first line to reach that position
+00767                                                                 currHV += delta * yStep;
+00768                                                         }
+00769                                                 }
+00770 
+00771                                         }
+00772                                 }
+00773                                         
+00774                         }
+00775                         //nlinfo("display: %f ms", (float) (1000.f * NLMISC::CTime::ticksToSecond(NLMISC::CTime::getPerformanceTime()) - startDate));
+00776                 }
+00777         }
+00778 
+00779         //=========================================//
+00780         //                      display end poly               //
+00781         //=========================================//
+00782 
+00783         if (endClippedPoly.Vertices.size() != 0)
+00784         {       
+00785                 CMatrix mtx; /*= HrcObs->WorldMatrix;*/
+00786                 // mtx.setPos(NLMISC::CVector(-obsPos.x, -obsPos.y, obsPos.z));
+00787 
+00788                 mtx.setPos(HrcObs->WorldMatrix.getPos() + NLMISC::CVector(-obsPos.x, -obsPos.y, 0));
+00789                 // set right obsever position
+00790                 drv->setConstant(7, 0, 0, obsPos.z /* - zHeight*/ , 0.f);
+00791                 //setAttenuationFactor(drv, true, obsPos, camMat.getJ(), farDist);                              
+00792                 DrawPoly2D(shape->_VB, drv, mtx, endClippedPoly);
+00793         }
+00794 
+00795         /*if (endTransitionClippedPoly.Vertices.size() != 0)
+00796         {                               
+00797                 disableAttenuation(drv);                                
+00798                 DrawPoly2D(shape->_VB, drv, HrcObs->WorldMatrix, endTransitionClippedPoly);
+00799         }*/
+00800 
+00801 
+00802         if (drv->isVertexProgramSupported())
+00803         {
+00804                 bool result =  drv->activeVertexProgram(NULL);
+00805                 if (!result) nlwarning("no vertex program setupped");
+00806         }
+00807         
+00808 
+00809         this->traverseSons();
+00810 }
+00811 
+00812 //***********************
+00813 // Water MATERIAL SETUP //
+00814 //***********************
+00815 
+00816 void CWaterRenderObs::setupMaterialNVertexShader(IDriver *drv, CWaterShape *shape, const NLMISC::CVector &obsPos, bool above, float maxDist, float zHeight)
+00817 {       
+00818         CMaterial WaterMat;
+00819         WaterMat.setLighting(false);
+00820         WaterMat.setDoubleSided(true);  
+00821         WaterMat.setColor(NLMISC::CRGBA::White);
+00822 
+00823         WaterMat.setBlend(true);
+00824         WaterMat.setSrcBlend(CMaterial::srcalpha);
+00825         WaterMat.setDstBlend(CMaterial::invsrcalpha);
+00826         WaterMat.setZWrite(true);
+00827 
+00828         if (drv->isVertexProgramSupported())    
+00829         {
+00830                 const uint cstOffset = 4; // 4 places for the matrix
+00831                 NLMISC::CVectorH cst[13];
+00832                 
+00833                 
+00834                 //=========================//
+00835                 //      setup Water material   //
+00836                 //=========================//
+00837         
+00838                 uint alphaMapStage, envMapStage;        
+00839                 WaterMat.setColor(NLMISC::CRGBA::White);
+00840 
+00841                 bool useBumpedVersion = false;
+00842                 bool useEMBM = false;
+00843                 if (drv->getNbTextureStages() >= 4 && (drv->supportTextureShaders() || drv->supportEMBM()))
+00844                 {
+00845                         if (drv->supportTextureShaders())
+00846                         {
+00847                                 useBumpedVersion = true;
+00848                         }
+00849                         else // must support EMBM on stages 0 and 1
+00850                         {
+00851                                 if (drv->isEMBMSupportedAtStage(0) && drv->isEMBMSupportedAtStage(1))
+00852                                 {
+00853                                         useBumpedVersion = true;
+00854                                         useEMBM = true;
+00855                                 }
+00856                         }
+00857                 }               
+00858 
+00859                 
+00860                 if (!useBumpedVersion)
+00861                 {                                               
+00862                         WaterMat.texEnvOpRGB(0, CMaterial::Modulate);
+00863                         alphaMapStage = 1;
+00864                         envMapStage  = 0;
+00865                 }
+00866                 else
+00867                 {
+00868                         shape->updateHeightMapNormalizationFactors();
+00869 
+00870                         // setup bump proj matrix                       
+00871                         const float idMat[] = {0.25f * shape->_HeightMapNormalizationFactor[0], 0, 0, 0.25f * shape->_HeightMapNormalizationFactor[0]}; 
+00872                         const float idMat2[] = {shape->_HeightMapNormalizationFactor[1], 0, 0, shape->_HeightMapNormalizationFactor[1]};        
+00873 
+00874                         WaterMat.setTexture(0, shape->_BumpMap[0]);
+00875                         WaterMat.setTexture(1, shape->_BumpMap[1]);                             
+00876                         WaterMat.texEnvOpRGB(2, CMaterial::Replace);
+00877                         alphaMapStage = 3;
+00878                         envMapStage   = 2;
+00879 
+00880                         // Version with texture shaders
+00881                         if (!useEMBM)
+00882                         {                                               
+00883                                 drv->setMatrix2DForTextureOffsetAddrMode(1, idMat);
+00884                                 drv->setMatrix2DForTextureOffsetAddrMode(2, idMat2);                            
+00885 
+00886 
+00887                                 //if (shape->_BumpMap[0]->supportSharing()) nlinfo(shape->_BumpMap[0]->getShareName().c_str());
+00888                                 //if (shape->_BumpMap[1]->supportSharing()) nlinfo(shape->_BumpMap[1]->getShareName().c_str());
+00889 
+00890                                 /*WaterMat.texEnvOpRGB(1, CMaterial::Replace);
+00891                                 WaterMat.texEnvOpRGB(1, CMaterial::Replace);*/
+00892                                 WaterMat.enableTexAddrMode();
+00893                                 WaterMat.setTexAddressingMode(0, CMaterial::FetchTexture);              
+00894                                 WaterMat.setTexAddressingMode(1, CMaterial::OffsetTexture);
+00895                                 WaterMat.setTexAddressingMode(2, CMaterial::OffsetTexture);
+00896                                 WaterMat.setTexAddressingMode(3, shape->_ColorMap ? CMaterial::FetchTexture : CMaterial::TextureOff);                           
+00897                         }
+00898                         else // version with EMBM
+00899                         {
+00900                                 drv->setEMBMMatrix(0, idMat2);          
+00901                                 drv->setEMBMMatrix(1, idMat2);
+00902                                 WaterMat.texEnvOpRGB(0, CMaterial::EMBM);
+00903                                 //WaterMat.texEnvOpRGB(0, CMaterial::Replace);
+00904                                 //WaterMat.texEnvOpRGB(0, CMaterial::EMBM);
+00905                                 WaterMat.texEnvOpRGB(1, CMaterial::EMBM);
+00906                                 WaterMat.setTexture(0, NULL);                   
+00907                         }
+00908                 }
+00909                 
+00910 
+00911                 if (!above && shape->_EnvMap[1])
+00912                 {
+00913                         WaterMat.setTexture(envMapStage, shape->_EnvMap[1]);    
+00914                         //if (shape->_EnvMap[1]->supportSharing()) nlinfo(shape->_EnvMap[1]->getShareName().c_str());
+00915                 }
+00916                 else
+00917                 {
+00918                         WaterMat.setTexture(envMapStage, shape->_EnvMap[0]);
+00919                 }
+00920                 shape->envMapUpdate();
+00921 
+00922                 
+00923                 if (shape->_ColorMap)
+00924                 {                       
+00925                         WaterMat.setTexture(alphaMapStage, shape->_ColorMap);
+00926                         //if (shape->_ColorMap->supportSharing()) nlinfo(shape->_ColorMap->getShareName().c_str());
+00927 
+00928 
+00929                         // setup 2x3 matrix for lookup in diffuse map
+00930                         cst[13 - cstOffset].set(shape->_ColorMapMatColumn0.x, shape->_ColorMapMatColumn1.x, 0, shape->_ColorMapMatColumn0.x * obsPos.x + shape->_ColorMapMatColumn1.x * obsPos.y + shape->_ColorMapMatPos.x); 
+00931                         cst[14 - cstOffset].set(shape->_ColorMapMatColumn0.y, shape->_ColorMapMatColumn1.y, 0, shape->_ColorMapMatColumn0.y * obsPos.x + shape->_ColorMapMatColumn1.y * obsPos.y + shape->_ColorMapMatPos.y);                   
+00932                         WaterMat.texEnvOpRGB(alphaMapStage, CMaterial::Modulate);
+00933                         WaterMat.texEnvOpAlpha(alphaMapStage, CMaterial::Modulate);
+00934                 }
+00935                 else
+00936                 {
+00937                         cst[13 - cstOffset].set(0, 0, 0, 0);
+00938                         cst[14 - cstOffset].set(0, 0, 0, 0);                    
+00939                 }
+00940 
+00941                 cst[16 - cstOffset].set(0.1f, 0.1f, 0.1f, 0.1f); // used to avoid imprecision when performing a RSQ to get distance from the origin
+00942                 // cst[16 - cstOffset].set(0.0f, 0.0f, 0.0f, 0.0f); // used to avoid imprecision when performing a RSQ to get distance from the origin
+00943 
+00944                                         
+00945 
+00946 
+00947                 cst[5  - cstOffset].set(0.f, 0.f, 0.f, 0.f); // claping negative values to 0
+00948 
+00949                 // slope of attenuation of normal / height with distance                
+00950                 const float invMaxDist = shape->_WaveHeightFactor / maxDist;
+00951                 cst[6  - cstOffset].set(invMaxDist, shape->_WaveHeightFactor, 0, 0);            
+00952 
+00953                 /*cst[6  - cstOffset].set(invMaxDist, invMaxDist, invMaxDist, invMaxDist); // upcoming light vectorshape->_WaveHeightFactor             
+00954                 cst[15  - cstOffset].set(shape->_WaveHeightFactor, shape->_WaveHeightFactor, shape->_WaveHeightFactor, shape->_WaveHeightFactor);
+00955                 */
+00956 
+00957 
+00958                                 
+00959 
+00961                 drv->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity);
+00962 
+00963                 // retrieve current time
+00964                 float date  = 0.001f * NLMISC::CTime::getLocalTime();
+00965                 // set bumpmaps pos
+00966                 cst[9  - cstOffset].set(obsPos.x * shape->_HeightMapScale[0].x + date * shape->_HeightMapSpeed[0].x, shape->_HeightMapScale[0].y * obsPos.y + date * shape->_HeightMapSpeed[0].y, 0.f, 0.f); // bump map 0 offset
+00967                 cst[10  - cstOffset].set(shape->_HeightMapScale[0].x, shape->_HeightMapScale[0].y, 0, 0); // bump map 0 scale
+00968                 cst[11  - cstOffset].set(shape->_HeightMapScale[1].x * obsPos.x + date * shape->_HeightMapSpeed[1].x, shape->_HeightMapScale[1].y * obsPos.y + date * shape->_HeightMapSpeed[0].y, 0.f, 0.f); // bump map 1 offset
+00969                 cst[12  - cstOffset].set(shape->_HeightMapScale[1].x, shape->_HeightMapScale[1].y, 0, 0); // bump map 1 scale
+00970 
+00971                                 
+00972                         
+00973                 
+00974 
+00975 
+00976                 cst[4  - cstOffset].set(1.f, 1.f, 1.f, 1.f); // use with min man, and to get the 1 constant             
+00977                 cst[7  - cstOffset].set(0, 0, obsPos.z - zHeight, 0.f);
+00978                 cst[8  - cstOffset].set(0.5f, 0.5f, 0.f, 0.f); // used to scale reflected ray into the envmap
+00979 
+00980         
+00981                 
+00982 
+00984                 drv->setConstant(4, sizeof(cst) / sizeof(cst[0]), (float *) &cst[0]);
+00985 
+00986                 shape->initVertexProgram();             
+00987                 bool result;
+00988                 if (useBumpedVersion)
+00989                 {
+00990                         if (!useEMBM)
+00991                         {                       
+00992                                 result = shape->getColorMap() ? drv->activeVertexProgram((shape->_VertexProgramBump2Diffuse).get())
+00993                                                                                                 : drv->activeVertexProgram((shape->_VertexProgramBump2).get());
+00994                         }
+00995                         else
+00996                         {
+00997                                 result = shape->getColorMap() ? drv->activeVertexProgram((shape->_VertexProgramBump1Diffuse).get())
+00998                                                                                                 : drv->activeVertexProgram((shape->_VertexProgramBump1).get());
+00999                         }
+01000                 }
+01001                 else
+01002                 {
+01003                         result = shape->getColorMap() ? drv->activeVertexProgram((shape->_VertexProgramNoBumpDiffuse).get())
+01004                                                                                 : drv->activeVertexProgram((shape->_VertexProgramNoBump).get());
+01005                 }
+01006                 if (!result) nlwarning("no vertex program setupped");                           
+01007         }
+01008         else
+01009         {               
+01010                 WaterMat.setColor(NLMISC::CRGBA(0, 32, 190, 128));      
+01011         }
+01012 
+01013 
+01014         // temp for test
+01015 /*      WaterMat = CMaterial();
+01016         WaterMat.initUnlit();
+01017         WaterMat.setDoubleSided(true);
+01018         WaterMat.setColor(CRGBA::Red);
+01019 
+01020 
+01021          WaterMat.texEnvOpRGB(0, CMaterial::Replace);
+01022         WaterMat.texEnvOpAlpha(0, CMaterial::Replace);
+01023         WaterMat.texEnvArg0RGB(0, CMaterial::Diffuse, CMaterial::SrcColor);
+01024         WaterMat.texEnvArg0Alpha(0, CMaterial::Diffuse, CMaterial::SrcAlpha);
+01025         */
+01026 
+01027         drv->setupMaterial(WaterMat);
+01028 }
+01029 
+01030 //=======================================================================================
+01031 //                                                      wave maker implementation
+01032 //=======================================================================================
+01033 
+01034 
+01035 CWaveMakerModel::CWaveMakerModel() : _Time(0), _Scene(NULL)
+01036 {
+01037         // AnimDetail behavior: Must be traversed in AnimDetail, even if no channel mixer registered
+01038         CTransform::setIsForceAnimDetail(true);
+01039 }
+01040 
+01041 //================================================
+01042 
+01043 void CWaveMakerModel::registerBasic()
+01044 {
+01045         CMOT::registerModel(WaveMakerModelClassId, TransformShapeId, CWaveMakerModel::creator);
+01046         CMOT::registerObs(AnimDetailTravId, WaveMakerModelClassId, CWaveMakerDetailObs::creator);       
+01047 }
+01048 
+01049 //================================================
+01050 
+01051 ITrack* CWaveMakerModel::getDefaultTrack (uint valueId)
+01052 {
+01053         nlassert(Shape);
+01054         CWaveMakerShape *ws = NLMISC::safe_cast<CWaveMakerShape *>((IShape *) Shape);
+01055         switch (valueId)
+01056         {
+01057                 case PosValue:                  return ws->getDefaultPos(); break;      
+01058                 default: // delegate to parent
+01059                         return CTransformShape::getDefaultTrack(valueId);
+01060                 break;
+01061         }
+01062 }
+01063 
+01064 //================================================
+01065 
+01066 void    CWaveMakerDetailObs::traverse(IObs *caller)
+01067 {
+01068         CTransformAnimDetailObs::traverse(caller);
+01070         CWaveMakerModel *wmm = NLMISC::safe_cast<CWaveMakerModel *>(Model);
+01071         nlassert(wmm->_Scene);
+01073         CWaveMakerShape *wms = NLMISC::safe_cast<CWaveMakerShape *>((IShape *) wmm->Shape);
+01074         const NLMISC::CVector   worldPos = this->ClipObs->HrcObs->WorldMatrix.getPos();
+01075         const NLMISC::CVector2f pos2d(worldPos.x, worldPos.y);
+01077         CWaterHeightMap &whm = GetWaterPoolManager().getPoolByID(wms->_PoolID);
+01078         // get the time delta 
+01079         const TAnimationTime deltaT  = std::min(wmm->_Scene->getEllapsedTime(), (TAnimationTime) whm.getPropagationTime());
+01080         wmm->_Time += deltaT;
+01081         if (!wms->_ImpulsionMode)
+01082         {
+01083                 whm.perturbate(pos2d, wms->_Intensity * cosf(2.f / wms->_Period * (float) NLMISC::Pi * wmm->_Time), wms->_Radius);
+01084         }
+01085         else
+01086         {
+01087                 if (wmm->_Time > wms->_Period)
+01088                 {
+01089                         wmm->_Time -= wms->_Period;
+01090                         whm.perturbate(pos2d, wms->_Intensity, wms->_Radius);
+01091                 }
+01092         }
+01093         this->traverseSons();
+01094 }
+01095 
+01096 
+01097 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1