text: #pragma once
  
  #include <cmath>
  #include <limits>
  
  const float pi = 3.14159265358979f;
  
  constexpr float deg2rad(float degrees) noexcept { return degrees * (pi / 180.0f); }
  constexpr float rad2deg(float radians) noexcept { return radians * (180.0f / pi); }
  
  class Vector
  {
  public:
  	Vector(void)
  	{
  		Invalidate();
  	}
  	Vector(float X, float Y, float Z)
  	{
  		x = X;
  		y = Y;
  		z = Z;
  	}
  	Vector(const float* clr)
  	{
  		x = clr[0];
  		y = clr[1];
  		z = clr[2];
  	}
  
  	void Init(float ix = 0.0f, float iy = 0.0f, float iz = 0.0f)
  	{
  		x = ix; y = iy; z = iz;
  	}
  	bool IsValid() const
  	{
  		return std::isfinite(x) && std::isfinite(y) && std::isfinite(z);
  	}
  	void Invalidate()
  	{
  		x = y = z = NULL;
  	}
  
  	float& operator[](int i)
  	{
  		return ((float*)this)[i];
  	}
  	float operator[](int i) const
  	{
  		return ((float*)this)[i];
  	}
  
  	void Zero()
  	{
  		x = y = z = 0.0f;
  	}
  
  	bool operator==(const Vector& src) const
  	{
  		return (src.x == x) && (src.y == y) && (src.z == z);
  	}
  	bool operator!=(const Vector& src) const
  	{
  		return (src.x != x) || (src.y != y) || (src.z != z);
  	}
  
  	Vector& operator+=(const Vector& v)
  	{
  		x += v.x; y += v.y; z += v.z;
  		return *this;
  	}
  	Vector& operator-=(const Vector& v)
  	{
  		x -= v.x; y -= v.y; z -= v.z;
  		return *this;
  	}
  	Vector& operator*=(float fl)
  	{
  		x *= fl;
  		y *= fl;
  		z *= fl;
  		return *this;
  	}
  	Vector& operator*=(const Vector& v)
  	{
  		x *= v.x;
  		y *= v.y;
  		z *= v.z;
  		return *this;
  	}
  	Vector& operator/=(const Vector& v)
  	{
  		x /= v.x;
  		y /= v.y;
  		z /= v.z;
  		return *this;
  	}
  	Vector& operator+=(float fl)
  	{
  		x += fl;
  		y += fl;
  		z += fl;
  		return *this;
  	}
  	Vector& operator/=(float fl)
  	{
  		x /= fl;
  		y /= fl;
  		z /= fl;
  		return *this;
  	}
  	Vector& operator-=(float fl)
  	{
  		x -= fl;
  		y -= fl;
  		z -= fl;
  		return *this;
  	}
  	Vector& operator=(const Vector& vOther)
  	{
  		x = vOther.x; y = vOther.y; z = vOther.z;
  		return *this;
  	}
  	Vector operator-(void) const
  	{
  		return Vector(-x, -y, -z);
  	}
  	Vector operator+(const Vector& v) const
  	{
  		return Vector(x + v.x, y + v.y, z + v.z);
  	}
  	Vector operator-(const Vector& v) const
  	{
  		return Vector(x - v.x, y - v.y, z - v.z);
  	}
  	Vector operator*(float fl) const
  	{
  		return Vector(x * fl, y * fl, z * fl);
  	}
  	Vector operator*(const Vector& v) const
  	{
  		return Vector(x * v.x, y * v.y, z * v.z);
  	}
  	Vector operator/(float fl) const
  	{
  		return Vector(x / fl, y / fl, z / fl);
  	}
  	Vector operator/(const Vector& v) const
  	{
  		return Vector(x / v.x, y / v.y, z / v.z);
  	}
  
  	// Custom mathematical helpers from here.
  	Vector& normalize() noexcept {
  		x = std::isfinite(x) ? std::remainder(x, 360.0f) : 0.0f;
  		y = std::isfinite(y) ? std::remainder(y, 360.0f) : 0.0f;
  		z = 0.0f;
  
  		return *this;
  	}
  	Vector toAngle() const {
  		return Vector{
  			rad2deg(std::atan2(-z, std::hypot(x, y))),
  			rad2deg(std::atan2(y, x)),
  			0.0f
  		};
  	}
  	bool notNull() const {
  		return x || y || z;
  	}
  	float dotMultiply(const Vector& vecOther) const {
  		return x * vecOther.x + y * vecOther.y + z * vecOther.z;
  	}
  
  	float x, y, z;
  };
  
  inline Vector operator*(float lhs, const Vector& rhs)
  {
  	return rhs * lhs;
  }
  inline Vector operator/(float lhs, const Vector& rhs)
  {
  	return rhs / lhs;
  }