TurtleBrains  0.3.1
High quality, portable, C++ framework for rapid 2D 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 #if defined(tb_with_math_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 /* tb_with_math_operators */
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  #if defined(tb_with_math_operators)
464  inline Vector3 operator+(const Vector3& rightSide) const { return Vector3(x + rightSide.x, y + rightSide.y, z + rightSide.z); }
468 
473  inline Vector3& operator+=(const Vector3& rightSide) { x += rightSide.x, y += rightSide.y; z += rightSide.z; return *this; }
474 
478  inline Vector3 operator-(const Vector3& rightSide) const { return Vector3(x - rightSide.x, y - rightSide.y, z - rightSide.z); }
479 
483  inline Vector3& operator-=(const Vector3& rightSide) { x -= rightSide.x, y -= rightSide.y; z -= rightSide.z; return *this; }
484 
485 
489  inline Vector3 operator*(float scalar) const { return Vector3(x * scalar, y * scalar, z * scalar); }
490 
495  friend Vector3 operator*(float scalar, const Vector3& rightSide) { return Vector3(scalar * rightSide.x, scalar * rightSide.y, scalar * rightSide.z); }
496 
501  inline Vector3& operator*=(float scalar) { x *= scalar; y *= scalar; z *= scalar; return *this; }
502 
506  inline Vector3 operator/(float scalar) const { return Vector3(x / scalar, y / scalar, z / scalar); }
507 
512  inline Vector3& operator/=(float scalar) { x /= scalar; y /= scalar; z /= scalar; return *this; }
513 
514 
518  inline Vector3 operator-(void) const { return Vector3(-x, -y, -z); }
519 
523  inline float operator*(const Vector3 &rhs) const { return (x * rhs.x) + (y * rhs.y) + (z * rhs.z); }
524 
529  inline Vector3 operator^(const Vector3& rightSide) const
530  {
531  return Vector3((y * rightSide.z) - (rightSide.y * z), -((x * rightSide.z) - (rightSide.x * z)), (x * rightSide.y) - (rightSide.x * y));
532  }
533 
534 
539  inline float Magnitude(void) const { return sqrt((x * x) + (y * y) + (z * z)); }
540 
545  inline float MagnitudeSquared(void) const { return (x * x) + (y * y) + (z * z); }
546 
551  inline Vector3 GetNormalized(void) const
552  {
553  const float magnitude(Magnitude());
554  if (true == IsZero(magnitude)) { return Zero(); }
555  return Vector3(x / magnitude, y / magnitude, z / magnitude);
556  }
557 
563  inline float Normalize(void)
564  {
565  const float magnitude(Magnitude());
566  if (false == IsZero(magnitude))
567  {
568  x /= magnitude;
569  y /= magnitude;
570  z /= magnitude;
571  }
572  return magnitude;
573  }
574 
578  inline void Scale(float scalar) { *this *= scalar; }
579 
587  inline void SetLength(float length) { Normalize(); *this *= length; }
588  #endif /* tb_with_math_operators */
589  };
590 
591 //--------------------------------------------------------------------------------------------------------------------//
592 //--------------------------------------------------------------------------------------------------------------------//
593 //--------------------------------------------------------------------------------------------------------------------//
594 
599  class Vector4
600  {
601  public:
605  static Vector4 Zero(void) { return Vector4(0.0f, 0.0f, 0.0f, 0.0f); }
606 
607  union
608  {
609  float mComponents[4];
610 
611 #if defined(tb_visual_cpp)
612 #pragma warning(push)
613 #pragma warning(disable: 4201)
614  struct { float x, y, z, w; };
615 #pragma warning(pop)
616 #else
617  struct { float x, y, z, w; };
618 #endif
619  };
620 
627  inline explicit Vector4(const SkipInitialization& fastAndStupid)
628  {
629  tb_unused(fastAndStupid);
630  }
631 
635  inline Vector4(void) :
636  x(0.0f),
637  y(0.0f),
638  z(0.0f),
639  w(0.0f)
640  {
641  }
642 
651  inline Vector4(const float valueX, const float valueY, const float valueZ, const float valueW) :
652  x(valueX),
653  y(valueY),
654  z(valueZ),
655  w(valueW)
656  {
657  }
658 
666  inline explicit Vector4(const Vector2& other, const float valueZ, const float valueW) :
667  x(other.x),
668  y(other.y),
669  z(valueZ),
670  w(valueW)
671  {
672  }
673 
680  inline explicit Vector4(const Vector3& other, const float valueW) :
681  x(other.x),
682  y(other.y),
683  z(other.z),
684  w(valueW)
685  {
686  }
687 
694  inline Vector4(const Vector4& other) :
695  x(other.x),
696  y(other.y),
697  z(other.z),
698  w(other.w)
699  {
700  }
701 
705  ~Vector4(void)
706  {
707  }
708 
714  inline Vector4& operator=(const Vector4& other)
715  {
716  if (&other != this)
717  {
718  x = other.x;
719  y = other.y;
720  z = other.z;
721  w = other.w;
722  }
723  return *this;
724  }
725 
735  inline bool operator==(const Vector4& other) const
736  {
737  return (true == IsEqual(x, other.x) && true == IsEqual(y, other.y) &&
738  true == IsEqual(z, other.z) && true == IsEqual(w, other.w)) ? true : false;
739  }
740 
745  inline bool operator!=(const Vector4& other) const
746  {
747  return (true == operator==(other)) ? false : true;
748  }
749 
753  inline operator const float*(void) const { return mComponents; }
754 
759  inline operator float*(void) { return mComponents; }
760 
764  inline const float& operator[](const size_t index) const { return mComponents[index]; }
765 
770  inline float& operator[](const size_t index) { return mComponents[index]; }
771 
772 #if defined(tb_with_math_operators)
773  inline Vector4 operator+(const Vector4& rightSide) const { return Vector4(x + rightSide.x, y + rightSide.y, z + rightSide.z, w + rightSide.w); }
777 
782  inline Vector4& operator+=(const Vector4& rightSide) { x += rightSide.x, y += rightSide.y; z += rightSide.z; w += rightSide.w; return *this; }
783 
787  inline Vector4 operator-(const Vector4& rightSide) const { return Vector4(x - rightSide.x, y - rightSide.y, z - rightSide.z, w - rightSide.w); }
788 
792  inline Vector4& operator-=(const Vector4& rightSide) { x -= rightSide.x, y -= rightSide.y; z -= rightSide.z; w -= rightSide.w; return *this; }
793 
794 
798  inline Vector4 operator*(float scalar) const { return Vector4(x * scalar, y * scalar, z * scalar, w * scalar); }
799 
804  friend Vector4 operator*(float scalar, const Vector4& rightSide) { return Vector4(scalar * rightSide.x, scalar * rightSide.y, scalar * rightSide.z, scalar * rightSide.w); }
805 
810  inline Vector4& operator*=(float scalar) { x *= scalar; y *= scalar; z *= scalar; w *= scalar; return *this; }
811 
815  inline Vector4 operator/(float scalar) const { return Vector4(x / scalar, y / scalar, z / scalar, w / scalar); }
816 
821  inline Vector4& operator/=(float scalar) { x /= scalar; y /= scalar; z /= scalar; w /= scalar; return *this; }
822 
823 
827  inline Vector4 operator-(void) const { return Vector4(-x, -y, -z, -w); }
828 
832  inline float operator*(const Vector4& rightSide) const { return (x * rightSide.x) + (y * rightSide.y) + (z * rightSide.z) + (w * rightSide.w); }
833 
834  //TODO: TIM: Reconsider: Does this work, and if it does, how do we want to support it? Document if needed.
835  //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)); }
836 
841  inline float Magnitude(void) const { return sqrt((x * x) + (y * y) + (z * z) + (w * w)); }
842 
847  inline float MagnitudeSquared(void) const { return (x * x) + (y * y) + (z * z) + (w * w); }
848 
853  inline Vector4 GetNormalized(void) const
854  {
855  const float magnitude(Magnitude());
856  if (true == IsZero(magnitude)) { return Zero(); }
857  return Vector4(x / magnitude, y / magnitude, z / magnitude, w / magnitude);
858  }
859 
865  inline float Normalize(void)
866  {
867  const float magnitude(Magnitude());
868  if (false == IsZero(magnitude))
869  {
870  x /= magnitude;
871  y /= magnitude;
872  z /= magnitude;
873  w /= magnitude;
874  }
875  return magnitude;
876  }
877 
881  inline void Scale(float scalar) { *this *= scalar; }
882 
890  inline void SetLength(float length) { Normalize(); *this *= length; }
891 #endif /* tb_with_math_operators */
892  };
893 
894 //--------------------------------------------------------------------------------------------------------------------//
895 //--------------------------------------------------------------------------------------------------------------------//
896 //--------------------------------------------------------------------------------------------------------------------//
897 
908  inline Vector2* Vector2Add(Vector2* result, const Vector2* leftSide, const Vector2* rightSide)
909  {
910  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
911  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
912  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
913 
914  result->x = leftSide->x + rightSide->x;
915  result->y = leftSide->y + rightSide->y;
916  return result;
917  }
918 
922  inline Vector3* Vector3Add(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
923  {
924  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
925  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
926  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
927 
928  result->x = leftSide->x + rightSide->x;
929  result->y = leftSide->y + rightSide->y;
930  result->z = leftSide->z + rightSide->z;
931  return result;
932  }
933 
937  inline Vector4* Vector4Add(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
938  {
939  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
940  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
941  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
942 
943  result->x = leftSide->x + rightSide->x;
944  result->y = leftSide->y + rightSide->y;
945  result->z = leftSide->z + rightSide->z;
946  result->w = leftSide->w + rightSide->w;
947  return result;
948  }
949 
960  inline Vector2* Vector2Subtract(Vector2* result, const Vector2* leftSide, const Vector2* rightSide)
961  {
962  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
963  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
964  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
965 
966  result->x = leftSide->x - rightSide->x;
967  result->y = leftSide->y - rightSide->y;
968  return result;
969  }
970 
974  inline Vector3* Vector3Subtract(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
975  {
976  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
977  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
978  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
979 
980  result->x = leftSide->x - rightSide->x;
981  result->y = leftSide->y - rightSide->y;
982  result->z = leftSide->z - rightSide->z;
983  return result;
984  }
985 
989  inline Vector4* Vector4Subtract(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
990  {
991  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
992  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
993  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
994 
995  result->x = leftSide->x - rightSide->x;
996  result->y = leftSide->y - rightSide->y;
997  result->z = leftSide->z - rightSide->z;
998  result->w = leftSide->w - rightSide->w;
999  return result;
1000  }
1001 
1011  inline Vector2* Vector2Scale(Vector2* result, const Vector2* input, const float scalar)
1012  {
1013  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1014  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1015 
1016  result->x = input->x * scalar;
1017  result->y = input->y * scalar;
1018  return result;
1019  }
1020 
1024  inline Vector3* Vector3Scale(Vector3* result, const Vector3* input, const float scalar)
1025  {
1026  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1027  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1028 
1029  result->x = input->x * scalar;
1030  result->y = input->y * scalar;
1031  result->z = input->z * scalar;
1032  return result;
1033  }
1034 
1038  inline Vector4* Vector4Scale(Vector4* result, const Vector4* input, const float scalar)
1039  {
1040  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1041  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1042 
1043  result->x = input->x * scalar;
1044  result->y = input->y * scalar;
1045  result->z = input->z * scalar;
1046  result->w = input->w * scalar;
1047  return result;
1048  }
1049 
1059  inline Vector2* Vector2ScaleDivide(Vector2* result, const Vector2* input, const float scalar)
1060  {
1061  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1062  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1063 
1064  result->x = input->x / scalar;
1065  result->y = input->y / scalar;
1066  return result;
1067  }
1068 
1072  inline Vector3* Vector3ScaleDivide(Vector3* result, const Vector3* input, const float scalar)
1073  {
1074  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1075  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1076 
1077  result->x = input->x / scalar;
1078  result->y = input->y / scalar;
1079  result->z = input->z / scalar;
1080  return result;
1081  }
1082 
1086  inline Vector4* Vector4ScaleDivide(Vector4* result, const Vector4* input, const float scalar)
1087  {
1088  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1089  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1090 
1091  result->x = input->x / scalar;
1092  result->y = input->y / scalar;
1093  result->z = input->z / scalar;
1094  result->w = input->w / scalar;
1095  return result;
1096  }
1097 
1106  inline Vector2* Vector2Negate(Vector2* result, const Vector2* input)
1107  {
1108  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1109  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1110 
1111  result->x = -input->x;
1112  result->y = -input->y;
1113  return result;
1114  }
1115 
1119  inline Vector3* Vector3Negate(Vector3* result, const Vector3* input)
1120  {
1121  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1122  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1123 
1124  result->x = -input->x;
1125  result->y = -input->y;
1126  result->z = -input->z;
1127  return result;
1128  }
1129 
1133  inline Vector4* Vector4Negate(Vector4* result, const Vector4* input)
1134  {
1135  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1136  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1137 
1138  result->x = -input->x;
1139  result->y = -input->y;
1140  result->z = -input->z;
1141  result->w = -input->w;
1142  return result;
1143  }
1144 
1153  inline float Vector2DotProduct(const Vector2* leftSide, const Vector2* rightSide)
1154  {
1155  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1156  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1157  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y);
1158  }
1159 
1163  inline float Vector3DotProduct(const Vector3* leftSide, const Vector3* rightSide)
1164  {
1165  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1166  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1167  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y) + (leftSide->z * rightSide->z);
1168  }
1169 
1173  inline float Vector4DotProduct(const Vector4* leftSide, const Vector4* rightSide)
1174  {
1175  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1176  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1177  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y) + (leftSide->z * rightSide->z) + (leftSide->w * rightSide->w);
1178  }
1179 
1193  inline Vector3* Vector3CrossProduct(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
1194  {
1195  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1196  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1197  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1198  tb_error_if(leftSide == rightSide, "tbExternalError: Invalid parameter; expected leftSide to be different from rightSide.");
1199  tb_error_if(result == leftSide || result == rightSide, "Invalid parameter; expected result to be different than leftSide and rightSide");
1200 
1201  result->x = ((leftSide->y * rightSide->z) - (rightSide->y * leftSide->z));
1202  result->y = -(((leftSide->x * rightSide->z) - (rightSide->x * leftSide->z)));
1203  result->z = ((leftSide->x * rightSide->y) - (rightSide->x * leftSide->y));
1204  return result;
1205  }
1206 
1211  inline Vector4* Vector4CrossProduct(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
1212  {
1213  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1214  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1215  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1216  tb_error_if(result == leftSide || result == rightSide, "Invalid parameter; expected result to be different than leftSide and rightSide");
1217 
1218  tb_error_if(true, "Not sure if this is an accurate Vector4 CrossProduct");
1219  result->x = ((leftSide->y * rightSide->z) - (rightSide->y * leftSide->z));
1220  result->y = -(((leftSide->x * rightSide->z) - (rightSide->x * leftSide->z)));
1221  result->z = ((leftSide->x * rightSide->y) - (rightSide->x * leftSide->y));
1222  result->w = 0.0f;
1223  return result;
1224  }
1225 
1233  inline float Vector2Magnitude(const Vector2* input)
1234  {
1235  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1236  return sqrt((input->x * input->x) + (input->y * input->y));
1237  }
1238 
1242  inline float Vector3Magnitude(const Vector3* input)
1243  {
1244  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1245  return sqrt((input->x * input->x) + (input->y * input->y) + (input->z * input->z));
1246  }
1247 
1251  inline float Vector4Magnitude(const Vector4* input)
1252  {
1253  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1254  return sqrt((input->x * input->x) + (input->y * input->y) + (input->z * input->z) + (input->w * input->w));
1255  }
1256 
1265  inline float Vector2MagnitudeSquared(const Vector2* input)
1266  {
1267  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1268  return (input->x * input->x) + (input->y * input->y);
1269  }
1270 
1274  inline float Vector3MagnitudeSquared(const Vector3* input)
1275  {
1276  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1277  return (input->x * input->x) + (input->y * input->y) + (input->z * input->z);
1278  }
1279 
1283  inline float Vector4MagnitudeSquared(const Vector4* input)
1284  {
1285  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1286  return (input->x * input->x) + (input->y * input->y) + (input->z * input->z) + (input->w * input->w);
1287  }
1288 
1297  inline Vector2* Vector2Normalize(Vector2* result, const Vector2* input)
1298  {
1299  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1300 
1301  const float magnitude = Vector2Magnitude(input);
1302  if (true == IsZero(magnitude))
1303  {
1304  result->x = 0.0f;
1305  result->y = 0.0f;
1306  }
1307  else
1308  {
1309  result->x = input->x / magnitude;
1310  result->y = input->y / magnitude;
1311  }
1312  return result;
1313  }
1314 
1318  inline Vector3* Vector3Normalize(Vector3* result, const Vector3* input)
1319  {
1320  const float magnitude = Vector3Magnitude(input);
1321  if (true == IsZero(magnitude))
1322  {
1323  result->x = 0.0f;
1324  result->y = 0.0f;
1325  result->z = 0.0f;
1326  }
1327  else
1328  {
1329  result->x = input->x / magnitude;
1330  result->y = input->y / magnitude;
1331  result->z = input->z / magnitude;
1332  }
1333  return result;
1334  }
1335 
1339  inline Vector4* Vector4Normalize(Vector4* result, const Vector4* input)
1340  {
1341  const float magnitude = Vector4Magnitude(input);
1342  if (true == IsZero(magnitude))
1343  {
1344  result->x = 0.0f;
1345  result->y = 0.0f;
1346  result->z = 0.0f;
1347  result->w = 0.0f;
1348  }
1349  else
1350  {
1351  result->x = input->x / magnitude;
1352  result->y = input->y / magnitude;
1353  result->z = input->z / magnitude;
1354  result->w = input->w / magnitude;
1355  }
1356  return result;
1357  }
1358 
1369  inline Vector2* Vector2NormalizeMagnitude(Vector2* result, const Vector2* input, float& magnitude)
1370  {
1371  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1372 
1373  magnitude = Vector2Magnitude(input);
1374  if (true == IsZero(magnitude))
1375  {
1376  result->x = 0.0f;
1377  result->y = 0.0f;
1378  }
1379  else
1380  {
1381  result->x = input->x / magnitude;
1382  result->y = input->y / magnitude;
1383  }
1384  return result;
1385  }
1386 
1390  inline Vector3* Vector3NormalizeMagnitude(Vector3* result, const Vector3* input, float &magnitude)
1391  {
1392  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1393 
1394  magnitude = Vector3Magnitude(input);
1395  if (true == IsZero(magnitude))
1396  {
1397  result->x = 0.0f;
1398  result->y = 0.0f;
1399  result->z = 0.0f;
1400  }
1401  else
1402  {
1403  result->x = input->x / magnitude;
1404  result->y = input->y / magnitude;
1405  result->z = input->z / magnitude;
1406  }
1407  return result;
1408  }
1409 
1413  inline Vector4* Vector4NormalizeMag(Vector4* result, const Vector4* input, float &magnitude)
1414  {
1415  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1416 
1417  magnitude = Vector4Magnitude(input);
1418  if (true == IsZero(magnitude))
1419  {
1420  result->x = 0.0f;
1421  result->y = 0.0f;
1422  result->z = 0.0f;
1423  result->w = 0.0f;
1424  }
1425  else
1426  {
1427  result->x = input->x / magnitude;
1428  result->y = input->y / magnitude;
1429  result->z = input->z / magnitude;
1430  result->w = input->w / magnitude;
1431  }
1432  return result;
1433  }
1434 
1439  inline float Vector3AngleBetween(const Vector3* left, const Vector3* right)
1440  {
1441  const float productOfMagnitudes(Vector3Magnitude(left) * Vector3Magnitude(right));
1442  if (true == IsZero(productOfMagnitudes)) { return 0.0f; }
1443  const float value(Vector3DotProduct(left, right) / productOfMagnitudes);
1444  const float clampedValue((value < -1.0f) ? -1.0f : (value > 1.0f) ? 1.0f : value); //Clamp: -1.0f <= value <= 1.0f
1445  return acos(clampedValue);
1446  }
1447 
1452  static inline Vector3* OrientationToForwardVector3(Vector3 *result, float orientation)
1453  {
1454  result->x = sin(orientation);
1455  result->y = 0.0f;
1456  result->z = -cos(orientation);
1457 
1458  return result;
1459  }
1460 
1465  static inline Vector2& OrientationToForwardVector2(Vector2& result, float orientation)
1466  {
1467  result.x = sin(orientation);
1468  result.y = -cos(orientation);
1469  return result;
1470  }
1471 
1481  static inline float ForwardVector3ToOrientation(const Vector3& forward)
1482  {
1483  Vector3 vZAxis(0.0f, 0.0f, -1.0f);
1484  float orientation = acos((vZAxis.x * forward.x) + (vZAxis.y * forward.y) + (vZAxis.z * forward.z));
1485  if (forward.x < 0.0f)
1486  {
1487  orientation = fabs(orientation - kTwoPi);
1488  }
1489  return orientation;
1490  }
1491 
1501  static inline float ForwardVector2ToOrientation(const Vector2& forward)
1502  {
1503  Vector2 yAxis(0.0f, -1.0f);
1504  float orientation = acos((yAxis.x * forward.x) + (yAxis.y * forward.y));
1505  if (forward.x < 0.0f)
1506  {
1507  orientation = fabs(orientation - kTwoPi);
1508  }
1509  return orientation;
1510  }
1511 
1512  }; /* namespace Math */
1513 }; /* namespace TurtleBrains */
1514 
1515 namespace tbMath = TurtleBrains::Math;
1516 
1517 #endif /* _TurtleBrains_Vector_h_ */
Vector2 * Vector2NormalizeMagnitude(Vector2 *result, const Vector2 *input, float &magnitude)
Definition: tb_vector.h:1369
Definition: tb_vector.h:47
Vector4(const Vector2 &other, const float valueZ, const float valueW)
Definition: tb_vector.h:666
const float & operator[](const size_t index) const
Definition: tb_vector.h:764
Vector3 operator-(void) const
Definition: tb_vector.h:518
Vector4 * Vector4Negate(Vector4 *result, const Vector4 *input)
Definition: tb_vector.h:1133
friend Vector4 operator*(float scalar, const Vector4 &rightSide)
Definition: tb_vector.h:804
Vector4(const float valueX, const float valueY, const float valueZ, const float valueW)
Definition: tb_vector.h:651
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:1452
Vector4 operator/(float scalar) const
Definition: tb_vector.h:815
Vector4(const SkipInitialization &fastAndStupid)
Definition: tb_vector.h:627
Contains objects and functions for dealing with Vector and Matrix math.
float Vector4DotProduct(const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:1173
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:529
static float ForwardVector2ToOrientation(const Vector2 &forward)
Definition: tb_vector.h:1501
float Normalize(void)
Definition: tb_vector.h:268
Vector4(const Vector3 &other, const float valueW)
Definition: tb_vector.h:680
Vector4 & operator/=(float scalar)
Definition: tb_vector.h:821
Vector4(const Vector4 &other)
Definition: tb_vector.h:694
float Vector4MagnitudeSquared(const Vector4 *input)
Definition: tb_vector.h:1283
Vector2(void)
Definition: tb_vector.h:83
Definition: tb_vector.h:39
Definition: tb_vector.h:303
float Normalize(void)
Definition: tb_vector.h:865
Vector4 * Vector4CrossProduct(Vector4 *result, const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:1211
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:937
Vector4 * Vector4Subtract(Vector4 *result, const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:989
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:960
Vector3 GetNormalized(void) const
Definition: tb_vector.h:551
void SetLength(float length)
Definition: tb_vector.h:291
friend Vector3 operator*(float scalar, const Vector3 &rightSide)
Definition: tb_vector.h:495
float Magnitude(void) const
Definition: tb_vector.h:539
void Scale(float scalar)
Definition: tb_vector.h:282
Vector2 operator-(void) const
Definition: tb_vector.h:233
Here is some information about the primary namespace.
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:922
static Vector2 Zero(void)
Definition: tb_vector.h:53
Vector3 * Vector3Scale(Vector3 *result, const Vector3 *input, const float scalar)
Definition: tb_vector.h:1024
#define tb_unused(parameter)
Definition: tb_defines.h:19
float Vector4Magnitude(const Vector4 *input)
Definition: tb_vector.h:1251
Vector3 operator+(const Vector3 &rightSide) const
Definition: tb_vector.h:467
static float ForwardVector3ToOrientation(const Vector3 &forward)
Definition: tb_vector.h:1481
Vector3 * Vector3Normalize(Vector3 *result, const Vector3 *input)
Definition: tb_vector.h:1318
Vector4 & operator*=(float scalar)
Definition: tb_vector.h:810
void Scale(float scalar)
Definition: tb_vector.h:578
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:1390
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:1233
Vector2 * Vector2Negate(Vector2 *result, const Vector2 *input)
Definition: tb_vector.h:1106
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:714
Vector2 operator+(const Vector2 &rightSide) const
Definition: tb_vector.h:184
Vector3 & operator-=(const Vector3 &rightSide)
Definition: tb_vector.h:483
Vector2 & operator=(const Vector2 &other)
Definition: tb_vector.h:125
float operator*(const Vector4 &rightSide) const
Definition: tb_vector.h:832
Vector2 & operator*=(float scalar)
Definition: tb_vector.h:217
float Magnitude(void) const
Definition: tb_vector.h:841
float operator*(const Vector3 &rhs) const
Definition: tb_vector.h:523
static Vector4 Zero(void)
Definition: tb_vector.h:605
Vector4 * Vector4Scale(Vector4 *result, const Vector4 *input, const float scalar)
Definition: tb_vector.h:1038
Vector4 * Vector4Normalize(Vector4 *result, const Vector4 *input)
Definition: tb_vector.h:1339
Vector3 * Vector3Subtract(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:974
Vector2 * Vector2Add(Vector2 *result, const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.h:908
void Scale(float scalar)
Definition: tb_vector.h:881
bool operator!=(const Vector4 &other) const
Definition: tb_vector.h:745
Vector4 * Vector4NormalizeMag(Vector4 *result, const Vector4 *input, float &magnitude)
Definition: tb_vector.h:1413
const float & operator[](const size_t index) const
Definition: tb_vector.h:455
static Vector2 & OrientationToForwardVector2(Vector2 &result, float orientation)
Definition: tb_vector.h:1465
~Vector4(void)
Definition: tb_vector.h:705
Vector2 * Vector2Normalize(Vector2 *result, const Vector2 *input)
Definition: tb_vector.h:1297
~Vector3(void)
Definition: tb_vector.h:389
float MagnitudeSquared(void) const
Definition: tb_vector.h:847
float Vector3AngleBetween(const Vector3 *left, const Vector3 *right)
Definition: tb_vector.h:1439
float Vector2MagnitudeSquared(const Vector2 *input)
Definition: tb_vector.h:1265
Vector2 operator/(float scalar) const
Definition: tb_vector.h:222
void SetLength(float length)
Definition: tb_vector.h:890
float & operator[](const size_t index)
Definition: tb_vector.h:770
float Normalize(void)
Definition: tb_vector.h:563
float MagnitudeSquared(void) const
Definition: tb_vector.h:250
float Vector3DotProduct(const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:1163
Vector2(const SkipInitialization &fastAndStupid)
Definition: tb_vector.h:75
Vector4 GetNormalized(void) const
Definition: tb_vector.h:853
Vector4 operator+(const Vector4 &rightSide) const
Definition: tb_vector.h:776
Vector3 * Vector3ScaleDivide(Vector3 *result, const Vector3 *input, const float scalar)
Definition: tb_vector.h:1072
bool IsZero(const float value, const float tolerance=tbMath::kTolerance)
Definition: tb_math.h:49
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:1059
bool IsEqual(const float leftValue, const float rightValue, const float tolerance=tbMath::kTolerance)
Definition: tb_math.h:30
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:1193
friend Vector2 operator*(float scalar, const Vector2 &rightSide)
Definition: tb_vector.h:211
float MagnitudeSquared(void) const
Definition: tb_vector.h:545
float Vector2DotProduct(const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.h:1153
Vector4 * Vector4ScaleDivide(Vector4 *result, const Vector4 *input, const float scalar)
Definition: tb_vector.h:1086
const float & operator[](const size_t index) const
Definition: tb_vector.h:172
Vector4 operator*(float scalar) const
Definition: tb_vector.h:798
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:735
~Vector2(void)
Definition: tb_vector.h:116
Vector4 & operator+=(const Vector4 &rightSide)
Definition: tb_vector.h:782
void SetLength(float length)
Definition: tb_vector.h:587
Vector4(void)
Definition: tb_vector.h:635
float Vector3MagnitudeSquared(const Vector3 *input)
Definition: tb_vector.h:1274
Vector3 & operator/=(float scalar)
Definition: tb_vector.h:512
Definition: tb_vector.h:37
Vector3 & operator*=(float scalar)
Definition: tb_vector.h:501
Vector3 operator-(const Vector3 &rightSide) const
Definition: tb_vector.h:478
Vector3(const Vector3 &other)
Definition: tb_vector.h:379
Vector4 operator-(const Vector4 &rightSide) const
Definition: tb_vector.h:787
#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:489
float operator*(const Vector2 &rhs) const
Definition: tb_vector.h:238
Vector4 & operator-=(const Vector4 &rightSide)
Definition: tb_vector.h:792
Vector3 * Vector3Negate(Vector3 *result, const Vector3 *input)
Definition: tb_vector.h:1119
Vector2 & operator-=(const Vector2 &rightSide)
Definition: tb_vector.h:200
Vector3 operator/(float scalar) const
Definition: tb_vector.h:506
Vector4 operator-(void) const
Definition: tb_vector.h:827
float Vector3Magnitude(const Vector3 *input)
Definition: tb_vector.h:1242
Definition: tb_vector.h:599
Vector3 & operator+=(const Vector3 &rightSide)
Definition: tb_vector.h:473
Vector2 * Vector2Scale(Vector2 *result, const Vector2 *input, const float scalar)
Definition: tb_vector.h:1011