vector3D.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #ifndef VECTOR3D_H
  2. #define VECTOR3D_H
  3. // ===============================
  4. // AUTHOR : Angel Ortiz (angelo12 AT vt DOT edu)
  5. // CREATE DATE : 2018-07-18
  6. // PURPOSE : Template vector class used for all vector operations, 3d, 2d and 4d
  7. // vectors included. It is capable of performing most normal vector
  8. // operations and allows for access using both x,y,z and array indexing
  9. // ===============================
  10. // SPECIAL NOTES: Homogeneous coordinates are used with 3D vectors by hiding in the
  11. // implementation a 4th variable w taht contains the 4th coordinate.
  12. // In the words of Douglas Adams:
  13. // "This has made a lot of people very angry and been widely regarded as a bad move"
  14. // ===============================
  15. //Headers
  16. #include <string>
  17. #include <type_traits>
  18. #include "math.h"
  19. //Basic 3D vector class for general calculations
  20. template<typename T>
  21. struct Vector3{
  22. //I know this is undefined behaviour and really not recommended but
  23. //Using an operator overload for looping was slowing down my program 20%
  24. union {
  25. //Anonymous struct and array union hack
  26. T data[3];
  27. struct {
  28. T x;
  29. T y;
  30. T z;
  31. };
  32. };
  33. //W component only ever used in perspective projection and clipping,
  34. //Just imagine it isn't here
  35. T w;
  36. //Constructors
  37. Vector3(): x(0), y(0), z(0), w(1) {};
  38. Vector3(T val): x(val), y(val), z(val), w(1) {};
  39. Vector3(T x1, T y1, T z1) : x(x1), y(y1), z(z1), w(1) {};
  40. //Homogenous coordinates to cartesian transformation
  41. Vector3 &perspectiveDivide(){
  42. x /= w;
  43. y /= w;
  44. z /= w;
  45. return *this;
  46. }
  47. //Scalar-vector operations
  48. Vector3 operator-() const
  49. {return Vector3(-x, -y, -z);}
  50. Vector3 operator*(const T &rhs) const //Scalar-vector multiplication
  51. {return Vector3(x*rhs, y*rhs, z*rhs);}
  52. Vector3 operator+(const T &rhs) const //Scalar-vector addition
  53. {return Vector3(x+rhs, y+rhs, z+rhs);}
  54. //Vector-vector operations
  55. Vector3 operator-(const Vector3 &rhs) const
  56. {return Vector3(x - rhs.x, y - rhs.y, z - rhs.z);}
  57. Vector3 operator+(const Vector3 &rhs) const
  58. {return Vector3(x + rhs.x, y + rhs.y, z + rhs.z);}
  59. void operator+=(const Vector3 &rhs) {
  60. x += rhs.x;
  61. y += rhs.y;
  62. z += rhs.z;
  63. }
  64. void operator-=(const Vector3 &rhs)
  65. {(*this) = (*this) - rhs ;}
  66. Vector3 operator*(const Vector3 &rhs) const
  67. {return Vector3(x * rhs.x, y * rhs.y, z * rhs.z);}
  68. Vector3 crossProduct(const Vector3 &r) const
  69. {return Vector3( (y*r.z - z*r.y), (z*r.x - x*r.z), (x*r.y - y*r.x) );}
  70. T dotProduct(const Vector3 &rhs) const
  71. {return x*rhs.x + y*rhs.y + z*rhs.z;}
  72. T dot2D(const Vector3 &rhs) const
  73. {return x*rhs.x + y*rhs.y;}
  74. T length() const
  75. {return std::sqrt(x*x + y*y + z*z);}
  76. //Used to account for edge case of len = 0 but branching impedes SIMD
  77. //auto vectorization
  78. Vector3 &normalized(){
  79. T len = length();
  80. T factor = 1.0f / len;
  81. x *= factor;
  82. y *= factor;
  83. z *= factor;
  84. return *this;
  85. }
  86. //Only used for blinn shading within specular reflection calculations
  87. static Vector3 reflect(const Vector3 &I, const Vector3 &N){
  88. return I - ((N * I.dotProduct(N)) * 2.0f);
  89. }
  90. //Print for debugging purposes
  91. void print() const{
  92. std::string str;
  93. if(std::is_same<T,float>::value){
  94. str = "Vecf:(%f, %f, %f)\n";
  95. }
  96. else if(std::is_same<T,int>::value) {
  97. str = "Veci:(%d, %d, %d)\n";
  98. }
  99. printf(str.c_str(),x,y,z);
  100. }
  101. void zero() {
  102. x = 0;
  103. y = 0;
  104. z = 0;
  105. }
  106. };
  107. //Shorthands for the common vector types
  108. typedef Vector3<float> Vector3f;
  109. typedef Vector3<int> Vector3i;
  110. #endif