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
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #define ACG_GLMATRIX_C
00053
00054
00055
00056
00057
00058 #include "GLMatrixT.hh"
00059 #include <math.h>
00060
00061
00062
00063
00064
00065 namespace ACG {
00066
00067
00068
00069
00070
00071 template<typename Scalar>
00072 void
00073 GLMatrixT<Scalar>::
00074 scale( Scalar _x, Scalar _y, Scalar _z,
00075 MultiplyFrom _mult_from )
00076 {
00077 GLMatrixT<Scalar> m;
00078 m.identity();
00079
00080 m(0,0) = _x;
00081 m(1,1) = _y;
00082 m(2,2) = _z;
00083
00084 if (_mult_from == MULT_FROM_RIGHT) *this *= m;
00085 else leftMult(m);
00086 }
00087
00088
00089
00090
00091
00092 template<typename Scalar>
00093 void
00094 GLMatrixT<Scalar>::
00095 translate( Scalar _x, Scalar _y, Scalar _z,
00096 MultiplyFrom _mult_from )
00097 {
00098 GLMatrixT<Scalar> m;
00099 m.identity();
00100
00101 m(0,3) = _x;
00102 m(1,3) = _y;
00103 m(2,3) = _z;
00104
00105 if (_mult_from == MULT_FROM_RIGHT) *this *= m;
00106 else leftMult(m);
00107 }
00108
00109
00110
00111
00112
00113 template<typename Scalar>
00114 void
00115 GLMatrixT<Scalar>::
00116 rotateXYZ( Axis _axis, Scalar _angle,
00117 MultiplyFrom _mult_from )
00118 {
00119 GLMatrixT<Scalar> m;
00120 m.identity();
00121
00122 Scalar ca = cos(_angle * (M_PI/180.0));
00123 Scalar sa = sin(_angle * (M_PI/180.0));
00124
00125 switch (_axis)
00126 {
00127 case X:
00128 m(1,1) = m(2,2) = ca; m(2,1) = sa; m(1,2) = -sa;
00129 break;
00130
00131 case Y:
00132 m(0,0) = m(2,2) = ca; m(0,2) = sa; m(2,0) = -sa;
00133 break;
00134
00135 case Z:
00136 m(0,0) = m(1,1) = ca; m(1,0) = sa; m(0,1) = -sa;
00137 break;
00138 }
00139
00140
00141 if (_mult_from == MULT_FROM_RIGHT) *this *= m;
00142 else leftMult(m);
00143 }
00144
00145
00146
00147
00148
00149
00150
00151 template <typename Scalar>
00152 void
00153 GLMatrixT<Scalar>::
00154 rotate( Scalar angle, Scalar x, Scalar y, Scalar z,
00155 MultiplyFrom _mult_from )
00156 {
00157 GLMatrixT<Scalar> m;
00158 Scalar mag, s, c;
00159 Scalar xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
00160
00161 mag = sqrt( x*x + y*y + z*z );
00162 if(mag == 0.) {
00163 return;
00164 }
00165
00166 s = sin( angle * ( M_PI /180.) );
00167 c = cos( angle * ( M_PI /180.) );
00168
00169 x /= mag;
00170 y /= mag;
00171 z /= mag;
00172
00173 xx = x * x;
00174 yy = y * y;
00175 zz = z * z;
00176 xy = x * y;
00177 yz = y * z;
00178 zx = z * x;
00179 xs = x * s;
00180 ys = y * s;
00181 zs = z * s;
00182 one_c = 1.0F - c;
00183
00184 m(0,0) = (one_c * xx) + c;
00185 m(0,1) = (one_c * xy) - zs;
00186 m(0,2) = (one_c * zx) + ys;
00187 m(0,3) = 0.0F;
00188
00189 m(1,0) = (one_c * xy) + zs;
00190 m(1,1) = (one_c * yy) + c;
00191 m(1,2) = (one_c * yz) - xs;
00192 m(1,3) = 0.0F;
00193
00194 m(2,0) = (one_c * zx) - ys;
00195 m(2,1) = (one_c * yz) + xs;
00196 m(2,2) = (one_c * zz) + c;
00197 m(2,3) = 0.0F;
00198
00199 m(3,0) = 0.0F;
00200 m(3,1) = 0.0F;
00201 m(3,2) = 0.0F;
00202 m(3,3) = 1.0F;
00203
00204 if (_mult_from == MULT_FROM_RIGHT) *this *= m;
00205 else leftMult(m);
00206 }
00207
00208
00209
00210
00211
00212 template<typename Scalar>
00213 void
00214 GLMatrixT<Scalar>::
00215 lookAt(const VectorT<Scalar,3>& eye,
00216 const VectorT<Scalar,3>& center,
00217 const VectorT<Scalar,3>& up)
00218 {
00219 VectorT<Scalar,3> z(eye);
00220 z -= center;
00221 z.normalize();
00222
00223 VectorT<Scalar,3> x(up % z);
00224 x.normalize();
00225
00226 VectorT<Scalar,3> y(z % x);
00227 y.normalize();
00228
00229 GLMatrixT<Scalar> m;
00230 m(0,0)=x[0]; m(0,1)=x[1]; m(0,2)=x[2]; m(0,3)=0.0;
00231 m(1,0)=y[0]; m(1,1)=y[1]; m(1,2)=y[2]; m(1,3)=0.0;
00232 m(2,0)=z[0]; m(2,1)=z[1]; m(2,2)=z[2]; m(2,3)=0.0;
00233 m(3,0)=0.0; m(3,1)=0.0; m(3,2)=0.0; m(3,3)=1.0;
00234
00235 *this *= m;
00236 translate(-eye[0], -eye[1], -eye[2]);
00237 }
00238
00239
00240
00241
00242
00243 template<typename Scalar>
00244 void
00245 GLMatrixT<Scalar>::
00246 inverse_lookAt(const VectorT<Scalar,3>& eye,
00247 const VectorT<Scalar,3>& center,
00248 const VectorT<Scalar,3>& up)
00249 {
00250 VectorT<Scalar,3> z(eye);
00251 z -= center;
00252 z.normalize();
00253
00254 VectorT<Scalar,3> x(up % z);
00255 x.normalize();
00256
00257 VectorT<Scalar,3> y(z % x);
00258 y.normalize();
00259
00260 GLMatrixT<Scalar> m;
00261 m(0,0)=x[0]; m(0,1)=y[0]; m(0,2)=z[0]; m(0,3)=eye[0];
00262 m(1,0)=x[1]; m(1,1)=y[1]; m(1,2)=z[1]; m(1,3)=eye[1];
00263 m(2,0)=x[2]; m(2,1)=y[2]; m(2,2)=z[2]; m(2,3)=eye[2];
00264 m(3,0)=0.0; m(3,1)=0.0; m(3,2)=0.0; m(3,3)=1.0;
00265
00266 leftMult(m);
00267 }
00268
00269
00270
00271
00272
00273 template<typename Scalar>
00274 void
00275 GLMatrixT<Scalar>::
00276 perspective(Scalar fovY, Scalar aspect,
00277 Scalar near_plane, Scalar far_plane)
00278 {
00279 Scalar ymax = near_plane * tan( fovY * M_PI / 360.0 );
00280 Scalar ymin = -ymax;
00281 Scalar xmin = ymin * aspect;
00282 Scalar xmax = ymax * aspect;
00283 frustum(xmin, xmax, ymin, ymax, near_plane, far_plane);
00284 }
00285
00286
00287
00288
00289
00290 template<typename Scalar>
00291 void
00292 GLMatrixT<Scalar>::
00293 inverse_perspective(Scalar fovY, Scalar aspect,
00294 Scalar near_plane, Scalar far_plane)
00295 {
00296 Scalar ymax = near_plane * tan( fovY * M_PI / 360.0 );
00297 Scalar ymin = -ymax;
00298 Scalar xmin = ymin * aspect;
00299 Scalar xmax = ymax * aspect;
00300 inverse_frustum(xmin, xmax, ymin, ymax, near_plane, far_plane);
00301 }
00302
00303
00304
00305
00306
00307 template<typename Scalar>
00308 void
00309 GLMatrixT<Scalar>::
00310 frustum( Scalar left,Scalar right,
00311 Scalar bottom, Scalar top,
00312 Scalar near_plane, Scalar far_plane )
00313 {
00314 assert(near_plane > 0.0 && far_plane > near_plane);
00315
00316 GLMatrixT<Scalar> m;
00317 Scalar x, y, a, b, c, d;
00318
00319 x = (2.0*near_plane) / (right-left);
00320 y = (2.0*near_plane) / (top-bottom);
00321 a = (right+left) / (right-left);
00322 b = (top+bottom) / (top-bottom);
00323 c = -(far_plane+near_plane) / ( far_plane-near_plane);
00324 d = -(2.0*far_plane*near_plane) / (far_plane-near_plane);
00325
00326 m(0,0) = x; m(0,1) = 0.0F; m(0,2) = a; m(0,3) = 0.0F;
00327 m(1,0) = 0.0F; m(1,1) = y; m(1,2) = b; m(1,3) = 0.0F;
00328 m(2,0) = 0.0F; m(2,1) = 0.0F; m(2,2) = c; m(2,3) = d;
00329 m(3,0) = 0.0F; m(3,1) = 0.0F; m(3,2) = -1.0F; m(3,3) = 0.0F;
00330
00331 *this *= m;
00332 }
00333
00334
00335
00336
00337
00338 template<typename Scalar>
00339 void
00340 GLMatrixT<Scalar>::
00341 inverse_frustum(Scalar left,Scalar right,
00342 Scalar bottom, Scalar top,
00343 Scalar near_plane, Scalar far_plane)
00344 {
00345 assert(near_plane > 0.0 && far_plane > near_plane);
00346
00347 GLMatrixT<Scalar> m;
00348 Scalar x, y, a, b, c, d;
00349
00350 x = (right-left) / (2.0*near_plane);
00351 y = (top-bottom) / (2.0*near_plane);
00352 a = (right+left) / (2.0*near_plane);
00353 b = (top+bottom) / (2.0*near_plane);
00354 c = (far_plane+near_plane) / (2.0*far_plane*near_plane);
00355 d = (near_plane-far_plane) / (2.0*far_plane*near_plane);
00356
00357 m(0,0)=x; m(0,1)= 0.0F; m(0,2)= 0.0F; m(0,3)= a;
00358 m(1,0)=0.0F; m(1,1)= y; m(1,2)= 0.0F; m(1,3)= b;
00359 m(2,0)=0.0F; m(2,1)= 0.0F; m(2,2)= 0.0F; m(2,3)= -1.0;
00360 m(3,0)=0.0F; m(3,1)= 0.0F; m(3,2)= d; m(3,3)= c;
00361
00362 leftMult(m);
00363 }
00364
00365
00366
00367
00368
00369 template<typename Scalar>
00370 void
00371 GLMatrixT<Scalar>::
00372 ortho(Scalar left, Scalar right,
00373 Scalar bottom, Scalar top,
00374 Scalar near_plane, Scalar far_plane)
00375 {
00376 GLMatrixT<Scalar> m;
00377
00378 Scalar r_l = right-left;
00379 Scalar t_b = top - bottom;
00380 Scalar f_n = far_plane - near_plane;
00381
00382 assert(r_l > 0.0 && t_b > 0.0 && f_n > 0.0);
00383
00384 m(1,0) = m(0,1) = m(0,2) =
00385 m(2,0) = m(2,1) = m(1,2) =
00386 m(3,0) = m(3,1) = m(3,2) = 0.0;
00387
00388 m(0,0) = 2.0 / r_l;
00389 m(1,1) = 2.0 / t_b;
00390 m(2,2) = -2.0 / f_n;
00391
00392 m(0,3) = -(right + left) / r_l;
00393 m(1,3) = -(top + bottom) / t_b;
00394 m(2,3) = -(far_plane + near_plane) / f_n;
00395
00396 m(3,3) = 1.0;
00397
00398 *this *= m;
00399 }
00400
00401
00402
00403
00404 template<typename Scalar>
00405 void
00406 GLMatrixT<Scalar>::
00407 inverse_ortho(Scalar left, Scalar right,
00408 Scalar bottom, Scalar top,
00409 Scalar near_plane, Scalar far_plane)
00410 {
00411 GLMatrixT<Scalar> m;
00412
00413 m(1,0) = m(0,1) = m(0,2) =
00414 m(2,0) = m(2,1) = m(1,2) =
00415 m(3,0) = m(3,1) = m(3,2) = 0.0;
00416
00417
00418 m(0,0) = 0.5 * (right - left);
00419 m(1,1) = 0.5 * (top - bottom);
00420 m(2,2) = -0.5 * (far_plane - near_plane);
00421
00422 m(0,3) = 0.5 * (right + left);
00423 m(1,3) = 0.5 * (top + bottom);
00424 m(2,3) = -0.5 * (far_plane + near_plane);
00425
00426 m(3,3) = 1.0;
00427
00428 leftMult(m);
00429 }
00430
00431
00432
00433
00434
00435 #undef MAT
00436 #undef M
00437
00438
00439
00440 }
00441