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: Quaternion()23 Quaternion() 24 : x(0.0f), y(0.0f), z(0.0f), w(1.0f) 25 {} 26 Quaternion(Float aX,Float aY,Float aZ,Float aW)27 Quaternion(Float aX, Float aY, Float aZ, Float aW) 28 : x(aX), y(aY), z(aZ), w(aW) 29 {} 30 31 Quaternion(const Quaternion & aOther)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 Set(Float aX,Float aY,Float aZ,Float aW)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 Length()68 Float Length() const 69 { 70 return sqrt(x*x + y*y + z*z + w*w); 71 } 72 Conjugate()73 Quaternion& Conjugate() 74 { 75 x *= -1.f; y *= -1.f; z *= -1.f; 76 return *this; 77 } 78 Normalize()79 Quaternion& Normalize() 80 { 81 Float l = Length(); 82 if (l) { 83 l = 1.0f / l; 84 x *= l; y *= l; z *= l; w *= l; 85 } else { 86 x = y = z = 0.f; 87 w = 1.f; 88 } 89 return *this; 90 } 91 Invert()92 Quaternion& Invert() 93 { 94 return Conjugate().Normalize(); 95 } 96 RotatePoint(const Point3D & aPoint)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 112