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 "../core/tb_configuration.h"
13 #include "../core/tb_error.h"
14 #include "../core/tb_defines.h" //For tb_unsused
15 #include "tb_math.h"
16 
17 namespace TurtleBrains
18 {
19  namespace Math
20  {
21 
30  enum SkipInitialization { kSkipInitialization = 0, };
31 
37  {
42  };
43 
48  class Vector2
49  {
50  public:
54  static const Vector2 kZero;
55 
56  union
57  {
58  float mComponents[2];
59  struct { float x, y; };
60  };
61 
68  inline explicit Vector2(const SkipInitialization& fastAndStupid)
69  {
70  tb_unused(fastAndStupid);
71  }
72 
76  inline Vector2(void) :
77  x(0.0f),
78  y(0.0f)
79  {
80  }
81 
88  inline Vector2(const float valueX, const float valueY) :
89  x(valueX),
90  y(valueY)
91  {
92  }
93 
100  inline Vector2(const Vector2& other) :
101  x(other.x),
102  y(other.y)
103  {
104  }
105 
109  inline ~Vector2(void)
110  {
111  }
112 
118  inline Vector2& operator=(const Vector2& other)
119  {
120  if (&other != this)
121  {
122  x = other.x;
123  y = other.y;
124  }
125  return *this;
126  }
127 
137  inline bool operator==(const Vector2& other) const
138  {
139  return (true == IsEqual(x, other.x) && true == IsEqual(y, other.y)) ? true : false;
140  }
141 
146  inline bool operator!=(const Vector2& other) const
147  {
148  return (true == operator==(other)) ? false : true;
149  }
150 
154  inline operator const float*(void) const { return mComponents; }
155 
160  inline operator float*(void) { return mComponents; }
161 
165  inline const float& operator[](const size_t index) const { return mComponents[index]; }
166 
171  inline float& operator[](const size_t index) { return mComponents[index]; }
172 
173 #ifndef tb_math_less_operators
174  inline Vector2 operator+(const Vector2& rightSide) const { return Vector2(x + rightSide.x, y + rightSide.y); }
178 
183  inline Vector2& operator+=(const Vector2& rightSide) { x += rightSide.x, y += rightSide.y; return *this; }
184 
188  inline Vector2 operator-(const Vector2& rightSide) const { return Vector2(x - rightSide.x, y - rightSide.y); }
189 
193  inline Vector2& operator-=(const Vector2& rightSide) { x -= rightSide.x, y -= rightSide.y; return *this; }
194 
198  inline Vector2 operator*(float scalar) const { return Vector2(x * scalar, y * scalar); }
199 
204  friend Vector2 operator*(float scalar, const Vector2& rightSide) { return Vector2(scalar * rightSide.x, scalar * rightSide.y); }
205 
210  inline Vector2& operator*=(float scalar) { x *= scalar; y *= scalar; return *this; }
211 
215  inline Vector2 operator/(float scalar) const { return Vector2(x / scalar, y / scalar); }
216 
221  inline Vector2& operator/=(float scalar) { x /= scalar; y /= scalar; return *this; }
222 
226  inline Vector2 operator-(void) const { return Vector2(-x, -y); }
227 
231  inline float operator*(const Vector2 &rhs) const { return (x * rhs.x) + (y * rhs.y); }
232 
237  inline float Magnitude(void) const { return sqrt((x * x) + (y * y)); }
238 
243  inline float MagnitudeSquared(void) const { return (x * x) + (y * y); }
244 
249  inline Vector2 GetNormalized(void) const
250  {
251  const float magnitude(Magnitude());
252  if (true == IsZero(magnitude)) { return kZero; }
253  return Vector2(x / magnitude, y / magnitude);
254  }
255 
261  inline float Normalize(void)
262  {
263  const float magnitude(Magnitude());
264  if (false == IsZero(magnitude))
265  {
266  x /= magnitude;
267  y /= magnitude;
268  }
269  return magnitude;
270  }
271 
275  inline void Scale(float scalar) { *this *= scalar; }
276 
284  inline void SetLength(float length) { Normalize(); *this *= length; }
285 #endif
286  };
287 
288 //--------------------------------------------------------------------------------------------------------------------//
289 //--------------------------------------------------------------------------------------------------------------------//
290 //--------------------------------------------------------------------------------------------------------------------//
291 
296  class Vector3
297  {
298  public:
302  static const Vector3 kZero;
303 
304  union
305  {
306  float mComponents[3];
307  struct { float x, y, z; };
308  };
309 
316  inline explicit Vector3(const SkipInitialization& fastAndStupid)
317  {
318  tb_unused(fastAndStupid);
319  }
320 
324  Vector3(void) :
325  x(0.0f),
326  y(0.0f),
327  z(0.0f)
328  {
329  }
330 
338  inline Vector3(const float valueX, const float valueY, const float valueZ) :
339  x(valueX),
340  y(valueY),
341  z(valueZ)
342  {
343  }
344 
351  inline explicit Vector3(const Vector2& other, const float valueZ) :
352  x(other.x),
353  y(other.y),
354  z(valueZ)
355  {
356  }
357 
364  Vector3(const Vector3& other) :
365  x(other.x),
366  y(other.y),
367  z(other.z)
368  {
369  }
370 
374  ~Vector3(void)
375  {
376  }
377 
383  inline Vector3& operator=(const Vector3& other)
384  {
385  if (&other != this)
386  {
387  x = other.x;
388  y = other.y;
389  z = other.z;
390  }
391  return *this;
392  }
393 
394  //
395  // TODO: TIM: Planning: Would this be useful to have, or just dangerous?
396  //
397  //inline Vector3& operator=(const Vector2 &v)
398  //{
399  // x = v.x; y = v.y; /* z = z; */
400  // return (*this);
401  //}
402 
412  inline bool operator==(const Vector3& other) const
413  {
414  return (true == IsEqual(x, other.x) && true == IsEqual(y, other.y) && true == IsEqual(z, other.z)) ? true : false;
415  }
416 
421  inline bool operator!=(const Vector3& other) const
422  {
423  return (true == operator==(other)) ? false : true;
424  }
425 
429  inline operator const float*(void) const { return mComponents; }
430 
435  inline operator float*(void) { return mComponents; }
436 
440  inline const float& operator[](const size_t index) const { return mComponents[index]; }
441 
446  inline float& operator[](const size_t index) { return mComponents[index]; }
447 
448  //TODO: TIM: Reconsider: This could be dangerous, do we want to support it?
449  //inline operator Vector2(void) { return Vector2(x, y); }
450 
451  #ifndef tb_math_less_operators
452  inline Vector3 operator+(const Vector3& rightSide) const { return Vector3(x + rightSide.x, y + rightSide.y, z + rightSide.z); }
456 
461  inline Vector3& operator+=(const Vector3& rightSide) { x += rightSide.x, y += rightSide.y; z += rightSide.z; return *this; }
462 
466  inline Vector3 operator-(const Vector3& rightSide) const { return Vector3(x - rightSide.x, y - rightSide.y, z - rightSide.z); }
467 
471  inline Vector3& operator-=(const Vector3& rightSide) { x -= rightSide.x, y -= rightSide.y; z += rightSide.z; return *this; }
472 
473 
477  inline Vector3 operator*(float scalar) const { return Vector3(x * scalar, y * scalar, z * scalar); }
478 
483  friend Vector3 operator*(float scalar, const Vector3& rightSide) { return Vector3(scalar * rightSide.x, scalar * rightSide.y, scalar * rightSide.z); }
484 
489  inline Vector3& operator*=(float scalar) { x *= scalar; y *= scalar; z *= scalar; return *this; }
490 
494  inline Vector3 operator/(float scalar) const { return Vector3(x / scalar, y / scalar, z / scalar); }
495 
500  inline Vector3& operator/=(float scalar) { x /= scalar; y /= scalar; z /= scalar; return *this; }
501 
502 
506  inline Vector3 operator-(void) const { return Vector3(-x, -y, -z); }
507 
511  inline float operator*(const Vector3 &rhs) const { return (x * rhs.x) + (y * rhs.y) + (z * rhs.z); }
512 
517  inline Vector3 operator^(const Vector3& rightSide) const
518  {
519  return Vector3((y * rightSide.z) - (rightSide.y * z), -((x * rightSide.z) - (rightSide.x * z)), (x * rightSide.y) - (rightSide.x * y));
520  }
521 
522 
527  inline float Magnitude(void) const { return sqrt((x * x) + (y * y) + (z * z)); }
528 
533  inline float MagnitudeSquared(void) const { return (x * x) + (y * y) + (z * z); }
534 
539  inline Vector3 GetNormalized(void) const
540  {
541  const float magnitude(Magnitude());
542  if (true == IsZero(magnitude)) { return kZero; }
543  return Vector3(x / magnitude, y / magnitude, z / magnitude);
544  }
545 
551  inline float Normalize(void)
552  {
553  const float magnitude(Magnitude());
554  if (false == IsZero(magnitude))
555  {
556  x /= magnitude;
557  y /= magnitude;
558  z /= magnitude;
559  }
560  return magnitude;
561  }
562 
566  inline void Scale(float scalar) { *this *= scalar; }
567 
575  inline void SetLength(float length) { Normalize(); *this *= length; }
576  #endif
577  };
578 
579 //--------------------------------------------------------------------------------------------------------------------//
580 //--------------------------------------------------------------------------------------------------------------------//
581 //--------------------------------------------------------------------------------------------------------------------//
582 
587  class Vector4
588  {
589  public:
593  static const Vector4 kZero;
594 
595  union
596  {
597  float mComponents[4];
598  struct { float x, y, z, w; };
599  };
600 
607  inline explicit Vector4(const SkipInitialization& fastAndStupid)
608  {
609  tb_unused(fastAndStupid);
610  }
611 
615  inline Vector4(void) :
616  x(0.0f),
617  y(0.0f),
618  z(0.0f),
619  w(0.0f)
620  {
621  }
622 
631  inline Vector4(const float valueX, const float valueY, const float valueZ, const float valueW) :
632  x(valueX),
633  y(valueY),
634  z(valueZ),
635  w(valueW)
636  {
637  }
638 
646  inline explicit Vector4(const Vector2& other, const float valueZ, const float valueW) :
647  x(other.x),
648  y(other.y),
649  z(valueZ),
650  w(valueW)
651  {
652  }
653 
660  inline explicit Vector4(const Vector3& other, const float valueW) :
661  x(other.x),
662  y(other.y),
663  z(other.z),
664  w(valueW)
665  {
666  }
667 
674  inline Vector4(const Vector4& other) :
675  x(other.x),
676  y(other.y),
677  z(other.z),
678  w(other.w)
679  {
680  }
681 
685  ~Vector4(void)
686  {
687  }
688 
694  inline Vector4& operator=(const Vector4& other)
695  {
696  if (&other != this)
697  {
698  x = other.x;
699  y = other.y;
700  z = other.z;
701  w = other.w;
702  }
703  return *this;
704  }
705 
715  inline bool operator==(const Vector4& other) const
716  {
717  return (true == IsEqual(x, other.x) && true == IsEqual(y, other.y) &&
718  true == IsEqual(z, other.z) && true == IsEqual(w, other.w)) ? true : false;
719  }
720 
725  inline bool operator!=(const Vector4& other) const
726  {
727  return (true == operator==(other)) ? false : true;
728  }
729 
733  inline operator const float*(void) const { return mComponents; }
734 
739  inline operator float*(void) { return mComponents; }
740 
744  inline const float& operator[](const size_t index) const { return mComponents[index]; }
745 
750  inline float& operator[](const size_t index) { return mComponents[index]; }
751 
752  //TODO: TIM: Reconsider: This could be dangerous, do we want to support it?
753  //inline operator Vector2(void) { return Vector2(x, y); }
754  //inline operator Vector3(void) { return Vector3(x, y, z); }
755 
756 #ifndef tb_math_less_operators
757  inline Vector4 operator+(const Vector4& rightSide) const { return Vector4(x + rightSide.x, y + rightSide.y, z + rightSide.z, w + rightSide.w); }
761 
766  inline Vector4& operator+=(const Vector4& rightSide) { x += rightSide.x, y += rightSide.y; z += rightSide.z; w += rightSide.w; return *this; }
767 
771  inline Vector4 operator-(const Vector4& rightSide) const { return Vector4(x - rightSide.x, y - rightSide.y, z - rightSide.z, w - rightSide.w); }
772 
776  inline Vector4& operator-=(const Vector4& rightSide) { x -= rightSide.x, y -= rightSide.y; z -= rightSide.z; w -= rightSide.w; return *this; }
777 
778 
782  inline Vector4 operator*(float scalar) const { return Vector4(x * scalar, y * scalar, z * scalar, w * scalar); }
783 
788  friend Vector4 operator*(float scalar, const Vector4& rightSide) { return Vector4(scalar * rightSide.x, scalar * rightSide.y, scalar * rightSide.z, scalar * rightSide.w); }
789 
794  inline Vector4& operator*=(float scalar) { x *= scalar; y *= scalar; z *= scalar; w *= scalar; return *this; }
795 
799  inline Vector4 operator/(float scalar) const { return Vector4(x / scalar, y / scalar, z / scalar, w / scalar); }
800 
805  inline Vector4& operator/=(float scalar) { x /= scalar; y /= scalar; z /= scalar; w /= scalar; return *this; }
806 
807 
811  inline Vector4 operator-(void) const { return Vector4(-x, -y, -z, -w); }
812 
816  inline float operator*(const Vector4& rightSide) const { return (x * rightSide.x) + (y * rightSide.y) + (z * rightSide.z) + (w * rightSide.w); }
817 
818  //TODO: TIM: Reconsider: Does this work, and if it does, how do we want to support it? Document if needed.
819  //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)); }
820 
825  inline float Magnitude(void) const { return sqrt((x * x) + (y * y) + (z * z) + (w * w)); }
826 
831  inline float MagnitudeSquared(void) const { return (x * x) + (y * y) + (z * z) + (w * w); }
832 
837  inline Vector4 GetNormalized(void) const
838  {
839  const float magnitude(Magnitude());
840  if (true == IsZero(magnitude)) { return kZero; }
841  return Vector4(x / magnitude, y / magnitude, z / magnitude, w / magnitude);
842  }
843 
849  inline float Normalize(void)
850  {
851  const float magnitude(Magnitude());
852  if (false == IsZero(magnitude))
853  {
854  x /= magnitude;
855  y /= magnitude;
856  z /= magnitude;
857  w /= magnitude;
858  }
859  return magnitude;
860  }
861 
865  inline void Scale(float scalar) { *this *= scalar; }
866 
874  inline void SetLength(float length) { Normalize(); *this *= length; }
875 #endif
876  };
877 
878 //--------------------------------------------------------------------------------------------------------------------//
879 //--------------------------------------------------------------------------------------------------------------------//
880 //--------------------------------------------------------------------------------------------------------------------//
881 
892  inline Vector2* Vector2Add(Vector2* result, const Vector2* leftSide, const Vector2* rightSide)
893  {
894  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
895  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
896  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
897 
898  result->x = leftSide->x + rightSide->x;
899  result->y = leftSide->y + rightSide->y;
900  return result;
901  }
902 
906  inline Vector3* Vector3Add(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
907  {
908  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
909  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
910  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
911 
912  result->x = leftSide->x + rightSide->x;
913  result->y = leftSide->y + rightSide->y;
914  result->z = leftSide->z + rightSide->z;
915  return result;
916  }
917 
921  inline Vector4* Vector4Add(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
922  {
923  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
924  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
925  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
926 
927  result->x = leftSide->x + rightSide->x;
928  result->y = leftSide->y + rightSide->y;
929  result->z = leftSide->z + rightSide->z;
930  result->w = leftSide->w + rightSide->w;
931  return result;
932  }
933 
944  inline Vector2* Vector2Subtract(Vector2* result, const Vector2* leftSide, const Vector2* 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  return result;
953  }
954 
958  inline Vector3* Vector3Subtract(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
959  {
960  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
961  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
962  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
963 
964  result->x = leftSide->x - rightSide->x;
965  result->y = leftSide->y - rightSide->y;
966  result->z = leftSide->z - rightSide->z;
967  return result;
968  }
969 
973  inline Vector4* Vector4Subtract(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
974  {
975  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
976  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
977  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
978 
979  result->x = leftSide->x - rightSide->x;
980  result->y = leftSide->y - rightSide->y;
981  result->z = leftSide->z - rightSide->z;
982  result->w = leftSide->w - rightSide->w;
983  return result;
984  }
985 
995  inline Vector2* Vector2Scale(Vector2* result, const Vector2* input, const float scalar)
996  {
997  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
998  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
999 
1000  result->x = input->x * scalar;
1001  result->y = input->y * scalar;
1002  return result;
1003  }
1004 
1008  inline Vector3* Vector3Scale(Vector3* result, const Vector3* input, const float scalar)
1009  {
1010  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1011  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1012 
1013  result->x = input->x * scalar;
1014  result->y = input->y * scalar;
1015  result->z = input->z * scalar;
1016  return result;
1017  }
1018 
1022  inline Vector4* Vector4Scale(Vector4* result, const Vector4* input, const float scalar)
1023  {
1024  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1025  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1026 
1027  result->x = input->x * scalar;
1028  result->y = input->y * scalar;
1029  result->z = input->z * scalar;
1030  result->w = input->w * scalar;
1031  return result;
1032  }
1033 
1043  inline Vector2* Vector2ScaleDivide(Vector2* result, const Vector2* input, const float scalar)
1044  {
1045  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1046  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1047 
1048  result->x = input->x / scalar;
1049  result->y = input->y / scalar;
1050  return result;
1051  }
1052 
1056  inline Vector3* Vector3ScaleDivide(Vector3* result, const Vector3* input, const float scalar)
1057  {
1058  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1059  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1060 
1061  result->x = input->x / scalar;
1062  result->y = input->y / scalar;
1063  result->z = input->z / scalar;
1064  return result;
1065  }
1066 
1070  inline Vector4* Vector4ScaleDivide(Vector4* result, const Vector4* input, const float scalar)
1071  {
1072  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1073  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1074 
1075  result->x = input->x / scalar;
1076  result->y = input->y / scalar;
1077  result->z = input->z / scalar;
1078  result->w = input->w / scalar;
1079  return result;
1080  }
1081 
1090  inline Vector2* Vector2Negate(Vector2* result, const Vector2* input)
1091  {
1092  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1093  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1094 
1095  result->x = -input->x;
1096  result->y = -input->y;
1097  return result;
1098  }
1099 
1103  inline Vector3* Vector3Negate(Vector3* result, const Vector3* input)
1104  {
1105  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1106  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1107 
1108  result->x = -input->x;
1109  result->y = -input->y;
1110  result->z = -input->z;
1111  return result;
1112  }
1113 
1117  inline Vector4* Vector4Negate(Vector4* result, const Vector4* input)
1118  {
1119  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1120  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1121 
1122  result->x = -input->x;
1123  result->y = -input->y;
1124  result->z = -input->z;
1125  result->w = -input->w;
1126  return result;
1127  }
1128 
1137  inline float Vector2DotProduct(const Vector2* leftSide, const Vector2* rightSide)
1138  {
1139  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1140  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1141  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y);
1142  }
1143 
1147  inline float Vector3DotProduct(const Vector3* leftSide, const Vector3* rightSide)
1148  {
1149  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1150  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1151  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y) + (leftSide->z * rightSide->z);
1152  }
1153 
1157  inline float Vector4DotProduct(const Vector4* leftSide, const Vector4* rightSide)
1158  {
1159  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1160  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1161  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y) + (leftSide->z * rightSide->z) + (leftSide->w * rightSide->w);
1162  }
1163 
1174  inline Vector3* Vector3CrossProduct(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
1175  {
1176  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1177  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1178  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1179  tb_error_if(leftSide == rightSide, "tbExternalError: Invalid parameter; expected leftSide to be different from rightSide.");
1180  tb_error_if(result == leftSide || result == rightSide, "Invalid parameter; expected result to be different than leftSide and rightSide");
1181 
1182  result->x = ((leftSide->y * rightSide->z) - (rightSide->y * leftSide->z));
1183  result->y = -(((leftSide->x * rightSide->z) - (rightSide->x * leftSide->z)));
1184  result->z = ((leftSide->x * rightSide->y) - (rightSide->x * leftSide->y));
1185  return result;
1186  }
1187 
1192  inline Vector4* Vector4CrossProduct(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
1193  {
1194  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1195  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1196  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1197  tb_error_if(result == leftSide || result == rightSide, "Invalid parameter; expected result to be different than leftSide and rightSide");
1198 
1199  tb_error_if(true, "Not sure if this is an accurate Vector4 CrossProduct");
1200  result->x = ((leftSide->y * rightSide->z) - (rightSide->y * leftSide->z));
1201  result->y = -(((leftSide->x * rightSide->z) - (rightSide->x * leftSide->z)));
1202  result->z = ((leftSide->x * rightSide->y) - (rightSide->x * leftSide->y));
1203  result->w = 0.0f;
1204  return result;
1205  }
1206 
1214  inline float Vector2Magnitude(const Vector2* input)
1215  {
1216  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1217  return sqrt((input->x * input->x) + (input->y * input->y));
1218  }
1219 
1223  inline float Vector3Magnitude(const Vector3* input)
1224  {
1225  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1226  return sqrt((input->x * input->x) + (input->y * input->y) + (input->z * input->z));
1227  }
1228 
1232  inline float Vector4Magnitude(const Vector4* input)
1233  {
1234  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1235  return sqrt((input->x * input->x) + (input->y * input->y) + (input->z * input->z) + (input->w * input->w));
1236  }
1237 
1246  inline float Vector2MagnitudeSquared(const Vector2* input)
1247  {
1248  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1249  return (input->x * input->x) + (input->y * input->y);
1250  }
1251 
1255  inline float Vector3MagnitudeSquared(const Vector3* input)
1256  {
1257  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1258  return (input->x * input->x) + (input->y * input->y) + (input->z * input->z);
1259  }
1260 
1264  inline float Vector4MagnitudeSquared(const Vector4* input)
1265  {
1266  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1267  return (input->x * input->x) + (input->y * input->y) + (input->z * input->z) + (input->w * input->w);
1268  }
1269 
1278  inline Vector2* Vector2Normalize(Vector2* result, const Vector2* input)
1279  {
1280  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1281 
1282  const float magnitude = Vector2Magnitude(input);
1283  if (true == IsZero(magnitude))
1284  {
1285  result->x = 0.0f;
1286  result->y = 0.0f;
1287  }
1288  else
1289  {
1290  result->x = input->x / magnitude;
1291  result->y = input->y / magnitude;
1292  }
1293  return result;
1294  }
1295 
1299  inline Vector3* Vector3Normalize(Vector3* result, const Vector3* input)
1300  {
1301  const float magnitude = Vector3Magnitude(input);
1302  if (true == IsZero(magnitude))
1303  {
1304  result->x = 0.0f;
1305  result->y = 0.0f;
1306  result->z = 0.0f;
1307  }
1308  else
1309  {
1310  result->x = input->x / magnitude;
1311  result->y = input->y / magnitude;
1312  result->z = input->z / magnitude;
1313  }
1314  return result;
1315  }
1316 
1320  inline Vector4* Vector4Normalize(Vector4* result, const Vector4* input)
1321  {
1322  const float magnitude = Vector4Magnitude(input);
1323  if (true == IsZero(magnitude))
1324  {
1325  result->x = 0.0f;
1326  result->y = 0.0f;
1327  result->z = 0.0f;
1328  result->w = 0.0f;
1329  }
1330  else
1331  {
1332  result->x = input->x / magnitude;
1333  result->y = input->y / magnitude;
1334  result->z = input->z / magnitude;
1335  result->w = input->w / magnitude;
1336  }
1337  return result;
1338  }
1339 
1350  inline Vector2* Vector2NormalizeMagnitude(Vector2* result, const Vector2* input, float& magnitude)
1351  {
1352  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1353 
1354  magnitude = Vector2Magnitude(input);
1355  if (true == IsZero(magnitude))
1356  {
1357  result->x = 0.0f;
1358  result->y = 0.0f;
1359  }
1360  else
1361  {
1362  result->x = input->x / magnitude;
1363  result->y = input->y / magnitude;
1364  }
1365  return result;
1366  }
1367 
1371  inline Vector3* Vector3NormalizeMagnitude(Vector3* result, const Vector3* input, float &magnitude)
1372  {
1373  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1374 
1375  magnitude = Vector3Magnitude(input);
1376  if (true == IsZero(magnitude))
1377  {
1378  result->x = 0.0f;
1379  result->y = 0.0f;
1380  result->z = 0.0f;
1381  }
1382  else
1383  {
1384  result->x = input->x / magnitude;
1385  result->y = input->y / magnitude;
1386  result->z = input->z / magnitude;
1387  }
1388  return result;
1389  }
1390 
1394  inline Vector4* Vector4NormalizeMag(Vector4* result, const Vector4* input, float &magnitude)
1395  {
1396  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1397 
1398  magnitude = Vector4Magnitude(input);
1399  if (true == IsZero(magnitude))
1400  {
1401  result->x = 0.0f;
1402  result->y = 0.0f;
1403  result->z = 0.0f;
1404  result->w = 0.0f;
1405  }
1406  else
1407  {
1408  result->x = input->x / magnitude;
1409  result->y = input->y / magnitude;
1410  result->z = input->z / magnitude;
1411  result->w = input->w / magnitude;
1412  }
1413  return result;
1414  }
1415 
1420  inline float Vector3AngleBetween(const Vector3* left, const Vector3* right)
1421  {
1422  const float productOfMagnitudes(Vector3Magnitude(left) * Vector3Magnitude(right));
1423  if (true == IsZero(productOfMagnitudes)) { return 0.0f; }
1424  const float value(Vector3DotProduct(left, right) / productOfMagnitudes);
1425  const float clampedValue((value < -1.0f) ? -1.0f : (value > 1.0f) ? 1.0f : value); //Clamp: -1.0f <= value <= 1.0f
1426  return acos(clampedValue);
1427  }
1428 
1433  static inline Vector3* OrientationToForwardVector3(Vector3 *result, float orientation)
1434  {
1435  result->x = sin(orientation);
1436  result->y = 0.0f;
1437  result->z = -cos(orientation);
1438 
1439  return result;
1440  }
1441 
1446  static inline Vector2& OrientationToForwardVector2(Vector2& result, float orientation)
1447  {
1448  result.x = sin(orientation);
1449  result.y = -cos(orientation);
1450  return result;
1451  }
1452 
1462  static inline float ForwardVector3ToOrientation(const Vector3& forward)
1463  {
1464  Vector3 vZAxis(0.0f, 0.0f, -1.0f);
1465  float orientation = acos((vZAxis.x * forward.x) + (vZAxis.y * forward.y) + (vZAxis.z * forward.z));
1466  if (forward.x < 0.0f)
1467  {
1468  orientation = fabs(orientation - kTwoPi);
1469  }
1470  return orientation;
1471  }
1472 
1482  static inline float ForwardVector2ToOrientation(const Vector2& forward)
1483  {
1484  Vector2 yAxis(0.0f, -1.0f);
1485  float orientation = acos((yAxis.x * forward.x) + (yAxis.y * forward.y));
1486  if (forward.x < 0.0f)
1487  {
1488  orientation = fabs(orientation - kTwoPi);
1489  }
1490  return orientation;
1491  }
1492 
1493  }; /* namespace Math */
1494 }; /* namespace TurtleBrains */
1495 
1496 namespace tbMath = TurtleBrains::Math;
1497 
1498 #endif /* _TurtleBrains_Vector_h_ */
Vector2 * Vector2NormalizeMagnitude(Vector2 *result, const Vector2 *input, float &magnitude)
Definition: tb_vector.h:1350
Definition: tb_vector.h:48
Vector4(const Vector2 &other, const float valueZ, const float valueW)
Definition: tb_vector.h:646
const float & operator[](const size_t index) const
Definition: tb_vector.h:744
Vector3 operator-(void) const
Definition: tb_vector.h:506
Vector4 * Vector4Negate(Vector4 *result, const Vector4 *input)
Definition: tb_vector.h:1117
friend Vector4 operator*(float scalar, const Vector4 &rightSide)
Definition: tb_vector.h:788
Vector4(const float valueX, const float valueY, const float valueZ, const float valueW)
Definition: tb_vector.h:631
float & operator[](const size_t index)
Definition: tb_vector.h:446
Vector2 GetNormalized(void) const
Definition: tb_vector.h:249
Vector3(const SkipInitialization &fastAndStupid)
Definition: tb_vector.h:316
bool operator!=(const Vector2 &other) const
Definition: tb_vector.h:146
Vector2 operator*(float scalar) const
Definition: tb_vector.h:198
static Vector3 * OrientationToForwardVector3(Vector3 *result, float orientation)
Definition: tb_vector.h:1433
Vector4 operator/(float scalar) const
Definition: tb_vector.h:799
Vector4(const SkipInitialization &fastAndStupid)
Definition: tb_vector.h:607
Contains objects and functions for dealing with Vector and Matrix math.
float Vector4DotProduct(const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:1157
Vector3 & operator=(const Vector3 &other)
Definition: tb_vector.h:383
float & operator[](const size_t index)
Definition: tb_vector.h:171
Vector2 & operator/=(float scalar)
Definition: tb_vector.h:221
bool operator==(const Vector3 &other) const
Definition: tb_vector.h:412
Vector3 operator^(const Vector3 &rightSide) const
Definition: tb_vector.h:517
static float ForwardVector2ToOrientation(const Vector2 &forward)
Definition: tb_vector.h:1482
float Normalize(void)
Definition: tb_vector.h:261
Vector4(const Vector3 &other, const float valueW)
Definition: tb_vector.h:660
Vector4 & operator/=(float scalar)
Definition: tb_vector.h:805
Vector4(const Vector4 &other)
Definition: tb_vector.h:674
float Vector4MagnitudeSquared(const Vector4 *input)
Definition: tb_vector.h:1264
Vector2(void)
Definition: tb_vector.h:76
Definition: tb_vector.h:40
Definition: tb_vector.h:296
float Normalize(void)
Definition: tb_vector.h:849
static const Vector2 kZero
Definition: tb_vector.h:54
Vector4 * Vector4CrossProduct(Vector4 *result, const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:1192
Vector3(const Vector2 &other, const float valueZ)
Definition: tb_vector.h:351
Vector4 * Vector4Add(Vector4 *result, const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:921
Vector4 * Vector4Subtract(Vector4 *result, const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.h:973
bool operator==(const Vector2 &other) const
Definition: tb_vector.h:137
Vector2 * Vector2Subtract(Vector2 *result, const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.h:944
Vector3 GetNormalized(void) const
Definition: tb_vector.h:539
void SetLength(float length)
Definition: tb_vector.h:284
friend Vector3 operator*(float scalar, const Vector3 &rightSide)
Definition: tb_vector.h:483
float Magnitude(void) const
Definition: tb_vector.h:527
void Scale(float scalar)
Definition: tb_vector.h:275
Vector2 operator-(void) const
Definition: tb_vector.h:226
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:324
Vector3 * Vector3Add(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:906
Vector3 * Vector3Scale(Vector3 *result, const Vector3 *input, const float scalar)
Definition: tb_vector.h:1008
#define tb_unused(parameter)
Definition: tb_defines.h:19
float Vector4Magnitude(const Vector4 *input)
Definition: tb_vector.h:1232
Vector3 operator+(const Vector3 &rightSide) const
Definition: tb_vector.h:455
static float ForwardVector3ToOrientation(const Vector3 &forward)
Definition: tb_vector.h:1462
Vector3 * Vector3Normalize(Vector3 *result, const Vector3 *input)
Definition: tb_vector.h:1299
Vector4 & operator*=(float scalar)
Definition: tb_vector.h:794
void Scale(float scalar)
Definition: tb_vector.h:566
Definition: tb_vector.h:41
VectorComponent
Definition: tb_vector.h:36
SkipInitialization
Definition: tb_vector.h:30
Vector3 * Vector3NormalizeMagnitude(Vector3 *result, const Vector3 *input, float &magnitude)
Definition: tb_vector.h:1371
bool operator!=(const Vector3 &other) const
Definition: tb_vector.h:421
float Magnitude(void) const
Definition: tb_vector.h:237
float Vector2Magnitude(const Vector2 *input)
Definition: tb_vector.h:1214
Vector2 * Vector2Negate(Vector2 *result, const Vector2 *input)
Definition: tb_vector.h:1090
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:188
Vector4 & operator=(const Vector4 &other)
Definition: tb_vector.h:694
Vector2 operator+(const Vector2 &rightSide) const
Definition: tb_vector.h:177
Vector3 & operator-=(const Vector3 &rightSide)
Definition: tb_vector.h:471
Vector2 & operator=(const Vector2 &other)
Definition: tb_vector.h:118
float operator*(const Vector4 &rightSide) const
Definition: tb_vector.h:816
Vector2 & operator*=(float scalar)
Definition: tb_vector.h:210
float Magnitude(void) const
Definition: tb_vector.h:825
float operator*(const Vector3 &rhs) const
Definition: tb_vector.h:511
Vector4 * Vector4Scale(Vector4 *result, const Vector4 *input, const float scalar)
Definition: tb_vector.h:1022
Vector4 * Vector4Normalize(Vector4 *result, const Vector4 *input)
Definition: tb_vector.h:1320
Vector3 * Vector3Subtract(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:958
Vector2 * Vector2Add(Vector2 *result, const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.h:892
void Scale(float scalar)
Definition: tb_vector.h:865
bool operator!=(const Vector4 &other) const
Definition: tb_vector.h:725
Vector4 * Vector4NormalizeMag(Vector4 *result, const Vector4 *input, float &magnitude)
Definition: tb_vector.h:1394
const float & operator[](const size_t index) const
Definition: tb_vector.h:440
static Vector2 & OrientationToForwardVector2(Vector2 &result, float orientation)
Definition: tb_vector.h:1446
~Vector4(void)
Definition: tb_vector.h:685
Vector2 * Vector2Normalize(Vector2 *result, const Vector2 *input)
Definition: tb_vector.h:1278
~Vector3(void)
Definition: tb_vector.h:374
float MagnitudeSquared(void) const
Definition: tb_vector.h:831
float Vector3AngleBetween(const Vector3 *left, const Vector3 *right)
Definition: tb_vector.h:1420
float Vector2MagnitudeSquared(const Vector2 *input)
Definition: tb_vector.h:1246
Vector2 operator/(float scalar) const
Definition: tb_vector.h:215
void SetLength(float length)
Definition: tb_vector.h:874
float & operator[](const size_t index)
Definition: tb_vector.h:750
float Normalize(void)
Definition: tb_vector.h:551
float MagnitudeSquared(void) const
Definition: tb_vector.h:243
float Vector3DotProduct(const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:1147
static const Vector4 kZero
Definition: tb_vector.h:593
Vector2(const SkipInitialization &fastAndStupid)
Definition: tb_vector.h:68
Vector4 GetNormalized(void) const
Definition: tb_vector.h:837
Vector4 operator+(const Vector4 &rightSide) const
Definition: tb_vector.h:760
Vector3 * Vector3ScaleDivide(Vector3 *result, const Vector3 *input, const float scalar)
Definition: tb_vector.h:1056
bool IsZero(const float value, const float tolerance=tbMath::kTolerance)
Definition: tb_math.h:41
Vector2(const Vector2 &other)
Definition: tb_vector.h:100
Vector2(const float valueX, const float valueY)
Definition: tb_vector.h:88
Vector2 * Vector2ScaleDivide(Vector2 *result, const Vector2 *input, const float scalar)
Definition: tb_vector.h:1043
bool IsEqual(const float leftValue, const float rightValue, const float tolerance=tbMath::kTolerance)
Definition: tb_math.h:28
Vector3(const float valueX, const float valueY, const float valueZ)
Definition: tb_vector.h:338
Vector3 * Vector3CrossProduct(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:1174
friend Vector2 operator*(float scalar, const Vector2 &rightSide)
Definition: tb_vector.h:204
static const Vector3 kZero
Definition: tb_vector.h:302
float MagnitudeSquared(void) const
Definition: tb_vector.h:533
float Vector2DotProduct(const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.h:1137
Vector4 * Vector4ScaleDivide(Vector4 *result, const Vector4 *input, const float scalar)
Definition: tb_vector.h:1070
const float & operator[](const size_t index) const
Definition: tb_vector.h:165
Vector4 operator*(float scalar) const
Definition: tb_vector.h:782
Vector2 & operator+=(const Vector2 &rightSide)
Definition: tb_vector.h:183
Definition: tb_vector.h:39
bool operator==(const Vector4 &other) const
Definition: tb_vector.h:715
~Vector2(void)
Definition: tb_vector.h:109
Vector4 & operator+=(const Vector4 &rightSide)
Definition: tb_vector.h:766
void SetLength(float length)
Definition: tb_vector.h:575
Vector4(void)
Definition: tb_vector.h:615
float Vector3MagnitudeSquared(const Vector3 *input)
Definition: tb_vector.h:1255
Vector3 & operator/=(float scalar)
Definition: tb_vector.h:500
Definition: tb_vector.h:38
Vector3 & operator*=(float scalar)
Definition: tb_vector.h:489
Vector3 operator-(const Vector3 &rightSide) const
Definition: tb_vector.h:466
Vector3(const Vector3 &other)
Definition: tb_vector.h:364
Vector4 operator-(const Vector4 &rightSide) const
Definition: tb_vector.h:771
#define tb_error_if(errorTest, message,...)
Definition: tb_error.h:37
Vector3 operator*(float scalar) const
Definition: tb_vector.h:477
float operator*(const Vector2 &rhs) const
Definition: tb_vector.h:231
Vector4 & operator-=(const Vector4 &rightSide)
Definition: tb_vector.h:776
Vector3 * Vector3Negate(Vector3 *result, const Vector3 *input)
Definition: tb_vector.h:1103
Vector2 & operator-=(const Vector2 &rightSide)
Definition: tb_vector.h:193
Vector3 operator/(float scalar) const
Definition: tb_vector.h:494
Vector4 operator-(void) const
Definition: tb_vector.h:811
float Vector3Magnitude(const Vector3 *input)
Definition: tb_vector.h:1223
Definition: tb_vector.h:587
Vector3 & operator+=(const Vector3 &rightSide)
Definition: tb_vector.h:461
Vector2 * Vector2Scale(Vector2 *result, const Vector2 *input, const float scalar)
Definition: tb_vector.h:995