Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/linmath/lquaternion_src.I

Go to the documentation of this file.
00001 // Filename: lquaternion_src.I
00002 // Created by:  frang (06Jun00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 ////////////////////////////////////////////////////////////////////
00020 //     Function: LQuaternion::Default Constructor
00021 //       Access: public
00022 //  Description:
00023 ////////////////////////////////////////////////////////////////////
00024 INLINE_LINMATH FLOATNAME(LQuaternion)::
00025 FLOATNAME(LQuaternion)() {
00026 }
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: LQuaternion::Copy Constructor
00030 //       Access: public
00031 //  Description:
00032 ////////////////////////////////////////////////////////////////////
00033 INLINE_LINMATH FLOATNAME(LQuaternion)::
00034 FLOATNAME(LQuaternion)(const FLOATNAME(LVecBase4) &copy) :
00035   FLOATNAME(LVecBase4)(copy)
00036 {
00037 }
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: LQuaternion::Constructor
00041 //       Access: public
00042 //  Description:
00043 ////////////////////////////////////////////////////////////////////
00044 INLINE_LINMATH FLOATNAME(LQuaternion)::
00045 FLOATNAME(LQuaternion)(FLOATTYPE r, FLOATTYPE i, FLOATTYPE j, FLOATTYPE k) {
00046   set(r, i, j, k);
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: LQuaternion::xform
00051 //       Access: Published
00052 //  Description: Transforms a 3-d vector by the indicated rotation
00053 ////////////////////////////////////////////////////////////////////
00054 INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LQuaternion)::
00055 xform(const FLOATNAME(LVecBase3) &v) const {
00056   FLOATNAME(LQuaternion) v_quat(0.0f, v[0], v[1], v[2]);
00057 
00058   FLOATNAME(LQuaternion) inv(_v.data[0], -_v.data[1], -_v.data[2], -_v.data[3]);
00059   v_quat = inv * v_quat * (*this);
00060 
00061   return FLOATNAME(LVecBase3)(v_quat[1], v_quat[2], v_quat[3]);
00062 }
00063 
00064 ////////////////////////////////////////////////////////////////////
00065 //     Function: LQuaternion::multiply
00066 //       Access: Published
00067 //  Description: actual multiply call (non virtual)
00068 ////////////////////////////////////////////////////////////////////
00069 INLINE_LINMATH FLOATNAME(LQuaternion) FLOATNAME(LQuaternion)::
00070 multiply(const FLOATNAME(LQuaternion) &rhs) const {
00071   FLOATTYPE r = (rhs._v.v._0 * _v.v._0) - (rhs._v.v._1 * _v.v._1) - (rhs._v.v._2 * _v.v._2) - (rhs._v.v._3 * _v.v._3);
00072   FLOATTYPE i = (rhs._v.v._1 * _v.v._0) + (rhs._v.v._0 * _v.v._1) - (rhs._v.v._3 * _v.v._2) + (rhs._v.v._2 * _v.v._3);
00073   FLOATTYPE j = (rhs._v.v._2 * _v.v._0) + (rhs._v.v._3 * _v.v._1) + (rhs._v.v._0 * _v.v._2) - (rhs._v.v._1 * _v.v._3);
00074   FLOATTYPE k = (rhs._v.v._3 * _v.v._0) - (rhs._v.v._2 * _v.v._1) + (rhs._v.v._1 * _v.v._2) + (rhs._v.v._0 * _v.v._3);
00075 
00076   return FLOATNAME(LQuaternion)(r, i , j, k);
00077 }
00078 
00079 ////////////////////////////////////////////////////////////////////
00080 //     Function: LQuaternion::unary -
00081 //       Access: Public
00082 //  Description:
00083 ////////////////////////////////////////////////////////////////////
00084 INLINE_LINMATH FLOATNAME(LQuaternion) FLOATNAME(LQuaternion)::
00085 operator - () const {
00086   return FLOATNAME(LVecBase4)::operator - ();
00087 }
00088 
00089 ////////////////////////////////////////////////////////////////////
00090 //     Function: LQuaternion::Multiply Operator
00091 //       Access: public
00092 //  Description:
00093 ////////////////////////////////////////////////////////////////////
00094 INLINE_LINMATH FLOATNAME(LQuaternion) FLOATNAME(LQuaternion)::
00095 operator *(const FLOATNAME(LQuaternion)& c) const {
00096   return multiply(c);
00097 }
00098 
00099 ////////////////////////////////////////////////////////////////////
00100 //     Function: LQuaternion::Multiply Assignment Operator
00101 //       Access: public
00102 //  Description:
00103 ////////////////////////////////////////////////////////////////////
00104 INLINE_LINMATH FLOATNAME(LQuaternion)& FLOATNAME(LQuaternion)::
00105 operator *=(const FLOATNAME(LQuaternion)& c) {
00106   (*this) = operator*(c);
00107   return *this;
00108 }
00109 
00110 ////////////////////////////////////////////////////////////////////
00111 //     Function: LQuaternion::Multiply Operator
00112 //       Access: public
00113 //  Description: Quat * Matrix = matrix
00114 ////////////////////////////////////////////////////////////////////
00115 INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LQuaternion)::
00116 operator *(const FLOATNAME(LMatrix3) &m) {
00117   FLOATNAME(LMatrix3) result;
00118   extract_to_matrix(result);
00119   return result * m;
00120 }
00121 
00122 ////////////////////////////////////////////////////////////////////
00123 //     Function: LQuaternion::Multiply Operator
00124 //       Access: public
00125 //  Description: Quat * Matrix = matrix
00126 ////////////////////////////////////////////////////////////////////
00127 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LQuaternion)::
00128 operator *(const FLOATNAME(LMatrix4) &m) {
00129   FLOATNAME(LMatrix3) m_upper_3 = m.get_upper_3();
00130   FLOATNAME(LMatrix3) this_quat;
00131   extract_to_matrix(this_quat);
00132 
00133   FLOATNAME(LMatrix4) result;
00134   result.set_upper_3(this_quat * m_upper_3);
00135   result.set_row(3, m.get_row(3));
00136   result.set_col(3, m.get_col(3));
00137 
00138   return result;
00139 }
00140 
00141 ////////////////////////////////////////////////////////////////////
00142 //     Function: LQuaternion::almost_equal
00143 //       Access: public
00144 //  Description: Returns true if two quaternions are memberwise equal
00145 //               within a specified tolerance.
00146 ////////////////////////////////////////////////////////////////////
00147 INLINE_LINMATH bool FLOATNAME(LQuaternion)::
00148 almost_equal(const FLOATNAME(LQuaternion)& c, FLOATTYPE threshold) const {
00149   return (IS_THRESHOLD_EQUAL(_v.data[0], c._v.data[0], threshold) &&
00150           IS_THRESHOLD_EQUAL(_v.data[1], c._v.data[1], threshold) &&
00151           IS_THRESHOLD_EQUAL(_v.data[2], c._v.data[2], threshold) &&
00152           IS_THRESHOLD_EQUAL(_v.data[3], c._v.data[3], threshold));
00153 }
00154 
00155 ////////////////////////////////////////////////////////////////////
00156 //     Function: LQuaternion::almost_equal
00157 //       Access: public
00158 //  Description: Returns true if two quaternions are memberwise equal
00159 //               within a default tolerance based on the numeric type.
00160 ////////////////////////////////////////////////////////////////////
00161 INLINE_LINMATH bool FLOATNAME(LQuaternion)::
00162 almost_equal(const FLOATNAME(LQuaternion)& c) const {
00163   return almost_equal(c, NEARLY_ZERO(FLOATTYPE));
00164 }
00165 
00166 ////////////////////////////////////////////////////////////////////
00167 //     Function: LQuaternion::output
00168 //       Access: public
00169 //  Description:
00170 ////////////////////////////////////////////////////////////////////
00171 INLINE_LINMATH void FLOATNAME(LQuaternion)::
00172 output(ostream& os) const {
00173   os << MAYBE_ZERO(_v.data[0]) << " + "
00174      << MAYBE_ZERO(_v.data[1]) << "i + "
00175      << MAYBE_ZERO(_v.data[2]) << "j + "
00176      << MAYBE_ZERO(_v.data[3]) << "k";
00177 }
00178 
00179 ////////////////////////////////////////////////////////////////////
00180 //     Function: LQuaternion::set_from_matrix
00181 //       Access: Public
00182 //  Description:
00183 ////////////////////////////////////////////////////////////////////
00184 INLINE_LINMATH void FLOATNAME(LQuaternion)::
00185 set_from_matrix(const FLOATNAME(LMatrix4) &m) {
00186   set_from_matrix(m.get_upper_3());
00187 }
00188 
00189 ////////////////////////////////////////////////////////////////////
00190 //     Function: LQuaternion::get_axis
00191 //       Access: Public
00192 //  Description: This, along with get_angle(), returns the rotation
00193 //               represented by the quaternion as an angle about an
00194 //               arbitrary axis.  This returns the axis.
00195 ////////////////////////////////////////////////////////////////////
00196 INLINE_LINMATH FLOATNAME(LVector3) FLOATNAME(LQuaternion)::
00197 get_axis() const {
00198   return ::normalize(FLOATNAME(LVector3)(_v.data[1], _v.data[2], _v.data[3]));
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: LQuaternion::get_angle
00203 //       Access: Public
00204 //  Description: This, along with get_axis(), returns the rotation
00205 //               represented by the quaternion as an angle about an
00206 //               arbitrary axis.  This returns the angle, in degrees
00207 //               counterclockwise about the axis.
00208 ////////////////////////////////////////////////////////////////////
00209 INLINE_LINMATH FLOATTYPE FLOATNAME(LQuaternion)::
00210 get_angle() const {
00211   return rad_2_deg(acos(_v.data[0]) * 2.0);
00212 }
00213 
00214 
00215 ////////////////////////////////////////////////////////////////////
00216 //     Function: LQuaternion::get_r
00217 //       Access: public
00218 //  Description:
00219 ////////////////////////////////////////////////////////////////////
00220 INLINE_LINMATH FLOATTYPE FLOATNAME(LQuaternion)::
00221 get_r() const {
00222   return _v.data[0];
00223 }
00224 
00225 ////////////////////////////////////////////////////////////////////
00226 //     Function: LQuaternion::get_i
00227 //       Access: public
00228 //  Description:
00229 ////////////////////////////////////////////////////////////////////
00230 INLINE_LINMATH FLOATTYPE FLOATNAME(LQuaternion)::
00231 get_i() const {
00232   return _v.data[1];
00233 }
00234 
00235 ////////////////////////////////////////////////////////////////////
00236 //     Function: LQuaternion::get_j
00237 //       Access: public
00238 //  Description:
00239 ////////////////////////////////////////////////////////////////////
00240 INLINE_LINMATH FLOATTYPE FLOATNAME(LQuaternion)::
00241 get_j() const {
00242   return _v.data[2];
00243 }
00244 
00245 ////////////////////////////////////////////////////////////////////
00246 //     Function: LQuaternion::get_k
00247 //       Access: public
00248 //  Description:
00249 ////////////////////////////////////////////////////////////////////
00250 INLINE_LINMATH FLOATTYPE FLOATNAME(LQuaternion)::
00251 get_k() const {
00252   return _v.data[3];
00253 }
00254 
00255 ////////////////////////////////////////////////////////////////////
00256 //     Function: LQuaternion::set_r
00257 //       Access: public
00258 //  Description:
00259 ////////////////////////////////////////////////////////////////////
00260 INLINE_LINMATH void FLOATNAME(LQuaternion)::
00261 set_r(FLOATTYPE r) {
00262   _v.data[0] = r;
00263 }
00264 
00265 ////////////////////////////////////////////////////////////////////
00266 //     Function: LQuaternion::set_i
00267 //       Access: public
00268 //  Description:
00269 ////////////////////////////////////////////////////////////////////
00270 INLINE_LINMATH void FLOATNAME(LQuaternion)::
00271 set_i(FLOATTYPE i) {
00272   _v.data[1] = i;
00273 }
00274 
00275 ////////////////////////////////////////////////////////////////////
00276 //     Function: LQuaternion::set_j
00277 //       Access: public
00278 //  Description:
00279 ////////////////////////////////////////////////////////////////////
00280 INLINE_LINMATH void FLOATNAME(LQuaternion)::
00281 set_j(FLOATTYPE j) {
00282   _v.data[2] = j;
00283 }
00284 
00285 ////////////////////////////////////////////////////////////////////
00286 //     Function: LQuaternion::set_k
00287 //       Access: public
00288 //  Description:
00289 ////////////////////////////////////////////////////////////////////
00290 INLINE_LINMATH void FLOATNAME(LQuaternion)::
00291 set_k(FLOATTYPE k) {
00292   _v.data[3] = k;
00293 }
00294 
00295 ////////////////////////////////////////////////////////////////////
00296 //     Function: LQuaternion::normalize
00297 //       Access: public
00298 //  Description:
00299 ////////////////////////////////////////////////////////////////////
00300 INLINE_LINMATH bool FLOATNAME(LQuaternion)::
00301 normalize() {
00302   FLOATTYPE l2 = (*this).dot(*this);
00303   if (l2 == (FLOATTYPE)0.0f) {
00304     set(0.0f, 0.0f, 0.0f, 0.0f);
00305     return false;
00306 
00307   } else if (!IS_THRESHOLD_EQUAL(l2, 1.0f, NEARLY_ZERO(FLOATTYPE) * NEARLY_ZERO(FLOATTYPE))) {
00308     (*this) /= csqrt(l2);
00309   }
00310 
00311   return true;
00312 }
00313 
00314 ////////////////////////////////////////////////////////////////////
00315 //     Function: LQuaternion::invert_from
00316 //       Access: Public
00317 //  Description: Computes the inverse of the other quat, and stores
00318 //               the result in this quat.  This is a fully general
00319 //               operation and makes no assumptions about the type of
00320 //               transform represented by the quat.
00321 //
00322 //               The other quat must be a different object than this
00323 //               quat.  However, if you need to invert a quat in
00324 //               place, see invert_in_place.
00325 //
00326 //               The return value is true if the quat was
00327 //               successfully inverted, false if there was a
00328 //               singularity.
00329 ////////////////////////////////////////////////////////////////////
00330 INLINE_LINMATH bool FLOATNAME(LQuaternion)::
00331 invert_from(const FLOATNAME(LQuaternion) &other) {
00332   set(-other._v.v._0, other._v.v._1, other._v.v._2, other._v.v._3);
00333   return true;
00334 }
00335 
00336 ////////////////////////////////////////////////////////////////////
00337 //     Function: LQuaternion::invert_in_place
00338 //       Access: Public
00339 //  Description: Inverts the current quat.  Returns true if the
00340 //               inverse is successful, false if the quat was
00341 //               singular.
00342 ////////////////////////////////////////////////////////////////////
00343 INLINE_LINMATH bool FLOATNAME(LQuaternion)::
00344 invert_in_place() {
00345   _v.v._0 = -_v.v._0;
00346   return true;
00347 }
00348 
00349 ////////////////////////////////////////////////////////////////////
00350 //     Function: LQuaternion::is_identity
00351 //       Access: Public
00352 //  Description: Returns true if this quaternion represents the
00353 //               identity transformation: no rotation.
00354 ////////////////////////////////////////////////////////////////////
00355 INLINE_LINMATH bool FLOATNAME(LQuaternion)::
00356 is_identity() const {
00357   return (IS_NEARLY_EQUAL(_v.v._0, -1.0f) || IS_NEARLY_EQUAL(_v.v._0, 1.0f));
00358 }
00359 
00360 ////////////////////////////////////////////////////////////////////
00361 //     Function: LQuaternion::ident_quat
00362 //       Access: Public, Static
00363 //  Description: Returns an identity quaternion.
00364 ////////////////////////////////////////////////////////////////////
00365 INLINE_LINMATH const FLOATNAME(LQuaternion) &FLOATNAME(LQuaternion)::
00366 ident_quat() {
00367   return _ident_quat;
00368 }
00369 
00370 ////////////////////////////////////////////////////////////////////
00371 //     Function: invert
00372 //  Description: Inverts the given quat and returns it.
00373 ////////////////////////////////////////////////////////////////////
00374 INLINE_LINMATH FLOATNAME(LQuaternion)
00375 invert(const FLOATNAME(LQuaternion) &a) {
00376   FLOATNAME(LQuaternion) result;
00377   bool nonsingular = result.invert_from(a);
00378   nassertr(nonsingular, FLOATNAME(LQuaternion)::ident_quat());
00379   return result;
00380 }
00381 
00382 ////////////////////////////////////////////////////////////////////
00383 //     Function: operator *(Matrix3, Quat)
00384 //       Access: public
00385 //  Description:
00386 ////////////////////////////////////////////////////////////////////
00387 INLINE_LINMATH FLOATNAME(LMatrix3) operator *(const FLOATNAME(LMatrix3) &m,
00388                              const FLOATNAME(LQuaternion) &q) {
00389   FLOATNAME(LMatrix3) q_matrix;
00390   q.extract_to_matrix(q_matrix);
00391 
00392   return m * q_matrix;
00393 }
00394 
00395 ////////////////////////////////////////////////////////////////////
00396 //     Function: operator *(Matrix4, Quat)
00397 //       Access: public
00398 //  Description:
00399 ////////////////////////////////////////////////////////////////////
00400 INLINE_LINMATH FLOATNAME(LMatrix4) operator *(const FLOATNAME(LMatrix4) &m,
00401                              const FLOATNAME(LQuaternion) &q) {
00402   FLOATNAME(LMatrix4) q_matrix;
00403   q.extract_to_matrix(q_matrix);
00404 
00405   // preserve the homogeneous coords and the translate
00406   FLOATNAME(LVector4) m_row3 = m.get_row(3);
00407   FLOATNAME(LVector4) m_col3 = m.get_col(3);
00408 
00409   q_matrix = m * q_matrix;
00410   q_matrix.set_row(3, m_row3);
00411   q_matrix.set_col(3, m_col3);
00412 
00413   return q_matrix;
00414 }

Generated on Fri May 2 00:40:13 2003 for Panda by doxygen1.3