1 | /*
|
---|
2 | Copyright (C) 2005-2006 Feeling Software Inc.
|
---|
3 | MIT License: http://www.opensource.org/licenses/mit-license.php
|
---|
4 | */
|
---|
5 |
|
---|
6 | /**
|
---|
7 | @file FMVector3.h The file containing the class and global functions for 3 dimensional vectors.
|
---|
8 | */
|
---|
9 |
|
---|
10 | #ifndef _FM_VECTOR3_H_
|
---|
11 | #define _FM_VECTOR3_H_
|
---|
12 |
|
---|
13 | /**
|
---|
14 | A 3 dimensional vector.
|
---|
15 |
|
---|
16 | Simple, non-optimized vector class: * is the dot-product, ^ is the
|
---|
17 | cross-product.
|
---|
18 |
|
---|
19 | @ingroup FMath
|
---|
20 | */
|
---|
21 | class FCOLLADA_EXPORT FMVector3
|
---|
22 | {
|
---|
23 | public:
|
---|
24 | float x; /**< The first coordinate. */
|
---|
25 | float y; /**< The second coordinate. */
|
---|
26 | float z; /**< The third coordinate. */
|
---|
27 |
|
---|
28 | public:
|
---|
29 | /**
|
---|
30 | * Creates an empty FMVector3.
|
---|
31 | */
|
---|
32 | #ifndef _DEBUG
|
---|
33 | FMVector3() {}
|
---|
34 | #else
|
---|
35 | FMVector3() { x = 123456789.0f; y = 123456789.0f; z = 123456789.0f; }
|
---|
36 | #endif
|
---|
37 |
|
---|
38 | /**
|
---|
39 | * Creates the FMVector3 with the coordinates given.
|
---|
40 | *
|
---|
41 | * @param _x The first coordinate.
|
---|
42 | * @param _y The second coordinate.
|
---|
43 | * @param _z The third coordinate.
|
---|
44 | */
|
---|
45 | FMVector3(float _x, float _y, float _z) { x = _x; y = _y; z = _z; }
|
---|
46 |
|
---|
47 | /**
|
---|
48 | * Creates the FMVector3 from a list of \c floats.
|
---|
49 | *
|
---|
50 | * It takes the first 3 \c floats starting from and including \a startIndex
|
---|
51 | * (0 indexing) in the array as the 3 coordinates. The first as the first
|
---|
52 | * coordinate, the second as the second, and the third as the third.
|
---|
53 | *
|
---|
54 | * @param source The \c float array.
|
---|
55 | * @param startIndex The index of the first element.
|
---|
56 | */
|
---|
57 | FMVector3(const float* source, uint32 startIndex = 0);
|
---|
58 |
|
---|
59 | /**
|
---|
60 | * Get the squared length.
|
---|
61 | *
|
---|
62 | * @return The squared length of this FMVector3.
|
---|
63 | */
|
---|
64 | inline float LengthSquared() const { return x * x + y * y + z * z; }
|
---|
65 |
|
---|
66 | /**
|
---|
67 | * Retrieves the length of the vector.
|
---|
68 | *
|
---|
69 | * @return The length of this FMVector3.
|
---|
70 | */
|
---|
71 | inline float Length() const { return sqrtf(x * x + y * y + z * z); }
|
---|
72 |
|
---|
73 | /**
|
---|
74 | * Normalize this FMVector3.
|
---|
75 | */
|
---|
76 | inline void NormalizeIt() { float l = Length(); if (!IsEquivalent(l, 0.0f)) { x /= l; y /= l; z /= l; }}
|
---|
77 |
|
---|
78 | /**
|
---|
79 | * Get a normalized FMVector3 with the same direction as this FMVector3.
|
---|
80 | *
|
---|
81 | * @return A FMVector3 with length 1 and same direction as this FMVector3.
|
---|
82 | */
|
---|
83 | inline FMVector3 Normalize() const { float l = Length(); return FMVector3(x / l, y / l, z / l); }
|
---|
84 |
|
---|
85 | /**
|
---|
86 | * Project this FMVector3 onto another FMVector3.
|
---|
87 | *
|
---|
88 | * @param unto The FMVector3 to project onto.
|
---|
89 | */
|
---|
90 | inline void Project(const FMVector3& unto) { (*this) = Projected(unto); }
|
---|
91 |
|
---|
92 | /**
|
---|
93 | * Get the projection of this FMVector3 onto another FMVector3.
|
---|
94 | *
|
---|
95 | * @param unto The FMVector3 to project onto.
|
---|
96 | * @return The projected FMVector3.
|
---|
97 | */
|
---|
98 | inline FMVector3 Projected(const FMVector3& unto);
|
---|
99 |
|
---|
100 | /**
|
---|
101 | * Get this FMVector3 as an array of \c floats.
|
---|
102 | *
|
---|
103 | * @return The \c float array.
|
---|
104 | */
|
---|
105 | inline operator float*() { return &x; }
|
---|
106 |
|
---|
107 | /**
|
---|
108 | * Get this FMVector3 as an array of \c floats.
|
---|
109 | *
|
---|
110 | * @return The \c float array.
|
---|
111 | */
|
---|
112 | inline operator const float*() const { return &x; }
|
---|
113 |
|
---|
114 | /**
|
---|
115 | * Assign this FMVector3 to the given float array.
|
---|
116 | *
|
---|
117 | * Assigns each coordinate of this FMVector3 to the elements in the \c
|
---|
118 | * float array. The first element to the first coordinate, the second to
|
---|
119 | * the second, and the third to the third. It returns this FMVector3.
|
---|
120 | *
|
---|
121 | * @param v The \c float array to assign with.
|
---|
122 | * @return This FMVector3.
|
---|
123 | */
|
---|
124 | inline FMVector3& operator =(const float* v) { x = *v; y = *(v + 1); z = *(v + 2); return *this; }
|
---|
125 |
|
---|
126 | /**
|
---|
127 | * Update each component of this FMVector to the minimum of two FMVector3s.
|
---|
128 | *
|
---|
129 | * Updates each of the three components to be the minimum of the current
|
---|
130 | * value and that of the corresponding value of the given FMVector3.
|
---|
131 | *
|
---|
132 | * @param min The FMVector to take values from.
|
---|
133 | */
|
---|
134 | inline void ComponentMinimum(const FMVector3& min) { if (x < min.x) x = min.x; if (y < min.y) y = min.y; if (z < min.z) z = min.z; }
|
---|
135 |
|
---|
136 | /**
|
---|
137 | * Update each component of this FMVector to the maximum of two FMVector3s.
|
---|
138 | *
|
---|
139 | * Updates each of the three components to be the maximum of the current
|
---|
140 | * value and that of the corresponding value of the given FMVector3.
|
---|
141 | *
|
---|
142 | * @param max The FMVector to take values from.
|
---|
143 | */
|
---|
144 | inline void ComponentMaximum(const FMVector3& max) { if (x > max.x) x = max.x; if (y > max.y) y = max.y; if (z > max.z) z = max.z; }
|
---|
145 |
|
---|
146 | /**
|
---|
147 | * Clamp each component of this FMVector by the corresponding components
|
---|
148 | * in the specified min and max FMVector3.
|
---|
149 | *
|
---|
150 | * Clamp refers to setting a value within a given range. If the value is
|
---|
151 | * lower than the minimum of the range, it is set to the minimum; same for
|
---|
152 | * the maximum.
|
---|
153 | *
|
---|
154 | * @param min The FMVector to take the minimum values from.
|
---|
155 | * @param max The FMVector to take the maximum values from.
|
---|
156 | */
|
---|
157 | inline void ComponentClamp(const FMVector3& min, const FMVector3& max) { ComponentMinimum(min); ComponentMaximum(max); }
|
---|
158 |
|
---|
159 | public:
|
---|
160 | static const FMVector3 XAxis; /**< The FMVector3 representing the x axis */
|
---|
161 | static const FMVector3 YAxis; /**< The FMVector3 representing the y axis */
|
---|
162 | static const FMVector3 ZAxis; /**< The FMVector3 representing the z axis */
|
---|
163 | static const FMVector3 Zero; /**< The FMVector3 representing zero */
|
---|
164 | static const FMVector3 Origin;/**< The FMVector3 representing the origin */
|
---|
165 | };
|
---|
166 |
|
---|
167 | /**
|
---|
168 | * Vector addition with two FMVector3.
|
---|
169 | *
|
---|
170 | * @param a The first vector.
|
---|
171 | * @param b The second vector.
|
---|
172 | * @return The FMVector3 representation of the resulting vector.
|
---|
173 | */
|
---|
174 | inline FMVector3 operator +(const FMVector3& a, const FMVector3& b) { return FMVector3(a.x + b.x, a.y + b.y, a.z + b.z); }
|
---|
175 |
|
---|
176 | /**
|
---|
177 | * Vector subtraction with two FMVector3.
|
---|
178 | *
|
---|
179 | * @param a The first vector.
|
---|
180 | * @param b The second vector.
|
---|
181 | * @return The FMVector3 representation of the resulting vector.
|
---|
182 | */
|
---|
183 | inline FMVector3 operator -(const FMVector3& a, const FMVector3& b) { return FMVector3(a.x - b.x, a.y - b.y, a.z - b.z); }
|
---|
184 |
|
---|
185 | /**
|
---|
186 | * Positive operator of the given FMVector3.
|
---|
187 | *
|
---|
188 | * It applies the positive operator to each of the components of the FMVector3.
|
---|
189 | *
|
---|
190 | * @param a The vector to apply the positive operator to.
|
---|
191 | * @return The FMVector3 representation of the resulting vector.
|
---|
192 | */
|
---|
193 | inline FMVector3 operator +(const FMVector3& a) { return FMVector3(+a.x, +a.y, +a.z); }
|
---|
194 |
|
---|
195 | /**
|
---|
196 | * Negates the given FMVector3.
|
---|
197 | *
|
---|
198 | * It negates each of the components of the FMVector3.
|
---|
199 | *
|
---|
200 | * @param a The vector to negate.
|
---|
201 | * @return The FMVector3 representation of the resulting vector.
|
---|
202 | */
|
---|
203 | inline FMVector3 operator -(const FMVector3& a) { return FMVector3(-a.x, -a.y, -a.z); }
|
---|
204 |
|
---|
205 | /**
|
---|
206 | * Dot product of two FMVector3.
|
---|
207 | *
|
---|
208 | * @param a The first vector.
|
---|
209 | * @param b The second vector.
|
---|
210 | * @return The result of the dot product.
|
---|
211 | */
|
---|
212 | inline float operator *(const FMVector3& a, const FMVector3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
|
---|
213 |
|
---|
214 | /**
|
---|
215 | * Scalar multiplication with a FMVector3.
|
---|
216 | *
|
---|
217 | * @param a The vector.
|
---|
218 | * @param b The scalar.
|
---|
219 | * @return The FMVector3 representing the resulting vector.
|
---|
220 | */
|
---|
221 | inline FMVector3 operator *(const FMVector3& a, float b) { return FMVector3(a.x * b, a.y * b, a.z * b); }
|
---|
222 |
|
---|
223 | /**
|
---|
224 | * Scalar multiplication with a FMVector3.
|
---|
225 | *
|
---|
226 | * @param a The scalar.
|
---|
227 | * @param b The vector.
|
---|
228 | * @return The FMVector3 representing the resulting vector.
|
---|
229 | */
|
---|
230 | inline FMVector3 operator *(float a, const FMVector3& b) { return FMVector3(a * b.x, a * b.y, a * b.z); }
|
---|
231 |
|
---|
232 | /**
|
---|
233 | * Cross product of two FMVector3.
|
---|
234 | *
|
---|
235 | * @param a The first vector.
|
---|
236 | * @param b The second vector.
|
---|
237 | * @return The result of the dot product.
|
---|
238 | */
|
---|
239 | inline FMVector3 operator ^(const FMVector3& a, const FMVector3& b) { return FMVector3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); }
|
---|
240 |
|
---|
241 | /**
|
---|
242 | * Assignment of the addition of two FMVector3.
|
---|
243 | *
|
---|
244 | * @param b The first vector, which will also be assigned to the result.
|
---|
245 | * @param a The second vector.
|
---|
246 | * @return The first vector, after it has been assigned new values.
|
---|
247 | */
|
---|
248 | inline FMVector3& operator +=(FMVector3& b, const FMVector3& a) { b.x += a.x; b.y += a.y; b.z += a.z; return b; }
|
---|
249 |
|
---|
250 | /**
|
---|
251 | * Assignment of the subtraction of two FMVector3.
|
---|
252 | *
|
---|
253 | * @param b The first vector, which will also be assigned to the result.
|
---|
254 | * @param a The second vector.
|
---|
255 | * @return The first vector, after it has been assigned new values.
|
---|
256 | */
|
---|
257 | inline FMVector3& operator -=(FMVector3& b, const FMVector3& a) { b.x -= a.x; b.y -= a.y; b.z -= a.z; return b; }
|
---|
258 |
|
---|
259 | /**
|
---|
260 | * Assignment of the scalar multiplication of a FMVector3.
|
---|
261 | *
|
---|
262 | * @param b The vector, which will also be assigned to the result.
|
---|
263 | * @param a The scalar.
|
---|
264 | * @return The vector, after it has been assigned new values.
|
---|
265 | */
|
---|
266 | inline FMVector3& operator *=(FMVector3& b, float a) { b.x *= a; b.y *= a; b.z *= a; return b; }
|
---|
267 |
|
---|
268 | /**
|
---|
269 | * Assignment of the scalar division of a FMVector3.
|
---|
270 | *
|
---|
271 | * @param b The vector, which will also be assigned to the result.
|
---|
272 | * @param a The scalar.
|
---|
273 | * @return The vector, after it has been assigned new values.
|
---|
274 | */
|
---|
275 | inline FMVector3& operator /=(FMVector3& b, float a) { b.x /= a; b.y /= a; b.z /= a; return b; }
|
---|
276 |
|
---|
277 | /**
|
---|
278 | Returns whether two 3D vectors or points are equivalent.
|
---|
279 | @param p A first vector.
|
---|
280 | @param q A second vector.
|
---|
281 | @return Whether the vectors are equivalent.
|
---|
282 | */
|
---|
283 | inline bool IsEquivalent(const FMVector3& p, const FMVector3& q) { return IsEquivalent(p.x, q.x) && IsEquivalent(p.y, q.y) && IsEquivalent(p.z, q.z); }
|
---|
284 |
|
---|
285 | /**
|
---|
286 | Check if two FMVector3 are equivalent (they have relatively the same component values).
|
---|
287 | @param a The first vector.
|
---|
288 | @param b The second vector.
|
---|
289 | @return Whether the vectors are equivalent.
|
---|
290 | */
|
---|
291 | inline bool operator == (const FMVector3& a, const FMVector3& b) { return IsEquivalent(a, b); }
|
---|
292 |
|
---|
293 | // Already documented above.
|
---|
294 | inline FMVector3 FMVector3::Projected(const FMVector3& unto) { return ((*this) * unto) / unto.LengthSquared() * unto; }
|
---|
295 |
|
---|
296 | /** A dynamically-sized array of 3D vectors or points. */
|
---|
297 | typedef vector<FMVector3> FMVector3List;
|
---|
298 |
|
---|
299 | #endif // _FM_VECTOR3_H_
|
---|