00001
00002
00003
00004
00005
00006 #ifndef _GMTL_XFORMS_H_
00007 #define _GMTL_XFORMS_H_
00008
00009 #include <gmtl/Point.h>
00010 #include <gmtl/Vec.h>
00011 #include <gmtl/Matrix.h>
00012 #include <gmtl/MatrixOps.h>
00013 #include <gmtl/Quat.h>
00014 #include <gmtl/QuatOps.h>
00015 #include <gmtl/Ray.h>
00016 #include <gmtl/LineSeg.h>
00017 #include <gmtl/Util/StaticAssert.h>
00018
00019 namespace gmtl
00020 {
00039 template <typename DATA_TYPE>
00040 inline VecBase<DATA_TYPE, 3>& xform( VecBase<DATA_TYPE, 3>& result, const Quat<DATA_TYPE>& rot, const VecBase<DATA_TYPE, 3>& vector )
00041 {
00042
00043 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." );
00044
00045
00046
00047
00048
00049
00050
00051 Quat<DATA_TYPE> rot_conj( -rot[Xelt], -rot[Yelt], -rot[Zelt], rot[Welt] );
00052 Quat<DATA_TYPE> pure( vector[0], vector[1], vector[2], (DATA_TYPE)0.0 );
00053 Quat<DATA_TYPE> temp(
00054 pure[Welt]*rot_conj[Xelt] + pure[Xelt]*rot_conj[Welt] + pure[Yelt]*rot_conj[Zelt] - pure[Zelt]*rot_conj[Yelt],
00055 pure[Welt]*rot_conj[Yelt] + pure[Yelt]*rot_conj[Welt] + pure[Zelt]*rot_conj[Xelt] - pure[Xelt]*rot_conj[Zelt],
00056 pure[Welt]*rot_conj[Zelt] + pure[Zelt]*rot_conj[Welt] + pure[Xelt]*rot_conj[Yelt] - pure[Yelt]*rot_conj[Xelt],
00057 pure[Welt]*rot_conj[Welt] - pure[Xelt]*rot_conj[Xelt] - pure[Yelt]*rot_conj[Yelt] - pure[Zelt]*rot_conj[Zelt] );
00058
00059 result.set(
00060 rot[Welt]*temp[Xelt] + rot[Xelt]*temp[Welt] + rot[Yelt]*temp[Zelt] - rot[Zelt]*temp[Yelt],
00061 rot[Welt]*temp[Yelt] + rot[Yelt]*temp[Welt] + rot[Zelt]*temp[Xelt] - rot[Xelt]*temp[Zelt],
00062 rot[Welt]*temp[Zelt] + rot[Zelt]*temp[Welt] + rot[Xelt]*temp[Yelt] - rot[Yelt]*temp[Xelt] );
00063 return result;
00064 }
00065
00073 template <typename DATA_TYPE>
00074 inline VecBase<DATA_TYPE, 3> operator*( const Quat<DATA_TYPE>& rot, const VecBase<DATA_TYPE, 3>& vector )
00075 {
00076 VecBase<DATA_TYPE, 3> temporary;
00077 return xform( temporary, rot, vector );
00078 }
00079
00080
00087 template <typename DATA_TYPE>
00088 inline VecBase<DATA_TYPE, 3> operator*=(VecBase<DATA_TYPE, 3>& vector, const Quat<DATA_TYPE>& rot)
00089 {
00090 VecBase<DATA_TYPE, 3> temporary = vector;
00091 return xform( vector, rot, temporary);
00092 }
00093
00094
00112 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00113 inline Vec<DATA_TYPE, COLS>& xform( Vec<DATA_TYPE, COLS>& result, const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Vec<DATA_TYPE, COLS>& vector )
00114 {
00115
00116
00117
00118 result = Vec<DATA_TYPE, COLS>();
00119
00120 for (unsigned iRow = 0; iRow < ROWS; ++iRow)
00121 for (unsigned iCol = 0; iCol < COLS; ++iCol)
00122 result[iRow] += matrix( iRow, iCol ) * vector[iCol];
00123
00124 return result;
00125 }
00126
00127
00138 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00139 inline Vec<DATA_TYPE, COLS> operator*( const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Vec<DATA_TYPE, COLS>& vector )
00140 {
00141
00142 Vec<DATA_TYPE, COLS> temporary;
00143 return xform( temporary, matrix, vector );
00144 }
00145
00146
00147
00148
00157 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS, unsigned VEC_SIZE>
00158 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 )
00159 {
00160 GMTL_STATIC_ASSERT( VEC_SIZE == COLS - 1, Vec_of_wrong_size_for_xform );
00161
00162
00163
00164 Vec<DATA_TYPE, COLS> temp_vector, temp_result;
00165 for (unsigned x = 0; x < VEC_SIZE; ++x)
00166 temp_vector[x] = vector[x];
00167 temp_vector[COLS-1] = (DATA_TYPE)0.0;
00168
00169
00170 xform<DATA_TYPE, ROWS, COLS>( temp_result, matrix, temp_vector );
00171
00172
00173
00174
00175 if (Math::isEqual( temp_result[VEC_SIZE], (DATA_TYPE)0, (DATA_TYPE)0.0001 ) == false)
00176 {
00177 DATA_TYPE w_coord_div = DATA_TYPE( 1.0 ) / temp_result[VEC_SIZE];
00178 for (unsigned x = 0; x < VEC_SIZE; ++x)
00179 result[x] = temp_result[x] * w_coord_div;
00180 }
00181 else
00182 {
00183 for (unsigned x = 0; x < VEC_SIZE; ++x)
00184 result[x] = temp_result[x];
00185 }
00186
00187 return result;
00188 }
00189
00198 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
00199 inline Vec<DATA_TYPE, COLS_MINUS_ONE> operator*( const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Vec<DATA_TYPE, COLS_MINUS_ONE>& vector )
00200 {
00201 Vec<DATA_TYPE, COLS_MINUS_ONE> temporary;
00202 return xform( temporary, matrix, vector );
00203 }
00204
00221 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00222 inline Point<DATA_TYPE, COLS>& xform( Point<DATA_TYPE, COLS>& result, const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Point<DATA_TYPE, COLS>& point )
00223 {
00224
00225
00226
00227 result = Point<DATA_TYPE, COLS>();
00228
00229 for (unsigned iRow = 0; iRow < ROWS; ++iRow)
00230 for (unsigned iCol = 0; iCol < COLS; ++iCol)
00231 result[iRow] += matrix( iRow, iCol ) * point[iCol];
00232
00233 return result;
00234 }
00235
00244 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00245 inline Point<DATA_TYPE, COLS> operator*( const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Point<DATA_TYPE, COLS>& point )
00246 {
00247 Point<DATA_TYPE, COLS> temporary;
00248 return xform( temporary, matrix, point );
00249 }
00250
00251
00252
00253
00263 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS, unsigned PNT_SIZE>
00264 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 )
00265 {
00266
00267 GMTL_STATIC_ASSERT( PNT_SIZE == COLS-1, Point_not_of_size_mat_col_minus_1_as_required_for_xform);
00268
00269
00270 Point<DATA_TYPE, PNT_SIZE+1> temp_point, temp_result;
00271 for (unsigned x = 0; x < PNT_SIZE; ++x)
00272 temp_point[x] = point[x];
00273 temp_point[PNT_SIZE] = (DATA_TYPE)1.0;
00274
00275
00276 xform<DATA_TYPE, ROWS, COLS>( temp_result, matrix, temp_point );
00277
00278
00279
00280
00281 if (Math::isEqual( temp_result[PNT_SIZE], (DATA_TYPE)0, (DATA_TYPE)0.0001 ) == false)
00282 {
00283 DATA_TYPE w_coord_div = DATA_TYPE( 1.0 ) / temp_result[PNT_SIZE];
00284 for (unsigned x = 0; x < PNT_SIZE; ++x)
00285 result[x] = temp_result[x] * w_coord_div;
00286 }
00287 else
00288 {
00289 for (unsigned x = 0; x < PNT_SIZE; ++x)
00290 result[x] = temp_result[x];
00291 }
00292
00293 return result;
00294 }
00295
00304 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
00305 inline Point<DATA_TYPE, COLS_MINUS_ONE> operator*( const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Point<DATA_TYPE, COLS_MINUS_ONE>& point )
00306 {
00307 Point<DATA_TYPE, COLS_MINUS_ONE> temporary;
00308 return xform( temporary, matrix, point );
00309 }
00310
00318 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00319 inline Point<DATA_TYPE, COLS> operator*( const Point<DATA_TYPE, COLS>& point, const Matrix<DATA_TYPE, ROWS, COLS>& matrix )
00320 {
00321 Point<DATA_TYPE, COLS> temporary;
00322 return xform( temporary, matrix, point );
00323 }
00324
00325
00333 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00334 inline Point<DATA_TYPE, COLS> operator*=(Point<DATA_TYPE, COLS>& point, const Matrix<DATA_TYPE, ROWS, COLS>& matrix)
00335 {
00336 Point<DATA_TYPE, COLS> temporary = point;
00337 return xform( point, matrix, temporary);
00338 }
00339
00348 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
00349 inline Point<DATA_TYPE, COLS_MINUS_ONE>& operator*=( Point<DATA_TYPE, COLS_MINUS_ONE>& point, const Matrix<DATA_TYPE, ROWS, COLS>& matrix )
00350 {
00351 Point<DATA_TYPE, COLS_MINUS_ONE> temporary = point;
00352 return xform( point, matrix, temporary);
00353 }
00354
00355
00366 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00367 inline Ray<DATA_TYPE>& xform( Ray<DATA_TYPE>& result, const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Ray<DATA_TYPE>& ray )
00368 {
00369 gmtl::Point<DATA_TYPE, 3> pos;
00370 gmtl::Vec<DATA_TYPE, 3> dir;
00371 result.setOrigin( xform( pos, matrix, ray.getOrigin() ) );
00372 result.setDir( xform( dir, matrix, ray.getDir() ) );
00373 return result;
00374 }
00375
00383 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00384 inline Ray<DATA_TYPE> operator*( const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const Ray<DATA_TYPE>& ray )
00385 {
00386 Ray<DATA_TYPE> temporary;
00387 return xform( temporary, matrix, ray );
00388 }
00389
00390
00398 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00399 inline Ray<DATA_TYPE>& operator*=( Ray<DATA_TYPE>& ray, const Matrix<DATA_TYPE, ROWS, COLS>& matrix )
00400 {
00401 Ray<DATA_TYPE> temporary = ray;
00402 return xform( ray, matrix, temporary);
00403 }
00404
00413 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00414 inline LineSeg<DATA_TYPE>& xform( LineSeg<DATA_TYPE>& result, const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const LineSeg<DATA_TYPE>& seg )
00415 {
00416 gmtl::Point<DATA_TYPE, 3> pos;
00417 gmtl::Vec<DATA_TYPE, 3> dir;
00418 result.setOrigin( xform( pos, matrix, seg.getOrigin() ) );
00419 result.setDir( xform( dir, matrix, seg.getDir() ) );
00420 return result;
00421 }
00422
00430 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00431 inline LineSeg<DATA_TYPE> operator*( const Matrix<DATA_TYPE, ROWS, COLS>& matrix, const LineSeg<DATA_TYPE>& seg )
00432 {
00433 LineSeg<DATA_TYPE> temporary;
00434 return xform( temporary, matrix, seg );
00435 }
00436
00437
00445 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00446 inline LineSeg<DATA_TYPE>& operator*=( LineSeg<DATA_TYPE>& seg, const Matrix<DATA_TYPE, ROWS, COLS>& matrix )
00447 {
00448 LineSeg<DATA_TYPE> temporary = seg;
00449 return xform( seg, matrix, temporary);
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 }
00507
00508 #endif