aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/include/vector3d.h
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/include/vector3d.h
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-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.h916
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
10namespace irr 10namespace irr
11{ 11{
12namespace core 12namespace 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