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 #ifndef _GMTL_XFORMS_H_
00036 #define _GMTL_XFORMS_H_
00037
00038 #include <gmtl/Point.h>
00039 #include <gmtl/Vec.h>
00040 #include <gmtl/Matrix.h>
00041 #include <gmtl/MatrixOps.h>
00042 #include <gmtl/Quat.h>
00043 #include <gmtl/QuatOps.h>
00044 #include <gmtl/Generate.h>
00045
00046 namespace gmtl
00047 {
00066 template <typename DATA_TYPE>
00067 inline VecBase<DATA_TYPE, 3>& xform( VecBase<DATA_TYPE, 3>& result, const Quat<DATA_TYPE>& rot, const VecBase<DATA_TYPE, 3>& vector )
00068 {
00069
00070 gmtlASSERT( Math::isEqual( length( rot ), (DATA_TYPE)1.0, (DATA_TYPE)0.0001 ) && "must pass a rotation quaternion to xform(result,quat,vec) - by definition, a rotation quaternion is normalized). if you need non-rotation quaternion support, let us know." );
00071
00072
00073
00074
00075
00076
00077
00078 Quat<DATA_TYPE> rot_conj( -rot[Xelt], -rot[Yelt], -rot[Zelt], rot[Welt] );
00079 Quat<DATA_TYPE> pure( vector[0], vector[1], vector[2], (DATA_TYPE)0.0 );
00080 Quat<DATA_TYPE> temp(
00081 pure[Welt]*rot_conj[Xelt] + pure[Xelt]*rot_conj[Welt] + pure[Yelt]*rot_conj[Zelt] - pure[Zelt]*rot_conj[Yelt],
00082 pure[Welt]*rot_conj[Yelt] + pure[Yelt]*rot_conj[Welt] + pure[Zelt]*rot_conj[Xelt] - pure[Xelt]*rot_conj[Zelt],
00083 pure[Welt]*rot_conj[Zelt] + pure[Zelt]*rot_conj[Welt] + pure[Xelt]*rot_conj[Yelt] - pure[Yelt]*rot_conj[Xelt],
00084 pure[Welt]*rot_conj[Welt] - pure[Xelt]*rot_conj[Xelt] - pure[Yelt]*rot_conj[Yelt] - pure[Zelt]*rot_conj[Zelt] );
00085
00086 result.set(
00087 rot[Welt]*temp[Xelt] + rot[Xelt]*temp[Welt] + rot[Yelt]*temp[Zelt] - rot[Zelt]*temp[Yelt],
00088 rot[Welt]*temp[Yelt] + rot[Yelt]*temp[Welt] + rot[Zelt]*temp[Xelt] - rot[Xelt]*temp[Zelt],
00089 rot[Welt]*temp[Zelt] + rot[Zelt]*temp[Welt] + rot[Xelt]*temp[Yelt] - rot[Yelt]*temp[Xelt] );
00090 return result;
00091 }
00092
00100 template <typename DATA_TYPE>
00101 inline VecBase<DATA_TYPE, 3> operator*( const Quat<DATA_TYPE>& rot, const VecBase<DATA_TYPE, 3>& vector )
00102 {
00103 VecBase<DATA_TYPE, 3> temporary;
00104 return xform( temporary, rot, vector );
00105 }
00106
00107
00114 template <typename DATA_TYPE>
00115 inline VecBase<DATA_TYPE, 3> operator*=(VecBase<DATA_TYPE, 3>& vector, const Quat<DATA_TYPE>& rot)
00116 {
00117 VecBase<DATA_TYPE, 3> temporary = vector;
00118 return xform( vector, rot, temporary);
00119 }
00120
00121
00139 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00140 inline Vec<DATA_TYPE, COLS>& xform( Vec<DATA_TYPE, COLS>& result, const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Vec<DATA_TYPE, COLS>& vector )
00141 {
00142
00143
00144
00145 result = Vec<DATA_TYPE, COLS>();
00146
00147 for (unsigned iRow = 0; iRow < ROWS; ++iRow)
00148 for (unsigned iCol = 0; iCol < COLS; ++iCol)
00149 result[iRow] += matrix( iRow, iCol ) * vector[iCol];
00150
00151 return result;
00152 }
00153
00154
00165 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00166 inline Vec<DATA_TYPE, COLS> operator*( const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Vec<DATA_TYPE, COLS>& vector )
00167 {
00168
00169 Vec<DATA_TYPE, COLS> temporary;
00170 return xform( temporary, matrix, vector );
00171 }
00172
00173
00174
00175
00184 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS, unsigned VEC_SIZE>
00185 inline Vec<DATA_TYPE, VEC_SIZE>& xform( Vec<DATA_TYPE, VEC_SIZE >& result, const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Vec<DATA_TYPE, VEC_SIZE >& vector )
00186 {
00187 gmtlASSERT( VEC_SIZE == COLS - 1 );
00188
00189
00190
00191 Vec<DATA_TYPE, COLS> temp_vector, temp_result;
00192 for (unsigned x = 0; x < VEC_SIZE; ++x)
00193 temp_vector[x] = vector[x];
00194 temp_vector[COLS-1] = (DATA_TYPE)0.0;
00195
00196
00197 xform<DATA_TYPE, ROWS, COLS>( temp_result, matrix, temp_vector );
00198
00199
00200
00201
00202 if (Math::isEqual( temp_result[VEC_SIZE], (DATA_TYPE)0, (DATA_TYPE)0.0001 ) == false)
00203 {
00204 DATA_TYPE w_coord_div = DATA_TYPE( 1.0 ) / temp_result[VEC_SIZE];
00205 for (unsigned x = 0; x < VEC_SIZE; ++x)
00206 result[x] = temp_result[x] * w_coord_div;
00207 }
00208 else
00209 {
00210 for (unsigned x = 0; x < VEC_SIZE; ++x)
00211 result[x] = temp_result[x];
00212 }
00213
00214 return result;
00215 }
00216
00225 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
00226 inline Vec<DATA_TYPE, COLS_MINUS_ONE> operator*( const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Vec<DATA_TYPE, COLS_MINUS_ONE>& vector )
00227 {
00228 Vec<DATA_TYPE, COLS_MINUS_ONE> temporary;
00229 return xform( temporary, matrix, vector );
00230 }
00231
00248 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00249 inline Point<DATA_TYPE, COLS>& xform( Point<DATA_TYPE, COLS>& result, const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Point<DATA_TYPE, COLS>& point )
00250 {
00251
00252
00253
00254 result = Point<DATA_TYPE, COLS>();
00255
00256 for (unsigned iRow = 0; iRow < ROWS; ++iRow)
00257 for (unsigned iCol = 0; iCol < COLS; ++iCol)
00258 result[iRow] += matrix( iRow, iCol ) * point[iCol];
00259
00260 return result;
00261 }
00262
00271 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00272 inline Point<DATA_TYPE, COLS> operator*( const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Point<DATA_TYPE, COLS>& point )
00273 {
00274 Point<DATA_TYPE, COLS> temporary;
00275 return xform( temporary, matrix, point );
00276 }
00277
00278
00279
00280
00290 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS, unsigned PNT_SIZE>
00291 inline Point<DATA_TYPE, PNT_SIZE>& xform( Point<DATA_TYPE, PNT_SIZE>& result, const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Point<DATA_TYPE, PNT_SIZE>& point )
00292 {
00293 gmtlASSERT( PNT_SIZE == COLS - 1 && "The precondition of this method is that the vector size must be one less than the number of columns in the matrix. eg. if Mat<n,k>, then Vec<k-1>." );
00294
00295
00296 Point<DATA_TYPE, PNT_SIZE+1> temp_point, temp_result;
00297 for (unsigned x = 0; x < PNT_SIZE; ++x)
00298 temp_point[x] = point[x];
00299 temp_point[PNT_SIZE] = (DATA_TYPE)1.0;
00300
00301
00302 xform<DATA_TYPE, ROWS, COLS>( temp_result, matrix, temp_point );
00303
00304
00305
00306
00307 if (Math::isEqual( temp_result[PNT_SIZE], (DATA_TYPE)0, (DATA_TYPE)0.0001 ) == false)
00308 {
00309 DATA_TYPE w_coord_div = DATA_TYPE( 1.0 ) / temp_result[PNT_SIZE];
00310 for (unsigned x = 0; x < PNT_SIZE; ++x)
00311 result[x] = temp_result[x] * w_coord_div;
00312 }
00313 else
00314 {
00315 for (unsigned x = 0; x < PNT_SIZE; ++x)
00316 result[x] = temp_result[x];
00317 }
00318
00319 return result;
00320 }
00321
00330 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
00331 inline Point<DATA_TYPE, COLS_MINUS_ONE> operator*( const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Point<DATA_TYPE, COLS_MINUS_ONE>& point )
00332 {
00333 Point<DATA_TYPE, COLS_MINUS_ONE> temporary;
00334 return xform( temporary, matrix, point );
00335 }
00336
00344 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00345 inline Point<DATA_TYPE, COLS> operator*( const Point<DATA_TYPE, COLS>& point, const Matrix<DATA_TYPE, ROWS, COLS>& matrix )
00346 {
00347 Point<DATA_TYPE, COLS> temporary;
00348 return xform( temporary, matrix, point );
00349 }
00350
00351
00359 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00360 inline Point<DATA_TYPE, COLS> operator*=(Point<DATA_TYPE, COLS>& point, const Matrix<DATA_TYPE, ROWS, COLS>& matrix)
00361 {
00362 Point<DATA_TYPE, COLS> temporary = point;
00363 return xform( point, matrix, temporary);
00364 }
00365
00374 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
00375 inline Point<DATA_TYPE, COLS_MINUS_ONE> operator*=(Point<DATA_TYPE, COLS_MINUS_ONE>& point, const Matrix<DATA_TYPE, ROWS, COLS>& matrix)
00376 {
00377 Point<DATA_TYPE, COLS_MINUS_ONE> temporary = point;
00378 return xform( point, matrix, temporary);
00379 }
00380
00381
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 };
00437
00438 #endif