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/>.
19 #include "nel/3d/frustum.h"
20 #include "nel/misc/matrix.h"
24 using namespace NLMISC
;
34 void CFrustum::init(float left
, float right
, float bottom
, float top
, float znear
, float zfar
, bool perspective
)
42 Perspective
= perspective
;
45 void CFrustum::init(float width
, float height
, float znear
, float zfar
, bool perspective
)
47 init(-width
/2, width
/2, -height
/2, height
/2, znear
, zfar
, perspective
);
49 void CFrustum::initPerspective(float fov
, float aspectRatio
, float znear
, float zfar
)
52 w
= 2*znear
*(float)tan(fov
/2);
53 h
= aspectRatio
!= 0.f
? w
/aspectRatio
: 0.f
;
54 init(w
,h
,znear
,zfar
,true);
56 void CFrustum::getValues(float &left
, float &right
, float &bottom
, float &top
, float &znear
, float &zfar
) const
67 // ***************************************************************************
68 CVector
CFrustum::project(const CVector
&vec
) const
75 // Fast transform to openGL like axis.
91 ret
.x
= (2*Near
*pt
.x
+ decalX
*pt
.z
)*OOw
;
93 ret
.y
= (2*Near
*pt
.y
+ decalY
*pt
.z
)*OOh
;
98 ret
.x
= (2*pt
.x
-decalX
)*OOw
;
99 ret
.y
= (2*pt
.y
-decalY
)*OOh
;
104 ret
.x
= 0.5f
*(ret
.x
+1);
105 ret
.y
= 0.5f
*(ret
.y
+1);
112 // ***************************************************************************
113 CVector
CFrustum::projectZ(const CVector
&vec
) const
116 float decalX
, decalY
;
118 float OOw
= 1.0f
, OOh
= 1.0f
;
120 // Fast transform to openGL like axis.
126 decalX
= (Right
+Left
);
127 decalY
= (Top
+Bottom
);
133 // project to -1..+1.
136 ret
.x
= (2*Near
*pt
.x
+ decalX
*pt
.z
)*OOw
;
138 ret
.y
= (2*Near
*pt
.y
+ decalY
*pt
.z
)*OOh
;
143 ret
.x
= (2*pt
.x
-decalX
)*OOw
;
144 ret
.y
= (2*pt
.y
-decalY
)*OOh
;
149 ret
.x
= 0.5f
*(ret
.x
+1);
150 ret
.y
= 0.5f
*(ret
.y
+1);
157 // ***************************************************************************
158 CVector
CFrustum::unProject(const CVector
&vec
) const
161 float decalX
, decalY
;
164 decalX
= (Right
+Left
);
165 decalY
= (Top
+Bottom
);
169 // vec is a vector in a left hand axis.
179 // Map Z to Near..Far.
180 // Z IN is 1/Z, and is in 0..1.
183 // Map ret.z to 1/Far..1/Near.
184 pt
.z
= 1/Far
+(1/Near
-1/Far
)*pt
.z
;
185 // Inverse, so ret.z E Near..Far.
187 // Actually, pt.z==w, homogenous coordinate.
193 // w of homogenous coordinate.
199 // unproject. (Projection is: x'= x/w. y'= y/w).
202 ret
.x
= (pt
.x
*w
-decalX
*Zin
)/(2*Near
);
203 ret
.y
= (pt
.y
*h
-decalY
*Zin
)/(2*Near
);
210 /*ret.x= (pt.x*w+decalX)/2;
211 ret.y= (pt.y*h+decalY)/2;
215 // Fast transform from openGL like axis.
225 // ***************************************************************************
226 CVector
CFrustum::unProjectZ(const CVector
&vec
) const
229 float decalX
, decalY
;
232 decalX
= (Right
+Left
);
233 decalY
= (Top
+Bottom
);
237 // vec is a vector in a left hand axis.
250 // w of homogenous coordinate.
256 // unproject. (Projection is: x'= x/w. y'= y/w).
259 ret
.x
= (pt
.x
*w
-decalX
*Zin
)/(2*Near
);
260 ret
.y
= (pt
.y
*h
-decalY
*Zin
)/(2*Near
);
267 /*ret.x= (pt.x*w+decalX)/2;
268 ret.y= (pt.y*h+decalY)/2;
270 // Yoyo: crash avoid for lem
274 // Fast transform from openGL like axis.
283 // ***************************************************************************
284 float CFrustum::getAspectRatio() const