Advertisement
candlemaster1

vmath/vec2.h

Mar 26th, 2017
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.98 KB | None | 0 0
  1. #ifndef HVH_VMATH_VEC2_H
  2. #define HVH_VMATH_VEC2_H
  3.  
  4. #include "vmath_includes.h"
  5.  
  6. namespace vmath
  7. {
  8.  
  9. class vec2
  10. {
  11. public:
  12.     //// Constructors
  13.     vec2() = default;
  14.     vec2(const vec2&) = default;
  15.     constexpr vec2(float x, float y) : x(x), y(y) {}
  16.  
  17. private:
  18.     friend class vec3;
  19.     friend class vec4;
  20.  
  21.     // Here we define swizzle proxies.
  22.     template <typename T, int X, int Y>
  23.     struct SWIZZLE_READ_ONLY
  24.     {
  25.         inline operator vec2() const
  26.         {
  27.             T* self = (T*)this;
  28.             return{ self->data[X], self->data[Y] };
  29.         }
  30.  
  31.         inline vec2 operator + (vec2 rhs)
  32.             { T* self = (T*)this; return{ self->data[X] + rhs.data[0], self->data[Y] + rhs.data[1] }; }
  33.         inline vec2 operator - (vec2 rhs)
  34.             { T* self = (T*)this; return{ self->data[X] - rhs.data[0], self->data[Y] - rhs.data[1] }; }
  35.         inline vec2 operator * (vec2 rhs)
  36.             { T* self = (T*)this; return{ self->data[X] * rhs.data[0], self->data[Y] * rhs.data[1] }; }
  37.         inline vec2 operator / (vec2 rhs)
  38.             { T* self = (T*)this; return{ self->data[X] / rhs.data[0], self->data[Y] / rhs.data[1] }; }
  39.  
  40.         inline vec2 operator + (float rhs)
  41.             { T* self = (T*)this; return{ self->data[X] + rhs, self->data[Y] + rhs }; }
  42.         inline vec2 operator - (float rhs)
  43.             { T* self = (T*)this; return{ self->data[X] - rhs, self->data[Y] - rhs }; }
  44.         inline vec2 operator * (float rhs)
  45.             { T* self = (T*)this; return{ self->data[X] * rhs, self->data[Y] * rhs }; }
  46.         inline vec2 operator / (float rhs)
  47.             { T* self = (T*)this; return{ self->data[X] / rhs, self->data[Y] / rhs }; }
  48.     };
  49.  
  50.     template <typename T, int X, int Y>
  51.     struct SWIZZLE_READWRITE : public SWIZZLE_READ_ONLY<T, X, Y>
  52.     {
  53.         static_assert(X != Y, "Read+Write swizzling cannot be defined for multiple identical elements.");
  54.  
  55.         inline T& operator = (vec2 rhs)
  56.         {
  57.             T* self = (T*)this;
  58.             self->data[X] = rhs.data[0];
  59.             self->data[Y] = rhs.data[1];
  60.             return *self;
  61.         }
  62.        
  63.         // Any non-const, non-static member functions need to be defined here.
  64.  
  65.         inline vec2& operator += (vec2 rhs)
  66.             { T* self = (T*)this; self->data[X] += rhs.data[0]; self->data[Y] += rhs.data[1]; return (vec2&)*self; }
  67.         inline vec2& operator -= (vec2 rhs)
  68.             { T* self = (T*)this; self->data[X] -= rhs.data[0]; self->data[Y] -= rhs.data[1]; return (vec2&)*self; }
  69.         inline vec2& operator *= (vec2 rhs)
  70.             { T* self = (T*)this; self->data[X] *= rhs.data[0]; self->data[Y] *= rhs.data[1]; return (vec2&)*self; }
  71.         inline vec2& operator /= (vec2 rhs)
  72.             { T* self = (T*)this; self->data[X] /= rhs.data[0]; self->data[Y] /= rhs.data[1]; return (vec2&)*self; }
  73.  
  74.         inline vec2& operator += (float rhs)
  75.             { T* self = (T*)this; self->data[X] += rhs; self->data[Y] += rhs; return (vec2&)*self; }
  76.         inline vec2& operator -= (float rhs)
  77.             { T* self = (T*)this; self->data[X] -= rhs; self->data[Y] -= rhs; return (vec2&)*self; }
  78.         inline vec2& operator *= (float rhs)
  79.             { T* self = (T*)this; self->data[X] *= rhs; self->data[Y] *= rhs; return (vec2&)*self; }
  80.         inline vec2& operator /= (float rhs)
  81.             { T* self = (T*)this; self->data[X] /= rhs; self->data[Y] /= rhs; return (vec2&)*self; }
  82.  
  83.         inline void normalize()
  84.         {
  85.             T* self = (T*)this;
  86.             vec2 temp = { self->data[X], self->data[Y] };
  87.             temp.normalize();
  88.             self->data[X] = temp.data[0]; self->data[Y] = temp.data[1];
  89.         }
  90.  
  91.         inline void clamp(vec2 minimum, vec2 maximum)
  92.         {
  93.             T* self = (T*)this;
  94.             vec2 temp = { self->data[X], self->data[Y] };
  95.             temp.clamp(minimum, maximum);
  96.             self->data[X] = temp.data[0]; self->data[Y] = temp.data[1];
  97.         }
  98.  
  99.         inline void clamp_magnitude(float max_magnitude)
  100.         {
  101.             T* self = (T*)this;
  102.             vec2 temp = { self->data[X], self->data[Y] };
  103.             temp.clamp_magnitude(max_magnitude);
  104.             self->data[X] = temp.data[0]; self->data[Y] = temp.data[1];
  105.         }
  106.  
  107.         inline void move_towards(vec2 target, float max_dist)
  108.         {
  109.             T* self = (T*)this;
  110.             vec2 temp = { self->data[X], self->data[Y] };
  111.             temp.move_towards(target, max_dist);
  112.             self->data[X] = temp.data[0]; self->data[Y] = temp.data[1];
  113.         }
  114.     };
  115.  
  116. public:
  117.  
  118.     //// Data storage
  119.     union
  120.     {
  121.         struct { float x, y; };
  122.         struct { float r, g; };
  123.         struct { float s, t; };
  124.         float data[2];
  125.  
  126.         //// Swizzles
  127.         // xy
  128.         SWIZZLE_READ_ONLY<vec2, 0, 0> xx;
  129.         SWIZZLE_READWRITE<vec2, 0, 1> xy;
  130.         SWIZZLE_READ_ONLY<vec2, 1, 1> yy;
  131.         SWIZZLE_READWRITE<vec2, 1, 0> yx;
  132.         // rg
  133.         SWIZZLE_READ_ONLY<vec2, 0, 0> rr;
  134.         SWIZZLE_READWRITE<vec2, 0, 1> rg;
  135.         SWIZZLE_READ_ONLY<vec2, 1, 1> gg;
  136.         SWIZZLE_READWRITE<vec2, 1, 0> gr;
  137.         // st
  138.         SWIZZLE_READ_ONLY<vec2, 0, 0> ss;
  139.         SWIZZLE_READWRITE<vec2, 0, 1> st;
  140.         SWIZZLE_READ_ONLY<vec2, 1, 1> tt;
  141.         SWIZZLE_READWRITE<vec2, 1, 0> ts;
  142.     };
  143.  
  144.     //// Operator Overloads
  145.  
  146.     // Equality test operators.
  147.     inline constexpr bool operator == (vec2 rhs) const
  148.         { return ((x == rhs.x) && (y == rhs.y)); }
  149.     inline constexpr bool operator != (vec2 rhs) const
  150.         { return ((x != rhs.x) || (y != rhs.y)); }
  151.  
  152.     // Arithmetic operators (vector with vector)
  153.     inline constexpr vec2 operator + (vec2 rhs) const
  154.         { return { x+rhs.x, y+rhs.y }; }
  155.     inline constexpr vec2 operator - (vec2 rhs) const
  156.         { return { x-rhs.x, y-rhs.y }; }
  157.     inline constexpr vec2 operator * (vec2 rhs) const
  158.         { return { x*rhs.x, y*rhs.y }; }
  159.     inline constexpr vec2 operator / (vec2 rhs) const
  160.         { return { x / rhs.x, y / rhs.y }; }
  161.  
  162.     // Arithmetic operators (vector with float)
  163.     inline constexpr vec2 operator + (float rhs) const
  164.         { return { x+rhs, y+rhs }; }
  165.     inline constexpr vec2 operator - (float rhs) const
  166.         { return { x-rhs, y-rhs }; }
  167.     inline constexpr vec2 operator * (float rhs) const
  168.         { return { x*rhs, y*rhs }; }
  169.     inline constexpr vec2 operator / (float rhs) const
  170.         { return { x/rhs, y/rhs }; }
  171.  
  172.     // Arithmetic operator (float with vector)
  173.     friend inline constexpr vec2 operator + (const float lhs, const vec2 rhs)
  174.         { return { lhs+rhs.x, lhs+rhs.y }; }
  175.     friend inline constexpr vec2 operator - (const float lhs, const vec2 rhs)
  176.         { return { lhs-rhs.x, lhs-rhs.y }; }
  177.     friend inline constexpr vec2 operator * (const float lhs, const vec2 rhs)
  178.         { return { lhs*rhs.x, lhs*rhs.y }; }
  179.     friend inline constexpr vec2 operator / (const float lhs, const vec2 rhs)
  180.         { return { lhs/rhs.x, lhs/rhs.y }; }
  181.  
  182.     // Arithmetic-assignment operators (vector with vector)
  183.     inline vec2& operator += (vec2 rhs)
  184.         { return *this = *this + rhs; }
  185.     inline vec2& operator -= (vec2 rhs)
  186.         { return *this = *this - rhs; }
  187.     inline vec2& operator *= (vec2 rhs)
  188.         { return *this = *this * rhs; }
  189.     inline vec2& operator /= (vec2 rhs)
  190.         { return *this = *this / rhs; }
  191.  
  192.     // Arithmetic-assignment operators (vector with float)
  193.     inline vec2& operator += (float rhs)
  194.         { return *this = *this + rhs; }
  195.     inline vec2& operator -= (float rhs)
  196.         { return *this = *this - rhs; }
  197.     inline vec2& operator *= (float rhs)
  198.         { return *this = *this * rhs; }
  199.     inline vec2& operator /= (float rhs)
  200.         { return *this = *this / rhs; }
  201.  
  202.     // Negation operator (unary minus)
  203.     inline constexpr vec2 operator - () const
  204.         { return { -x, -y }; }
  205.  
  206.     //// Member functions
  207.  
  208.     inline constexpr bool is_zero() const
  209.         { return ((x == 0.0f) && (y == 0.0f)); }
  210.  
  211.     inline constexpr float sum() const
  212.         { return x + y; }
  213.  
  214.     inline float magnitude() const
  215.         { return sqrtf((x*x) + (y*y)); }
  216.  
  217.     inline float mag() const
  218.         { return magnitude(); }
  219.  
  220.     inline float magnitude_squared() const
  221.         { return (x*x) + (y*y); }
  222.  
  223.     inline float sqrmag() const
  224.         { return magnitude_squared(); }
  225.  
  226.     inline vec2 normalized() const
  227.         { return *this / magnitude(); }
  228.  
  229.     inline void normalize()
  230.         { *this = normalized(); }
  231.  
  232.     static inline vec2 minimum(vec2 lhs, vec2 rhs)
  233.         { return { fminf(lhs.x, rhs.x), fminf(lhs.y, rhs.y) }; }
  234.  
  235.     static inline vec2 maximum(vec2 lhs, vec2 rhs)
  236.         { return { fmaxf(lhs.x, rhs.x), fmaxf(lhs.y, rhs.y) }; }
  237.  
  238.     inline vec2 clamped(vec2 lower, vec2 upper) const
  239.         { return minimum(upper, maximum(lower, *this)); }
  240.  
  241.     inline void clamp(vec2 lower, vec2 upper)
  242.         { *this = clamped(lower, upper); }
  243.  
  244.     inline vec2 clamped_magnitude(float max_magnitude) const
  245.     {
  246.         float mag = magnitude();
  247.         if (mag <= max_magnitude)
  248.             return *this;
  249.         else
  250.             return this->normalized() * max_magnitude;
  251.     }
  252.     inline void clamp_magnitude(float max_magnitude)
  253.         { *this = clamped_magnitude(max_magnitude); }
  254.  
  255.     static inline float distance(vec2 a, vec2 b)
  256.         { return (a-b).magnitude(); }
  257.  
  258.     static inline float distance_squared(vec2 a, vec2 b)
  259.         { return (a-b).magnitude_squared(); }
  260.  
  261.     inline vec2 moved_towards(vec2 target, float max_dist) const
  262.     {
  263.         if (distance(*this, target) <= max_dist)
  264.             return target;
  265.         else
  266.             return *this + ((target - *this).normalized() * max_dist);
  267.     }
  268.     inline void move_towards(vec2 target, float max_dist)
  269.         { *this = moved_towards(target, max_dist); }
  270.  
  271.     static inline constexpr float determinant(vec2 a, vec2 b)
  272.         { return (a.x * b.y) - (a.y * b.x); }
  273.  
  274.     static inline constexpr float det(vec2 a, vec2 b)
  275.         { return determinant(a, b); }
  276.  
  277.     static inline constexpr float dot(vec2 a, vec2 b)
  278.         { return (a.x * b.x) + (a.y * b.y); }
  279.  
  280.     static inline vec2 lerp(vec2 from, vec2 to, float amount)
  281.         { return (from * (1.0f - amount)) + (to * amount); }
  282.  
  283.     static inline float angle(vec2 from, vec2 to)
  284.         { return atan2f(det(from, to), dot(from, to)); }
  285.  
  286.     static vec2 smooth_damp(vec2 from, vec2 to, vec2& velocity, float smooth_time, float delta_time, float max_speed)
  287.     {
  288.         if (smooth_time <= 0.0f)
  289.             smooth_time = 0.0001f;
  290.         float num = 2 / smooth_time;
  291.         float num2 = num * delta_time;
  292.         float num3 = 1 / (1 + num2 + 0.48f * num2 * num2 + 0.235f * num2 * num2);
  293.         vec2 num4 = from - to;
  294.         vec2 num5 = to;
  295.         float max_dist = max_speed * smooth_time;
  296.         num4.clamp_magnitude(max_dist);
  297.         num5 = from - num4;
  298.         vec2 num7 = ((num4 * num) + velocity) * delta_time;
  299.         velocity = (velocity - num * num7) * num3;
  300.         vec2 num8 = to + (num4 + num7) * num3;
  301.         if (((num5 - from).magnitude() > 0) == (num8.magnitude() > num5.magnitude()))
  302.         {
  303.             num8 = num5;
  304.             velocity = (num8 - num5) / delta_time;
  305.         }
  306.  
  307.         return num8;
  308.     }
  309. };
  310.  
  311. constexpr vec2 VEC2_ZERO = { 0, 0 };
  312. constexpr vec2 VEC2_ONE = { 1, 1 };
  313.  
  314. } // namespace vmath
  315. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement