Ocular Engine
Vector3.hpp
1 
17 #pragma once
18 #ifndef __H__OCULAR_MATH_VECTOR_3__H__
19 #define __H__OCULAR_MATH_VECTOR_3__H__
20 
21 #include "Vector2.hpp"
22 #include "Euler.hpp"
23 #include "Equality.hpp"
24 #include "Utilities/Types.hpp"
25 #include "Exceptions/Exception.hpp"
26 
27 #include <cmath>
28 
29 //------------------------------------------------------------------------------------------
30 
35 namespace Ocular
36 {
41  namespace Math
42  {
46  template<typename T>
47  class Vector3
48  {
49  public:
50 
51  Vector3(T const* values)
52  {
53  x = values[0];
54  y = values[1];
55  z = values[2];
56  }
57 
58  Vector3(Quaternion const& quat)
59  {
60  x = static_cast<T>(quat.getPitch());
61  y = static_cast<T>(quat.getYaw());
62  z = static_cast<T>(quat.getRoll());
63  }
64 
65  Vector3(Euler const& euler)
66  {
67  x = static_cast<T>(euler.getPitch());
68  y = static_cast<T>(euler.getYaw());
69  z = static_cast<T>(euler.getRoll());
70  }
71 
72  Vector3(Vector2<T> const& vec)
73  {
74  x = vec.x;
75  y = vec.y;
76  z = 0.0f;
77  }
78 
79  Vector3(T const x, T const y, T const z)
80  {
81  this->x = x;
82  this->y = y;
83  this->z = z;
84  }
85 
86  Vector3()
87  {
88  this->x = static_cast<T>(0);
89  this->y = static_cast<T>(0);
90  this->z = static_cast<T>(0);
91  }
92 
93  ~Vector3()
94  {
95 
96  }
97 
98  //------------------------------------------------------------------------------
99  // OPERATORS
100  //------------------------------------------------------------------------------
101 
102  T& operator[](unsigned const& index)
103  {
104  switch(index)
105  {
106  case 0:
107  return x;
108 
109  case 1:
110  return y;
111 
112  case 2:
113  return z;
114 
115  default:
116  THROW_EXCEPTION("Out-Of-Bounds Vector Access");
117  return x;
118  }
119  }
120 
121  T operator[](unsigned const& index) const
122  {
123  switch(index)
124  {
125  case 0:
126  return x;
127 
128  case 1:
129  return y;
130 
131  case 2:
132  return z;
133 
134  default:
135  THROW_EXCEPTION("Out-Of-Bounds Vector Access");
136  return x;
137  }
138  }
139 
140  Vector3<T> operator-()
141  {
142  return Vector3<T>(-x, -y, -z);
143  }
144 
145  Vector3<T>& operator=(Vector3<T> const& rhs)
146  {
147  x = rhs.x;
148  y = rhs.y;
149  z = rhs.z;
150 
151  return *this;
152  }
153 
154  Vector3<T>& operator+=(Vector3<T> const& rhs)
155  {
156  x += rhs.x;
157  y += rhs.y;
158  z += rhs.z;
159 
160  return *this;
161  }
162 
163  Vector3<T>& operator+=(T const rhs)
164  {
165  x += rhs;
166  y += rhs;
167  z += rhs;
168 
169  return *this;
170  }
171 
172  Vector3<T>& operator-=(Vector3<T> const& rhs)
173  {
174  x -= rhs.x;
175  y -= rhs.y;
176  z -= rhs.z;
177 
178  return *this;
179  }
180 
181  Vector3<T>& operator-=(T const rhs)
182  {
183  x -= rhs;
184  y -= rhs;
185  z -= rhs;
186 
187  return *this;
188  }
189 
190  Vector3<T>& operator*=(Vector3<T> const& rhs)
191  {
192  x *= rhs.x;
193  y *= rhs.y;
194  z *= rhs.z;
195 
196  return *this;
197  }
198 
199  Vector3<T>& operator*=(T const rhs)
200  {
201  x *= rhs;
202  y *= rhs;
203  z *= rhs;
204 
205  return *this;
206  }
207 
208  Vector3<T>& operator/=(Vector3<T> const& rhs)
209  {
210  x /= rhs.x;
211  y /= rhs.y;
212  z /= rhs.z;
213 
214  return *this;
215  }
216 
217  Vector3<T>& operator/=(T const rhs)
218  {
219  x /= rhs;
220  y /= rhs;
221  z /= rhs;
222 
223  return *this;
224  }
225 
226  //------------------------------------------------------------------------------
227  // OPERATIONS
228  //------------------------------------------------------------------------------
229 
233  Vector2<T> xy() const
234  {
235  return Vector2<T>(x, y);
236  }
237 
241  T getMagnitude() const
242  {
243  return std::sqrt((x * x) + (y * y) + (z * z));
244  }
245 
249  T getLength() const
250  {
251  return getMagnitude();
252  }
253 
260  void normalize()
261  {
262  // Normalization is simply multiplying the vector by the reciprocal of its magnitude.
263 
264  T length = getMagnitude();
265 
266  if(IsEqual<T>(length, static_cast<T>(0)))
267  {
268  x = static_cast<T>(0);
269  y = static_cast<T>(0);
270  z = static_cast<T>(0);
271  }
272  else
273  {
274  x /= static_cast<T>(length);
275  y /= static_cast<T>(length);
276  z /= static_cast<T>(length);
277  }
278  }
279 
284  {
285  Vector3<T> result(x, y, z);
286  result.normalize();
287 
288  return result;
289  }
290 
299  Vector3<T> cross(Vector3<T> const& rhs) const
300  {
301  return Vector3<T>((y * rhs.z) - (z * rhs.y),
302  (z * rhs.x) - (x * rhs.z),
303  (x * rhs.y) - (y * rhs.x));
304  }
305 
313  T dot(Vector3<T> const& rhs) const
314  {
315  return (x * rhs.x) + (y * rhs.y) + (z * rhs.z);
316  }
317 
325  double angleBetween(Vector3<T> const& rhs) const
326  {
327  Vector3<T> normalLHS = getNormalized();
328  Vector3<T> normalRHS = rhs.getNormalized();
329 
330  double angle = std::acos(normalLHS.dot(normalRHS));
331 
332  if(angle > PI)
333  {
334  angle = PI_TWO - angle;
335  }
336 
337  return angle;
338  }
339 
344  T distanceTo(Vector3<T> const& rhs) const
345  {
346  Vector3<T> distance = (*this) - rhs;
347  return distance.getMagnitude();
348  }
349 
361  static Vector3<T> Lerp(Vector3<T> const from, Vector3<T> const to, T fraction)
362  {
363  T zero = static_cast<T>(0);
364  T one = static_cast<T>(1);
365 
366  // Adapted from http://msdn.microsoft.com/en-us/library/windows/desktop/bb509618(v=vs.85).aspx
367  fraction = Clamp<T>(fraction, zero, one);
368  return (from * (one - fraction)) + (to * fraction);
369  }
370 
384  static Vector3<T> Slerp(Vector3<T> const& from, Vector3<T> const& to, double fraction)
385  {
386  // Adapted from http://en.wikipedia.org/wiki/Slerp
387 
388  fraction = Clamp<double>(fraction, 0.0, 1.0);
389  double omega = from.angleBetween(to);
390 
391  double lhs = std::sin((1.0 - fraction) * omega) / std::sin(omega);
392  double rhs = std::sin(fraction * omega) / std::sin(omega);
393 
394  return (from * lhs) + (to * rhs);
395  }
396 
404  static Vector3<T> Midpoint(Vector3<T> const& a, Vector3<T> const& b)
405  {
406  T two = static_cast<T>(2);
407 
408  return Vector3<T>(((a.x + b.x) / two),
409  ((a.y + b.y) / two),
410  ((a.z + b.z) / two));
411  }
412 
413  //------------------------------------------------------------------------------
414  // SPECIAL STATIC VECTORS
415  //------------------------------------------------------------------------------
416 
417  // Ocular uses a right-handed coordinate system
418 
419  static Vector3<T> Identity() { return Vector3<T>(static_cast<T>( 0.0f), static_cast<T>( 0.0f), static_cast<T>( 0.0f)); }
420  static Vector3<T> Up() { return Vector3<T>(static_cast<T>( 0.0f), static_cast<T>( 1.0f), static_cast<T>( 0.0f)); }
421  static Vector3<T> Down() { return Vector3<T>(static_cast<T>( 0.0f), static_cast<T>(-1.0f), static_cast<T>( 0.0f)); }
422  static Vector3<T> Left() { return Vector3<T>(static_cast<T>(-1.0f), static_cast<T>( 0.0f), static_cast<T>( 0.0f)); }
423  static Vector3<T> Right() { return Vector3<T>(static_cast<T>( 1.0f), static_cast<T>( 0.0f), static_cast<T>( 0.0f)); }
424  static Vector3<T> Forward() { return Vector3<T>(static_cast<T>( 0.0f), static_cast<T>( 0.0f), static_cast<T>(-1.0f)); }
425  static Vector3<T> Backward() { return Vector3<T>(static_cast<T>( 0.0f), static_cast<T>( 0.0f), static_cast<T>( 1.0f)); }
426 
427  //------------------------------------------------------------------------------
428  // VARIABLES
429  //------------------------------------------------------------------------------
430 
431  union{ T x, r, u, s; };
432  union{ T y, g, v, t; };
433  union{ T z, b, w; };
434 
435  static bool OCULAR_INTERNAL_Force;
436 
437  protected:
438 
439  private:
440  };
441 
442  //----------------------------------------------------------------------------------
443 
444  template<typename T>
445  bool operator==(Vector3<T> const& lhs, Vector3<T> const& rhs)
446  {
447  return IsEqual<T>(lhs.x, rhs.x) && IsEqual<T>(lhs.y, rhs.y) && IsEqual<T>(lhs.z, rhs.z);
448  }
449 
450  template<typename T>
451  bool operator!=(Vector3<T> const& lhs, Vector3<T> const& rhs)
452  {
453  return !(lhs == rhs);
454  }
455 
456  template<typename T>
457  bool operator>(Vector3<T> const& lhs, Vector3<T> const& rhs)
458  {
459  return ((lhs.x > rhs.x) && (lhs.y > rhs.y) && (lhs.z > rhs.z));
460  }
461 
462  template<typename T>
463  bool operator<(Vector3<T> const& lhs, Vector3<T> const& rhs)
464  {
465  return ((lhs.x < rhs.x) && (lhs.y < rhs.y) && (lhs.z < rhs.z));
466  }
467 
468  template<typename T>
469  Vector3<T> operator+(Vector3<T> const& lhs, Vector3<T> const& rhs)
470  {
471  return Vector3<T>(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
472  }
473 
474  template<typename T>
475  Vector3<T> operator+(Vector3<T> const& lhs, T const& rhs)
476  {
477  return Vector3<T>(lhs.x + rhs, lhs.y + rhs, lhs.z + rhs);
478  }
479 
480  template<typename T>
481  Vector3<T> operator-(Vector3<T> const& lhs, Vector3<T> const& rhs)
482  {
483  return Vector3<T>(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
484  }
485 
486  template<typename T>
487  Vector3<T> operator-(Vector3<T> const& lhs, T const& rhs)
488  {
489  return Vector3<T>(lhs.x - rhs, lhs.y - rhs, lhs.z - rhs);
490  }
491 
492  template<typename T>
493  Vector3<T> operator*(Vector3<T> const& lhs, Vector3<T> const& rhs)
494  {
495  return Vector3<T>(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z);
496  }
497 
498  template<typename T>
499  Vector3<T> operator*(Vector3<T> const& lhs, T const& rhs)
500  {
501  return Vector3<T>(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);
502  }
503 
504  template<typename T>
505  Vector3<T> operator/(Vector3<T> const& lhs, Vector3<T> const& rhs)
506  {
507  return Vector3<T>(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z);
508  }
509 
510  template<typename T>
511  Vector3<T> operator/(Vector3<T> const& lhs, T const& rhs)
512  {
513  return Vector3<T>(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);
514  }
515 
516  //--------------------------------------------
517  // Common vector formats
518 
519  typedef Vector3<float> Vector3f;
520  typedef Vector3<double> Vector3d;
521 
522  typedef Vector3f Point3f;
523  typedef Vector3d Point3d;
524 
525  }
529 }
534 OCULAR_REGISTER_TYPE_CUSTOM(Ocular::Math::Vector3f, "Vector3f");
535 OCULAR_REGISTER_TYPE_CUSTOM(Ocular::Math::Vector3d, "Vector3d");
536 
537 //------------------------------------------------------------------------------------------
538 
539 #endif
Definition: Euler.hpp:39
Note: Once this library is made dynamic, this will no longer be needed.
Definition: Common.hpp:70
static Vector3< T > Lerp(Vector3< T > const from, Vector3< T > const to, T fraction)
Definition: Vector3.hpp:361
double angleBetween(Vector3< T > const &rhs) const
Definition: Vector3.hpp:325
Vector3< T > cross(Vector3< T > const &rhs) const
Definition: Vector3.hpp:299
Vector3< T > getNormalized() const
Definition: Vector3.hpp:283
static Vector3< T > Slerp(Vector3< T > const &from, Vector3< T > const &to, double fraction)
Definition: Vector3.hpp:384
void normalize()
Definition: Vector3.hpp:260
T distanceTo(Vector3< T > const &rhs) const
Definition: Vector3.hpp:344
T getMagnitude() const
Definition: Vector3.hpp:241
T dot(Vector3< T > const &rhs) const
Definition: Vector3.hpp:313
T getLength() const
Definition: Vector3.hpp:249
static Vector3< T > Midpoint(Vector3< T > const &a, Vector3< T > const &b)
Definition: Vector3.hpp:404