union {
struct {
- MT X;
- MT Y;
+ MT x;
+ MT y;
};
- MT XY[2];
+ MT xy[2];
} __attribute__((packed));
// --- constructors and deconstructors ---
Vector2()
- : XY{0, 0}
+ : xy{0, 0}
{
}
Vector2(const MT& val)
- : XY{val, val}
+ : xy{val, val}
{
}
Vector2(const MT& x, const MT& y)
- : XY{x, y}
+ : xy{x, y}
{
}
Vector2(const Vector3<MT>& vec)
- : XY{vec.X, vec.Y}
+ : xy{vec.x, vec.y}
{
}
Vector2(const Vector4<MT>& vec)
- : XY{vec.X, vec.Y}
+ : xy{vec.x, vec.y}
{
}
Vector2(const Vector2& rhs)
- : XY{rhs.X, rhs.Y}
+ : xy{rhs.x, rhs.y}
{
}
Vector2(const Vector2&& rhs)
- : XY{std::move(rhs.X), std::move(rhs.Y)}
+ : xy{std::move(rhs.x), std::move(rhs.y)}
{
}
{
if (this != &rhs)
{
- X = rhs.X;
- Y = rhs.Y;
+ x = rhs.x;
+ y = rhs.y;
}
return *this;
{
if (this != &rhs)
{
- X = std::move(rhs.X);
- Y = std::move(rhs.Y);
+ x = std::move(rhs.x);
+ y = std::move(rhs.y);
}
return *this;
bool operator==(const Vector2& rhs)
{
- return X == rhs.X && Y == rhs.Y;
+ return x == rhs.x && y == rhs.y;
}
bool operator!=(const Vector2& rhs)
const MT operator[](const size_t& index) const
{
- return XY[index];
+ return xy[index];
}
MT& operator[](const size_t& index)
{
- return XY[index];
+ return xy[index];
}
Vector2& operator~()
{
- X = -X;
- Y = -Y;
+ x = -x;
+ y = -y;
return *this;
}
Vector2 operator-() const
{
- return {-X, -Y};
+ return {-x, -y};
}
// --- other operators ---
Vector2& operator+=(const Vector2& rhs)
{
- X += rhs.X;
- Y += rhs.Y;
+ x += rhs.x;
+ y += rhs.y;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X += val;
- Y += val;
+ x += val;
+ y += val;
return *this;
}
Vector2 operator+(const Vector2& rhs) const
{
- return {X + rhs.X, Y + rhs.Y};
+ return {x + rhs.x, y + rhs.y};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X + val, Y + val};
+ return {x + val, y + val};
}
// ---
Vector2& operator-=(const Vector2& rhs)
{
- X -= rhs.X;
- Y -= rhs.Y;
+ x -= rhs.x;
+ y -= rhs.y;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X -= val;
- Y -= val;
+ x -= val;
+ y -= val;
return *this;
}
Vector2 operator-(const Vector2& rhs) const
{
- return {X - rhs.X, Y - rhs.Y};
+ return {x - rhs.x, y - rhs.y};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X - val, Y - val};
+ return {x - val, y - val};
}
// ---
Vector2& operator*=(const Vector2& rhs)
{
- X *= rhs.X;
- Y *= rhs.Y;
+ x *= rhs.x;
+ y *= rhs.y;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X *= val;
- Y *= val;
+ x *= val;
+ y *= val;
return *this;
}
Vector2 operator*(const Vector2& rhs) const
{
- return {X * rhs.X, Y * rhs.Y};
+ return {x * rhs.x, y * rhs.y};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X * val, Y * val};
+ return {x * val, y * val};
}
// ---
Vector2& operator/=(const Vector2& rhs)
{
- X /= rhs.X;
- Y /= rhs.Y;
+ x /= rhs.x;
+ y /= rhs.y;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X /= val;
- Y /= val;
+ x /= val;
+ y /= val;
return *this;
}
Vector2 operator/(const Vector2& rhs) const
{
- return {X / rhs.X, Y / rhs.Y};
+ return {x / rhs.x, y / rhs.y};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X / val, Y / val};
+ return {x / val, y / val};
}
// --- public methods ---
MT dotProduct(const Vector2& vec) const
{
- return X * vec.X + Y * vec.Y;
+ return x * vec.x + y * vec.y;
}
bool isNull() const
{
- return X == 0 && Y == 0;
+ return x == 0 && y == 0;
}
MT length() const
{
- return std::sqrt(X * X + Y * Y);
+ return std::sqrt(x * x + y * y);
}
MT lengthSquared() const
{
- return X * X + Y * Y;
+ return x * x + y * y;
}
void normalize()
{
- *this /= std::sqrt(X * X + Y * Y);
+ *this /= std::sqrt(x * x + y * y);
}
Vector2 normalized() const
{
- const MT len = std::sqrt(X * X + Y * Y);
+ const MT len = std::sqrt(x * x + y * y);
- return {X / len, Y / len};
+ return {x / len, y / len};
}
std::string string() const
{
std::stringstream result;
- result << X << ", " << Y;
+ result << x << ", " << y;
return result.str();
}
Vector3<MT> vector3() const
{
- return {X, Y, 0};
+ return {x, y, 0};
}
Vector4<MT> vector4() const
{
- return {X, Y, 0, 0};
+ return {x, y, 0, 0};
}
// --- static methods ---
static MT toDotProduct(const Vector2& vec1, const Vector2& vec2)
{
- return vec1.X * vec2.X + vec1.Y * vec2.Y;
+ return vec1.x * vec2.x + vec1.y * vec2.y;
}
static std::string toString(const Vector2& vec)
{
std::stringstream result;
- result << vec.X << ", " << vec.Y;
+ result << vec.x << ", " << vec.y;
return result.str();
}
static Vector3<MT> toVector3(const Vector2& vec)
{
- return {vec.X, vec.Y, 0};
+ return {vec.x, vec.y, 0};
}
static Vector4<MT> toVector4(const Vector2& vec)
{
- return {vec.X, vec.Y, 0, 0};
+ return {vec.x, vec.y, 0, 0};
}
};
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return lhs.X == rhs.X && lhs.Y == rhs.Y;
+ return lhs.x == rhs.x && lhs.y == rhs.y;
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- lhs << rhs.X << rhs.Y;
+ lhs << rhs.x << rhs.y;
return lhs;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- lhs >> rhs.X >> rhs.Y;
+ lhs >> rhs.x >> rhs.y;
return lhs;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X + vec2.X, vec1.Y + vec2.Y};
+ return {vec1.x + vec2.x, vec1.y + vec2.y};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X + val, vec.Y + val};
+ return {vec.x + val, vec.y + val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val + vec.X, val + vec.Y};
+ return {val + vec.x, val + vec.y};
}
// ---
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X - vec2.X, vec1.Y - vec2.Y};
+ return {vec1.x - vec2.x, vec1.y - vec2.y};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X - val, vec.Y - val};
+ return {vec.x - val, vec.y - val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val - vec.X, val - vec.Y};
+ return {val - vec.x, val - vec.y};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {-vec.X, -vec.Y};
+ return {-vec.x, -vec.y};
}
// ---
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X * vec2.X, vec1.Y * vec2.Y};
+ return {vec1.x * vec2.x, vec1.y * vec2.y};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X * val, vec.Y * val};
+ return {vec.x * val, vec.y * val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val * vec.X, val + vec.Y};
+ return {val * vec.x, val + vec.y};
}
// ---
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X / vec2.X, vec1.Y / vec2.Y};
+ return {vec1.x / vec2.x, vec1.y / vec2.y};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X / val, vec.Y / val};
+ return {vec.x / val, vec.y / val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val / vec.X, val / vec.Y};
+ return {val / vec.x, val / vec.y};
}
// ****************************************************************************************************************** //
union {
struct {
- MT X;
- MT Y;
- MT Z;
+ MT x;
+ MT y;
+ MT z;
};
- MT XYZ[3];
+ MT xyz[3];
} __attribute__((packed));
// --- constructors and deconstructors ---
Vector3()
- : XYZ{0, 0, 0}
+ : xyz{0, 0, 0}
{
}
Vector3(const MT& val)
- : XYZ{val, val, val}
+ : xyz{val, val, val}
{
}
Vector3(const MT& x, const MT& y, const MT& z)
- : XYZ{x, y, z}
+ : xyz{x, y, z}
{
}
Vector3(const Vector2<MT>& vec)
- : XYZ{vec.X, vec.Y, 0}
+ : xyz{vec.x, vec.y, 0}
{
}
Vector3(const Vector2<MT>& vec, const MT& val)
- : XYZ{vec.X, vec.Y, val}
+ : xyz{vec.x, vec.y, val}
{
}
Vector3(const Vector4<MT>& vec)
- : XYZ{vec.X, vec.Y, vec.Z}
+ : xyz{vec.x, vec.y, vec.z}
{
}
Vector3(const Vector3& rhs)
- : XYZ{rhs.X, rhs.Y, rhs.Z}
+ : xyz{rhs.x, rhs.y, rhs.z}
{
}
Vector3(const Vector3&& rhs)
- : XYZ{std::move(rhs.X), std::move(rhs.Y), std::move(rhs.Z)}
+ : xyz{std::move(rhs.x), std::move(rhs.y), std::move(rhs.z)}
{
}
{
if (this != &rhs)
{
- X = rhs.X;
- Y = rhs.Y;
- Z = rhs.Z;
+ x = rhs.x;
+ y = rhs.y;
+ z = rhs.z;
}
return *this;
{
if (this != &rhs)
{
- X = std::move(rhs.X);
- Y = std::move(rhs.Y);
- Z = std::move(rhs.Z);
+ x = std::move(rhs.x);
+ y = std::move(rhs.y);
+ z = std::move(rhs.z);
}
return *this;
bool operator==(const Vector3& rhs) const
{
- return X == rhs.X && Y == rhs.Y && Z == rhs.Z;
+ return x == rhs.x && y == rhs.y && z == rhs.z;
}
bool operator!=(const Vector3& rhs) const
const MT operator[](const size_t& index) const
{
- return XYZ[index];
+ return xyz[index];
}
MT& operator[](const size_t& index)
{
- return XYZ[index];
+ return xyz[index];
}
Vector3& operator~()
{
- X = -X;
- Y = -Y;
- Z = -Z;
+ x = -x;
+ y = -y;
+ z = -z;
return *this;
}
Vector3 operator-() const
{
- return {-X, -Y, -Z};
+ return {-x, -y, -z};
}
// --- other operators ---
Vector3& operator+=(const Vector3& rhs)
{
- X += rhs.X;
- Y += rhs.Y;
- Z += rhs.Z;
+ x += rhs.x;
+ y += rhs.y;
+ z += rhs.z;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X += val;
- Y += val;
- Z += val;
+ x += val;
+ y += val;
+ z += val;
return *this;
}
Vector3 operator+(const Vector3& rhs) const
{
- return {X + rhs.X, Y + rhs.Y, Z + rhs.Z};
+ return {x + rhs.x, y + rhs.y, z + rhs.z};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X + val, Y + val, Z + val};
+ return {x + val, y + val, z + val};
}
// ---
Vector3& operator-=(const Vector3& rhs)
{
- X -= rhs.X;
- Y -= rhs.Y;
- Z -= rhs.Z;
+ x -= rhs.x;
+ y -= rhs.y;
+ z -= rhs.z;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X -= val;
- Y -= val;
- Z -= val;
+ x -= val;
+ y -= val;
+ z -= val;
return *this;
}
Vector3 operator-(const Vector3& rhs) const
{
- return {X - rhs.X, Y - rhs.Y, Z - rhs.Z};
+ return {x - rhs.x, y - rhs.y, z - rhs.z};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X - val, Y - val, Z - val};
+ return {x - val, y - val, z - val};
}
// ---
Vector3& operator*=(const Vector3& rhs)
{
- X *= rhs.X;
- Y *= rhs.Y;
- Z *= rhs.Z;
+ x *= rhs.x;
+ y *= rhs.y;
+ z *= rhs.z;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X *= val;
- Y *= val;
- Z *= val;
+ x *= val;
+ y *= val;
+ z *= val;
return *this;
}
Vector3 operator*(const Vector3& rhs) const
{
- return {X * rhs.X, Y * rhs.Y, Z * rhs.Z};
+ return {x * rhs.x, y * rhs.y, z * rhs.z};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X * val, Y * val, Z * val};
+ return {x * val, y * val, z * val};
}
// ---
Vector3& operator/=(const Vector3& rhs)
{
- X /= rhs.X;
- Y /= rhs.Y;
- Z /= rhs.Z;
+ x /= rhs.x;
+ y /= rhs.y;
+ z /= rhs.z;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X /= val;
- Y /= val;
- Z /= val;
+ x /= val;
+ y /= val;
+ z /= val;
return *this;
}
Vector3 operator/(const Vector3& rhs) const
{
- return {X / rhs.X, Y / rhs.Y, Z / rhs.Z};
+ return {x / rhs.x, y / rhs.y, z / rhs.z};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X / val, Y / val, Z / val};
+ return {x / val, y / val, z / val};
}
// --- public methods ---
Vector3 crossProduct(const Vector3& vec) const
{
- return {Y * vec.Z - Z * vec.Y, Z * vec.X - X * vec.Z, X * vec.Y - Y * vec.X};
+ return {y * vec.z - z * vec.y, z * vec.x - x * vec.z, x * vec.y - y * vec.x};
}
MT distanceToLine(const Vector3& origin, const Vector3& direction) const
MT dotProduct(const Vector3& vec) const
{
- return X * vec.X + Y * vec.Y + Z * vec.Z;
+ return x * vec.x + y * vec.y + z * vec.z;
}
bool isNull() const
{
- return X == 0 && Y == 0 && Z == 0;
+ return x == 0 && y == 0 && z == 0;
}
MT length() const
{
- return std::sqrt(X * X + Y * Y + Z * Z);
+ return std::sqrt(x * x + y * y + z * z);
}
MT lengthSquared() const
{
- return X * X + Y * Y + Z * Z;
+ return x * x + y * y + z * z;
}
Vector3 normal(const Vector3& vec) const
void normalize()
{
- *this /= std::sqrt(X * X + Y * Y + Z * Z);
+ *this /= std::sqrt(x * x + y * y + z * z);
}
Vector3 normalized() const
{
- const MT len = std::sqrt(X * X + Y * Y + Z * Z);
+ const MT len = std::sqrt(x * x + y * y + z * z);
- return {X / len, Y / len, Z / len};
+ return {x / len, y / len, z / len};
}
std::string string() const
{
std::stringstream result;
- result << X << ", " << Y << ", " << Z;
+ result << x << ", " << y << ", " << z;
return result.str();
}
Vector2<MT> vector2() const
{
- return {X, Y};
+ return {x, y};
}
Vector4<MT> vector4() const
{
- return {X, Y, Z, 0};
+ return {x, y, z, 0};
}
// --- static methods ---
static Vector3 toCrossProduct(const Vector3& vec1, const Vector3& vec2)
{
- return {vec1.Y * vec2.Z - vec1.Z * vec2.Y,
- vec1.Z * vec2.X - vec1.X * vec2.Z,
- vec1.X * vec2.Y - vec1.Y * vec2.X};
+ return {vec1.y * vec2.z - vec1.z * vec2.y,
+ vec1.z * vec2.x - vec1.x * vec2.z,
+ vec1.x * vec2.y - vec1.y * vec2.x};
}
static MT toDotProduct(const Vector3& vec1, const Vector3& vec2)
{
- return vec1.X * vec2.X + vec1.Y * vec2.Y + vec1.Z * vec2.Z;
+ return vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;
}
static Vector3 toNormal(const Vector3& vec1, const Vector3& vec2)
{
std::stringstream result;
- result << vec.X << ", " << vec.Y << ", " << vec.Z;
+ result << vec.x << ", " << vec.y << ", " << vec.z;
return result.str();
}
static Vector2<MT> toVector2(const Vector3& vec)
{
- return {vec.X, vec.Y};
+ return {vec.x, vec.y};
}
static Vector4<MT> toVector4(const Vector3& vec)
{
- return {vec.X, vec.Y, vec.Z, 0};
+ return {vec.x, vec.y, vec.z, 0};
}
};
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z;
+ return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z;
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- lhs << rhs.X << rhs.Y << rhs.Z;
+ lhs << rhs.x << rhs.y << rhs.z;
return lhs;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- lhs >> rhs.X >> rhs.Y >> rhs.Z;
+ lhs >> rhs.x >> rhs.y >> rhs.z;
return lhs;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X + vec2.X, vec1.Y + vec2.Y, vec1.Z + vec2.Z};
+ return {vec1.x + vec2.x, vec1.y + vec2.y, vec1.z + vec2.z};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X + val, vec.Y + val, vec.Z + val};
+ return {vec.x + val, vec.y + val, vec.z + val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val + vec.X, val + vec.Y, val + vec.Z};
+ return {val + vec.x, val + vec.y, val + vec.z};
}
// ---
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X - vec2.X, vec1.Y - vec2.Y, vec1.Z - vec2.Z};
+ return {vec1.x - vec2.x, vec1.y - vec2.y, vec1.z - vec2.z};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X - val, vec.Y - val, vec.Z - val};
+ return {vec.x - val, vec.y - val, vec.z - val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val - vec.X, val - vec.Y, val - vec.Z};
+ return {val - vec.x, val - vec.y, val - vec.z};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {-vec.X, -vec.Y, -vec.Z};
+ return {-vec.x, -vec.y, -vec.z};
}
// ---
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X * vec2.X, vec1.Y * vec2.Y, vec1.Z * vec2.Z};
+ return {vec1.x * vec2.x, vec1.y * vec2.y, vec1.z * vec2.z};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X * val, vec.Y * val, vec.Z * val};
+ return {vec.x * val, vec.y * val, vec.z * val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val * vec.X, val + vec.Y, val * vec.Z};
+ return {val * vec.x, val + vec.y, val * vec.z};
}
// ---
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X / vec2.X, vec1.Y / vec2.Y, vec1.Z / vec2.Z};
+ return {vec1.x / vec2.x, vec1.y / vec2.y, vec1.z / vec2.z};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X / val, vec.Y / val, vec.Z / val};
+ return {vec.x / val, vec.y / val, vec.z / val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val / vec.X, val / vec.Y, val / vec.Z};
+ return {val / vec.x, val / vec.y, val / vec.z};
}
// ****************************************************************************************************************** //
union {
struct {
- MT X;
- MT Y;
- MT Z;
- MT W;
+ MT x;
+ MT y;
+ MT z;
+ MT w;
};
- MT XYZW[4];
+ MT xyzw[4];
} __attribute__((packed));
// --- constructors and deconstructors ---
Vector4()
- : XYZW{0, 0, 0, 0}
+ : xyzw{0, 0, 0, 0}
{
}
Vector4(const MT& val)
- : XYZW{val, val, val, val}
+ : xyzw{val, val, val, val}
{
}
Vector4(const MT& x, const MT& y, const MT& z, const MT& w)
- : XYZW{x, y, z, w}
+ : xyzw{x, y, z, w}
{
}
Vector4(const Vector2<MT>& vec)
- : XYZW{vec.X, vec.Y, 0, 0}
+ : xyzw{vec.x, vec.y, 0, 0}
{
}
Vector4(const Vector2<MT>& vec, const MT& val1, const MT& val2)
- : XYZW{vec.X, vec.Y, val1, val2}
+ : xyzw{vec.x, vec.y, val1, val2}
{
}
Vector4(const Vector2<MT>& vec1, const Vector2<MT>& vec2)
- : XYZW{vec1.X, vec1.Y, vec2.X, vec2.Y}
+ : xyzw{vec1.x, vec1.y, vec2.x, vec2.y}
{
}
Vector4(const Vector3<MT>& vec)
- : XYZW{vec.X, vec.Y, vec.Z, 0}
+ : xyzw{vec.x, vec.y, vec.z, 0}
{
}
Vector4(const Vector3<MT>& vec, const MT& val)
- : XYZW{vec.X, vec.Y, vec.Z, val}
+ : xyzw{vec.x, vec.y, vec.z, val}
{
}
Vector4(const Vector4& rhs)
- : XYZW{rhs.X, rhs.Y, rhs.Z, rhs.W}
+ : xyzw{rhs.x, rhs.y, rhs.z, rhs.w}
{
}
Vector4(const Vector4&& rhs)
- : XYZW{std::move(rhs.X), std::move(rhs.Y), std::move(rhs.Z), std::move(rhs.W)}
+ : xyzw{std::move(rhs.x), std::move(rhs.y), std::move(rhs.z), std::move(rhs.w)}
{
}
{
if (this != &rhs)
{
- X = rhs.X;
- Y = rhs.Y;
- Z = rhs.Z;
- W = rhs.W;
+ x = rhs.x;
+ y = rhs.y;
+ z = rhs.z;
+ w = rhs.w;
}
return *this;
{
if (this != &rhs)
{
- X = std::move(rhs.X);
- Y = std::move(rhs.Y);
- Z = std::move(rhs.Z);
- W = std::move(rhs.W);
+ x = std::move(rhs.x);
+ y = std::move(rhs.y);
+ z = std::move(rhs.z);
+ w = std::move(rhs.w);
}
return *this;
bool operator==(const Vector4& rhs) const
{
- return X == rhs.X && Y == rhs.Y && Z == rhs.Z && W == rhs.W;
+ return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
}
bool operator!=(const Vector4& rhs) const
const MT operator[](const size_t& index) const
{
- return XYZW[index];
+ return xyzw[index];
}
MT& operator[](const size_t& index)
{
- return XYZW[index];
+ return xyzw[index];
}
Vector4& operator~()
{
- X = -X;
- Y = -Y;
- Z = -Z;
- W = -W;
+ x = -x;
+ y = -y;
+ z = -z;
+ w = -w;
return *this;
}
Vector4 operator-() const
{
- return {-X, -Y, -Z, -W};
+ return {-x, -y, -z, -w};
}
// --- other operators ---
Vector4& operator+=(const Vector4& rhs)
{
- X += rhs.X;
- Y += rhs.Y;
- Z += rhs.Z;
+ x += rhs.x;
+ y += rhs.y;
+ z += rhs.z;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X += val;
- Y += val;
- Z += val;
- W += val;
+ x += val;
+ y += val;
+ z += val;
+ w += val;
return *this;
}
Vector4 operator+(const Vector4& rhs) const
{
- return {X + rhs.X, Y + rhs.Y, Z + rhs.Z, W + rhs.W};
+ return {x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X + val, Y + val, Z + val, W + val};
+ return {x + val, y + val, z + val, w + val};
}
// ---
Vector4& operator-=(const Vector4& rhs)
{
- X -= rhs.X;
- Y -= rhs.Y;
- Z -= rhs.Z;
- W -= rhs.W;
+ x -= rhs.x;
+ y -= rhs.y;
+ z -= rhs.z;
+ w -= rhs.w;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X -= val;
- Y -= val;
- Z -= val;
- W -= val;
+ x -= val;
+ y -= val;
+ z -= val;
+ w -= val;
return *this;
}
Vector4 operator-(const Vector4& rhs) const
{
- return {X - rhs.X, Y - rhs.Y, Z - rhs.Z, W - rhs.W};
+ return {x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X - val, Y - val, Z - val, W - val};
+ return {x - val, y - val, z - val, w - val};
}
Vector4& operator*=(const Vector4& rhs)
{
- X *= rhs.X;
- Y *= rhs.Y;
- Z *= rhs.Z;
- W *= rhs.W;
+ x *= rhs.x;
+ y *= rhs.y;
+ z *= rhs.z;
+ w *= rhs.w;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X *= val;
- Y *= val;
- Z *= val;
- W *= val;
+ x *= val;
+ y *= val;
+ z *= val;
+ w *= val;
return *this;
}
Vector4 operator*(const Vector4& rhs) const
{
- return {X * rhs.X, Y * rhs.Y, Z * rhs.Z, W * rhs.W};
+ return {x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X * val, Y * val, Z * val, W * val};
+ return {x * val, y * val, z * val, w * val};
}
// ---
Vector4& operator/=(const Vector4& rhs)
{
- X /= rhs.X;
- Y /= rhs.Y;
- Z /= rhs.Z;
- W /= rhs.W;
+ x /= rhs.x;
+ y /= rhs.y;
+ z /= rhs.z;
+ w /= rhs.w;
return *this;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- X /= val;
- Y /= val;
- Z /= val;
- W /= val;
+ x /= val;
+ y /= val;
+ z /= val;
+ w /= val;
return *this;
}
Vector4 operator/(const Vector4& rhs) const
{
- return {X / rhs.X, Y / rhs.Y, Z / rhs.Z, W / rhs.W};
+ return {x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {X / val, Y / val, Z / val, W / val};
+ return {x / val, y / val, z / val, w / val};
}
// --- public methods ---
MT dotProduct(const Vector4& vec) const
{
- return X * vec.X + Y * vec.Y + Z * vec.Z + W * vec.W;
+ return x * vec.x + y * vec.y + z * vec.z + w * vec.w;
}
bool isNull() const
{
- return X == 0 && Y == 0 && Z == 0 && W == 0;
+ return x == 0 && y == 0 && z == 0 && w == 0;
}
MT length() const
{
- return std::sqrt(X * X + Y * Y + Z * Z + W * W);
+ return std::sqrt(x * x + y * y + z * z + w * w);
}
MT lengthSquared() const
{
- return X * X + Y * Y + Z * Z + W * W;
+ return x * x + y * y + z * z + w * w;
}
void normalize()
{
- *this /= std::sqrt(X * X + Y * Y + Z * Z + W * W);
+ *this /= std::sqrt(x * x + y * y + z * z + w * w);
}
Vector4 normalized() const
{
- const MT len = std::sqrt(X * X + Y * Y + Z * Z + W * W);
+ const MT len = std::sqrt(x * x + y * y + z * z + w * w);
- return {X / len, Y / len, Z / len, W / len};
+ return {x / len, y / len, z / len, w / len};
}
std::string string() const
{
std::stringstream result;
- result << X << ", " << Y << ", " << Z << ", " << W;
+ result << x << ", " << y << ", " << z << ", " << w;
return result.str();
}
Vector2<MT> vector2() const
{
- return {X, Y};
+ return {x, y};
}
Vector3<MT> vector3() const
{
- return {X, Y, Z};
+ return {x, y, z};
}
// --- static methods ---
static MT toDotProduct(const Vector4& vec1, const Vector4& vec2)
{
- return vec1.X * vec2.X + vec1.Y * vec2.Y + vec1.Z * vec2.Z + vec1.W * vec2.W;
+ return vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z + vec1.w * vec2.w;
}
static std::string toString(const Vector4& vec)
{
std::stringstream result;
- result << vec.X << ", " << vec.Y << ", " << vec.Z << ", " << vec.W;
+ result << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w;
return result.str();
}
static Vector2<MT> toVector2(const Vector4& vec)
{
- return {vec.X, vec.Y};
+ return {vec.x, vec.y};
}
static Vector3<MT> toVector3(const Vector4& vec)
{
- return {vec.X, vec.X, vec.Z};
+ return {vec.x, vec.x, vec.z};
}
};
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z && lhs.W == rhs.W;
+ return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w;
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- lhs << rhs.X << rhs.Y << rhs.Z << rhs.W;
+ lhs << rhs.x << rhs.y << rhs.z << rhs.w;
return lhs;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- lhs >> rhs.X >> rhs.Y >> rhs.Z >> rhs.W;
+ lhs >> rhs.x >> rhs.y >> rhs.z >> rhs.w;
return lhs;
}
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X + vec2.X, vec1.Y + vec2.Y, vec1.Z + vec2.Z, vec1.W + vec2.W};
+ return {vec1.x + vec2.x, vec1.y + vec2.y, vec1.z + vec2.z, vec1.w + vec2.w};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X + val, vec.Y + val, vec.Z + val, vec.W + val};
+ return {vec.x + val, vec.y + val, vec.z + val, vec.w + val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val + vec.X, val + vec.Y, val + vec.Z, val + vec.W};
+ return {val + vec.x, val + vec.y, val + vec.z, val + vec.w};
}
// ---
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X - vec2.X, vec1.Y - vec2.Y, vec1.Z - vec2.Z, vec1.W - vec2.W};
+ return {vec1.x - vec2.x, vec1.y - vec2.y, vec1.z - vec2.z, vec1.w - vec2.w};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X - val, vec.Y - val, vec.Z - val, vec.W - val};
+ return {vec.x - val, vec.y - val, vec.z - val, vec.w - val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val - vec.X, val - vec.Y, val - vec.Z, val - vec.W};
+ return {val - vec.x, val - vec.y, val - vec.z, val - vec.w};
}
template <typename T>
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {-vec.X, -vec.Y, -vec.Z, -vec.W};
+ return {-vec.x, -vec.y, -vec.z, -vec.w};
}
// ---
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X * vec2.X, vec1.Y * vec2.Y, vec1.Z * vec2.Z, vec1.W * vec2.W};
+ return {vec1.x * vec2.x, vec1.y * vec2.y, vec1.z * vec2.z, vec1.w * vec2.w};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X * val, vec.Y * val, vec.Z * val, vec.W * val};
+ return {vec.x * val, vec.y * val, vec.z * val, vec.w * val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val * vec.X, val + vec.Y, val * vec.Z, val * vec.W};
+ return {val * vec.x, val + vec.y, val * vec.z, val * vec.w};
}
// ---
static_assert (std::is_integral<T>::value || std::is_floating_point<T>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec1.X / vec2.X, vec1.Y / vec2.Y, vec1.Z / vec2.Z, vec1.W / vec2.W};
+ return {vec1.x / vec2.x, vec1.y / vec2.y, vec1.z / vec2.z, vec1.w / vec2.w};
}
template <typename Vec, typename Val>
std::is_integral<Val>::value || std::is_floating_point<Val>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {vec.X / val, vec.Y / val, vec.Z / val, vec.W / val};
+ return {vec.x / val, vec.y / val, vec.z / val, vec.w / val};
}
template <typename Val, typename Vec>
std::is_integral<Vec>::value || std::is_floating_point<Vec>::value,
"ERROR: template parameter is not an integral or floating point type");
- return {val / vec.X, val / vec.Y, val / vec.Z, val / vec.W};
+ return {val / vec.x, val / vec.y, val / vec.z, val / vec.w};
}