1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "nel/3d/heat_haze.h"
21 #include "nel/3d/scene.h"
22 #include "nel/3d/deform_2d.h"
23 #include "nel/misc/vector_2f.h"
33 struct CSinWave
: public CDeform2d::IPerturbUV
35 virtual ~CSinWave() {}
37 virtual void perturbUV(float x
, float y
, float &du
, float &dv
) const
39 du
= 0.01f
* sinf(25.f
* y
+ Phase
);
40 dv
= 0.05f
* cosf(19.3f
* x
+ Phase
);
47 void CHeatHaze::performHeatHaze(uint width
, uint height
, CScene
&s
, IDriver
*drv
)
49 NLMISC::CMatrix m
= s
.getCam()->getMatrix();
50 NLMISC::CMatrix im
= m
.inverted();
52 // compute the shape of the horizon
54 // first we compute the direction of the world up vector in the viewer basis.
55 NLMISC::CVector up
= im
* NLMISC::CVector::K
;
56 // project onto the I and K vectors
57 float upNorm
= (up
.x
* up
.x
+ up
.z
* up
.z
);
59 const float threshold
= 10E-4f
;
61 if (upNorm
< threshold
) return; // the viewer is looking above or below himlself
63 // Compute the right vector. This is done by intersecting the horizon plane with a near plane.
64 // to do this, we transform the horizon plane into the view basis.This may be optimized, but is not critical.
67 h
.make(NLMISC::CVector::K
, NLMISC::CVector::Null
);
69 h
= h
* m
; // note : this multiply by the transposition of m
71 // intersect with near plane : we got y = 0, which gives us, as a right vector :
72 // if c is not 0, we got : x = 1 and z = (-a - d) / c as a working solution.
73 // Else we got x = (- d - c )/ a and z = 1
76 NLMISC::CVector right
;
78 if (fabsf(h
.c
) > threshold
)
80 right
.set(1, 0, (h
.a
+ h
.d
) / - h
.c
);
84 right
.set( (h
.d
+ h
.c
) / h
.a
, 0, 1);
89 // now, find a point on screen that lay on the horizon line
90 static std::vector
<NLMISC::CVector2f
> poly(4);
94 const sint xCenter
= width
>> 1;
95 const sint yCenter
= height
>> 1;
97 const float horizonHeight
= (float) (height
>> 2);
98 const float horizonWidth
= (float) (width
>> 2);
100 NLMISC::CVector tmp
;
102 tmp
= horizonWidth
* right
+ horizonHeight
* up
;
103 poly
[0] = NLMISC::CVector2f(xCenter
+ tmp
.x
, yCenter
+ tmp
.z
) ;
104 tmp
= horizonWidth
* right
- horizonHeight
* up
;
105 poly
[1] = NLMISC::CVector2f(xCenter
+ tmp
.x
, yCenter
+ tmp
.z
) ;
106 tmp
= - horizonWidth
* right
- horizonHeight
* up
;
107 poly
[2] = NLMISC::CVector2f(xCenter
+ tmp
.x
, yCenter
+ tmp
.z
);
108 tmp
= - horizonWidth
* right
+ horizonHeight
* up
;
109 poly
[3] = NLMISC::CVector2f(xCenter
+ tmp
.x
, yCenter
+ tmp
.z
);
112 CDeform2d::doDeform(poly
, drv
, &_SinWave
);