TurtleBrains  0.2.1
High quality, portable, C++ API for native application and game development.
tb_vector.h
1 
9 #ifndef _TurtleBrains_Vector_h_
10 #define _TurtleBrains_Vector_h_
11 
12 #include "tb_math.h"
13 #include "../core/tb_error.h"
14 #include "../core/tb_defines.h" //For tb_unsused
15 
16 namespace TurtleBrains
17 {
18  namespace Math
19  {
20 
29  enum SkipInitialization { kSkipInitialization = 0, };
30 
36  {
41  };
42 
47  class Vector2
48  {
49  public:
53  static Vector2 Zero(void) { return Vector2(0.0f, 0.0f); }
54 
55  union
56  {
57  float mComponents[2];
58 
59 #if defined(tb_visual_cpp)
60 #pragma warning(push)
61 #pragma warning(disable: 4201)
62  struct { float x, y; };
63 #pragma warning(pop)
64 #else
65  struct { float x, y; };
66 #endif
67  };
68 
75  inline explicit Vector2(const SkipInitialization& fastAndStupid)
76  {
77  tb_unused(fastAndStupid);
78  }
79 
83  inline Vector2(void) :
84  x(0.0f),
85  y(0.0f)
86  {
87  }
88 
95  inline Vector2(const float valueX, const float valueY) :
96  x(valueX),
97  y(valueY)
98  {
99  }
100 
107  inline Vector2(const Vector2& other) :
108  x(other.x),
109  y(other.y)
110  {
111  }
112 
116  inline ~Vector2(void)
117  {
118  }
119 
125  inline Vector2& operator=(const Vector2& other)
126  {
127  if (&other != this)
128  {
129  x = other.x;
130  y = other.y;
131  }
132  return *this;
133  }
134 
144  inline bool operator==(const Vector2& other) const
145  {
146  return (true == IsEqual(x, other.x) && true == IsEqual(y, other.y)) ? true : false;
147  }
148 
153  inline bool operator!=(const Vector2& other) const
154  {
155  return (true == operator==(other)) ? false : true;
156  }
157 
161  inline operator const float*(void) const { return mComponents; }
162 
167  inline operator float*(void) { return mComponents; }
168 
172  inline const float& operator[](const size_t index) const { return mComponents[index]; }
173 
178  inline float& operator[](const size_t index) { return mComponents[index]; }
179 
180 #ifndef tb_math_less_operators
181  inline Vector2 operator+(const Vector2& rightSide) const { return Vector2(x + rightSide.x, y + rightSide.y); }
185 
190  inline Vector2& operator+=(const Vector2& rightSide) { x += rightSide.x, y += rightSide.y; return *this; }
191 
195  inline Vector2 operator-(const Vector2& rightSide) const { return Vector2(x - rightSide.x, y - rightSide.y); }
196 
200  inline Vector2& operator-=(const Vector2& rightSide) { x -= rightSide.x, y -= rightSide.y; return *this; }
201 
205  inline Vector2 operator*(float scalar) const { return Vector2(x * scalar, y * scalar); }
206 
211  friend Vector2 operator*(float scalar, const Vector2& rightSide) { return Vector2(scalar * rightSide.x, scalar * rightSide.y); }
212 
217  inline Vector2& operator*=(float scalar) { x *= scalar; y *= scalar; return *this; }
218 
222  inline Vector2 operator/(float scalar) const { return Vector2(x / scalar, y / scalar); }
223 
228  inline Vector2& operator/=(float scalar) { x /= scalar; y /= scalar; return *this; }
229 
233  inline Vector2 operator-(void) const { return Vector2(-x, -y); }
234 
238  inline float operator*(const Vector2 &rhs) const { return (x * rhs.x) + (y * rhs.y); }
239 
244  inline float Magnitude(void) const { return sqrt((x * x) + (y * y)); }
245 
250  inline float MagnitudeSquared(void) const { return (x * x) + (y * y); }
251 
256  inline Vector2 GetNormalized(void) const
257  {
258  const float magnitude(Magnitude());
259  if (true == IsZero(magnitude)) { return Zero(); }
260  return Vector2(x / magnitude, y / magnitude);
261  }
262 
268  inline float Normalize(void)
269  {
270  const float magnitude(Magnitude());
271  if (false == IsZero(magnitude))
272  {
273  x /= magnitude;
274  y /= magnitude;
275  }
276  return magnitude;
277  }
278 
282  inline void Scale(float scalar) { *this *= scalar; }
283 
291  inline void SetLength(float length) { Normalize(); *this *= length; }
292 #endif
293  };
294 
295 //--------------------------------------------------------------------------------------------------------------------//
296 //--------------------------------------------------------------------------------------------------------------------//
297 //--------------------------------------------------------------------------------------------------------------------//
298 
303  class Vector3
304  {
305  public:
309  static Vector3 Zero(void) { return Vector3(0.0f, 0.0f, 0.0f); }
310 
311  union
312  {
313  float mComponents[3];
314 
315 #if defined(tb_visual_cpp)
316 #pragma warning(push)
317 #pragma warning(disable: 4201)
318  struct { float x, y, z; };
319 #pragma warning(pop)
320 #else
321  struct { float x, y, z; };
322 #endif
323  };
324 
331  inline explicit Vector3(const SkipInitialization& fastAndStupid)
332  {
333  tb_unused(fastAndStupid);
334  }
335 
339  Vector3(void) :
340  x(0.0f),
341  y(0.0f),
342  z(0.0f)
343  {
344  }
345 
353  inline Vector3(const float valueX, const float valueY, const float valueZ) :
354  x(valueX),
355  y(valueY),
356  z(valueZ)
357  {
358  }
359 
366  inline explicit Vector3(const Vector2& other, const float valueZ) :
367  x(other.x),
368  y(other.y),
369  z(valueZ)
370  {
371  }
372 
379  Vector3(const Vector3& other) :
380  x(other.x),
381  y(other.y),
382  z(other.z)
383  {
384  }
385 
389  ~Vector3(void)
390  {
391  }
392 
398  inline Vector3& operator=(const Vector3& other)
399  {
400  if (&other != this)
401  {
402  x = other.x;
403  y = other.y;
404  z = other.z;
405  }
406  return *this;
407  }
408 
409  //
410  // TODO: TIM: Planning: Would this be useful to have, or just dangerous?
411  //
412  //inline Vector3& operator=(const Vector2 &v)
413  //{
414  // x = v.x; y = v.y; /* z = z; */
415  // return (*this);
416  //}
417 
427  inline bool operator==(const Vector3& other) const
428  {
429  return (true == IsEqual(x, other.x) && true == IsEqual(y, other.y) && true == IsEqual(z, other.z)) ? true : false;
430  }
431 
436  inline bool operator!=(const Vector3& other) const
437  {
438  return (true == operator==(other)) ? false : true;
439  }
440 
444  inline operator const float*(void) const { return mComponents; }
445 
450  inline operator float*(void) { return mComponents; }
451 
455  inline const float& operator[](const size_t index) const { return mComponents[index]; }
456 
461  inline float& operator[](const size_t index) { return mComponents[index]; }
462 
463  //TODO: TIM: Reconsider: This could be dangerous, do we want to support it?
464  //inline operator Vector2(void) { return Vector2(x, y); }
465 
466  #ifndef tb_math_less_operators
467  inline Vector3 operator+(const Vector3& rightSide) const { return Vector3(x + rightSide.x, y + rightSide.y, z + rightSide.z); }
471 
476  inline Vector3& operator+=(const Vector3& rightSide) { x += rightSide.x, y += rightSide.y; z += rightSide.z; return *this; }
477 
481  inline Vector3 operator-(const Vector3& rightSide) const { return Vector3(x - rightSide.x, y - rightSide.y, z - rightSide.z); }
482 
486  inline Vector3& operator-=(const Vector3& rightSide) { x -= rightSide.x, y -= rightSide.y; z -= rightSide.z; return *this; }
487 
488 
492  inline Vector3 operator*(float scalar) const { return Vector3(x * scalar, y * scalar, z * scalar); }
493 
498  friend Vector3 operator*(float scalar, const Vector3& rightSide) { return Vector3(scalar * rightSide.x, scalar * rightSide.y, scalar * rightSide.z); }
499 
504  inline Vector3& operator*=(float scalar) { x *= scalar; y *= scalar; z *= scalar; return *this; }
505 
509  inline Vector3 operator/(float scalar) const { return Vector3(x / scalar, y / scalar, z / scalar); }
510 
515  inline Vector3& operator/=(float scalar) { x /= scalar; y /= scalar; z /= scalar; return *this; }
516 
517 
521  inline Vector3 operator-(void) const { return Vector3(-x, -y, -z); }
522 
526  inline float operator*(const Vector3 &rhs) const { return (x * rhs.x) + (y * rhs.y) + (z * rhs.z); }
527 
532  inline Vector3 operator^(const Vector3& rightSide) const
533  {
534  return Vector3((y * rightSide.z) - (rightSide.y * z), -((x * rightSide.z) - (rightSide.x * z)), (x * rightSide.y) - (rightSide.x * y));
535  }
536 
537 
542  inline float Magnitude(void) const { return sqrt((x * x) + (y * y) + (z * z)); }
543 
548  inline float MagnitudeSquared(void) const { return (x * x) + (y * y) + (z * z); }
549 
554  inline Vector3 GetNormalized(void) const
555  {
556  const float magnitude(Magnitude());
557  if (true == IsZero(magnitude)) { return Zero(); }
558  return Vector3(x / magnitude, y / magnitude, z / magnitude);
559  }
560 
566  inline float Normalize(void)
567  {
568  const float magnitude(Magnitude());
569  if (false == IsZero(magnitude))
570  {
571  x /= magnitude;
572  y /= magnitude;
573  z /= magnitude;
574  }
575  return magnitude;
576  }
577 
581  inline void Scale(float scalar) { *this *= scalar; }
582 
590  inline void SetLength(float length) { Normalize(); *this *= length; }
591  #endif
592  };
593 
594 //--------------------------------------------------------------------------------------------------------------------//
595 //--------------------------------------------------------------------------------------------------------------------//
596 //--------------------------------------------------------------------------------------------------------------------//
597 
602  class Vector4
603  {
604  public:
608  static Vector4 Zero(void) { return Vector4(0.0f, 0.0f, 0.0f, 0.0f); }
609 
610  union
611  {
612  float mComponents[4];
613 
614 #if defined(tb_visual_cpp)
615 #pragma warning(push)
616 #pragma warning(disable: 4201)
617  struct { float x, y, z, w; };
618 #pragma warning(pop)
619 #else
620  struct { float x, y, z, w; };
621 #endif
622  };
623 
630  inline explicit Vector4(const SkipInitialization& fastAndStupid)
631  {
632  tb_unused(fastAndStupid);
633  }
634 
638  inline Vector4(void) :
639  x(0.0f),
640  y(0.0f),
641  z(0.0f),
642  w(0.0f)
643  {
644  }
645 
654  inline Vector4(const float valueX, const float valueY, const float valueZ, const float valueW) :
655  x(valueX),
656  y(valueY),
657  z(valueZ),
658  w(valueW)
659  {
660  }
661 
669  inline explicit Vector4(const Vector2& other, const float valueZ, const float valueW) :
670  x(other.x),
671  y(other.y),
672  z(valueZ),
673  w(valueW)
674  {
675  }
676 
683  inline explicit Vector4(const Vector3& other, const float valueW) :
684  x(other.x),
685  y(other.y),
686  z(other.z),
687  w(valueW)
688  {
689  }
690 
697  inline Vector4(const Vector4& other) :
698  x(other.x),
699  y(other.y),
700  z(other.z),
701  w(other.w)
702  {
703  }
704 
708  ~Vector4(void)
709  {
710  }
711 
717  inline Vector4& operator=(const Vector4& other)
718  {
719  if (&other != this)
720  {
721  x = other.x;
722  y = other.y;
723  z = other.z;
724  w = other.w;
725  }
726  return *this;
727  }
728 
738  inline bool operator==(const Vector4& other) const
739  {
740  return (true == IsEqual(x, other.x) && true == IsEqual(y, other.y) &&
741  true == IsEqual(z, other.z) && true == IsEqual(w, other.w)) ? true : false;
742  }
743 
748  inline bool operator!=(const Vector4& other) const
749  {
750  return (true == operator==(other)) ? false : true;
751  }
752 
756  inline operator const float*(void) const { return mComponents; }
757 
762  inline operator float*(void) { return mComponents; }
763 
767  inline const float& operator[](const size_t index) const { return mComponents[index]; }
768 
773  inline float& operator[](const size_t index) { return mComponents[index]; }
774 
775  //TODO: TIM: Reconsider: This could be dangerous, do we want to support it?
776  //inline operator Vector2(void) { return Vector2(x, y); }
777  //inline operator Vector3(void) { return Vector3(x, y, z); }
778 
779 #ifndef tb_math_less_operators
780  inline Vector4 operator+(const Vector4& rightSide) const { return Vector4(x + rightSide.x, y + rightSide.y, z + rightSide.z, w + rightSide.w); }
784 
789  inline Vector4& operator+=(const Vector4& rightSide) { x += rightSide.x, y += rightSide.y; z += rightSide.z; w += rightSide.w; return *this; }
790 
794  inline Vector4 operator-(const Vector4& rightSide) const { return Vector4(x - rightSide.x, y - rightSide.y, z - rightSide.z, w - rightSide.w); }
795 
799  inline Vector4& operator-=(const Vector4& rightSide) { x -= rightSide.x, y -= rightSide.y; z -= rightSide.z; w -= rightSide.w; return *this; }
800 
801 
805  inline Vector4 operator*(float scalar) const { return Vector4(x * scalar, y * scalar, z * scalar, w * scalar); }
806 
811  friend Vector4 operator*(float scalar, const Vector4& rightSide) { return Vector4(scalar * rightSide.x, scalar * rightSide.y, scalar * rightSide.z, scalar * rightSide.w); }
812 
817  inline Vector4& operator*=(float scalar) { x *= scalar; y *= scalar; z *= scalar; w *= scalar; return *this; }
818 
822  inline Vector4 operator/(float scalar) const { return Vector4(x / scalar, y / scalar, z / scalar, w / scalar); }
823 
828  inline Vector4& operator/=(float scalar) { x /= scalar; y /= scalar; z /= scalar; w /= scalar; return *this; }
829 
830 
834  inline Vector4 operator-(void) const { return Vector4(-x, -y, -z, -w); }
835 
839  inline float operator*(const Vector4& rightSide) const { return (x * rightSide.x) + (y * rightSide.y) + (z * rightSide.z) + (w * rightSide.w); }
840 
841  //TODO: TIM: Reconsider: Does this work, and if it does, how do we want to support it? Document if needed.
842  //inline Vector4 operator^(const Vector4 &rhs) const { return Vector4((y * rhs.z) - (rhs.y * z), -((x * rhs.z) - (rhs.x * z)), (x * rhs.y) - (rhs.x * y)); }
843 
848  inline float Magnitude(void) const { return sqrt((x * x) + (y * y) + (z * z) + (w * w)); }
849 
854  inline float MagnitudeSquared(void) const { return (x * x) + (y * y) + (z * z) + (w * w); }
855 
860  inline Vector4 GetNormalized(void) const
861  {
862  const float magnitude(Magnitude());
863  if (true == IsZero(magnitude)) { return Zero(); }
864  return Vector4(x / magnitude, y / magnitude, z / magnitude, w / magnitude);
865  }
866 
872  inline float Normalize(void)
873  {
874  const float magnitude(Magnitude());
875  if (false == IsZero(magnitude))
876  {
877  x /= magnitude;
878  y /= magnitude;
879  z /= magnitude;
880  w /= magnitude;
881  }
882  return magnitude;
883  }
884 
888  inline void Scale(float scalar) { *this *= scalar; }
889 
897  inline void SetLength(float length) { Normalize(); *this *= length; }
898 #endif
899  };
900 
901 //--------------------------------------------------------------------------------------------------------------------//
902 //--------------------------------------------------------------------------------------------------------------------//
903 //--------------------------------------------------------------------------------------------------------------------//
904 
915  inline Vector2* Vector2Add(Vector2* result, const Vector2* leftSide, const Vector2* rightSide)
916  {
917  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
918  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
919  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
920 
921  result->x = leftSide->x + rightSide->x;
922  result->y = leftSide->y + rightSide->y;
923  return result;
924  }
925 
929  inline Vector3* Vector3Add(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
930  {
931  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
932  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
933  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
934 
935  result->x = leftSide->x + rightSide->x;
936  result->y = leftSide->y + rightSide->y;
937  result->z = leftSide->z + rightSide->z;
938  return result;
939  }
940 
944  inline Vector4* Vector4Add(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
945  {
946  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
947  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
948  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
949 
950  result->x = leftSide->x + rightSide->x;
951  result->y = leftSide->y + rightSide->y;
952  result->z = leftSide->z + rightSide->z;
953  result->w = leftSide->w + rightSide->w;
954  return result;
955  }
956 
967  inline Vector2* Vector2Subtract(Vector2* result, const Vector2* leftSide, const Vector2* rightSide)
968  {
969  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
970  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
971  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
972 
973  result->x = leftSide->x - rightSide->x;
974  result->y = leftSide->y - rightSide->y;
975  return result;
976  }
977 
981  inline Vector3* Vector3Subtract(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
982  {
983  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
984  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
985  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
986 
987  result->x = leftSide->x - rightSide->x;
988  result->y = leftSide->y - rightSide->y;
989  result->z = leftSide->z - rightSide->z;
990  return result;
991  }
992 
996  inline Vector4* Vector4Subtract(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
997  {
998  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
999  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1000  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1001 
1002  result->x = leftSide->x - rightSide->x;
1003  result->y = leftSide->y - rightSide->y;
1004  result->z = leftSide->z - rightSide->z;
1005  result->w = leftSide->w - rightSide->w;
1006  return result;
1007  }
1008 
1018  inline Vector2* Vector2Scale(Vector2* result, const Vector2* input, const float scalar)
1019  {
1020  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1021  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1022 
1023  result->x = input->x * scalar;
1024  result->y = input->y * scalar;
1025  return result;
1026  }
1027 
1031  inline Vector3* Vector3Scale(Vector3* result, const Vector3* input, const float scalar)
1032  {
1033  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1034  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1035 
1036  result->x = input->x * scalar;
1037  result->y = input->y * scalar;
1038  result->z = input->z * scalar;
1039  return result;
1040  }
1041 
1045  inline Vector4* Vector4Scale(Vector4* result, const Vector4* input, const float scalar)
1046  {
1047  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1048  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1049 
1050  result->x = input->x * scalar;
1051  result->y = input->y * scalar;
1052  result->z = input->z * scalar;
1053  result->w = input->w * scalar;
1054  return result;
1055  }
1056 
1066  inline Vector2* Vector2ScaleDivide(Vector2* result, const Vector2* input, const float scalar)
1067  {
1068  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1069  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1070 
1071  result->x = input->x / scalar;
1072  result->y = input->y / scalar;
1073  return result;
1074  }
1075 
1079  inline Vector3* Vector3ScaleDivide(Vector3* result, const Vector3* input, const float scalar)
1080  {
1081  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1082  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1083 
1084  result->x = input->x / scalar;
1085  result->y = input->y / scalar;
1086  result->z = input->z / scalar;
1087  return result;
1088  }
1089 
1093  inline Vector4* Vector4ScaleDivide(Vector4* result, const Vector4* input, const float scalar)
1094  {
1095  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1096  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1097 
1098  result->x = input->x / scalar;
1099  result->y = input->y / scalar;
1100  result->z = input->z / scalar;
1101  result->w = input->w / scalar;
1102  return result;
1103  }
1104 
1113  inline Vector2* Vector2Negate(Vector2* result, const Vector2* input)
1114  {
1115  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1116  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1117 
1118  result->x = -input->x;
1119  result->y = -input->y;
1120  return result;
1121  }
1122 
1126  inline Vector3* Vector3Negate(Vector3* result, const Vector3* input)
1127  {
1128  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1129  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1130 
1131  result->x = -input->x;
1132  result->y = -input->y;
1133  result->z = -input->z;
1134  return result;
1135  }
1136 
1140  inline Vector4* Vector4Negate(Vector4* result, const Vector4* input)
1141  {
1142  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1143  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1144 
1145  result->x = -input->x;
1146  result->y = -input->y;
1147  result->z = -input->z;
1148  result->w = -input->w;
1149  return result;
1150  }
1151 
1160  inline float Vector2DotProduct(const Vector2* leftSide, const Vector2* rightSide)
1161  {
1162  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1163  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1164  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y);
1165  }
1166 
1170  inline float Vector3DotProduct(const Vector3* leftSide, const Vector3* rightSide)
1171  {
1172  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1173  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1174  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y) + (leftSide->z * rightSide->z);
1175  }
1176 
1180  inline float Vector4DotProduct(const Vector4* leftSide, const Vector4* rightSide)
1181  {
1182  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1183  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1184  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y) + (leftSide->z * rightSide->z) + (leftSide->w * rightSide->w);
1185  }
1186 
1200  inline Vector3* Vector3CrossProduct(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
1201  {
1202  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1203  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1204  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1205  tb_error_if(leftSide == rightSide, "tbExternalError: Invalid parameter; expected leftSide to be different from rightSide.");
1206  tb_error_if(result == leftSide || result == rightSide, "Invalid parameter; expected result to be different than leftSide and rightSide");
1207 
1208  result->x = ((leftSide->y * rightSide->z) - (rightSide->y * leftSide->z));
1209  result->y = -(((leftSide->x * rightSide->z) - (rightSide->x * leftSide->z)));
1210  result->z = ((leftSide->x * rightSide->y) - (rightSide->x * leftSide->y));
1211  return result;
1212  }
1213 
1218  inline Vector4* Vector4CrossProduct(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
1219  {
1220  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1221  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1222  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1223  tb_error_if(result == leftSide || result == rightSide, "Invalid parameter; expected result to be different than leftSide and rightSide");
1224 
1225  tb_error_if(true, "Not sure if this is an accurate Vector4 CrossProduct");
1226  result->x = ((leftSide->y * rightSide->z) - (rightSide->y * leftSide->z));
1227  result->y = -(((leftSide->x * rightSide->z) - (rightSide->x * leftSide->z)));
1228  result->z = ((leftSide->x * rightSide->y) - (rightSide->x * leftSide->y));
1229  result->w = 0.0f;
1230  return result;
1231  }
1232 
1240  inline float Vector2Magnitude(const Vector2* input)
1241  {
1242  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1243  return sqrt((input->x * input->x) + (input->y * input->y));
1244  }
1245 
1249  inline float Vector3Magnitude(const Vector3* input)
1250  {
1251  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1252  return sqrt((input->x * input->x) + (input->y * input->y) + (input->z * input->z));
1253  }
1254 
1258  inline float Vector4Magnitude(const Vector4* input)
1259  {
1260  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1261  return sqrt((input->x * input->x) + (input->y * input->y) + (input->z * input->z) + (input->w * input->w));
1262  }
1263 
1272  inline float Vector2MagnitudeSquared(const Vector2* input)
1273  {
1274  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1275  return (input->x * input->x) + (input->y * input->y);
1276  }
1277 
1281  inline float Vector3MagnitudeSquared(const Vector3* input)
1282  {
1283  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1284  return (input->x * input->x) + (input->y * input->y) + (input->z * input->z);
1285  }
1286 
1290  inline float Vector4MagnitudeSquared(const Vector4* input)
1291  {
1292  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1293  return (input->x * input->x) + (input->y * input->y) + (input->z * input->z) + (input->w * input->w);
1294  }
1295 
1304  inline Vector2* Vector2Normalize(Vector2* result, const Vector2* input)
1305  {
1306  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1307 
1308  const float magnitude = Vector2Magnitude(input);
1309  if (true == IsZero(magnitude))
1310  {
1311  result->x = 0.0f;
1312  result->y = 0.0f;
1313  }
1314  else
1315  {
1316  result->x = input->x / magnitude;
1317  result->y = input->y / magnitude;
1318  }
1319  return result;
1320  }
1321 
1325  inline Vector3* Vector3Normalize(Vector3* result, const Vector3* input)
1326  {
1327  const float magnitude = Vector3Magnitude(input);
1328  if (true == IsZero(magnitude))
1329  {
1330  result->x = 0.0f;
1331  result->y = 0.0f;
1332  result->z = 0.0f;
1333  }
1334  else
1335  {
1336  result->x = input->x / magnitude;
1337  result->y = input->y / magnitude;
1338  result->z = input->z / magnitude;
1339  }
1340  return result;
1341  }
1342 
1346  inline Vector4* Vector4Normalize(Vector4* result, const Vector4* input)
1347  {
1348  const float magnitude = Vector4Magnitude(input);
1349  if (true == IsZero(magnitude))
1350  {
1351  result->x = 0.0f;
1352  result->y = 0.0f;
1353  result->z = 0.0f;
1354  result->w = 0.0f;
1355  }
1356  else
1357  {
1358  result->x = input->x / magnitude;
1359  result->y = input->y / magnitude;
1360  result->z = input->z / magnitude;
1361  result->w = input->w / magnitude;
1362  }
1363  return result;
1364  }
1365 
1376  inline Vector2* Vector2NormalizeMagnitude(Vector2* result, const Vector2* input, float& magnitude)
1377  {
1378  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1379 
1380  magnitude = Vector2Magnitude(input);
1381  if (true == IsZero(magnitude))
1382  {
1383  result->x = 0.0f;
1384  result->y = 0.0f;
1385  }
1386  else
1387  {
1388  result->x = input->x / magnitude;
1389  result->y = input->y / magnitude;
1390  }
1391  return result;
1392  }
1393 
1397  inline Vector3* Vector3NormalizeMagnitude(Vector3* result, const Vector3* input, float &magnitude)
1398  {
1399  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1400 
1401  magnitude = Vector3Magnitude(input);
1402  if (true == IsZero(magnitude))
1403  {
1404  result->x = 0.0f;
1405  result->y = 0.0f;
1406  result->z = 0.0f;
1407  }
1408  else
1409  {
1410  result->x = input->x / magnitude;
1411  result->y = input->y / magnitude;
1412  result->z = input->z / magnitude;
1413  }
1414  return result;
1415  }
1416 
1420  inline Vector4* Vector4NormalizeMag(Vector4* result, const Vector4* input, float &magnitude)
1421  {
1422  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1423 
1424  magnitude = Vector4Magnitude(input);
1425  if (true == IsZero(magnitude))
1426  {
1427  result->x = 0.0f;
1428  result->y = 0.0f;
1429  result->z = 0.0f;
1430  result->w = 0.0f;
1431  }
1432  else
1433  {
1434  result->x = input->x / magnitude;
1435  result->y = input->y / magnitude;
1436  result->z = input->z / magnitude;
1437  result->w = input->w / magnitude;
1438  }
1439  return result;
1440  }
1441 
1446  inline float Vector3AngleBetween(const Vector3* left, const Vector3* right)
1447  {
1448  const float productOfMagnitudes(Vector3Magnitude(left) * Vector3Magnitude(right));
1449  if (true == IsZero(productOfMagnitudes)) { return 0.0f; }
1450  const float value(Vector3DotProduct(left, right) / productOfMagnitudes);
1451  const float clampedValue((value < -1.0f) ? -1.0f : (value > 1.0f) ? 1.0f : value); //Clamp: -1.0f <= value <= 1.0f
1452  return acos(clampedValue);
1453  }
1454 
1459  static inline Vector3* OrientationToForwardVector3(Vector3 *result, float orientation)
1460  {
1461  result->x = sin(orientation);
1462  result->y = 0.0f;
1463  result->z = -cos(orientation);
1464 
1465  return result;
1466  }
1467 
1472  static inline Vector2& OrientationToForwardVector2(Vector2& result, float orientation)
1473  {
1474  result.x = sin(orientation);
1475  result.y = -cos(orientation);
1476  return result;
1477  }
1478 
1488  static inline float ForwardVector3ToOrientation(const Vector3& forward)
1489  {
1490  Vector3 vZAxis(0.0f, 0.0f, -1.0f);
1491  float orientation = acos((vZAxis.x * forward.x) + (vZAxis.y * forward.y) + (vZAxis.z * forward.z));
1492  if (forward.x < 0.0f)
1493  {
1494  orientation = fabs(orientation - kTwoPi);
1495  }
1496  return orientation;
1497  }
1498 
1508  static inline float ForwardVector2ToOrientation(const Vector2& forward)
1509  {
1510  Vector2 yAxis(0.0f, -1.0f);
1511  float orientation = acos((yAxis.x * forward.x) + (yAxis.y * forward.y));
1512  if (forward.x < 0.0f)
1513  {
1514  orientation = fabs(orientation - kTwoPi);
1515  }
1516  return orientation;
1517  }
1518 
1519  }; /* namespace Math */
1520 }; /* namespace TurtleBrains */
1521 
1522 namespace tbMath = TurtleBrains::Math;
1523 
1524 #endif /* _TurtleBrains_Vector_h_ */
Vector2 * Vector2NormalizeMagnitude(Vector2 *result, const Vector2 *input, float &magnitude)
Definition: tb_vector.h:1376
Definition: tb_vector.h:47
Vector4(const Vector2 &other, const float valueZ, const float valueW)
Definition: tb_vector.h:669
const float & operator[](const size_t index) const
Definition: tb_vector.h:767
Vector3 operator-(void) const
Definition: tb_vector.h:521
Vector4 * Vector4Negate(Vector4 *result, const Vector4 *input)
Definition: tb_vector.h:1140
friend Vector4 operator*(float scalar, const Vector4 &rightSide)
Definition: tb_vector.h:811
Vector4(const float valueX, const float valueY, const float valueZ, const float valueW)
Definition: tb_vector.h:654
float & operator[](const size_t index)
Definition: tb_vector.h:461
Vector2 GetNormalized(void) const
Definition: tb_vector.h:256
Vector3(const SkipInitialization &fastAndStupid)
Definition: tb_vector.h:331
bool operator!=(const Vector2 &other) const
Definition: tb_vector.h:153
Vector2 operator*(float scalar) const
Definition: tb_vector.h:205
static Vector3 * OrientationToForwardVector3(Vector3 *result, float orientation)
Definition: tb_vector.h:1459
Vector4 operator/(float scalar) const
Definition: tb_vector.h:822
Vector4(const SkipInitialization &fastAndStupid)
Definition: tb_vector.h:630
Contains objects and functions for dealing with Vector and Matrix math.
float Vector4DotProduct(const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:1180
Vector3 & operator=(const Vector3 &other)
Definition: tb_vector.h:398
float & operator[](const size_t index)
Definition: tb_vector.h:178
Vector2 & operator/=(float scalar)
Definition: tb_vector.h:228
bool operator==(const Vector3 &other) const
Definition: tb_vector.h:427
Vector3 operator^(const Vector3 &rightSide) const
Definition: tb_vector.h:532
static float ForwardVector2ToOrientation(const Vector2 &forward)
Definition: tb_vector.h:1508
float Normalize(void)
Definition: tb_vector.h:268
Vector4(const Vector3 &other, const float valueW)
Definition: tb_vector.h:683
Vector4 & operator/=(float scalar)
Definition: tb_vector.h:828
Vector4(const Vector4 &other)
Definition: tb_vector.h:697
float Vector4MagnitudeSquared(const Vector4 *input)
Definition: tb_vector.h:1290
Vector2(void)
Definition: tb_vector.h:83
Definition: tb_vector.h:39
Definition: tb_vector.h:303
float Normalize(void)
Definition: tb_vector.h:872
Vector4 * Vector4CrossProduct(Vector4 *result, const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:1218
Vector3(const Vector2 &other, const float valueZ)
Definition: tb_vector.h:366
Vector4 * Vector4Add(Vector4 *result, const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:944
Vector4 * Vector4Subtract(Vector4 *result, const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:996
bool operator==(const Vector2 &other) const
Definition: tb_vector.h:144
Vector2 * Vector2Subtract(Vector2 *result, const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.h:967
Vector3 GetNormalized(void) const
Definition: tb_vector.h:554
void SetLength(float length)
Definition: tb_vector.h:291
friend Vector3 operator*(float scalar, const Vector3 &rightSide)
Definition: tb_vector.h:498
float Magnitude(void) const
Definition: tb_vector.h:542
void Scale(float scalar)
Definition: tb_vector.h:282
Vector2 operator-(void) const
Definition: tb_vector.h:233
Contains all functions, classes and helpers related to game/application development written by Tim "B...
Definition: tb_application_dialog.h:21
Vector3(void)
Definition: tb_vector.h:339
Vector3 * Vector3Add(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:929
static Vector2 Zero(void)
Definition: tb_vector.h:53
Vector3 * Vector3Scale(Vector3 *result, const Vector3 *input, const float scalar)
Definition: tb_vector.h:1031
#define tb_unused(parameter)
Definition: tb_defines.h:19
float Vector4Magnitude(const Vector4 *input)
Definition: tb_vector.h:1258
Vector3 operator+(const Vector3 &rightSide) const
Definition: tb_vector.h:470
static float ForwardVector3ToOrientation(const Vector3 &forward)
Definition: tb_vector.h:1488
Vector3 * Vector3Normalize(Vector3 *result, const Vector3 *input)
Definition: tb_vector.h:1325
Vector4 & operator*=(float scalar)
Definition: tb_vector.h:817
void Scale(float scalar)
Definition: tb_vector.h:581
Definition: tb_vector.h:40
VectorComponent
Definition: tb_vector.h:35
SkipInitialization
Definition: tb_vector.h:29
Vector3 * Vector3NormalizeMagnitude(Vector3 *result, const Vector3 *input, float &magnitude)
Definition: tb_vector.h:1397
bool operator!=(const Vector3 &other) const
Definition: tb_vector.h:436
float Magnitude(void) const
Definition: tb_vector.h:244
float Vector2Magnitude(const Vector2 *input)
Definition: tb_vector.h:1240
Vector2 * Vector2Negate(Vector2 *result, const Vector2 *input)
Definition: tb_vector.h:1113
static const float kTwoPi(kPi *2.0f)
A constant for Pi * 2 stored in a float.
Vector2 operator-(const Vector2 &rightSide) const
Definition: tb_vector.h:195
Vector4 & operator=(const Vector4 &other)
Definition: tb_vector.h:717
Vector2 operator+(const Vector2 &rightSide) const
Definition: tb_vector.h:184
Vector3 & operator-=(const Vector3 &rightSide)
Definition: tb_vector.h:486
Vector2 & operator=(const Vector2 &other)
Definition: tb_vector.h:125
float operator*(const Vector4 &rightSide) const
Definition: tb_vector.h:839
Vector2 & operator*=(float scalar)
Definition: tb_vector.h:217
float Magnitude(void) const
Definition: tb_vector.h:848
float operator*(const Vector3 &rhs) const
Definition: tb_vector.h:526
static Vector4 Zero(void)
Definition: tb_vector.h:608
Vector4 * Vector4Scale(Vector4 *result, const Vector4 *input, const float scalar)
Definition: tb_vector.h:1045
Vector4 * Vector4Normalize(Vector4 *result, const Vector4 *input)
Definition: tb_vector.h:1346
Vector3 * Vector3Subtract(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:981
Vector2 * Vector2Add(Vector2 *result, const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.h:915
void Scale(float scalar)
Definition: tb_vector.h:888
bool operator!=(const Vector4 &other) const
Definition: tb_vector.h:748
Vector4 * Vector4NormalizeMag(Vector4 *result, const Vector4 *input, float &magnitude)
Definition: tb_vector.h:1420
const float & operator[](const size_t index) const
Definition: tb_vector.h:455
static Vector2 & OrientationToForwardVector2(Vector2 &result, float orientation)
Definition: tb_vector.h:1472
~Vector4(void)
Definition: tb_vector.h:708
Vector2 * Vector2Normalize(Vector2 *result, const Vector2 *input)
Definition: tb_vector.h:1304
~Vector3(void)
Definition: tb_vector.h:389
float MagnitudeSquared(void) const
Definition: tb_vector.h:854
float Vector3AngleBetween(const Vector3 *left, const Vector3 *right)
Definition: tb_vector.h:1446
float Vector2MagnitudeSquared(const Vector2 *input)
Definition: tb_vector.h:1272
Vector2 operator/(float scalar) const
Definition: tb_vector.h:222
void SetLength(float length)
Definition: tb_vector.h:897
float & operator[](const size_t index)
Definition: tb_vector.h:773
float Normalize(void)
Definition: tb_vector.h:566
float MagnitudeSquared(void) const
Definition: tb_vector.h:250
float Vector3DotProduct(const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:1170
Vector2(const SkipInitialization &fastAndStupid)
Definition: tb_vector.h:75
Vector4 GetNormalized(void) const
Definition: tb_vector.h:860
Vector4 operator+(const Vector4 &rightSide) const
Definition: tb_vector.h:783
Vector3 * Vector3ScaleDivide(Vector3 *result, const Vector3 *input, const float scalar)
Definition: tb_vector.h:1079
bool IsZero(const float value, const float tolerance=tbMath::kTolerance)
Definition: tb_math.h:42
Vector2(const Vector2 &other)
Definition: tb_vector.h:107
Vector2(const float valueX, const float valueY)
Definition: tb_vector.h:95
Vector2 * Vector2ScaleDivide(Vector2 *result, const Vector2 *input, const float scalar)
Definition: tb_vector.h:1066
bool IsEqual(const float leftValue, const float rightValue, const float tolerance=tbMath::kTolerance)
Definition: tb_math.h:29
Vector3(const float valueX, const float valueY, const float valueZ)
Definition: tb_vector.h:353
Vector3 * Vector3CrossProduct(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:1200
friend Vector2 operator*(float scalar, const Vector2 &rightSide)
Definition: tb_vector.h:211
float MagnitudeSquared(void) const
Definition: tb_vector.h:548
float Vector2DotProduct(const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.h:1160
Vector4 * Vector4ScaleDivide(Vector4 *result, const Vector4 *input, const float scalar)
Definition: tb_vector.h:1093
const float & operator[](const size_t index) const
Definition: tb_vector.h:172
Vector4 operator*(float scalar) const
Definition: tb_vector.h:805
Vector2 & operator+=(const Vector2 &rightSide)
Definition: tb_vector.h:190
Definition: tb_vector.h:38
bool operator==(const Vector4 &other) const
Definition: tb_vector.h:738
~Vector2(void)
Definition: tb_vector.h:116
Vector4 & operator+=(const Vector4 &rightSide)
Definition: tb_vector.h:789
void SetLength(float length)
Definition: tb_vector.h:590
Vector4(void)
Definition: tb_vector.h:638
float Vector3MagnitudeSquared(const Vector3 *input)
Definition: tb_vector.h:1281
Vector3 & operator/=(float scalar)
Definition: tb_vector.h:515
Definition: tb_vector.h:37
Vector3 & operator*=(float scalar)
Definition: tb_vector.h:504
Vector3 operator-(const Vector3 &rightSide) const
Definition: tb_vector.h:481
Vector3(const Vector3 &other)
Definition: tb_vector.h:379
Vector4 operator-(const Vector4 &rightSide) const
Definition: tb_vector.h:794
#define tb_error_if(errorTest, message,...)
Definition: tb_error.h:37
static Vector3 Zero(void)
Definition: tb_vector.h:309
Vector3 operator*(float scalar) const
Definition: tb_vector.h:492
float operator*(const Vector2 &rhs) const
Definition: tb_vector.h:238
Vector4 & operator-=(const Vector4 &rightSide)
Definition: tb_vector.h:799
Vector3 * Vector3Negate(Vector3 *result, const Vector3 *input)
Definition: tb_vector.h:1126
Vector2 & operator-=(const Vector2 &rightSide)
Definition: tb_vector.h:200
Vector3 operator/(float scalar) const
Definition: tb_vector.h:509
Vector4 operator-(void) const
Definition: tb_vector.h:834
float Vector3Magnitude(const Vector3 *input)
Definition: tb_vector.h:1249
Definition: tb_vector.h:602
Vector3 & operator+=(const Vector3 &rightSide)
Definition: tb_vector.h:476
Vector2 * Vector2Scale(Vector2 *result, const Vector2 *input, const float scalar)
Definition: tb_vector.h:1018