diff options
author | David Walter Seikel | 2013-01-13 18:54:10 +1000 |
---|---|---|
committer | David Walter Seikel | 2013-01-13 18:54:10 +1000 |
commit | 959831f4ef5a3e797f576c3de08cd65032c997ad (patch) | |
tree | e7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/include/vector3d.h | |
parent | Add info about changes to Irrlicht. (diff) | |
download | SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2 SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz |
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to 'libraries/irrlicht-1.8/include/vector3d.h')
-rw-r--r-- | libraries/irrlicht-1.8/include/vector3d.h | 916 |
1 files changed, 458 insertions, 458 deletions
diff --git a/libraries/irrlicht-1.8/include/vector3d.h b/libraries/irrlicht-1.8/include/vector3d.h index fd6c50d..d582978 100644 --- a/libraries/irrlicht-1.8/include/vector3d.h +++ b/libraries/irrlicht-1.8/include/vector3d.h | |||
@@ -1,458 +1,458 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | 1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt |
2 | // This file is part of the "Irrlicht Engine". | 2 | // This file is part of the "Irrlicht Engine". |
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | 3 | // For conditions of distribution and use, see copyright notice in irrlicht.h |
4 | 4 | ||
5 | #ifndef __IRR_POINT_3D_H_INCLUDED__ | 5 | #ifndef __IRR_POINT_3D_H_INCLUDED__ |
6 | #define __IRR_POINT_3D_H_INCLUDED__ | 6 | #define __IRR_POINT_3D_H_INCLUDED__ |
7 | 7 | ||
8 | #include "irrMath.h" | 8 | #include "irrMath.h" |
9 | 9 | ||
10 | namespace irr | 10 | namespace irr |
11 | { | 11 | { |
12 | namespace core | 12 | namespace core |
13 | { | 13 | { |
14 | 14 | ||
15 | //! 3d vector template class with lots of operators and methods. | 15 | //! 3d vector template class with lots of operators and methods. |
16 | /** The vector3d class is used in Irrlicht for three main purposes: | 16 | /** The vector3d class is used in Irrlicht for three main purposes: |
17 | 1) As a direction vector (most of the methods assume this). | 17 | 1) As a direction vector (most of the methods assume this). |
18 | 2) As a position in 3d space (which is synonymous with a direction vector from the origin to this position). | 18 | 2) As a position in 3d space (which is synonymous with a direction vector from the origin to this position). |
19 | 3) To hold three Euler rotations, where X is pitch, Y is yaw and Z is roll. | 19 | 3) To hold three Euler rotations, where X is pitch, Y is yaw and Z is roll. |
20 | */ | 20 | */ |
21 | template <class T> | 21 | template <class T> |
22 | class vector3d | 22 | class vector3d |
23 | { | 23 | { |
24 | public: | 24 | public: |
25 | //! Default constructor (null vector). | 25 | //! Default constructor (null vector). |
26 | vector3d() : X(0), Y(0), Z(0) {} | 26 | vector3d() : X(0), Y(0), Z(0) {} |
27 | //! Constructor with three different values | 27 | //! Constructor with three different values |
28 | vector3d(T nx, T ny, T nz) : X(nx), Y(ny), Z(nz) {} | 28 | vector3d(T nx, T ny, T nz) : X(nx), Y(ny), Z(nz) {} |
29 | //! Constructor with the same value for all elements | 29 | //! Constructor with the same value for all elements |
30 | explicit vector3d(T n) : X(n), Y(n), Z(n) {} | 30 | explicit vector3d(T n) : X(n), Y(n), Z(n) {} |
31 | //! Copy constructor | 31 | //! Copy constructor |
32 | vector3d(const vector3d<T>& other) : X(other.X), Y(other.Y), Z(other.Z) {} | 32 | vector3d(const vector3d<T>& other) : X(other.X), Y(other.Y), Z(other.Z) {} |
33 | 33 | ||
34 | // operators | 34 | // operators |
35 | 35 | ||
36 | vector3d<T> operator-() const { return vector3d<T>(-X, -Y, -Z); } | 36 | vector3d<T> operator-() const { return vector3d<T>(-X, -Y, -Z); } |
37 | 37 | ||
38 | vector3d<T>& operator=(const vector3d<T>& other) { X = other.X; Y = other.Y; Z = other.Z; return *this; } | 38 | vector3d<T>& operator=(const vector3d<T>& other) { X = other.X; Y = other.Y; Z = other.Z; return *this; } |
39 | 39 | ||
40 | vector3d<T> operator+(const vector3d<T>& other) const { return vector3d<T>(X + other.X, Y + other.Y, Z + other.Z); } | 40 | vector3d<T> operator+(const vector3d<T>& other) const { return vector3d<T>(X + other.X, Y + other.Y, Z + other.Z); } |
41 | vector3d<T>& operator+=(const vector3d<T>& other) { X+=other.X; Y+=other.Y; Z+=other.Z; return *this; } | 41 | vector3d<T>& operator+=(const vector3d<T>& other) { X+=other.X; Y+=other.Y; Z+=other.Z; return *this; } |
42 | vector3d<T> operator+(const T val) const { return vector3d<T>(X + val, Y + val, Z + val); } | 42 | vector3d<T> operator+(const T val) const { return vector3d<T>(X + val, Y + val, Z + val); } |
43 | vector3d<T>& operator+=(const T val) { X+=val; Y+=val; Z+=val; return *this; } | 43 | vector3d<T>& operator+=(const T val) { X+=val; Y+=val; Z+=val; return *this; } |
44 | 44 | ||
45 | vector3d<T> operator-(const vector3d<T>& other) const { return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z); } | 45 | vector3d<T> operator-(const vector3d<T>& other) const { return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z); } |
46 | vector3d<T>& operator-=(const vector3d<T>& other) { X-=other.X; Y-=other.Y; Z-=other.Z; return *this; } | 46 | vector3d<T>& operator-=(const vector3d<T>& other) { X-=other.X; Y-=other.Y; Z-=other.Z; return *this; } |
47 | vector3d<T> operator-(const T val) const { return vector3d<T>(X - val, Y - val, Z - val); } | 47 | vector3d<T> operator-(const T val) const { return vector3d<T>(X - val, Y - val, Z - val); } |
48 | vector3d<T>& operator-=(const T val) { X-=val; Y-=val; Z-=val; return *this; } | 48 | vector3d<T>& operator-=(const T val) { X-=val; Y-=val; Z-=val; return *this; } |
49 | 49 | ||
50 | vector3d<T> operator*(const vector3d<T>& other) const { return vector3d<T>(X * other.X, Y * other.Y, Z * other.Z); } | 50 | vector3d<T> operator*(const vector3d<T>& other) const { return vector3d<T>(X * other.X, Y * other.Y, Z * other.Z); } |
51 | vector3d<T>& operator*=(const vector3d<T>& other) { X*=other.X; Y*=other.Y; Z*=other.Z; return *this; } | 51 | vector3d<T>& operator*=(const vector3d<T>& other) { X*=other.X; Y*=other.Y; Z*=other.Z; return *this; } |
52 | vector3d<T> operator*(const T v) const { return vector3d<T>(X * v, Y * v, Z * v); } | 52 | vector3d<T> operator*(const T v) const { return vector3d<T>(X * v, Y * v, Z * v); } |
53 | vector3d<T>& operator*=(const T v) { X*=v; Y*=v; Z*=v; return *this; } | 53 | vector3d<T>& operator*=(const T v) { X*=v; Y*=v; Z*=v; return *this; } |
54 | 54 | ||
55 | vector3d<T> operator/(const vector3d<T>& other) const { return vector3d<T>(X / other.X, Y / other.Y, Z / other.Z); } | 55 | vector3d<T> operator/(const vector3d<T>& other) const { return vector3d<T>(X / other.X, Y / other.Y, Z / other.Z); } |
56 | vector3d<T>& operator/=(const vector3d<T>& other) { X/=other.X; Y/=other.Y; Z/=other.Z; return *this; } | 56 | vector3d<T>& operator/=(const vector3d<T>& other) { X/=other.X; Y/=other.Y; Z/=other.Z; return *this; } |
57 | vector3d<T> operator/(const T v) const { T i=(T)1.0/v; return vector3d<T>(X * i, Y * i, Z * i); } | 57 | vector3d<T> operator/(const T v) const { T i=(T)1.0/v; return vector3d<T>(X * i, Y * i, Z * i); } |
58 | vector3d<T>& operator/=(const T v) { T i=(T)1.0/v; X*=i; Y*=i; Z*=i; return *this; } | 58 | vector3d<T>& operator/=(const T v) { T i=(T)1.0/v; X*=i; Y*=i; Z*=i; return *this; } |
59 | 59 | ||
60 | //! sort in order X, Y, Z. Equality with rounding tolerance. | 60 | //! sort in order X, Y, Z. Equality with rounding tolerance. |
61 | bool operator<=(const vector3d<T>&other) const | 61 | bool operator<=(const vector3d<T>&other) const |
62 | { | 62 | { |
63 | return (X<other.X || core::equals(X, other.X)) || | 63 | return (X<other.X || core::equals(X, other.X)) || |
64 | (core::equals(X, other.X) && (Y<other.Y || core::equals(Y, other.Y))) || | 64 | (core::equals(X, other.X) && (Y<other.Y || core::equals(Y, other.Y))) || |
65 | (core::equals(X, other.X) && core::equals(Y, other.Y) && (Z<other.Z || core::equals(Z, other.Z))); | 65 | (core::equals(X, other.X) && core::equals(Y, other.Y) && (Z<other.Z || core::equals(Z, other.Z))); |
66 | } | 66 | } |
67 | 67 | ||
68 | //! sort in order X, Y, Z. Equality with rounding tolerance. | 68 | //! sort in order X, Y, Z. Equality with rounding tolerance. |
69 | bool operator>=(const vector3d<T>&other) const | 69 | bool operator>=(const vector3d<T>&other) const |
70 | { | 70 | { |
71 | return (X>other.X || core::equals(X, other.X)) || | 71 | return (X>other.X || core::equals(X, other.X)) || |
72 | (core::equals(X, other.X) && (Y>other.Y || core::equals(Y, other.Y))) || | 72 | (core::equals(X, other.X) && (Y>other.Y || core::equals(Y, other.Y))) || |
73 | (core::equals(X, other.X) && core::equals(Y, other.Y) && (Z>other.Z || core::equals(Z, other.Z))); | 73 | (core::equals(X, other.X) && core::equals(Y, other.Y) && (Z>other.Z || core::equals(Z, other.Z))); |
74 | } | 74 | } |
75 | 75 | ||
76 | //! sort in order X, Y, Z. Difference must be above rounding tolerance. | 76 | //! sort in order X, Y, Z. Difference must be above rounding tolerance. |
77 | bool operator<(const vector3d<T>&other) const | 77 | bool operator<(const vector3d<T>&other) const |
78 | { | 78 | { |
79 | return (X<other.X && !core::equals(X, other.X)) || | 79 | return (X<other.X && !core::equals(X, other.X)) || |
80 | (core::equals(X, other.X) && Y<other.Y && !core::equals(Y, other.Y)) || | 80 | (core::equals(X, other.X) && Y<other.Y && !core::equals(Y, other.Y)) || |
81 | (core::equals(X, other.X) && core::equals(Y, other.Y) && Z<other.Z && !core::equals(Z, other.Z)); | 81 | (core::equals(X, other.X) && core::equals(Y, other.Y) && Z<other.Z && !core::equals(Z, other.Z)); |
82 | } | 82 | } |
83 | 83 | ||
84 | //! sort in order X, Y, Z. Difference must be above rounding tolerance. | 84 | //! sort in order X, Y, Z. Difference must be above rounding tolerance. |
85 | bool operator>(const vector3d<T>&other) const | 85 | bool operator>(const vector3d<T>&other) const |
86 | { | 86 | { |
87 | return (X>other.X && !core::equals(X, other.X)) || | 87 | return (X>other.X && !core::equals(X, other.X)) || |
88 | (core::equals(X, other.X) && Y>other.Y && !core::equals(Y, other.Y)) || | 88 | (core::equals(X, other.X) && Y>other.Y && !core::equals(Y, other.Y)) || |
89 | (core::equals(X, other.X) && core::equals(Y, other.Y) && Z>other.Z && !core::equals(Z, other.Z)); | 89 | (core::equals(X, other.X) && core::equals(Y, other.Y) && Z>other.Z && !core::equals(Z, other.Z)); |
90 | } | 90 | } |
91 | 91 | ||
92 | //! use weak float compare | 92 | //! use weak float compare |
93 | bool operator==(const vector3d<T>& other) const | 93 | bool operator==(const vector3d<T>& other) const |
94 | { | 94 | { |
95 | return this->equals(other); | 95 | return this->equals(other); |
96 | } | 96 | } |
97 | 97 | ||
98 | bool operator!=(const vector3d<T>& other) const | 98 | bool operator!=(const vector3d<T>& other) const |
99 | { | 99 | { |
100 | return !this->equals(other); | 100 | return !this->equals(other); |
101 | } | 101 | } |
102 | 102 | ||
103 | // functions | 103 | // functions |
104 | 104 | ||
105 | //! returns if this vector equals the other one, taking floating point rounding errors into account | 105 | //! returns if this vector equals the other one, taking floating point rounding errors into account |
106 | bool equals(const vector3d<T>& other, const T tolerance = (T)ROUNDING_ERROR_f32 ) const | 106 | bool equals(const vector3d<T>& other, const T tolerance = (T)ROUNDING_ERROR_f32 ) const |
107 | { | 107 | { |
108 | return core::equals(X, other.X, tolerance) && | 108 | return core::equals(X, other.X, tolerance) && |
109 | core::equals(Y, other.Y, tolerance) && | 109 | core::equals(Y, other.Y, tolerance) && |
110 | core::equals(Z, other.Z, tolerance); | 110 | core::equals(Z, other.Z, tolerance); |
111 | } | 111 | } |
112 | 112 | ||
113 | vector3d<T>& set(const T nx, const T ny, const T nz) {X=nx; Y=ny; Z=nz; return *this;} | 113 | vector3d<T>& set(const T nx, const T ny, const T nz) {X=nx; Y=ny; Z=nz; return *this;} |
114 | vector3d<T>& set(const vector3d<T>& p) {X=p.X; Y=p.Y; Z=p.Z;return *this;} | 114 | vector3d<T>& set(const vector3d<T>& p) {X=p.X; Y=p.Y; Z=p.Z;return *this;} |
115 | 115 | ||
116 | //! Get length of the vector. | 116 | //! Get length of the vector. |
117 | T getLength() const { return core::squareroot( X*X + Y*Y + Z*Z ); } | 117 | T getLength() const { return core::squareroot( X*X + Y*Y + Z*Z ); } |
118 | 118 | ||
119 | //! Get squared length of the vector. | 119 | //! Get squared length of the vector. |
120 | /** This is useful because it is much faster than getLength(). | 120 | /** This is useful because it is much faster than getLength(). |
121 | \return Squared length of the vector. */ | 121 | \return Squared length of the vector. */ |
122 | T getLengthSQ() const { return X*X + Y*Y + Z*Z; } | 122 | T getLengthSQ() const { return X*X + Y*Y + Z*Z; } |
123 | 123 | ||
124 | //! Get the dot product with another vector. | 124 | //! Get the dot product with another vector. |
125 | T dotProduct(const vector3d<T>& other) const | 125 | T dotProduct(const vector3d<T>& other) const |
126 | { | 126 | { |
127 | return X*other.X + Y*other.Y + Z*other.Z; | 127 | return X*other.X + Y*other.Y + Z*other.Z; |
128 | } | 128 | } |
129 | 129 | ||
130 | //! Get distance from another point. | 130 | //! Get distance from another point. |
131 | /** Here, the vector is interpreted as point in 3 dimensional space. */ | 131 | /** Here, the vector is interpreted as point in 3 dimensional space. */ |
132 | T getDistanceFrom(const vector3d<T>& other) const | 132 | T getDistanceFrom(const vector3d<T>& other) const |
133 | { | 133 | { |
134 | return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z).getLength(); | 134 | return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z).getLength(); |
135 | } | 135 | } |
136 | 136 | ||
137 | //! Returns squared distance from another point. | 137 | //! Returns squared distance from another point. |
138 | /** Here, the vector is interpreted as point in 3 dimensional space. */ | 138 | /** Here, the vector is interpreted as point in 3 dimensional space. */ |
139 | T getDistanceFromSQ(const vector3d<T>& other) const | 139 | T getDistanceFromSQ(const vector3d<T>& other) const |
140 | { | 140 | { |
141 | return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z).getLengthSQ(); | 141 | return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z).getLengthSQ(); |
142 | } | 142 | } |
143 | 143 | ||
144 | //! Calculates the cross product with another vector. | 144 | //! Calculates the cross product with another vector. |
145 | /** \param p Vector to multiply with. | 145 | /** \param p Vector to multiply with. |
146 | \return Crossproduct of this vector with p. */ | 146 | \return Crossproduct of this vector with p. */ |
147 | vector3d<T> crossProduct(const vector3d<T>& p) const | 147 | vector3d<T> crossProduct(const vector3d<T>& p) const |
148 | { | 148 | { |
149 | return vector3d<T>(Y * p.Z - Z * p.Y, Z * p.X - X * p.Z, X * p.Y - Y * p.X); | 149 | return vector3d<T>(Y * p.Z - Z * p.Y, Z * p.X - X * p.Z, X * p.Y - Y * p.X); |
150 | } | 150 | } |
151 | 151 | ||
152 | //! Returns if this vector interpreted as a point is on a line between two other points. | 152 | //! Returns if this vector interpreted as a point is on a line between two other points. |
153 | /** It is assumed that the point is on the line. | 153 | /** It is assumed that the point is on the line. |
154 | \param begin Beginning vector to compare between. | 154 | \param begin Beginning vector to compare between. |
155 | \param end Ending vector to compare between. | 155 | \param end Ending vector to compare between. |
156 | \return True if this vector is between begin and end, false if not. */ | 156 | \return True if this vector is between begin and end, false if not. */ |
157 | bool isBetweenPoints(const vector3d<T>& begin, const vector3d<T>& end) const | 157 | bool isBetweenPoints(const vector3d<T>& begin, const vector3d<T>& end) const |
158 | { | 158 | { |
159 | const T f = (end - begin).getLengthSQ(); | 159 | const T f = (end - begin).getLengthSQ(); |
160 | return getDistanceFromSQ(begin) <= f && | 160 | return getDistanceFromSQ(begin) <= f && |
161 | getDistanceFromSQ(end) <= f; | 161 | getDistanceFromSQ(end) <= f; |
162 | } | 162 | } |
163 | 163 | ||
164 | //! Normalizes the vector. | 164 | //! Normalizes the vector. |
165 | /** In case of the 0 vector the result is still 0, otherwise | 165 | /** In case of the 0 vector the result is still 0, otherwise |
166 | the length of the vector will be 1. | 166 | the length of the vector will be 1. |
167 | \return Reference to this vector after normalization. */ | 167 | \return Reference to this vector after normalization. */ |
168 | vector3d<T>& normalize() | 168 | vector3d<T>& normalize() |
169 | { | 169 | { |
170 | f64 length = X*X + Y*Y + Z*Z; | 170 | f64 length = X*X + Y*Y + Z*Z; |
171 | if (length == 0 ) // this check isn't an optimization but prevents getting NAN in the sqrt. | 171 | if (length == 0 ) // this check isn't an optimization but prevents getting NAN in the sqrt. |
172 | return *this; | 172 | return *this; |
173 | length = core::reciprocal_squareroot(length); | 173 | length = core::reciprocal_squareroot(length); |
174 | 174 | ||
175 | X = (T)(X * length); | 175 | X = (T)(X * length); |
176 | Y = (T)(Y * length); | 176 | Y = (T)(Y * length); |
177 | Z = (T)(Z * length); | 177 | Z = (T)(Z * length); |
178 | return *this; | 178 | return *this; |
179 | } | 179 | } |
180 | 180 | ||
181 | //! Sets the length of the vector to a new value | 181 | //! Sets the length of the vector to a new value |
182 | vector3d<T>& setLength(T newlength) | 182 | vector3d<T>& setLength(T newlength) |
183 | { | 183 | { |
184 | normalize(); | 184 | normalize(); |
185 | return (*this *= newlength); | 185 | return (*this *= newlength); |
186 | } | 186 | } |
187 | 187 | ||
188 | //! Inverts the vector. | 188 | //! Inverts the vector. |
189 | vector3d<T>& invert() | 189 | vector3d<T>& invert() |
190 | { | 190 | { |
191 | X *= -1; | 191 | X *= -1; |
192 | Y *= -1; | 192 | Y *= -1; |
193 | Z *= -1; | 193 | Z *= -1; |
194 | return *this; | 194 | return *this; |
195 | } | 195 | } |
196 | 196 | ||
197 | //! Rotates the vector by a specified number of degrees around the Y axis and the specified center. | 197 | //! Rotates the vector by a specified number of degrees around the Y axis and the specified center. |
198 | /** \param degrees Number of degrees to rotate around the Y axis. | 198 | /** \param degrees Number of degrees to rotate around the Y axis. |
199 | \param center The center of the rotation. */ | 199 | \param center The center of the rotation. */ |
200 | void rotateXZBy(f64 degrees, const vector3d<T>& center=vector3d<T>()) | 200 | void rotateXZBy(f64 degrees, const vector3d<T>& center=vector3d<T>()) |
201 | { | 201 | { |
202 | degrees *= DEGTORAD64; | 202 | degrees *= DEGTORAD64; |
203 | f64 cs = cos(degrees); | 203 | f64 cs = cos(degrees); |
204 | f64 sn = sin(degrees); | 204 | f64 sn = sin(degrees); |
205 | X -= center.X; | 205 | X -= center.X; |
206 | Z -= center.Z; | 206 | Z -= center.Z; |
207 | set((T)(X*cs - Z*sn), Y, (T)(X*sn + Z*cs)); | 207 | set((T)(X*cs - Z*sn), Y, (T)(X*sn + Z*cs)); |
208 | X += center.X; | 208 | X += center.X; |
209 | Z += center.Z; | 209 | Z += center.Z; |
210 | } | 210 | } |
211 | 211 | ||
212 | //! Rotates the vector by a specified number of degrees around the Z axis and the specified center. | 212 | //! Rotates the vector by a specified number of degrees around the Z axis and the specified center. |
213 | /** \param degrees: Number of degrees to rotate around the Z axis. | 213 | /** \param degrees: Number of degrees to rotate around the Z axis. |
214 | \param center: The center of the rotation. */ | 214 | \param center: The center of the rotation. */ |
215 | void rotateXYBy(f64 degrees, const vector3d<T>& center=vector3d<T>()) | 215 | void rotateXYBy(f64 degrees, const vector3d<T>& center=vector3d<T>()) |
216 | { | 216 | { |
217 | degrees *= DEGTORAD64; | 217 | degrees *= DEGTORAD64; |
218 | f64 cs = cos(degrees); | 218 | f64 cs = cos(degrees); |
219 | f64 sn = sin(degrees); | 219 | f64 sn = sin(degrees); |
220 | X -= center.X; | 220 | X -= center.X; |
221 | Y -= center.Y; | 221 | Y -= center.Y; |
222 | set((T)(X*cs - Y*sn), (T)(X*sn + Y*cs), Z); | 222 | set((T)(X*cs - Y*sn), (T)(X*sn + Y*cs), Z); |
223 | X += center.X; | 223 | X += center.X; |
224 | Y += center.Y; | 224 | Y += center.Y; |
225 | } | 225 | } |
226 | 226 | ||
227 | //! Rotates the vector by a specified number of degrees around the X axis and the specified center. | 227 | //! Rotates the vector by a specified number of degrees around the X axis and the specified center. |
228 | /** \param degrees: Number of degrees to rotate around the X axis. | 228 | /** \param degrees: Number of degrees to rotate around the X axis. |
229 | \param center: The center of the rotation. */ | 229 | \param center: The center of the rotation. */ |
230 | void rotateYZBy(f64 degrees, const vector3d<T>& center=vector3d<T>()) | 230 | void rotateYZBy(f64 degrees, const vector3d<T>& center=vector3d<T>()) |
231 | { | 231 | { |
232 | degrees *= DEGTORAD64; | 232 | degrees *= DEGTORAD64; |
233 | f64 cs = cos(degrees); | 233 | f64 cs = cos(degrees); |
234 | f64 sn = sin(degrees); | 234 | f64 sn = sin(degrees); |
235 | Z -= center.Z; | 235 | Z -= center.Z; |
236 | Y -= center.Y; | 236 | Y -= center.Y; |
237 | set(X, (T)(Y*cs - Z*sn), (T)(Y*sn + Z*cs)); | 237 | set(X, (T)(Y*cs - Z*sn), (T)(Y*sn + Z*cs)); |
238 | Z += center.Z; | 238 | Z += center.Z; |
239 | Y += center.Y; | 239 | Y += center.Y; |
240 | } | 240 | } |
241 | 241 | ||
242 | //! Creates an interpolated vector between this vector and another vector. | 242 | //! Creates an interpolated vector between this vector and another vector. |
243 | /** \param other The other vector to interpolate with. | 243 | /** \param other The other vector to interpolate with. |
244 | \param d Interpolation value between 0.0f (all the other vector) and 1.0f (all this vector). | 244 | \param d Interpolation value between 0.0f (all the other vector) and 1.0f (all this vector). |
245 | Note that this is the opposite direction of interpolation to getInterpolated_quadratic() | 245 | Note that this is the opposite direction of interpolation to getInterpolated_quadratic() |
246 | \return An interpolated vector. This vector is not modified. */ | 246 | \return An interpolated vector. This vector is not modified. */ |
247 | vector3d<T> getInterpolated(const vector3d<T>& other, f64 d) const | 247 | vector3d<T> getInterpolated(const vector3d<T>& other, f64 d) const |
248 | { | 248 | { |
249 | const f64 inv = 1.0 - d; | 249 | const f64 inv = 1.0 - d; |
250 | return vector3d<T>((T)(other.X*inv + X*d), (T)(other.Y*inv + Y*d), (T)(other.Z*inv + Z*d)); | 250 | return vector3d<T>((T)(other.X*inv + X*d), (T)(other.Y*inv + Y*d), (T)(other.Z*inv + Z*d)); |
251 | } | 251 | } |
252 | 252 | ||
253 | //! Creates a quadratically interpolated vector between this and two other vectors. | 253 | //! Creates a quadratically interpolated vector between this and two other vectors. |
254 | /** \param v2 Second vector to interpolate with. | 254 | /** \param v2 Second vector to interpolate with. |
255 | \param v3 Third vector to interpolate with (maximum at 1.0f) | 255 | \param v3 Third vector to interpolate with (maximum at 1.0f) |
256 | \param d Interpolation value between 0.0f (all this vector) and 1.0f (all the 3rd vector). | 256 | \param d Interpolation value between 0.0f (all this vector) and 1.0f (all the 3rd vector). |
257 | Note that this is the opposite direction of interpolation to getInterpolated() and interpolate() | 257 | Note that this is the opposite direction of interpolation to getInterpolated() and interpolate() |
258 | \return An interpolated vector. This vector is not modified. */ | 258 | \return An interpolated vector. This vector is not modified. */ |
259 | vector3d<T> getInterpolated_quadratic(const vector3d<T>& v2, const vector3d<T>& v3, f64 d) const | 259 | vector3d<T> getInterpolated_quadratic(const vector3d<T>& v2, const vector3d<T>& v3, f64 d) const |
260 | { | 260 | { |
261 | // this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d; | 261 | // this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d; |
262 | const f64 inv = (T) 1.0 - d; | 262 | const f64 inv = (T) 1.0 - d; |
263 | const f64 mul0 = inv * inv; | 263 | const f64 mul0 = inv * inv; |
264 | const f64 mul1 = (T) 2.0 * d * inv; | 264 | const f64 mul1 = (T) 2.0 * d * inv; |
265 | const f64 mul2 = d * d; | 265 | const f64 mul2 = d * d; |
266 | 266 | ||
267 | return vector3d<T> ((T)(X * mul0 + v2.X * mul1 + v3.X * mul2), | 267 | return vector3d<T> ((T)(X * mul0 + v2.X * mul1 + v3.X * mul2), |
268 | (T)(Y * mul0 + v2.Y * mul1 + v3.Y * mul2), | 268 | (T)(Y * mul0 + v2.Y * mul1 + v3.Y * mul2), |
269 | (T)(Z * mul0 + v2.Z * mul1 + v3.Z * mul2)); | 269 | (T)(Z * mul0 + v2.Z * mul1 + v3.Z * mul2)); |
270 | } | 270 | } |
271 | 271 | ||
272 | //! Sets this vector to the linearly interpolated vector between a and b. | 272 | //! Sets this vector to the linearly interpolated vector between a and b. |
273 | /** \param a first vector to interpolate with, maximum at 1.0f | 273 | /** \param a first vector to interpolate with, maximum at 1.0f |
274 | \param b second vector to interpolate with, maximum at 0.0f | 274 | \param b second vector to interpolate with, maximum at 0.0f |
275 | \param d Interpolation value between 0.0f (all vector b) and 1.0f (all vector a) | 275 | \param d Interpolation value between 0.0f (all vector b) and 1.0f (all vector a) |
276 | Note that this is the opposite direction of interpolation to getInterpolated_quadratic() | 276 | Note that this is the opposite direction of interpolation to getInterpolated_quadratic() |
277 | */ | 277 | */ |
278 | vector3d<T>& interpolate(const vector3d<T>& a, const vector3d<T>& b, f64 d) | 278 | vector3d<T>& interpolate(const vector3d<T>& a, const vector3d<T>& b, f64 d) |
279 | { | 279 | { |
280 | X = (T)((f64)b.X + ( ( a.X - b.X ) * d )); | 280 | X = (T)((f64)b.X + ( ( a.X - b.X ) * d )); |
281 | Y = (T)((f64)b.Y + ( ( a.Y - b.Y ) * d )); | 281 | Y = (T)((f64)b.Y + ( ( a.Y - b.Y ) * d )); |
282 | Z = (T)((f64)b.Z + ( ( a.Z - b.Z ) * d )); | 282 | Z = (T)((f64)b.Z + ( ( a.Z - b.Z ) * d )); |
283 | return *this; | 283 | return *this; |
284 | } | 284 | } |
285 | 285 | ||
286 | 286 | ||
287 | //! Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector. | 287 | //! Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector. |
288 | /** Thanks to Arras on the Irrlicht forums for this method. This utility method is very useful for | 288 | /** Thanks to Arras on the Irrlicht forums for this method. This utility method is very useful for |
289 | orienting scene nodes towards specific targets. For example, if this vector represents the difference | 289 | orienting scene nodes towards specific targets. For example, if this vector represents the difference |
290 | between two scene nodes, then applying the result of getHorizontalAngle() to one scene node will point | 290 | between two scene nodes, then applying the result of getHorizontalAngle() to one scene node will point |
291 | it at the other one. | 291 | it at the other one. |
292 | Example code: | 292 | Example code: |
293 | // Where target and seeker are of type ISceneNode* | 293 | // Where target and seeker are of type ISceneNode* |
294 | const vector3df toTarget(target->getAbsolutePosition() - seeker->getAbsolutePosition()); | 294 | const vector3df toTarget(target->getAbsolutePosition() - seeker->getAbsolutePosition()); |
295 | const vector3df requiredRotation = toTarget.getHorizontalAngle(); | 295 | const vector3df requiredRotation = toTarget.getHorizontalAngle(); |
296 | seeker->setRotation(requiredRotation); | 296 | seeker->setRotation(requiredRotation); |
297 | 297 | ||
298 | \return A rotation vector containing the X (pitch) and Y (raw) rotations (in degrees) that when applied to a | 298 | \return A rotation vector containing the X (pitch) and Y (raw) rotations (in degrees) that when applied to a |
299 | +Z (e.g. 0, 0, 1) direction vector would make it point in the same direction as this vector. The Z (roll) rotation | 299 | +Z (e.g. 0, 0, 1) direction vector would make it point in the same direction as this vector. The Z (roll) rotation |
300 | is always 0, since two Euler rotations are sufficient to point in any given direction. */ | 300 | is always 0, since two Euler rotations are sufficient to point in any given direction. */ |
301 | vector3d<T> getHorizontalAngle() const | 301 | vector3d<T> getHorizontalAngle() const |
302 | { | 302 | { |
303 | vector3d<T> angle; | 303 | vector3d<T> angle; |
304 | 304 | ||
305 | const f64 tmp = (atan2((f64)X, (f64)Z) * RADTODEG64); | 305 | const f64 tmp = (atan2((f64)X, (f64)Z) * RADTODEG64); |
306 | angle.Y = (T)tmp; | 306 | angle.Y = (T)tmp; |
307 | 307 | ||
308 | if (angle.Y < 0) | 308 | if (angle.Y < 0) |
309 | angle.Y += 360; | 309 | angle.Y += 360; |
310 | if (angle.Y >= 360) | 310 | if (angle.Y >= 360) |
311 | angle.Y -= 360; | 311 | angle.Y -= 360; |
312 | 312 | ||
313 | const f64 z1 = core::squareroot(X*X + Z*Z); | 313 | const f64 z1 = core::squareroot(X*X + Z*Z); |
314 | 314 | ||
315 | angle.X = (T)(atan2((f64)z1, (f64)Y) * RADTODEG64 - 90.0); | 315 | angle.X = (T)(atan2((f64)z1, (f64)Y) * RADTODEG64 - 90.0); |
316 | 316 | ||
317 | if (angle.X < 0) | 317 | if (angle.X < 0) |
318 | angle.X += 360; | 318 | angle.X += 360; |
319 | if (angle.X >= 360) | 319 | if (angle.X >= 360) |
320 | angle.X -= 360; | 320 | angle.X -= 360; |
321 | 321 | ||
322 | return angle; | 322 | return angle; |
323 | } | 323 | } |
324 | 324 | ||
325 | //! Get the spherical coordinate angles | 325 | //! Get the spherical coordinate angles |
326 | /** This returns Euler degrees for the point represented by | 326 | /** This returns Euler degrees for the point represented by |
327 | this vector. The calculation assumes the pole at (0,1,0) and | 327 | this vector. The calculation assumes the pole at (0,1,0) and |
328 | returns the angles in X and Y. | 328 | returns the angles in X and Y. |
329 | */ | 329 | */ |
330 | vector3d<T> getSphericalCoordinateAngles() const | 330 | vector3d<T> getSphericalCoordinateAngles() const |
331 | { | 331 | { |
332 | vector3d<T> angle; | 332 | vector3d<T> angle; |
333 | const f64 length = X*X + Y*Y + Z*Z; | 333 | const f64 length = X*X + Y*Y + Z*Z; |
334 | 334 | ||
335 | if (length) | 335 | if (length) |
336 | { | 336 | { |
337 | if (X!=0) | 337 | if (X!=0) |
338 | { | 338 | { |
339 | angle.Y = (T)(atan2((f64)Z,(f64)X) * RADTODEG64); | 339 | angle.Y = (T)(atan2((f64)Z,(f64)X) * RADTODEG64); |
340 | } | 340 | } |
341 | else if (Z<0) | 341 | else if (Z<0) |
342 | angle.Y=180; | 342 | angle.Y=180; |
343 | 343 | ||
344 | angle.X = (T)(acos(Y * core::reciprocal_squareroot(length)) * RADTODEG64); | 344 | angle.X = (T)(acos(Y * core::reciprocal_squareroot(length)) * RADTODEG64); |
345 | } | 345 | } |
346 | return angle; | 346 | return angle; |
347 | } | 347 | } |
348 | 348 | ||
349 | //! Builds a direction vector from (this) rotation vector. | 349 | //! Builds a direction vector from (this) rotation vector. |
350 | /** This vector is assumed to be a rotation vector composed of 3 Euler angle rotations, in degrees. | 350 | /** This vector is assumed to be a rotation vector composed of 3 Euler angle rotations, in degrees. |
351 | The implementation performs the same calculations as using a matrix to do the rotation. | 351 | The implementation performs the same calculations as using a matrix to do the rotation. |
352 | 352 | ||
353 | \param[in] forwards The direction representing "forwards" which will be rotated by this vector. | 353 | \param[in] forwards The direction representing "forwards" which will be rotated by this vector. |
354 | If you do not provide a direction, then the +Z axis (0, 0, 1) will be assumed to be forwards. | 354 | If you do not provide a direction, then the +Z axis (0, 0, 1) will be assumed to be forwards. |
355 | \return A direction vector calculated by rotating the forwards direction by the 3 Euler angles | 355 | \return A direction vector calculated by rotating the forwards direction by the 3 Euler angles |
356 | (in degrees) represented by this vector. */ | 356 | (in degrees) represented by this vector. */ |
357 | vector3d<T> rotationToDirection(const vector3d<T> & forwards = vector3d<T>(0, 0, 1)) const | 357 | vector3d<T> rotationToDirection(const vector3d<T> & forwards = vector3d<T>(0, 0, 1)) const |
358 | { | 358 | { |
359 | const f64 cr = cos( core::DEGTORAD64 * X ); | 359 | const f64 cr = cos( core::DEGTORAD64 * X ); |
360 | const f64 sr = sin( core::DEGTORAD64 * X ); | 360 | const f64 sr = sin( core::DEGTORAD64 * X ); |
361 | const f64 cp = cos( core::DEGTORAD64 * Y ); | 361 | const f64 cp = cos( core::DEGTORAD64 * Y ); |
362 | const f64 sp = sin( core::DEGTORAD64 * Y ); | 362 | const f64 sp = sin( core::DEGTORAD64 * Y ); |
363 | const f64 cy = cos( core::DEGTORAD64 * Z ); | 363 | const f64 cy = cos( core::DEGTORAD64 * Z ); |
364 | const f64 sy = sin( core::DEGTORAD64 * Z ); | 364 | const f64 sy = sin( core::DEGTORAD64 * Z ); |
365 | 365 | ||
366 | const f64 srsp = sr*sp; | 366 | const f64 srsp = sr*sp; |
367 | const f64 crsp = cr*sp; | 367 | const f64 crsp = cr*sp; |
368 | 368 | ||
369 | const f64 pseudoMatrix[] = { | 369 | const f64 pseudoMatrix[] = { |
370 | ( cp*cy ), ( cp*sy ), ( -sp ), | 370 | ( cp*cy ), ( cp*sy ), ( -sp ), |
371 | ( srsp*cy-cr*sy ), ( srsp*sy+cr*cy ), ( sr*cp ), | 371 | ( srsp*cy-cr*sy ), ( srsp*sy+cr*cy ), ( sr*cp ), |
372 | ( crsp*cy+sr*sy ), ( crsp*sy-sr*cy ), ( cr*cp )}; | 372 | ( crsp*cy+sr*sy ), ( crsp*sy-sr*cy ), ( cr*cp )}; |
373 | 373 | ||
374 | return vector3d<T>( | 374 | return vector3d<T>( |
375 | (T)(forwards.X * pseudoMatrix[0] + | 375 | (T)(forwards.X * pseudoMatrix[0] + |
376 | forwards.Y * pseudoMatrix[3] + | 376 | forwards.Y * pseudoMatrix[3] + |
377 | forwards.Z * pseudoMatrix[6]), | 377 | forwards.Z * pseudoMatrix[6]), |
378 | (T)(forwards.X * pseudoMatrix[1] + | 378 | (T)(forwards.X * pseudoMatrix[1] + |
379 | forwards.Y * pseudoMatrix[4] + | 379 | forwards.Y * pseudoMatrix[4] + |
380 | forwards.Z * pseudoMatrix[7]), | 380 | forwards.Z * pseudoMatrix[7]), |
381 | (T)(forwards.X * pseudoMatrix[2] + | 381 | (T)(forwards.X * pseudoMatrix[2] + |
382 | forwards.Y * pseudoMatrix[5] + | 382 | forwards.Y * pseudoMatrix[5] + |
383 | forwards.Z * pseudoMatrix[8])); | 383 | forwards.Z * pseudoMatrix[8])); |
384 | } | 384 | } |
385 | 385 | ||
386 | //! Fills an array of 4 values with the vector data (usually floats). | 386 | //! Fills an array of 4 values with the vector data (usually floats). |
387 | /** Useful for setting in shader constants for example. The fourth value | 387 | /** Useful for setting in shader constants for example. The fourth value |
388 | will always be 0. */ | 388 | will always be 0. */ |
389 | void getAs4Values(T* array) const | 389 | void getAs4Values(T* array) const |
390 | { | 390 | { |
391 | array[0] = X; | 391 | array[0] = X; |
392 | array[1] = Y; | 392 | array[1] = Y; |
393 | array[2] = Z; | 393 | array[2] = Z; |
394 | array[3] = 0; | 394 | array[3] = 0; |
395 | } | 395 | } |
396 | 396 | ||
397 | //! Fills an array of 3 values with the vector data (usually floats). | 397 | //! Fills an array of 3 values with the vector data (usually floats). |
398 | /** Useful for setting in shader constants for example.*/ | 398 | /** Useful for setting in shader constants for example.*/ |
399 | void getAs3Values(T* array) const | 399 | void getAs3Values(T* array) const |
400 | { | 400 | { |
401 | array[0] = X; | 401 | array[0] = X; |
402 | array[1] = Y; | 402 | array[1] = Y; |
403 | array[2] = Z; | 403 | array[2] = Z; |
404 | } | 404 | } |
405 | 405 | ||
406 | 406 | ||
407 | //! X coordinate of the vector | 407 | //! X coordinate of the vector |
408 | T X; | 408 | T X; |
409 | 409 | ||
410 | //! Y coordinate of the vector | 410 | //! Y coordinate of the vector |
411 | T Y; | 411 | T Y; |
412 | 412 | ||
413 | //! Z coordinate of the vector | 413 | //! Z coordinate of the vector |
414 | T Z; | 414 | T Z; |
415 | }; | 415 | }; |
416 | 416 | ||
417 | //! partial specialization for integer vectors | 417 | //! partial specialization for integer vectors |
418 | // Implementor note: inline keyword needed due to template specialization for s32. Otherwise put specialization into a .cpp | 418 | // Implementor note: inline keyword needed due to template specialization for s32. Otherwise put specialization into a .cpp |
419 | template <> | 419 | template <> |
420 | inline vector3d<s32> vector3d<s32>::operator /(s32 val) const {return core::vector3d<s32>(X/val,Y/val,Z/val);} | 420 | inline vector3d<s32> vector3d<s32>::operator /(s32 val) const {return core::vector3d<s32>(X/val,Y/val,Z/val);} |
421 | template <> | 421 | template <> |
422 | inline vector3d<s32>& vector3d<s32>::operator /=(s32 val) {X/=val;Y/=val;Z/=val; return *this;} | 422 | inline vector3d<s32>& vector3d<s32>::operator /=(s32 val) {X/=val;Y/=val;Z/=val; return *this;} |
423 | 423 | ||
424 | template <> | 424 | template <> |
425 | inline vector3d<s32> vector3d<s32>::getSphericalCoordinateAngles() const | 425 | inline vector3d<s32> vector3d<s32>::getSphericalCoordinateAngles() const |
426 | { | 426 | { |
427 | vector3d<s32> angle; | 427 | vector3d<s32> angle; |
428 | const f64 length = X*X + Y*Y + Z*Z; | 428 | const f64 length = X*X + Y*Y + Z*Z; |
429 | 429 | ||
430 | if (length) | 430 | if (length) |
431 | { | 431 | { |
432 | if (X!=0) | 432 | if (X!=0) |
433 | { | 433 | { |
434 | angle.Y = round32((f32)(atan2((f64)Z,(f64)X) * RADTODEG64)); | 434 | angle.Y = round32((f32)(atan2((f64)Z,(f64)X) * RADTODEG64)); |
435 | } | 435 | } |
436 | else if (Z<0) | 436 | else if (Z<0) |
437 | angle.Y=180; | 437 | angle.Y=180; |
438 | 438 | ||
439 | angle.X = round32((f32)(acos(Y * core::reciprocal_squareroot(length)) * RADTODEG64)); | 439 | angle.X = round32((f32)(acos(Y * core::reciprocal_squareroot(length)) * RADTODEG64)); |
440 | } | 440 | } |
441 | return angle; | 441 | return angle; |
442 | } | 442 | } |
443 | 443 | ||
444 | //! Typedef for a f32 3d vector. | 444 | //! Typedef for a f32 3d vector. |
445 | typedef vector3d<f32> vector3df; | 445 | typedef vector3d<f32> vector3df; |
446 | 446 | ||
447 | //! Typedef for an integer 3d vector. | 447 | //! Typedef for an integer 3d vector. |
448 | typedef vector3d<s32> vector3di; | 448 | typedef vector3d<s32> vector3di; |
449 | 449 | ||
450 | //! Function multiplying a scalar and a vector component-wise. | 450 | //! Function multiplying a scalar and a vector component-wise. |
451 | template<class S, class T> | 451 | template<class S, class T> |
452 | vector3d<T> operator*(const S scalar, const vector3d<T>& vector) { return vector*scalar; } | 452 | vector3d<T> operator*(const S scalar, const vector3d<T>& vector) { return vector*scalar; } |
453 | 453 | ||
454 | } // end namespace core | 454 | } // end namespace core |
455 | } // end namespace irr | 455 | } // end namespace irr |
456 | 456 | ||
457 | #endif | 457 | #endif |
458 | 458 | ||