1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "nel/3d/water_shape.h"
23 #include "nel/3d/water_model.h"
24 #include "nel/3d/vertex_buffer.h"
25 #include "nel/3d/texture_bump.h"
26 #include "nel/3d/texture_blend.h"
27 #include "nel/3d/scene.h"
28 #include "nel/3d/water_pool_manager.h"
29 #include "nel/3d/water_height_map.h"
44 /////////////////////////
45 // WATER WITH NO WAVES //
46 /////////////////////////
48 static const char *WaterVPNoWave
=
50 DP4 o[HPOS].x, c[0], v[0]; #transform vertex in view space \n\
51 DP4 o[HPOS].y, c[1], v[0]; \n\
52 DP4 o[HPOS].z, c[2], v[0]; \n\
53 DP4 o[HPOS].w, c[3], v[0]; \n\
54 # MUL R1, R2.x, R1; \n\
55 DP4 o[FOGC].x, c[4], v[0]; #setup fog \n\
56 MUL R3, v[0], c[5]; #compute bump 0 uv's \n\
57 ADD o[TEX0], R3, c[6]; \n\
58 MUL R3, v[0], c[7]; #compute bump 1 uv's \n\
59 ADD o[TEX1], R3, c[8]; \n\
60 ADD R0, c[9], -v[0]; #r1 = eye - vertex \n\
61 DP3 R1, R0, R0; #r1 = eye - vertex, r2 = (eye - vertex)^2 \n\
62 RSQ R1, R1.x; #r1 = eye - vertex, r2 = 1/d(eye, vertex) \n\
64 DP3 R1.x, R0.xyww, R0.xyww; \n\
65 MAD o[TEX2], -R0, c[10], c[10]; #envmap tex coord \n\
68 // a diffuse texture is added
69 static const char *WaterVPNoWaveDiffuse
=
71 DP4 o[HPOS].x, c[0], v[0]; #transform vertex in view space \n\
72 DP4 o[HPOS].y, c[1], v[0]; \n\
73 DP4 o[HPOS].z, c[2], v[0]; \n\
74 DP4 o[HPOS].w, c[3], v[0]; \n\
75 # MUL R1, R2.x, R1; \n\
76 DP4 o[FOGC].x, c[4], v[0]; #setup fog \n\
77 MUL R3, v[0], c[5]; #compute bump 0 uv's \n\
78 ADD o[TEX0], R3, c[6]; \n\
79 MUL R3, v[0], c[7]; #compute bump 1 uv's \n\
80 ADD o[TEX1], R3, c[8]; \n\
81 ADD R0, c[9], -v[0]; #r1 = eye - vertex \n\
82 DP3 R1, R0, R0; #r1 = eye - vertex, r2 = (eye - vertex)^2 \n\
83 RSQ R1, R1.x; #r1 = eye - vertex, r2 = 1/d(eye, vertex) \n\
85 MAD o[TEX2], -R0, c[10], c[10]; #envmap tex coord \n\
86 DP4 o[TEX3].x, v[0], c[11]; #compute uv for diffuse texture \n\
87 DP4 o[TEX3].y, v[0], c[12]; \n\
90 CVertexProgramWaterVPNoWave::CVertexProgramWaterVPNoWave(bool diffuse
)
95 CSource
*source
= new CSource();
96 source
->Profile
= nelvp
;
97 source
->DisplayName
= "WaterVPNoWave/nelvp";
98 source
->ParamIndices
["modelViewProjection"] = 0;
99 source
->ParamIndices
["fog"] = 4;
100 source
->ParamIndices
["bumpMap0Scale"] = 5;
101 source
->ParamIndices
["bumpMap0Offset"] = 6;
102 source
->ParamIndices
["bumpMap1Scale"] = 7;
103 source
->ParamIndices
["bumpMap1Offset"] = 8;
104 source
->ParamIndices
["observerHeight"] = 9;
105 source
->ParamIndices
["scaleReflectedRay"] = 10;
108 source
->DisplayName
+= "/diffuse";
109 source
->ParamIndices
["diffuseMapVector0"] = 11;
110 source
->ParamIndices
["diffuseMapVector1"] = 12;
111 source
->setSourcePtr(WaterVPNoWaveDiffuse
);
115 source
->setSourcePtr(WaterVPNoWave
);
122 // CSource *source = new CSource();
123 // source->Profile = glsl330v;
124 // source->DisplayName = "WaterVPNoWave/glsl330v";
125 // if (diffuse) source->DisplayName += "/diffuse";
126 // source->setSource...
127 // addSource(source);
131 void CVertexProgramWaterVPNoWave::buildInfo()
133 m_Idx
.BumpMap0Scale
= getUniformIndex("bumpMap0Scale");
134 nlassert(m_Idx
.BumpMap0Scale
!= std::numeric_limits
<uint
>::max());
135 m_Idx
.BumpMap0Offset
= getUniformIndex("bumpMap0Offset");
136 nlassert(m_Idx
.BumpMap0Offset
!= std::numeric_limits
<uint
>::max());
137 m_Idx
.BumpMap1Scale
= getUniformIndex("bumpMap1Scale");
138 nlassert(m_Idx
.BumpMap1Scale
!= std::numeric_limits
<uint
>::max());
139 m_Idx
.BumpMap1Offset
= getUniformIndex("bumpMap1Offset");
140 nlassert(m_Idx
.BumpMap1Offset
!= std::numeric_limits
<uint
>::max());
141 m_Idx
.ObserverHeight
= getUniformIndex("observerHeight");
142 nlassert(m_Idx
.ObserverHeight
!= std::numeric_limits
<uint
>::max());
143 m_Idx
.ScaleReflectedRay
= getUniformIndex("scaleReflectedRay");
144 nlassert(m_Idx
.ScaleReflectedRay
!= std::numeric_limits
<uint
>::max());
147 m_Idx
.DiffuseMapVector0
= getUniformIndex("diffuseMapVector0");
148 nlassert(m_Idx
.DiffuseMapVector0
!= std::numeric_limits
<uint
>::max());
149 m_Idx
.DiffuseMapVector1
= getUniformIndex("diffuseMapVector1");
150 nlassert(m_Idx
.DiffuseMapVector1
!= std::numeric_limits
<uint
>::max());
158 // common start for Water vertex programs
159 /** The first part of the program does the following :
160 * - Compute linear distance to eye
161 * - Attenuate height with distance
162 * - Attenuate normal with distance (e.g at max distance, the normal is (0, 0, 1)
163 * - Transform vertex pos into view space
164 * - compute fog coordinate
165 * At the end of the program we got :
166 * R1 = (eye - vertex).normed()
167 * R0 = Attenuated normal at vertex
168 * R4 = position of point with attenuated height
171 static const char *WaterVPStartCode
=
173 ADD R1, c[7], -v[0]; #r1 = eye - vertex \n\
174 DP3 R2, R1, R1; #r1 = eye - vertex, r2 = (eye - vertex)^2 \n\
175 MAX R2, R2, c[16]; # avoid imprecision around 0 \n\
176 RSQ R2, R2.x; #r1 = eye - vertex, r2 = 1/d(eye, vertex) \n\
178 MAD R3, c[6].xxxx, -R3, c[6].yyyy; \n\
179 MAX R3, c[5], R3; \n\
180 MUL R0, R3, v[8]; #attenuate normal with distance \n\
181 MUL R4.z, R3, v[0]; #attenuate height with distance \n\
182 MOV R4.xyw, v[0]; \n\
183 MOV R0.z, c[4].x; #set normal z to 1 \n\
184 DP3 R3.x, R0, R0; \n\
185 RSQ R3.x, R3.x; #normalize normal in R3 \n\
186 MUL R0, R0, R3.x; \n\
187 DP4 o[HPOS].x, c[0], R4; #transform vertex in view space \n\
188 DP4 o[HPOS].y, c[1], R4; \n\
189 DP4 o[HPOS].z, c[2], R4; \n\
190 DP4 o[HPOS].w, c[3], R4; \n\
191 MUL R1, R1, R2.x; #normalize r1, r1 = (eye - vertex).normed \n\
192 # DP3 R2.x, R1.xyww, R1.xyww; \n\
193 # MUL R1, R2.x, R1; \n\
194 DP4 o[FOGC].x, c[18], R4; #setup fog \n\
196 /** This part of vertex program compute 2 layers of bump (for use with texture shaders)
198 static const char *WaterVpBump2LayersCode
=
199 " MUL R3, v[0], c[10]; #compute bump 0 uv's \n\
200 ADD o[TEX0], R3, c[9]; \n\
201 MUL R3, v[0], c[12]; #compute bump 1 uv's \n\
202 ADD o[TEX1], R3, c[11]; \n\
203 DP3 R2.x, R1, R0; \n\
204 MUL R0, R0, R2.x; \n\
206 ADD R0, R2, -R1; #compute reflection vector \n\
207 MAD o[TEX2], R0, c[8], c[8]; \n\
209 /** Version with one bump map only (Texture shaders support chaining of offset textures, EMBM does not)
211 static const char *WaterVpBump1LayersCode
=
212 "MUL R3, v[0], c[12]; #compute bump 1 uv's \n\
213 ADD o[TEX0], R3, c[11]; \n\
214 DP3 R2.x, R1, R0; \n\
215 MUL R0, R0, R2.x; \n\
217 ADD R0, R2, -R1; #compute reflection vector \n\
218 MAD o[TEX1], R0, c[8], c[8]; \n\
220 /** Optional diffuse texture in stage 3
222 static const char *WaterVpDiffuseMapStage3Code
=
223 "DP4 o[TEX3].x, R4, c[13]; #compute uv for diffuse texture \n\
224 DP4 o[TEX3].y, R4, c[14]; \n\
226 /** Optional diffuse texture in stage 2
228 static const char *WaterVpDiffuseMapStage2Code
=
229 "DP4 o[TEX2].x, R4, c[13]; #compute uv for diffuse texture \n\
230 DP4 o[TEX2].y, R4, c[14]; \n\
233 /** Optional diffuse texture in stage 1
235 static const char *WaterVpDiffuseMapStage1Code
=
236 "DP4 o[TEX1].x, R4, c[13]; #compute uv for diffuse texture \n\
237 DP4 o[TEX1].y, R4, c[14]; \n\
240 // Envmap is setup in texture 0, no bump is used
241 static const char *WaterVpNoBumpCode
=
242 " DP3 R2.x, R1, R0; #project view vector on normal for symetry \n\
243 MUL R0, R0, R2.x; \n\
245 ADD R0, R2, -R1; #compute reflection vector \n\
246 MAD o[TEX0], R0, c[8], c[8]; \n\
247 DP4 o[FOGC].x, c[18], R4; #setup fog \n\
252 uint32
CWaterShape::_XScreenGridSize
= 20;
253 uint32
CWaterShape::_YScreenGridSize
= 20;
255 uint32
CWaterShape::_XGridBorder
= 4;
256 uint32
CWaterShape::_YGridBorder
= 4;
257 uint32
CWaterShape::_MaxGridSize
;
258 bool CWaterShape::_GridSizeTouched
= true;
259 /*NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramBump1;
260 NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramBump2;
261 NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramBump1Diffuse;
262 NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramBump2Diffuse;
263 NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramNoBump;
264 NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramNoBumpDiffuse;*/
265 // water with no waves
266 NLMISC::CSmartPtr
<CVertexProgramWaterVPNoWave
> CWaterShape::_VertexProgramNoWave
;
267 NLMISC::CSmartPtr
<CVertexProgramWaterVPNoWave
> CWaterShape::_VertexProgramNoWaveDiffuse
;
270 /** Build a vertex program for water depending on requirements
272 static CVertexProgram *BuildWaterVP(bool diffuseMap, bool bumpMap, bool use2BumpMap)
274 std::string vp = WaterVPStartCode;
275 if (bumpMap && use2BumpMap)
277 vp += WaterVpBump2LayersCode;
278 if (diffuseMap) vp += WaterVpDiffuseMapStage3Code;
283 vp += WaterVpBump2LayersCode;
284 if (diffuseMap) vp += WaterVpDiffuseMapStage2Code;
288 vp += WaterVpNoBumpCode;
289 if (diffuseMap) vp += WaterVpDiffuseMapStage1Code;
293 return new CVertexProgram(vp.c_str());
298 //============================================
302 CWaterShape::CWaterShape() : _WaterPoolID(0), _TransitionRatio(0.6f
), _WaveHeightFactor(3), _ComputeLightmap(false), _SplashEnabled(true)
304 /* ***********************************************
305 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
306 * It can be loaded/called through CAsyncFileManager for instance
307 * ***********************************************/
309 _DefaultPos
.setDefaultValue(NLMISC::CVector::Null
);
310 _DefaultScale
.setDefaultValue(NLMISC::CVector(1, 1, 1));
311 _DefaultRotQuat
.setDefaultValue(CQuat::Identity
);
313 for (sint k
= 0; k
< 2; ++k
)
315 _HeightMapScale
[k
].set(1, 1);
316 _HeightMapSpeed
[k
].set(0, 0);
317 _HeightMapTouch
[k
] = true;
318 _UsesSceneWaterEnvMap
[k
] = false;
320 _ColorMapMatColumn0
.set(1, 0);
321 _ColorMapMatColumn1
.set(0, 1);
322 _ColorMapMatPos
.set(0, 0);
323 _EnvMapMeanColorComputed
= false;
326 //============================================
327 CRGBA
CWaterShape::computeEnvMapMeanColor()
330 // just used for water rendering in multiple parts with parallel projection
331 // -> drawn as an uniform polygon with envmap mean coloe
332 if (!_EnvMapMeanColorComputed
)
334 _EnvMapMeanColor
= NLMISC::CRGBA(0, 0, 255);
337 _EnvMap
[0]->generate();
338 _EnvMap
[0]->convertToType(CBitmap::RGBA
);
343 uint numPixs
= _EnvMap
[0]->getHeight() * _EnvMap
[0]->getWidth();
344 const CRGBA
*src
= (const CRGBA
*) (&_EnvMap
[0]->getPixels(0)[0]);
345 const CRGBA
*last
= src
+ numPixs
;
356 _EnvMapMeanColor
= NLMISC::CRGBA((uint8
) (r
/ numPixs
),
357 (uint8
) (g
/ numPixs
),
358 (uint8
) (b
/ numPixs
),
359 (uint8
) (a
/ numPixs
));
361 _EnvMap
[0]->release();
363 _EnvMapMeanColorComputed
= true;
365 return _EnvMapMeanColor
;
368 //============================================
369 CWaterShape::~CWaterShape()
371 /* ***********************************************
372 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
373 * It can be loaded/called through CAsyncFileManager for instance
374 * ***********************************************/
377 (_EnvMap
[0] && dynamic_cast<CTextureBlend
*>((ITexture
*) _EnvMap
[0]))
378 || (_EnvMap
[1] && dynamic_cast<CTextureBlend
*>((ITexture
*) _EnvMap
[1]))
381 GetWaterPoolManager().unRegisterWaterShape(this);
385 //============================================
386 void CWaterShape::initVertexProgram()
388 static bool created
= false;
392 /*_VertexProgramBump1 = BuildWaterVP(false, true, false);
393 _VertexProgramBump2 = BuildWaterVP(false, true, true);
395 _VertexProgramBump1Diffuse = BuildWaterVP(true, true, false);
396 _VertexProgramBump2Diffuse = BuildWaterVP(true, true, true);
398 _VertexProgramNoBump = BuildWaterVP(false, false, false);
399 _VertexProgramNoBumpDiffuse = BuildWaterVP(true, false, false);*/
401 _VertexProgramNoWave
= new CVertexProgramWaterVPNoWave(false);
402 _VertexProgramNoWaveDiffuse
= new CVertexProgramWaterVPNoWave(true);
407 //============================================
408 CTransformShape
*CWaterShape::createInstance(CScene
&scene
)
410 CWaterModel
*wm
= NLMISC::safe_cast
<CWaterModel
*>(scene
.createModel(WaterModelClassId
) );
412 // set default pos & scale
413 wm
->ITransformable::setPos( _DefaultPos
.getDefaultValue() );
414 wm
->ITransformable::setScale( _DefaultScale
.getDefaultValue() );
415 wm
->ITransformable::setRotQuat( _DefaultRotQuat
.getDefaultValue() );
418 if (scene
.getWaterCallback())
420 CWaterShape
*ws
= NLMISC::safe_cast
<CWaterShape
*>((IShape
*) wm
->Shape
);
421 scene
.getWaterCallback()->waterSurfaceAdded(getShape(), wm
->getMatrix(), ws
->isSplashEnabled(), ws
->getUseSceneWaterEnvMap(0) || ws
->getUseSceneWaterEnvMap(1));
426 //============================================
427 float CWaterShape::getNumTriangles (float distance
)
433 //============================================
434 void CWaterShape::flushTextures (IDriver
&driver
, uint selectedTexture
)
436 // Test if bump maps are supported by driver before to flush them.
437 // TEMP : can't flush texture for water, because the upload format depends on the shader
438 // Only the driver can determine it.
439 // BumpMaps may be uploaded with unsigned or signed format
443 (driver.supportTextureShaders() && driver.supportTextureAddrMode(CMaterial::OffsetTexture))
444 || driver.supportEMBM()
447 for (uint k = 0; k < 2; ++k)
449 if (_BumpMap[k] != NULL)
450 driver.setupTexture(*_BumpMap[k]);
451 if (_EnvMap[k] != NULL)
452 driver.setupTexture(*_EnvMap[k]);
455 if (_ColorMap != NULL)
456 driver.setupTexture(*_ColorMap);
460 //============================================
461 void CWaterShape::setScreenGridSize(uint32 x
, uint32 y
)
463 nlassert(x
> 0 && y
> 0);
464 _XScreenGridSize
= x
;
465 _YScreenGridSize
= y
;
466 _GridSizeTouched
= true;
469 //============================================
470 void CWaterShape::setGridBorderSize(uint32 x
, uint32 y
)
474 _GridSizeTouched
= true;
477 //============================================
478 void CWaterShape::setShape(const NLMISC::CPolygon2D
&poly
)
480 nlassert(poly
.Vertices
.size() != 0); // empty poly not allowed
485 //============================================
486 void CWaterShape::computeBBox()
488 nlassert(_Poly
.Vertices
.size() != 0);
489 NLMISC::CVector2f min
, max
;
490 min
= max
= _Poly
.Vertices
[0];
491 for (uint k
= 1; k
< _Poly
.Vertices
.size(); ++k
)
493 min
.minof(min
, _Poly
.Vertices
[k
]);
494 max
.maxof(max
, _Poly
.Vertices
[k
]);
496 _BBox
.setMinMax(CVector(min
.x
, min
.y
, 0), CVector(max
.x
, max
.y
, 0));
497 /* nlinfo("center x = %f, y = %f, z = %f", _BBox.getCenter().x, _BBox.getCenter().y, _BBox.getCenter().z);
498 nlinfo("halsize x = %f, y = %f, z = %f", _BBox.getHalfSize().x, _BBox.getHalfSize().y, _BBox.getHalfSize().z); */
501 //============================================
502 void CWaterShape::setHeightMap(uint k
, ITexture
*hm
)
507 _BumpMap
[k
] = new CTextureBump
;
509 static_cast<CTextureBump
*>( (ITexture
*) _BumpMap
[k
])->forceNormalize(true);
510 static_cast<CTextureBump
*>( (ITexture
*) _BumpMap
[k
])->setHeightMap(hm
);
511 _HeightMapTouch
[k
] = true; // must recompute normalization factor
514 //============================================
515 ITexture
*CWaterShape::getHeightMap(uint k
)
518 return ((CTextureBump
*) (ITexture
*) _BumpMap
[k
] )->getHeightMap();
521 //============================================
522 const ITexture
*CWaterShape::getHeightMap(uint k
) const
525 return ((CTextureBump
*) (ITexture
*) _BumpMap
[k
] )->getHeightMap();
528 //============================================
529 void CWaterShape::serial(NLMISC::IStream
&f
)
531 /* ***********************************************
532 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
533 * It can be loaded/called through CAsyncFileManager for instance
534 * ***********************************************/
536 // version 4 : added scene water env map
537 // version 3 : added '_Splashenabled' flag
538 sint ver
= f
.serialVersion(4);
541 // serial heightMap identifier
542 f
.serial(_WaterPoolID
);
544 ITexture
*map
= NULL
;
547 f
.serialPolyPtr(map
); _EnvMap
[0] = map
;
548 f
.serialPolyPtr(map
); _EnvMap
[1] = map
;
549 f
.serialPolyPtr(map
); _BumpMap
[0] = map
;
550 f
.serialPolyPtr(map
); _BumpMap
[1] = map
;
551 f
.serialPolyPtr(map
); _ColorMap
= map
;
556 map
= _EnvMap
[0]; f
.serialPolyPtr(map
);
557 map
= _EnvMap
[1]; f
.serialPolyPtr(map
);
558 map
= _BumpMap
[0]; f
.serialPolyPtr(map
);
559 map
= _BumpMap
[1]; f
.serialPolyPtr(map
);
560 map
= _ColorMap
; f
.serialPolyPtr(map
);
563 f
.serial(_HeightMapScale
[0], _HeightMapScale
[1],
564 _HeightMapSpeed
[0], _HeightMapSpeed
[1]);
566 f
.serial(_ColorMapMatColumn0
, _ColorMapMatColumn1
, _ColorMapMatPos
);
568 // serial default tracks
569 f
.serial(_DefaultPos
);
570 f
.serial(_DefaultScale
);
571 f
.serial(_DefaultRotQuat
);
573 f
.serial(_TransitionRatio
);
575 f
.serial(_WaveHeightFactor
);
578 f
.serial (_ComputeLightmap
);
584 f
.serial(_SplashEnabled
);
588 f
.serial(_UsesSceneWaterEnvMap
[0], _UsesSceneWaterEnvMap
[1]);
595 _UsesSceneWaterEnvMap[0] = true;
596 _UsesSceneWaterEnvMap[1] = true;
601 //============================================
602 bool CWaterShape::clip(const std::vector
<CPlane
> &pyramid
, const CMatrix
&worldMatrix
)
604 for (uint k
= 0; k
< pyramid
.size(); ++k
)
606 if (! _BBox
.clipBack(pyramid
[k
] * worldMatrix
)) return false;
611 //============================================
612 void CWaterShape::setHeightMapScale(uint k
, const NLMISC::CVector2f
&scale
)
615 _HeightMapScale
[k
] = scale
;
618 //============================================
619 NLMISC::CVector2f
CWaterShape::getHeightMapScale(uint k
) const
622 return _HeightMapScale
[k
];
625 //============================================
626 void CWaterShape::setHeightMapSpeed(uint k
, const NLMISC::CVector2f
&speed
)
629 _HeightMapSpeed
[k
] = speed
;
632 //============================================
633 NLMISC::CVector2f
CWaterShape::getHeightMapSpeed(uint k
) const
636 return _HeightMapSpeed
[k
];
639 //============================================
640 void CWaterShape::setColorMapMat(const NLMISC::CVector2f
&column0
, const NLMISC::CVector2f
&column1
, const NLMISC::CVector2f
&pos
)
642 _ColorMapMatColumn0
= column0
;
643 _ColorMapMatColumn1
= column1
;
644 _ColorMapMatPos
= pos
;
647 //============================================
648 void CWaterShape::getColorMapMat(NLMISC::CVector2f
&column0
, NLMISC::CVector2f
&column1
, NLMISC::CVector2f
&pos
)
650 column0
= _ColorMapMatColumn0
;
651 column1
= _ColorMapMatColumn1
;
652 pos
= _ColorMapMatPos
;
655 //============================================
656 void CWaterShape::envMapUpdate()
658 // if the color map is a blend texture, we MUST be registered to the water pool manager, so that, the
659 // setBlend message will be routed to this texture.
661 (_EnvMap
[0] && dynamic_cast<CTextureBlend
*>((ITexture
*) _EnvMap
[0]))
662 || (_EnvMap
[1] && dynamic_cast<CTextureBlend
*>((ITexture
*) _EnvMap
[1]))
665 if (!GetWaterPoolManager().isWaterShapeObserver(this))
667 GetWaterPoolManager().registerWaterShape(this);
672 if (GetWaterPoolManager().isWaterShapeObserver(this))
674 GetWaterPoolManager().unRegisterWaterShape(this);
679 //============================================
680 void CWaterShape::setColorMap(ITexture
*map
)
686 //============================================
687 void CWaterShape::setEnvMap(uint index
, ITexture
*envMap
)
690 _EnvMap
[index
] = envMap
;
693 //============================================
694 void CWaterShape::getShapeInWorldSpace(NLMISC::CPolygon
&poly
) const
696 poly
.Vertices
.resize(_Poly
.Vertices
.size());
697 // compute the matrix of the object in world space, by using the default tracks
698 NLMISC::CMatrix objMat
;
700 objMat
.translate(_DefaultPos
.getDefaultValue());
701 objMat
.rotate(_DefaultRotQuat
.getDefaultValue());
702 objMat
.scale(_DefaultScale
.getDefaultValue());
704 for (uint k
= 0; k
< _Poly
.Vertices
.size(); ++k
)
706 poly
.Vertices
[k
] = objMat
* NLMISC::CVector(_Poly
.Vertices
[k
].x
, _Poly
.Vertices
[k
].y
, 0);
711 //============================================
712 void CWaterShape::getShapeInWorldSpace(NLMISC::CPolygon
&poly
, const NLMISC::CMatrix
&objMat
) const
714 poly
.Vertices
.resize(_Poly
.Vertices
.size());
715 for (uint k
= 0; k
< _Poly
.Vertices
.size(); ++k
)
717 poly
.Vertices
[k
] = objMat
* NLMISC::CVector(_Poly
.Vertices
[k
].x
, _Poly
.Vertices
[k
].y
, 0);
722 //============================================
723 void CWaterShape::updateHeightMapNormalizationFactors()
725 for (uint k
= 0; k
< 2; ++k
)
727 if (_HeightMapTouch
[k
])
729 if (_BumpMap
[k
] != NULL
)
731 _BumpMap
[k
]->generate();
732 _HeightMapNormalizationFactor
[k
] = NLMISC::safe_cast
<CTextureBump
*>((ITexture
*)_BumpMap
[k
])->getNormalizationFactor();
733 if (_BumpMap
[k
]->getReleasable())
735 _BumpMap
[k
]->release();
740 _HeightMapNormalizationFactor
[k
] = 1.f
;
742 _HeightMapTouch
[k
] = false;
749 //======================================================//
751 //======================================================//
754 //============================================
755 CWaveMakerShape::CWaveMakerShape() : _Period(1),
763 //============================================
764 CWaveMakerShape::~CWaveMakerShape()
768 //============================================
769 void CWaveMakerShape::serial(NLMISC::IStream
&f
)
772 f
.serial(_Period
, _Radius
, _Intensity
, _PoolID
, _ImpulsionMode
);
775 //============================================
776 CTransformShape
*CWaveMakerShape::createInstance(CScene
&scene
)
778 CWaveMakerModel
*wmm
= NLMISC::safe_cast
<CWaveMakerModel
*>(scene
.createModel(WaveMakerModelClassId
) );
780 // set default pos & scale
781 wmm
->ITransformable::setPos( _DefaultPos
.getDefaultValue() );
785 //============================================
786 bool CWaveMakerShape::clip(const std::vector
<CPlane
> &pyramid
, const CMatrix
&worldMatrix
)
788 // we just test if not too far
789 const CWaterHeightMap
&whm
= GetWaterPoolManager().getPoolByID(_PoolID
);
790 const float maxDist
= 0.5f
* whm
.getUnitSize() * whm
.getSize();
791 const NLMISC::CVector pos
= worldMatrix
.getPos();
792 for (std::vector
<NLMISC::CPlane
>::const_iterator it
= pyramid
.begin(); it
!= pyramid
.end(); ++it
)
794 if ((*it
) * pos
> maxDist
) return false;
800 //============================================
801 void CWaveMakerShape::getAABBox(NLMISC::CAABBox
&bbox
) const
804 bbox
.setCenter(NLMISC::CVector::Null
);
805 bbox
.setHalfSize(NLMISC::CVector::Null
);