00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <math.h>
00042 #include <OSGConfig.h>
00043
00044 #include <OSGBaseFunctions.h>
00045 #include <OSGBaseTypes.h>
00046 #include <OSGVector.h>
00047 #include <OSGMatrix.h>
00048 #include <OSGLog.h>
00049 #include <OSGMatrixUtility.h>
00050
00051 OSG_BEGIN_NAMESPACE
00052
00053
00054 OSG_BASE_DLLMAPPING bool MatrixOrthogonal(Matrix &result,
00055 Real32 rLeft,
00056 Real32 rRight,
00057 Real32 rBottom,
00058 Real32 rTop,
00059 Real32 rNear,
00060 Real32 rFar)
00061 {
00062 result.setValueTransposed(
00063
00064 2.f / (rRight - rLeft),
00065 0.f,
00066 0.f,
00067 0.f,
00068
00069 0.f,
00070 2.f / (rTop - rBottom),
00071 0.f,
00072 0.f,
00073
00074 0.f,
00075 0.f,
00076 -2.f / (rFar - rNear),
00077 0.f,
00078
00079 -(rRight + rLeft ) / (rRight - rLeft ),
00080 -(rTop + rBottom) / (rTop - rBottom),
00081 -(rFar + rNear ) / (rFar - rNear ),
00082 1.);
00083
00084 return false;
00085 }
00086
00087
00088 OSG_BASE_DLLMAPPING bool MatrixFrustum(Matrix &result,
00089 Real32 rLeft,
00090 Real32 rRight,
00091 Real32 rBottom,
00092 Real32 rTop,
00093 Real32 rNear,
00094 Real32 rFar)
00095 {
00096 Real32 dz = rFar - rNear;
00097 Real32 dx = rRight - rLeft;
00098 Real32 dy = rTop - rBottom;
00099 Real32 n2 = 2.f * rNear;
00100
00101 result.setValueTransposed(
00102 n2 / dx,
00103 0.f,
00104 0.f,
00105 0.f,
00106
00107 0.f,
00108 n2 / dy,
00109 0.f,
00110 0.f,
00111
00112 (rRight + rLeft ) / dx,
00113 (rTop + rBottom) / dy,
00114 -(rFar + rNear ) / dz,
00115 -1.f,
00116
00117 0.f,
00118 0.f,
00119 -(rFar * n2) / dz,
00120 0.f);
00121
00122 return false;
00123 }
00124
00125
00126 OSG_BASE_DLLMAPPING bool MatrixPerspective(Matrix &result,
00127 Real32 rFovy,
00128 Real32 rAspect,
00129 Real32 rNear,
00130 Real32 rFar)
00131 {
00132 Real32 ct = osgtan(rFovy);
00133 bool error = false;
00134
00135 if(rNear > rFar)
00136 {
00137 SWARNING << "MatrixPerspective: near " << rNear << " > far " << rFar
00138 << "!\n" << std::endl;
00139 error = true;
00140 }
00141
00142 if(rFovy <= Eps)
00143 {
00144 SWARNING << "MatrixPerspective: fovy " << rFovy << " very small!\n"
00145 << std::endl;
00146 error = true;
00147 }
00148
00149 if(osgabs(rNear - rFar) < Eps)
00150 {
00151 SWARNING << "MatrixPerspective: near " << rNear << " ~= far " << rFar
00152 << "!\n" << std::endl;
00153 error = true;
00154 }
00155
00156 if(rAspect < Eps)
00157 {
00158 SWARNING << "MatrixPerspective: aspect ratio " << rAspect
00159 << " very small!\n" << std::endl;
00160 error = true;
00161 }
00162
00163 if(error)
00164 {
00165 result.setIdentity();
00166 return true;
00167 }
00168
00169 MatrixFrustum( result,
00170 -rNear * ct * rAspect,
00171 rNear * ct * rAspect,
00172 -rNear * ct,
00173 rNear * ct,
00174 rNear,
00175 rFar );
00176
00177 return false;
00178 }
00179
00180
00181 OSG_BASE_DLLMAPPING bool MatrixStereoPerspective(Matrix &projection,
00182 Matrix &projtrans,
00183 Real32 rFovy,
00184 Real32 rAspect,
00185 Real32 rNear,
00186 Real32 rFar,
00187 Real32 rZeroparallax,
00188 Real32 rEyedistance,
00189 Real32 rWhicheye,
00190 Real32 rOverlap)
00191 {
00192 Real32 rLeft;
00193 Real32 rRight;
00194 Real32 rTop;
00195 Real32 rBottom;
00196
00197 Real32 gltan;
00198 Real32 rEye = -rEyedistance * (rWhicheye - .5f);
00199 Real32 d;
00200
00201 bool error = false;
00202
00203 if(rNear > rFar)
00204 {
00205 SWARNING << "MatrixPerspective: near " << rNear << " > far " << rFar
00206 << "!\n" << std::endl;
00207 error = true;
00208 }
00209
00210 if(rFovy <= Eps)
00211 {
00212 SWARNING << "MatrixPerspective: fovy " << rFovy << " very small!\n"
00213 << std::endl;
00214 error = true;
00215 }
00216
00217 if(osgabs(rNear - rFar) < Eps)
00218 {
00219 SWARNING << "MatrixPerspective: near " << rNear << " ~= far " << rFar
00220 << "!\n" << std::endl;
00221 error = true;
00222 }
00223
00224 if(rAspect < Eps)
00225 {
00226 SWARNING << "MatrixPerspective: aspect ratio " << rAspect
00227 << " very small!\n" << std::endl;
00228 error = true;
00229 }
00230
00231 if(rZeroparallax < Eps)
00232 {
00233 SWARNING << "MatrixPerspective: zero parallax " << rZeroparallax
00234 << " very small, setting to 1!\n" << std::endl;
00235
00236 rZeroparallax = 1;
00237 error = true;
00238 }
00239
00240 if(error)
00241 {
00242 projection.setIdentity();
00243 projtrans.setIdentity();
00244 return true;
00245 }
00246
00247
00248 rTop = osgtan(rFovy / 2.0f) * rNear;
00249 rBottom = -rTop;
00250
00251
00252 gltan = osgtan(rFovy / 2.0f) * rAspect;
00253
00254 rLeft = (-gltan + rEye / rZeroparallax) * rNear;
00255 rRight = ( gltan + rEye / rZeroparallax) * rNear;
00256
00257 d = rRight - rLeft;
00258
00259 rLeft += d * (1 - rOverlap) * (rWhicheye - .5f);
00260 rRight += d * (1 - rOverlap) * (rWhicheye - .5f);
00261
00262 MatrixFrustum(projection, rLeft, rRight, rBottom, rTop, rNear, rFar);
00263
00264 projtrans.setIdentity();
00265
00266 projtrans[3][0] = rEye;
00267
00268 return false;
00269 }
00270
00276 OSG_BASE_DLLMAPPING bool MatrixLookAt(Matrix &result,
00277 Real32 fromx,
00278 Real32 fromy,
00279 Real32 fromz,
00280 Real32 atx,
00281 Real32 aty,
00282 Real32 atz,
00283 Real32 upx,
00284 Real32 upy,
00285 Real32 upz)
00286 {
00287 Vec3f view;
00288 Vec3f right;
00289 Vec3f newup;
00290 Vec3f up;
00291
00292 view.setValues(fromx - atx , fromy - aty, fromz - atz);
00293 view.normalize();
00294
00295 up.setValues(upx, upy, upz);
00296
00297 right = up.cross(view);
00298
00299 if(right.dot(right) < Eps)
00300 {
00301 return true;
00302 }
00303
00304 right.normalize();
00305
00306 newup = view.cross(right);
00307
00308 result.setIdentity ();
00309 result.setTranslate(fromx, fromy, fromz);
00310
00311 Matrix tmpm;
00312
00313 tmpm.setValue(right, newup, view);
00314
00315 result.mult(tmpm);
00316
00317 return false;
00318 }
00319
00320
00326 OSG_BASE_DLLMAPPING bool MatrixLookAt(Matrix &result,
00327 Pnt3f from,
00328 Pnt3f at,
00329 Vec3f up )
00330 {
00331 Vec3f view;
00332 Vec3f right;
00333 Vec3f newup;
00334 Vec3f tmp;
00335
00336 view = from - at;
00337 view.normalize();
00338
00339 right = up.cross(view);
00340
00341 if(right.dot(right) < Eps)
00342 {
00343 return true;
00344 }
00345
00346 right.normalize();
00347
00348 newup = view.cross(right);
00349
00350 result.setIdentity ();
00351 result.setTranslate(from[0], from[1], from[2]);
00352
00353 Matrix tmpm;
00354
00355 tmpm.setValue(right, newup, view);
00356
00357 result.mult(tmpm);
00358
00359 return false;
00360 }
00361
00362
00363 OSG_BASE_DLLMAPPING bool MatrixProjection(Matrix &OSG_CHECK_ARG(result),
00364 Real32 OSG_CHECK_ARG(rLeft),
00365 Real32 OSG_CHECK_ARG(rRight),
00366 Real32 OSG_CHECK_ARG(rBottom),
00367 Real32 OSG_CHECK_ARG(rTop),
00368 Real32 OSG_CHECK_ARG(rNear),
00369 Real32 OSG_CHECK_ARG(rFar) )
00370 {
00371 SFATAL << "MatrixProjection: Not yet implemented!" << std::endl;
00372 abort();
00373
00374 return false;
00375 }
00376
00377 OSG_END_NAMESPACE
00378
00379
00380
00381