Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef MOZILLA_GFX_QUATERNION_H_
7 : #define MOZILLA_GFX_QUATERNION_H_
8 :
9 : #include "Types.h"
10 : #include <math.h>
11 : #include <ostream>
12 : #include "mozilla/Attributes.h"
13 : #include "mozilla/DebugOnly.h"
14 : #include "mozilla/gfx/MatrixFwd.h"
15 : #include "mozilla/gfx/Point.h"
16 :
17 : namespace mozilla {
18 : namespace gfx {
19 :
20 : class Quaternion
21 : {
22 : public:
23 0 : Quaternion()
24 0 : : x(0.0f), y(0.0f), z(0.0f), w(1.0f)
25 0 : {}
26 :
27 : Quaternion(Float aX, Float aY, Float aZ, Float aW)
28 : : x(aX), y(aY), z(aZ), w(aW)
29 : {}
30 :
31 :
32 : Quaternion(const Quaternion& aOther)
33 : {
34 : memcpy(this, &aOther, sizeof(*this));
35 : }
36 :
37 : Float x, y, z, w;
38 :
39 : friend std::ostream& operator<<(std::ostream& aStream, const Quaternion& aQuat);
40 :
41 : void Set(Float aX, Float aY, Float aZ, Float aW)
42 : {
43 : x = aX; y = aY; z = aZ; w = aW;
44 : }
45 :
46 : // Assumes upper 3x3 of aMatrix is a pure rotation matrix (no scaling)
47 : void SetFromRotationMatrix(const Matrix4x4& aMatrix);
48 :
49 : // result = this * aQuat
50 : Quaternion operator*(const Quaternion &aQuat) const
51 : {
52 : Quaternion o;
53 : const Float bx = aQuat.x, by = aQuat.y, bz = aQuat.z, bw = aQuat.w;
54 :
55 : o.x = x*bw + w*bx + y*bz - z*by;
56 : o.y = y*bw + w*by + z*bx - x*bz;
57 : o.z = z*bw + w*bz + x*by - y*bx;
58 : o.w = w*bw - x*bx - y*by - z*bz;
59 : return o;
60 : }
61 :
62 : Quaternion& operator*=(const Quaternion &aQuat)
63 : {
64 : *this = *this * aQuat;
65 : return *this;
66 : }
67 :
68 0 : Float Length() const
69 : {
70 0 : return sqrt(x*x + y*y + z*z + w*w);
71 : }
72 :
73 0 : Quaternion& Conjugate()
74 : {
75 0 : x *= -1.f; y *= -1.f; z *= -1.f;
76 0 : return *this;
77 : }
78 :
79 0 : Quaternion& Normalize()
80 : {
81 0 : Float l = Length();
82 0 : if (l) {
83 0 : l = 1.0f / l;
84 0 : x *= l; y *= l; z *= l; w *= l;
85 : } else {
86 0 : x = y = z = 0.f;
87 0 : w = 1.f;
88 : }
89 0 : return *this;
90 : }
91 :
92 0 : Quaternion& Invert()
93 : {
94 0 : return Conjugate().Normalize();
95 : }
96 :
97 : Point3D RotatePoint(const Point3D& aPoint) {
98 : Float uvx = Float(2.0) * (y*aPoint.z - z*aPoint.y);
99 : Float uvy = Float(2.0) * (z*aPoint.x - x*aPoint.z);
100 : Float uvz = Float(2.0) * (x*aPoint.y - y*aPoint.x);
101 :
102 : return Point3D(aPoint.x + w*uvx + y*uvz - z*uvy,
103 : aPoint.y + w*uvy + z*uvx - x*uvz,
104 : aPoint.z + w*uvz + x*uvy - y*uvx);
105 : }
106 : };
107 :
108 : } // namespace gfx
109 : } // namespace mozilla
110 :
111 : #endif
|