text: #pragma once
  
  #include <cmath>
  
  class Matrix3x4;
  
  struct Vector {
      constexpr auto operator==(const Vector& v) const noexcept
      {
          return x == v.x && y == v.y && z == v.z;
      }
  
      constexpr auto operator!=(const Vector& v) const noexcept
      {
          return !(*this == v);
      }
  
      constexpr Vector& operator+=(const Vector& v) noexcept
      {
          x += v.x;
          y += v.y;
          z += v.z;
          return *this;
      }
  
      constexpr Vector& operator+=(float f) noexcept
      {
          x += f;
          y += f;
          z += f;
          return *this;
      }
  
      constexpr Vector& operator-=(const Vector& v) noexcept
      {
          x -= v.x;
          y -= v.y;
          z -= v.z;
          return *this;
      }
  
      constexpr Vector& operator-=(float f) noexcept
      {
          x -= f;
          y -= f;
          z -= f;
          return *this;
      }
  
      constexpr auto operator-(const Vector& v) const noexcept
      {
          return Vector{ x - v.x, y - v.y, z - v.z };
      }
  
      constexpr auto operator+(const Vector& v) const noexcept
      {
          return Vector{ x + v.x, y + v.y, z + v.z };
      }
  
      constexpr auto operator*(const Vector& v) const noexcept
      {
          return Vector{ x * v.x, y * v.y, z * v.z };
      }
  
      constexpr Vector& operator/=(float div) noexcept
      {
          x /= div;
          y /= div;
          z /= div;
          return *this;
      }
  
      constexpr auto operator*(float mul) const noexcept
      {
          return Vector{ x * mul, y * mul, z * mul };
      }
  
      constexpr auto operator-(float sub) const noexcept
      {
          return Vector{ x - sub, y - sub, z - sub };
      }
  
      constexpr auto operator+(float add) const noexcept
      {
          return Vector{ x + add, y + add, z + add };
      }
  
      auto length() const noexcept
      {
          return std::sqrt(x * x + y * y + z * z);
      }
  
      constexpr auto squareLength() const noexcept
      {
          return x * x + y * y + z * z;
      }
  
      constexpr auto dotProduct(const Vector& v) const noexcept
      {
          return x * v.x + y * v.y + z * v.z;
      }
  
      constexpr auto transform(const Matrix3x4& mat) const noexcept;
  
      auto distTo(const Vector& v) const noexcept
      {
          return (*this - v).length();
      }
  
      float x, y, z;
  };
  
  #include "Matrix3x4.h"
  
  constexpr auto Vector::transform(const Matrix3x4& mat) const noexcept
  {
      return Vector{ dotProduct({ mat[0][0], mat[0][1], mat[0][2] }) + mat[0][3],
                     dotProduct({ mat[1][0], mat[1][1], mat[1][2] }) + mat[1][3],
                     dotProduct({ mat[2][0], mat[2][1], mat[2][2] }) + mat[2][3] };
  }
  