aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/llquaternion.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llmath/llquaternion.h164
1 files changed, 137 insertions, 27 deletions
diff --git a/linden/indra/llmath/llquaternion.h b/linden/indra/llmath/llquaternion.h
index 6805437..048db2d 100644
--- a/linden/indra/llmath/llquaternion.h
+++ b/linden/indra/llmath/llquaternion.h
@@ -57,10 +57,10 @@ public:
57 LLQuaternion(); // Initializes Quaternion to (0,0,0,1) 57 LLQuaternion(); // Initializes Quaternion to (0,0,0,1)
58 explicit LLQuaternion(const LLMatrix4 &mat); // Initializes Quaternion from Matrix4 58 explicit LLQuaternion(const LLMatrix4 &mat); // Initializes Quaternion from Matrix4
59 explicit LLQuaternion(const LLMatrix3 &mat); // Initializes Quaternion from Matrix3 59 explicit LLQuaternion(const LLMatrix3 &mat); // Initializes Quaternion from Matrix3
60 LLQuaternion(F32 x, F32 y, F32 z, F32 w); // Initializes Quaternion to normQuat(x, y, z, w) 60 LLQuaternion(F32 x, F32 y, F32 z, F32 w); // Initializes Quaternion to normalize(x, y, z, w)
61 LLQuaternion(F32 angle, const LLVector4 &vec); // Initializes Quaternion to axis_angle2quat(angle, vec) 61 LLQuaternion(F32 angle, const LLVector4 &vec); // Initializes Quaternion to axis_angle2quat(angle, vec)
62 LLQuaternion(F32 angle, const LLVector3 &vec); // Initializes Quaternion to axis_angle2quat(angle, vec) 62 LLQuaternion(F32 angle, const LLVector3 &vec); // Initializes Quaternion to axis_angle2quat(angle, vec)
63 LLQuaternion(const F32 *q); // Initializes Quaternion to normQuat(x, y, z, w) 63 LLQuaternion(const F32 *q); // Initializes Quaternion to normalize(x, y, z, w)
64 LLQuaternion(const LLVector3 &x_axis, 64 LLQuaternion(const LLVector3 &x_axis,
65 const LLVector3 &y_axis, 65 const LLVector3 &y_axis,
66 const LLVector3 &z_axis); // Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis] 66 const LLVector3 &z_axis); // Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis]
@@ -71,15 +71,27 @@ public:
71 void quantize16(F32 lower, F32 upper); // changes the vector to reflect quatization 71 void quantize16(F32 lower, F32 upper); // changes the vector to reflect quatization
72 void quantize8(F32 lower, F32 upper); // changes the vector to reflect quatization 72 void quantize8(F32 lower, F32 upper); // changes the vector to reflect quatization
73 void loadIdentity(); // Loads the quaternion that represents the identity rotation 73 void loadIdentity(); // Loads the quaternion that represents the identity rotation
74 const LLQuaternion& setQuatInit(F32 x, F32 y, F32 z, F32 w); // Sets Quaternion to normQuat(x, y, z, w) 74
75 const LLQuaternion& setQuat(const LLQuaternion &quat); // Copies Quaternion 75 const LLQuaternion& set(F32 x, F32 y, F32 z, F32 w); // Sets Quaternion to normalize(x, y, z, w)
76 const LLQuaternion& setQuat(const F32 *q); // Sets Quaternion to normQuat(quat[VX], quat[VY], quat[VZ], quat[VW]) 76 const LLQuaternion& set(const LLQuaternion &quat); // Copies Quaternion
77 const LLQuaternion& setQuat(const LLMatrix3 &mat); // Sets Quaternion to mat2quat(mat) 77 const LLQuaternion& set(const F32 *q); // Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW])
78 const LLQuaternion& setQuat(const LLMatrix4 &mat); // Sets Quaternion to mat2quat(mat) 78 const LLQuaternion& set(const LLMatrix3 &mat); // Sets Quaternion to mat2quat(mat)
79 const LLQuaternion& setQuat(F32 angle, F32 x, F32 y, F32 z); // Sets Quaternion to axis_angle2quat(angle, x, y, z) 79 const LLQuaternion& set(const LLMatrix4 &mat); // Sets Quaternion to mat2quat(mat)
80 const LLQuaternion& setQuat(F32 angle, const LLVector3 &vec); // Sets Quaternion to axis_angle2quat(angle, vec) 80
81 const LLQuaternion& setQuat(F32 angle, const LLVector4 &vec); // Sets Quaternion to axis_angle2quat(angle, vec) 81 const LLQuaternion& setAngleAxis(F32 angle, F32 x, F32 y, F32 z); // Sets Quaternion to axis_angle2quat(angle, x, y, z)
82 const LLQuaternion& setQuat(F32 roll, F32 pitch, F32 yaw); // Sets Quaternion to euler2quat(pitch, yaw, roll) 82 const LLQuaternion& setAngleAxis(F32 angle, const LLVector3 &vec); // Sets Quaternion to axis_angle2quat(angle, vec)
83 const LLQuaternion& setAngleAxis(F32 angle, const LLVector4 &vec); // Sets Quaternion to axis_angle2quat(angle, vec)
84 const LLQuaternion& setEulerAngles(F32 roll, F32 pitch, F32 yaw); // Sets Quaternion to euler2quat(pitch, yaw, roll)
85
86 const LLQuaternion& setQuatInit(F32 x, F32 y, F32 z, F32 w); // deprecated
87 const LLQuaternion& setQuat(const LLQuaternion &quat); // deprecated
88 const LLQuaternion& setQuat(const F32 *q); // deprecated
89 const LLQuaternion& setQuat(const LLMatrix3 &mat); // deprecated
90 const LLQuaternion& setQuat(const LLMatrix4 &mat); // deprecated
91 const LLQuaternion& setQuat(F32 angle, F32 x, F32 y, F32 z); // deprecated
92 const LLQuaternion& setQuat(F32 angle, const LLVector3 &vec); // deprecated
93 const LLQuaternion& setQuat(F32 angle, const LLVector4 &vec); // deprecated
94 const LLQuaternion& setQuat(F32 roll, F32 pitch, F32 yaw); // deprecated
83 95
84 LLMatrix4 getMatrix4(void) const; // Returns the Matrix4 equivalent of Quaternion 96 LLMatrix4 getMatrix4(void) const; // Returns the Matrix4 equivalent of Quaternion
85 LLMatrix3 getMatrix3(void) const; // Returns the Matrix3 equivalent of Quaternion 97 LLMatrix3 getMatrix3(void) const; // Returns the Matrix3 equivalent of Quaternion
@@ -87,11 +99,16 @@ public:
87 void getAngleAxis(F32* angle, LLVector3 &vec) const; 99 void getAngleAxis(F32* angle, LLVector3 &vec) const;
88 void getEulerAngles(F32 *roll, F32* pitch, F32 *yaw) const; 100 void getEulerAngles(F32 *roll, F32* pitch, F32 *yaw) const;
89 101
90 F32 normQuat(); // Normalizes Quaternion and returns magnitude 102 F32 normalize(); // Normalizes Quaternion and returns magnitude
91 const LLQuaternion& conjQuat(void); // Conjugates Quaternion and returns result 103 F32 normQuat(); // deprecated
104
105 const LLQuaternion& conjugate(void); // Conjugates Quaternion and returns result
106 const LLQuaternion& conjQuat(void); // deprecated
92 107
93 // Other useful methods 108 // Other useful methods
94 const LLQuaternion& transQuat(); // Transpose 109 const LLQuaternion& transpose(); // transpose (same as conjugate)
110 const LLQuaternion& transQuat(); // deprecated
111
95 void shortestArc(const LLVector3 &a, const LLVector3 &b); // shortest rotation from a to b 112 void shortestArc(const LLVector3 &a, const LLVector3 &b); // shortest rotation from a to b
96 const LLQuaternion& constrain(F32 radians); // constrains rotation to a cone angle specified in radians 113 const LLQuaternion& constrain(F32 radians); // constrains rotation to a cone angle specified in radians
97 114
@@ -189,7 +206,7 @@ inline LLQuaternion::LLQuaternion(F32 x, F32 y, F32 z, F32 w)
189 mQ[VS] = w; 206 mQ[VS] = w;
190 207
191 //RN: don't normalize this case as its used mainly for temporaries during calculations 208 //RN: don't normalize this case as its used mainly for temporaries during calculations
192 //normQuat(); 209 //normalize();
193 /* 210 /*
194 F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); 211 F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]);
195 mag -= 1.f; 212 mag -= 1.f;
@@ -205,7 +222,7 @@ inline LLQuaternion::LLQuaternion(const F32 *q)
205 mQ[VZ] = q[VZ]; 222 mQ[VZ] = q[VZ];
206 mQ[VS] = q[VW]; 223 mQ[VS] = q[VW];
207 224
208 normQuat(); 225 normalize();
209 /* 226 /*
210 F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); 227 F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]);
211 mag -= 1.f; 228 mag -= 1.f;
@@ -224,33 +241,67 @@ inline void LLQuaternion::loadIdentity()
224} 241}
225 242
226 243
244inline const LLQuaternion& LLQuaternion::set(F32 x, F32 y, F32 z, F32 w)
245{
246 mQ[VX] = x;
247 mQ[VY] = y;
248 mQ[VZ] = z;
249 mQ[VS] = w;
250 normalize();
251 return (*this);
252}
253
254inline const LLQuaternion& LLQuaternion::set(const LLQuaternion &quat)
255{
256 mQ[VX] = quat.mQ[VX];
257 mQ[VY] = quat.mQ[VY];
258 mQ[VZ] = quat.mQ[VZ];
259 mQ[VW] = quat.mQ[VW];
260 normalize();
261 return (*this);
262}
263
264inline const LLQuaternion& LLQuaternion::set(const F32 *q)
265{
266 mQ[VX] = q[VX];
267 mQ[VY] = q[VY];
268 mQ[VZ] = q[VZ];
269 mQ[VS] = q[VW];
270 normalize();
271 return (*this);
272}
273
274
275// deprecated
227inline const LLQuaternion& LLQuaternion::setQuatInit(F32 x, F32 y, F32 z, F32 w) 276inline const LLQuaternion& LLQuaternion::setQuatInit(F32 x, F32 y, F32 z, F32 w)
228{ 277{
229 mQ[VX] = x; 278 mQ[VX] = x;
230 mQ[VY] = y; 279 mQ[VY] = y;
231 mQ[VZ] = z; 280 mQ[VZ] = z;
232 mQ[VS] = w; 281 mQ[VS] = w;
233 normQuat(); 282 normalize();
234 return (*this); 283 return (*this);
235} 284}
236 285
286// deprecated
237inline const LLQuaternion& LLQuaternion::setQuat(const LLQuaternion &quat) 287inline const LLQuaternion& LLQuaternion::setQuat(const LLQuaternion &quat)
238{ 288{
239 mQ[VX] = quat.mQ[VX]; 289 mQ[VX] = quat.mQ[VX];
240 mQ[VY] = quat.mQ[VY]; 290 mQ[VY] = quat.mQ[VY];
241 mQ[VZ] = quat.mQ[VZ]; 291 mQ[VZ] = quat.mQ[VZ];
242 mQ[VW] = quat.mQ[VW]; 292 mQ[VW] = quat.mQ[VW];
243 normQuat(); 293 normalize();
244 return (*this); 294 return (*this);
245} 295}
246 296
297// deprecated
247inline const LLQuaternion& LLQuaternion::setQuat(const F32 *q) 298inline const LLQuaternion& LLQuaternion::setQuat(const F32 *q)
248{ 299{
249 mQ[VX] = q[VX]; 300 mQ[VX] = q[VX];
250 mQ[VY] = q[VY]; 301 mQ[VY] = q[VY];
251 mQ[VZ] = q[VZ]; 302 mQ[VZ] = q[VZ];
252 mQ[VS] = q[VW]; 303 mQ[VS] = q[VW];
253 normQuat(); 304 normalize();
254 return (*this); 305 return (*this);
255} 306}
256 307
@@ -270,10 +321,36 @@ inline void LLQuaternion::getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const
270 else 321 else
271 sin_a = 1.f/sin_a; 322 sin_a = 1.f/sin_a;
272 323
273 *angle = 2.0f * (F32) acos( cos_a ); 324 F32 temp_angle = 2.0f * (F32) acos( cos_a );
274 *x = mQ[VX] * sin_a; 325 if (temp_angle > F_PI)
275 *y = mQ[VY] * sin_a; 326 {
276 *z = mQ[VZ] * sin_a; 327 // The (angle,axis) pair should never have angles outside [PI, -PI]
328 // since we want the _shortest_ (angle,axis) solution.
329 // Since acos is defined for [0, PI], and we multiply by 2.0, we
330 // can push the angle outside the acceptible range.
331 // When this happens we set the angle to the other portion of a
332 // full 2PI rotation, and negate the axis, which reverses the
333 // direction of the rotation (by the right-hand rule).
334 *angle = 2.f * F_PI - temp_angle;
335 *x = - mQ[VX] * sin_a;
336 *y = - mQ[VY] * sin_a;
337 *z = - mQ[VZ] * sin_a;
338 }
339 else
340 {
341 *angle = temp_angle;
342 *x = mQ[VX] * sin_a;
343 *y = mQ[VY] * sin_a;
344 *z = mQ[VZ] * sin_a;
345 }
346}
347
348inline const LLQuaternion& LLQuaternion::conjugate()
349{
350 mQ[VX] *= -1.f;
351 mQ[VY] *= -1.f;
352 mQ[VZ] *= -1.f;
353 return (*this);
277} 354}
278 355
279inline const LLQuaternion& LLQuaternion::conjQuat() 356inline const LLQuaternion& LLQuaternion::conjQuat()
@@ -285,12 +362,21 @@ inline const LLQuaternion& LLQuaternion::conjQuat()
285} 362}
286 363
287// Transpose 364// Transpose
365inline const LLQuaternion& LLQuaternion::transpose()
366{
367 mQ[VX] *= -1.f;
368 mQ[VY] *= -1.f;
369 mQ[VZ] *= -1.f;
370 return (*this);
371}
372
373// deprecated
288inline const LLQuaternion& LLQuaternion::transQuat() 374inline const LLQuaternion& LLQuaternion::transQuat()
289{ 375{
290 mQ[VX] = -mQ[VX]; 376 mQ[VX] *= -1.f;
291 mQ[VY] = -mQ[VY]; 377 mQ[VY] *= -1.f;
292 mQ[VZ] = -mQ[VZ]; 378 mQ[VZ] *= -1.f;
293 return *this; 379 return (*this);
294} 380}
295 381
296 382
@@ -382,6 +468,30 @@ inline const LLQuaternion& operator*=(LLQuaternion &a, const LLQuaternion &b)
382 return a; 468 return a;
383} 469}
384 470
471inline F32 LLQuaternion::normalize()
472{
473 F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]);
474
475 if (mag > FP_MAG_THRESHOLD)
476 {
477 F32 oomag = 1.f/mag;
478 mQ[VX] *= oomag;
479 mQ[VY] *= oomag;
480 mQ[VZ] *= oomag;
481 mQ[VS] *= oomag;
482 }
483 else
484 {
485 mQ[VX] = 0.f;
486 mQ[VY] = 0.f;
487 mQ[VZ] = 0.f;
488 mQ[VS] = 1.f;
489 }
490
491 return mag;
492}
493
494// deprecated
385inline F32 LLQuaternion::normQuat() 495inline F32 LLQuaternion::normQuat()
386{ 496{
387 F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); 497 F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]);