00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "nel/3d/frustum.h"
00029 #include "nel/misc/matrix.h"
00030 #include <math.h>
00031
00032
00033 using namespace NLMISC;
00034
00035 namespace NL3D
00036 {
00037
00038
00039 void CFrustum::init(float left, float right, float bottom, float top, float znear, float zfar, bool perspective)
00040 {
00041 Left= left;
00042 Right= right;
00043 Bottom= bottom;
00044 Top= top;
00045 Near= znear;
00046 Far= zfar;
00047 Perspective= perspective;
00048 }
00049
00050 void CFrustum::init(float width, float height, float znear, float zfar, bool perspective)
00051 {
00052 init(-width/2, width/2, -height/2, height/2, znear, zfar, perspective);
00053 }
00054 void CFrustum::initPerspective(float fov, float aspectRatio, float znear, float zfar)
00055 {
00056 float w,h;
00057 w= 2*znear*(float)tan(fov/2);
00058 h= w/aspectRatio;
00059 init(w,h,znear,zfar,true);
00060 }
00061 void CFrustum::getValues(float &left, float &right, float &bottom, float &top, float &znear, float &zfar) const
00062 {
00063 left= Left;
00064 right= Right;
00065 bottom= Bottom;
00066 top= Top;
00067 znear= Near;
00068 zfar= Far;
00069 }
00070
00071
00072
00073 CVector CFrustum::project(const CVector &vec) const
00074 {
00075 CVector ret;
00076 float decalX, decalY;
00077 float w, h;
00078 float OOw, OOh;
00079
00080
00081 CVector pt;
00082 pt.x= vec.x;
00083 pt.y= vec.z;
00084 pt.z= -vec.y;
00085
00086 decalX= (Right+Left);
00087 decalY= (Top+Bottom);
00088 w= Right-Left;
00089 h= Top-Bottom;
00090 OOw= 1.0f/w;
00091 OOh= 1.0f/h;
00092
00093
00094 if(Perspective)
00095 {
00096 ret.x= (2*Near*pt.x + decalX*pt.z)*OOw;
00097 ret.x/= -pt.z;
00098 ret.y= (2*Near*pt.y + decalY*pt.z)*OOh;
00099 ret.y/= -pt.z;
00100 }
00101 else
00102 {
00103 ret.x= (2*pt.x-decalX)*OOw;
00104 ret.y= (2*pt.y-decalY)*OOh;
00105 }
00106
00107
00108
00109 ret.x= 0.5f*(ret.x+1);
00110 ret.y= 0.5f*(ret.y+1);
00111 ret.z= 0;
00112
00113 return ret;
00114 }
00115
00116
00117
00118
00119 CVector CFrustum::unProject(const CVector &vec) const
00120 {
00121 CVector ret;
00122 float decalX, decalY;
00123 float w, h;
00124 float OOw, OOh;
00125
00126 decalX= (Right+Left);
00127 decalY= (Top+Bottom);
00128 w= Right-Left;
00129 h= Top-Bottom;
00130 OOw= 1.0f/w;
00131 OOh= 1.0f/h;
00132
00133
00134 CVector pt;
00135 pt.x= vec.x;
00136 pt.y= vec.y;
00137 pt.z= vec.z;
00138
00139
00140 pt.x= 2*(pt.x-0.5f);
00141 pt.y= 2*(pt.y-0.5f);
00142
00143
00144
00145
00146 pt.z= 1-pt.z;
00147
00148 pt.z= 1/Far+(1/Near-1/Far)*pt.z;
00149
00150 pt.z= 1/pt.z;
00151
00152
00153
00154
00155 if(Perspective)
00156 {
00157
00158 float Wh;
00159 float Zin;
00160 Wh= pt.z;
00161 Zin= -pt.z;
00162
00163
00164 pt.x= pt.x*Wh;
00165 pt.y= pt.y*Wh;
00166 ret.x= (pt.x*w-decalX*Zin)/(2*Near);
00167 ret.y= (pt.y*w-decalY*Zin)/(2*Near);
00168 ret.z= Zin;
00169 }
00170 else
00171 {
00172
00173 nlstop;
00174
00175
00176
00177 }
00178
00179
00180 pt =ret;
00181 ret.x= pt.x;
00182 ret.y= -pt.z;
00183 ret.z= pt.y;
00184
00185 return ret;
00186 }
00187
00188
00189
00190 }