445 lines
7.0 KiB
C
445 lines
7.0 KiB
C
|
#pragma once
|
||
|
|
||
|
#include "Types.h"
|
||
|
#include "UTF.h"
|
||
|
#include "Str.h"
|
||
|
#include "Math.h"
|
||
|
#include "Vec2.h"
|
||
|
#include "Log.h"
|
||
|
|
||
|
namespace ehs
|
||
|
{
|
||
|
template<typename T>
|
||
|
class Vec3
|
||
|
{
|
||
|
public:
|
||
|
T x;
|
||
|
T y;
|
||
|
T z;
|
||
|
|
||
|
Vec3(const T scalar = 0)
|
||
|
: x(scalar), y(scalar), z(scalar)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
Vec3(const T x, const T y, const T z)
|
||
|
: x(x), y(y), z(z)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
template<typename C>
|
||
|
Vec3(const Vec2<C>& vec, const T z = 0)
|
||
|
: x((T)vec.x), y((T)vec.y), z(z)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
template<typename C>
|
||
|
Vec3(const Vec3<C>& vec)
|
||
|
: x((T)vec.x), y((T)vec.y), z((T)vec.z)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
template<typename C>
|
||
|
Vec3<T>& operator=(const Vec2<C>& vec)
|
||
|
{
|
||
|
x = (T)vec.x;
|
||
|
y = (T)vec.y;
|
||
|
z = 0;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template<typename C>
|
||
|
Vec3<T>& operator=(const Vec3<C>& vec)
|
||
|
{
|
||
|
x = (T)vec.x;
|
||
|
y = (T)vec.y;
|
||
|
z = (T)vec.z;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
bool operator==(const Vec3<T>& vec) const
|
||
|
{
|
||
|
return Math::ComCmp(x, vec.x) && Math::ComCmp(y, vec.y) && Math::ComCmp(z, vec.z);
|
||
|
}
|
||
|
|
||
|
|
||
|
bool operator!=(const Vec3<T>& vec) const
|
||
|
{
|
||
|
return !Math::ComCmp(z, vec.z) || !Math::ComCmp(y, vec.y) || !Math::ComCmp(z, vec.z);
|
||
|
}
|
||
|
|
||
|
Vec3<T> operator+(const Vec3<T>& vec) const
|
||
|
{
|
||
|
Vec3<T> tmp;
|
||
|
|
||
|
tmp.x = x + vec.x;
|
||
|
tmp.y = y + vec.y;
|
||
|
tmp.z = z + vec.z;
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
Vec3<T>& operator+=(const Vec3<T>& vec)
|
||
|
{
|
||
|
x += vec.x;
|
||
|
y += vec.y;
|
||
|
z += vec.z;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Vec3<T> operator+(const T scalar) const
|
||
|
{
|
||
|
Vec3<T> tmp;
|
||
|
|
||
|
tmp.x = x + scalar;
|
||
|
tmp.y = y + scalar;
|
||
|
tmp.z = z + scalar;
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
Vec3<T>& operator+=(const T scalar)
|
||
|
{
|
||
|
x += scalar;
|
||
|
y += scalar;
|
||
|
z += scalar;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Vec3<T> operator-(const Vec3<T>& vec) const
|
||
|
{
|
||
|
Vec3<T> tmp;
|
||
|
|
||
|
tmp.x = x - vec.x;
|
||
|
tmp.y = y - vec.y;
|
||
|
tmp.z = z - vec.z;
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
Vec3<T>& operator-=(const Vec3<T>& vec)
|
||
|
{
|
||
|
x -= vec.x;
|
||
|
y -= vec.y;
|
||
|
z -= vec.z;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Vec3<T> operator-(const T scalar) const
|
||
|
{
|
||
|
Vec3<T> tmp;
|
||
|
|
||
|
tmp.x = x - scalar;
|
||
|
tmp.y = y - scalar;
|
||
|
tmp.z = z - scalar;
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
Vec3<T>& operator-=(const T scalar)
|
||
|
{
|
||
|
x -= scalar;
|
||
|
y -= scalar;
|
||
|
z -= scalar;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Vec3<T> operator*(const Vec3<T>& vec) const
|
||
|
{
|
||
|
Vec3<T> tmp;
|
||
|
|
||
|
tmp.x = x * vec.x;
|
||
|
tmp.y = y * vec.y;
|
||
|
tmp.z = z * vec.z;
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
Vec3<T>& operator*=(const Vec3<T>& vec)
|
||
|
{
|
||
|
x *= vec.x;
|
||
|
y *= vec.y;
|
||
|
z *= vec.z;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Vec3<T> operator*(const T scalar) const
|
||
|
{
|
||
|
Vec3<T> tmp;
|
||
|
|
||
|
tmp.x = x * scalar;
|
||
|
tmp.y = y * scalar;
|
||
|
tmp.z = z * scalar;
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
Vec3<T>& operator*=(const T scalar)
|
||
|
{
|
||
|
x *= scalar;
|
||
|
y *= scalar;
|
||
|
z *= scalar;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Vec3<T> operator/(const Vec3<T>& vec) const
|
||
|
{
|
||
|
Vec3<T> tmp;
|
||
|
|
||
|
tmp.x = x / vec.x;
|
||
|
tmp.y = y / vec.y;
|
||
|
tmp.z = z / vec.z;
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
Vec3<T>& operator/=(const Vec3<T>& vec)
|
||
|
{
|
||
|
x /= vec.x;
|
||
|
y /= vec.y;
|
||
|
z /= vec.z;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Vec3<T> operator/(const T scalar) const
|
||
|
{
|
||
|
Vec3<T> tmp;
|
||
|
|
||
|
tmp.x = x / scalar;
|
||
|
tmp.y = y / scalar;
|
||
|
tmp.z = z / scalar;
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
Vec3<T>& operator/=(const T scalar)
|
||
|
{
|
||
|
x /= scalar;
|
||
|
y /= scalar;
|
||
|
z /= scalar;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
bool operator<=(const Vec3<T>& other) const
|
||
|
{
|
||
|
return x <= other.x && y <= other.y && z <= other.z;
|
||
|
}
|
||
|
|
||
|
bool operator<(const Vec3<T>& other) const
|
||
|
{
|
||
|
return x < other.x && y < other.y && z < other.z;
|
||
|
}
|
||
|
|
||
|
bool operator>=(const Vec3<T>& other) const
|
||
|
{
|
||
|
return x >= other.x && y >= other.y && z >= other.z;
|
||
|
}
|
||
|
|
||
|
bool operator>(const Vec3<T>& other) const
|
||
|
{
|
||
|
return x > other.x && y > other.y && z > other.z;
|
||
|
}
|
||
|
|
||
|
Vec3 operator-()
|
||
|
{
|
||
|
return {-x, -y, -z};
|
||
|
}
|
||
|
|
||
|
T operator[](const UInt_64 index) const
|
||
|
{
|
||
|
switch (index)
|
||
|
{
|
||
|
case 0:
|
||
|
return x;
|
||
|
case 1:
|
||
|
return y;
|
||
|
case 2:
|
||
|
return z;
|
||
|
default:
|
||
|
EHS_LOG_INT("Error", 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 3.");
|
||
|
return x;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
T& operator[](const UInt_64 index)
|
||
|
{
|
||
|
switch (index)
|
||
|
{
|
||
|
case 0:
|
||
|
return x;
|
||
|
case 1:
|
||
|
return y;
|
||
|
case 2:
|
||
|
return z;
|
||
|
default:
|
||
|
EHS_LOG_INT("Error", 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 3.");
|
||
|
return x;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
operator Vec2<T>()
|
||
|
{
|
||
|
return Vec2<T>(x, y);
|
||
|
}
|
||
|
|
||
|
Vec3<T> GetAbs() const
|
||
|
{
|
||
|
Vec3<T> absolute;
|
||
|
|
||
|
absolute.x = Math::Abs(x);
|
||
|
absolute.y = Math::Abs(y);
|
||
|
absolute.z = Math::Abs(z);
|
||
|
|
||
|
return absolute;
|
||
|
}
|
||
|
|
||
|
void Abs()
|
||
|
{
|
||
|
x = Math::Abs(x);
|
||
|
y = Math::Abs(y);
|
||
|
z = Math::Abs(z);
|
||
|
}
|
||
|
|
||
|
Vec3<T> GetNorm() const
|
||
|
{
|
||
|
Vec3<T> norm;
|
||
|
|
||
|
T dis = GetMagnitude();
|
||
|
|
||
|
norm.x = x / dis;
|
||
|
norm.y = y / dis;
|
||
|
norm.z = z / dis;
|
||
|
|
||
|
return norm;
|
||
|
}
|
||
|
|
||
|
void Norm()
|
||
|
{
|
||
|
T dis = GetMagnitude();
|
||
|
|
||
|
x /= dis;
|
||
|
y /= dis;
|
||
|
z /= dis;
|
||
|
}
|
||
|
|
||
|
Vec3<T> GetCross(const Vec3<T>& vec) const
|
||
|
{
|
||
|
return Vec3<T>(
|
||
|
y * vec.z - z * vec.y,
|
||
|
z * vec.x - x * vec.z,
|
||
|
x * vec.y - y * vec.x
|
||
|
);
|
||
|
}
|
||
|
|
||
|
T GetDot(const Vec3<T>& vec) const
|
||
|
{
|
||
|
return x * vec.x + y * vec.y + z * vec.z;
|
||
|
}
|
||
|
|
||
|
T GetAngle(const Vec2<T>& vec) const
|
||
|
{
|
||
|
return Math::ACos(GetDot(vec) / Math::Sqrt(GetMagnitude2() * vec.GetMagnitude2()));
|
||
|
}
|
||
|
|
||
|
Vec2<T> GetProjection(const Vec2<T>& length) const
|
||
|
{
|
||
|
return operator*(length.GetDot(*this) / GetMagnitude2());
|
||
|
}
|
||
|
|
||
|
Vec2<T> GetPerpendicular(const Vec2<T>& length) const
|
||
|
{
|
||
|
return length - GetProjection(length);
|
||
|
}
|
||
|
|
||
|
Vec2<T> GetReflection(const Vec2<T>& normal) const
|
||
|
{
|
||
|
return operator-(normal * (GetDot(normal) * 2));
|
||
|
}
|
||
|
|
||
|
T GetMagnitude() const
|
||
|
{
|
||
|
return Math::Sqrt(x * x + y * y + z * z);
|
||
|
}
|
||
|
|
||
|
T GetMagnitude2() const
|
||
|
{
|
||
|
return x * x + y * y + z * z;
|
||
|
}
|
||
|
|
||
|
T GetDistance(const Vec3<T>& vec) const
|
||
|
{
|
||
|
return (T)Math::Sqrt(Math::Pow<T>(vec.x - x, 2) + Math::Pow<T>(vec.y - y, 2) + Math::Pow<T>(vec.z - z, 2));
|
||
|
}
|
||
|
|
||
|
T GetDistance2(const Vec3<T>& vec) const
|
||
|
{
|
||
|
return static_cast<T>(Math::Pow<T>(vec.x - x, 2) + Math::Pow<T>(vec.y - y, 2) + Math::Pow<T>(vec.z - z, 2));
|
||
|
}
|
||
|
|
||
|
Vec3<T> GetRads() const
|
||
|
{
|
||
|
Vec3<T> tmp;
|
||
|
|
||
|
tmp.x = Math::Rads(x);
|
||
|
tmp.y = Math::Rads(y);
|
||
|
tmp.z = Math::Rads(z);
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
void ToRads()
|
||
|
{
|
||
|
x = Math::Rads(x);
|
||
|
y = Math::Rads(y);
|
||
|
z = Math::Rads(z);
|
||
|
}
|
||
|
|
||
|
Vec3<T> GetDegr() const
|
||
|
{
|
||
|
Vec3<T> tmp;
|
||
|
|
||
|
tmp.x = Math::Degr(x);
|
||
|
tmp.y = Math::Degr(y);
|
||
|
tmp.z = Math::Degr(z);
|
||
|
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
void ToDegr()
|
||
|
{
|
||
|
x = Math::Degr(x);
|
||
|
y = Math::Degr(y);
|
||
|
z = Math::Degr(z);
|
||
|
}
|
||
|
|
||
|
static Vec3 Lerp(const Vec3& start, const Vec3& finish, const T t)
|
||
|
{
|
||
|
return start + (finish - start) * t;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
typedef Vec3<UInt_64> Vec3_u64;
|
||
|
typedef Vec3<SInt_64> Vec3_s64;
|
||
|
typedef Vec3<Int_64> Vec3_64;
|
||
|
typedef Vec3<UInt_32> Vec3_u32;
|
||
|
typedef Vec3<SInt_32> Vec3_s32;
|
||
|
typedef Vec3<Int_32> Vec3_32;
|
||
|
typedef Vec3<UInt_16> Vec3_u16;
|
||
|
typedef Vec3<SInt_16> Vec3_s16;
|
||
|
typedef Vec3<Int_16> Vec3_16;
|
||
|
typedef Vec3<UInt_8> Vec3_u8;
|
||
|
typedef Vec3<SInt_8> Vec3_s8;
|
||
|
typedef Vec3<Int_8> Vec3_8;
|
||
|
typedef Vec3<float> Vec3_f;
|
||
|
typedef Vec3<double> Vec3_d;
|
||
|
}
|