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) ©) : 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 }