#ifndef maths_hpp #define maths_hpp #include #include template T to_rad(T deg) { return deg * (((T)3.14159265358979323846) / 180.0f); } template T to_deg(T rad) { return rad * (180.0f / ((T)3.14159265358979323846)); } template struct v2 { T x, y; v2() : x(0), y(0) {} v2(T xy) : x(xy), y(xy) {} v2(T x, T y) : x(x), y(y) {} bool operator>(const v2& other) const { return x > other.x && y > other.y; } bool operator<(const v2& other) const { return x < other.x && y < other.y; } v2 operator+(const v2& other) const { return v2(x + other.x, y + other.y); } v2 operator-(const v2& other) const { return v2(x - other.x, y - other.y); } v2 operator*(const v2& other) const { return v2(x * other.x, y * other.y); } v2 operator/(const v2& other) const { return v2(x / other.x, y / other.y); } v2 operator+(T other) const { return v2(x + other, y + other); } v2 operator-(T other) const { return v2(x - other, y - other); } v2 operator*(T other) const { return v2(x * other, y * other); } v2 operator/(T other) const { return v2(x / other, y / other); } v2 operator+=(const v2& other) { *this = *this + other; return *this; } v2 operator-=(const v2& other) { *this = *this - other; return *this; } v2 operator*=(const v2& other) { *this = *this * other; return *this; } v2 operator/=(const v2& other) { *this = *this / other; return *this; } v2 operator+=(T other) { *this = *this + other; return *this; } v2 operator-=(T other) { *this = *this - other; return *this; } v2 operator*=(T other) { *this = *this * other; return *this; } v2 operator/=(T other) { *this = *this / other; return *this; } bool operator==(const v2& other) const { return x == other.x && y == other.y; } bool operator!=(const v2& other) const { return !(*this == other); } static T dot(const v2& a, const v2& b) { return a.x * b.x + a.y * b.y; } static T mag_sqrd(const v2& v) { return v2::dot(v, v); } static T mag(const v2& v) { return (T)sqrtf((float)v2::mag_sqrd(v)); } static v2 normalised(const v2& v) { const T l = v2::mag(v); return v2(v.x / l, v.y / l); } }; template v2 operator+(T lhs, v2 rhs) { return v2(lhs + rhs.x, lhs + rhs.y); } template v2 operator-(T lhs, v2 rhs) { return v2(lhs - rhs.x, lhs - rhs.y); } template v2 operator*(T lhs, v2 rhs) { return v2(lhs * rhs.x, lhs * rhs.y); } template v2 operator/(T lhs, v2 rhs) { return v2(lhs / rhs.x, lhs / rhs.y); } template v2 operator-(const v2& v) { return v2(-v.x, -v.y); } template struct v3 { T x, y, z; v3() : x(0), y(0), z(0) {} v3(T xyz) : x(xyz), y(xyz), z(xyz) {} v3(v2 xy, T z) : x(xy.x), y(xy.y), z(z) {} v3(T x, v2 yz) : x(x), y(yz.x), z(yz.y) {} v3(T x, T y, T z) : x(x), y(y), z(z) {} bool operator>(const v3& other) const { return x > other.x && y > other.y && z > other.z; } bool operator<(const v3& other) const { return x < other.x && y < other.y && z < other.z; } v3 operator+(const v3& other) const { return v3(x + other.x, y + other.y, z + other.z); } v3 operator-(const v3& other) const { return v3(x - other.x, y - other.y, z - other.z); } v3 operator*(const v3& other) const { return v3(x * other.x, y * other.y, z * other.z); } v3 operator/(const v3& other) const { return v3(x / other.x, y / other.y, z / other.z); } v3 operator+(T other) const { return v3(x + other, y + other, z + other); } v3 operator-(T other) const { return v3(x - other, y - other, z - other); } v3 operator*(T other) const { return v3(x * other, y * other, z * other); } v3 operator/(T other) const { return v3(x / other, y / other, z / other); } v3 operator+=(const v3& other) { *this = *this + other; return *this; } v3 operator-=(const v3& other) { *this = *this - other; return *this; } v3 operator*=(const v3& other) { *this = *this * other; return *this; } v3 operator/=(const v3& other) { *this = *this / other; return *this; } v3 operator+=(T other) { *this = *this + other; return *this; } v3 operator-=(T other) { *this = *this - other; return *this; } v3 operator*=(T other) { *this = *this * other; return *this; } v3 operator/=(T other) { *this = *this / other; return *this; } bool operator==(const v3& other) const { return x == other.x && y == other.y && z == other.z; } bool operator!=(const v3& other) const { return !(*this == other); } static T dot(const v3& a, const v3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } static v3 cross(const v3& a, const v3& b) { return v3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } static T mag_sqrd(const v3& v) { return v3::dot(v, v); } static T mag(const v3& v) { return (T)sqrtf((float)v3::mag_sqrd(v)); } static v3 normalised(const v3& v) { const T l = v3::mag(v); return v3(v.x / l, v.y / l, v.z / l); } }; template v3 operator+(T lhs, v3 rhs) { return v3(lhs + rhs.x, lhs + rhs.y, lhs + rhs.z); } template v3 operator-(T lhs, v3 rhs) { return v3(lhs - rhs.x, lhs - rhs.y, lhs - rhs.z); } template v3 operator*(T lhs, v3 rhs) { return v3(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z); } template v3 operator/(T lhs, v3 rhs) { return v3(lhs / rhs.x, lhs / rhs.y, lhs / rhs.z); } template v3 operator-(const v3& v) { return v3(-v.x, -v.y, -v.z); } template struct v4 { T x, y, z, w; v4() : x(0), y(0), z(0), w(0) {} v4(T xyzw) : x(xyzw), y(xyzw), z(xyzw), w(xyzw) {} v4(v2 xy, T z, T w) : x(xy.x), y(xy.y), z(z), w(w) {} v4(v3 xyz, T w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) {} v4(T x, v3 yzw) : x(x), y(yzw.x), z(yzw.y), w(yzw.z) {} v4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {} bool operator>(const v4& other) const { return x > other.x && y > other.y && z > other.z && w > other.w; } bool operator<(const v4& other) const { return x < other.x && y < other.y && z < other.z && w < other.w; } v4 operator+(const v4& other) const { return v4(x + other.x, y + other.y, z + other.z, w + other.w); } v4 operator-(const v4& other) const { return v4(x - other.x, y - other.y, z - other.z, w - other.w); } v4 operator*(const v4& other) const { return v4(x * other.x, y * other.y, z * other.z, w * other.w); } v4 operator/(const v4& other) const { return v4(x / other.x, y / other.y, z / other.z, w / other.w); } v4 operator+(T other) const { return v4(x + other, y + other, z + other, w + other); } v4 operator-(T other) const { return v4(x - other, y - other, z - other, w - other); } v4 operator*(T other) const { return v4(x * other, y * other, z * other, w * other); } v4 operator/(T other) const { return v4(x / other, y / other, z / other, w / other); } v4 operator+=(const v4& other) { *this = *this + other; return *this; } v4 operator-=(const v4& other) { *this = *this - other; return *this; } v4 operator*=(const v4& other) { *this = *this * other; return *this; } v4 operator/=(const v4& other) { *this = *this / other; return *this; } v4 operator+=(T other) { *this = *this + other; return *this; } v4 operator-=(T other) { *this = *this - other; return *this; } v4 operator*=(T other) { *this = *this * other; return *this; } v4 operator/=(T other) { *this = *this / other; return *this; } bool operator==(const v4& other) const { return x == other.x && y == other.y && z == other.z && w == other.w; } bool operator!=(const v4& other) const { return !(*this == other); } static T dot(const v4& a, const v4& b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } static T mag_sqrd(const v4& v) { return v4::dot(v, v); } static T mag(const v4& v) { return (T)sqrtf((float)v4::mag_sqrd(v)); } static v4 normalised(const v4& v) { const T l = v4::mag(v); return v4(v.x / l, v.y / l, v.z / l, v.w / l); } }; template v4 operator+(T lhs, v4 rhs) { return v4(lhs + rhs.x, lhs + rhs.y, lhs + rhs.z, lhs + rhs.w); } template v4 operator-(T lhs, v4 rhs) { return v4(lhs - rhs.x, lhs - rhs.y, lhs - rhs.z, lhs - rhs.w); } template v4 operator*(T lhs, v4 rhs) { return v4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs - rhs.w); } template v4 operator/(T lhs, v4 rhs) { return v4(lhs / rhs.x, lhs / rhs.y, lhs / rhs.z, lhs - rhs.w); } template v4 operator-(const v4& v) { return v4(-v.x, -v.y, -v.z, -v.w); } typedef v2 v2i; typedef v2 v2f; typedef v2 v2d; typedef v3 v3i; typedef v3 v3f; typedef v3 v3d; typedef v4 v4i; typedef v4 v4f; typedef v4 v4d; template struct v2; template struct v2; template struct v2; template struct v3; template struct v3; template struct v3; template struct v4; template struct v4; template struct v4; struct AABB { v3f min, max; }; struct m4f { float m[4][4]; m4f(); m4f(float d); static m4f identity(); static m4f screenspace(float hw, float hh); m4f operator*(const m4f& other) const; v4f operator*(const v4f& other) const; static m4f translate(m4f m, v3f v); static m4f rotate(m4f m, float a, v3f v); static m4f scale(m4f m, v3f v); v3f get_translation(); static m4f lookat(v3f c, v3f o, v3f u); static m4f pers(float fov, float asp, float n, float f); static m4f orth(float l, float r, float b, float t, float n, float f); static v4f transform(m4f m, v4f v); static AABB transform(m4f m, AABB aabb); m4f inverse(); m4f transposed(); }; inline static v4f make_color(uint32_t rgb, uint8_t a) { return v4f( (float)((rgb >> 16) & 0xff) / 255.0f, (float)((rgb >> 8) & 0xff) / 255.0f, (float)((rgb) & 0xff) / 255.0f, (float)a / 255.0f); } #endif