BasePoint4D.h (3387B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MOZILLA_BASEPOINT4D_H_ 8 #define MOZILLA_BASEPOINT4D_H_ 9 10 #include "mozilla/Assertions.h" 11 12 namespace mozilla { 13 namespace gfx { 14 15 /** 16 * Do not use this class directly. Subclass it, pass that subclass as the 17 * Sub parameter, and only use that subclass. This allows methods to safely 18 * cast 'this' to 'Sub*'. 19 */ 20 template <class T, class Sub> 21 struct BasePoint4D { 22 union { 23 struct { 24 T x, y, z, w; 25 }; 26 T components[4]; 27 }; 28 29 // Constructors 30 BasePoint4D() : x(0), y(0), z(0), w(0) {} 31 BasePoint4D(T aX, T aY, T aZ, T aW) : x(aX), y(aY), z(aZ), w(aW) {} 32 33 void MoveTo(T aX, T aY, T aZ, T aW) { 34 x = aX; 35 y = aY; 36 z = aZ; 37 w = aW; 38 } 39 void MoveBy(T aDx, T aDy, T aDz, T aDw) { 40 x += aDx; 41 y += aDy; 42 z += aDz; 43 w += aDw; 44 } 45 46 // Note that '=' isn't defined so we'll get the 47 // compiler generated default assignment operator 48 49 bool operator==(const Sub& aPoint) const { 50 return x == aPoint.x && y == aPoint.y && z == aPoint.z && w == aPoint.w; 51 } 52 bool operator!=(const Sub& aPoint) const { 53 return x != aPoint.x || y != aPoint.y || z != aPoint.z || w != aPoint.w; 54 } 55 56 Sub operator+(const Sub& aPoint) const { 57 return Sub(x + aPoint.x, y + aPoint.y, z + aPoint.z, w + aPoint.w); 58 } 59 Sub operator-(const Sub& aPoint) const { 60 return Sub(x - aPoint.x, y - aPoint.y, z - aPoint.z, w - aPoint.w); 61 } 62 Sub& operator+=(const Sub& aPoint) { 63 x += aPoint.x; 64 y += aPoint.y; 65 z += aPoint.z; 66 w += aPoint.w; 67 return *static_cast<Sub*>(this); 68 } 69 Sub& operator-=(const Sub& aPoint) { 70 x -= aPoint.x; 71 y -= aPoint.y; 72 z -= aPoint.z; 73 w -= aPoint.w; 74 return *static_cast<Sub*>(this); 75 } 76 77 Sub operator*(T aScale) const { 78 return Sub(x * aScale, y * aScale, z * aScale, w * aScale); 79 } 80 Sub operator/(T aScale) const { 81 return Sub(x / aScale, y / aScale, z / aScale, w / aScale); 82 } 83 84 Sub& operator*=(T aScale) { 85 x *= aScale; 86 y *= aScale; 87 z *= aScale; 88 w *= aScale; 89 return *static_cast<Sub*>(this); 90 } 91 92 Sub& operator/=(T aScale) { 93 x /= aScale; 94 y /= aScale; 95 z /= aScale; 96 w /= aScale; 97 return *static_cast<Sub*>(this); 98 } 99 100 Sub operator-() const { return Sub(-x, -y, -z, -w); } 101 102 T& operator[](int aIndex) { 103 MOZ_ASSERT(aIndex >= 0 && aIndex <= 3, "Invalid array index"); 104 return *((&x) + aIndex); 105 } 106 107 const T& operator[](int aIndex) const { 108 MOZ_ASSERT(aIndex >= 0 && aIndex <= 3, "Invalid array index"); 109 return *((&x) + aIndex); 110 } 111 112 T DotProduct(const Sub& aPoint) const { 113 return x * aPoint.x + y * aPoint.y + z * aPoint.z + w * aPoint.w; 114 } 115 116 // Ignores the 4th component! 117 Sub CrossProduct(const Sub& aPoint) const { 118 return Sub(y * aPoint.z - aPoint.y * z, z * aPoint.x - aPoint.z * x, 119 x * aPoint.y - aPoint.x * y, 0); 120 } 121 122 T Length() const { return sqrt(x * x + y * y + z * z + w * w); } 123 124 void Normalize() { *this /= Length(); } 125 126 bool HasPositiveWCoord() { return w > 0; } 127 }; 128 129 } // namespace gfx 130 } // namespace mozilla 131 132 #endif /* MOZILLA_BASEPOINT4D_H_ */