diff --git a/include/Defines.h b/include/Defines.h index 1514a66..921ebd2 100644 --- a/include/Defines.h +++ b/include/Defines.h @@ -15,7 +15,6 @@ struct Vec2 { }; constexpr Vec2(T X = 0, T Y = 0) : x(X), y(Y) {} - }; template @@ -48,6 +47,37 @@ inline bool operator==(const Vec3& vec3, const Vec3& other) { return vec3.x == other.x && vec3.y == other.y && vec3.z == other.z; } +template +struct Vec4 { + union { + T x; + T r; + }; + + union { + T y; + T g; + }; + + union { + T z; + T b; + }; + + union { + T w; + T a; + }; + + constexpr Vec4(Vec3 vec, T W = 1) : x(vec.x), y(vec.y), z(vec.z), w(W) {} + constexpr Vec4(T X = 0, T Y = 0, T Z = 0, T W = 0) : x(X), y(Y), z(Z), w(W) {} +}; + +template +inline bool operator==(const Vec4& vec4, const Vec4& other) { + return vec4.x == other.x && vec4.y == other.y && vec4.z == other.z && vec4.w = other.w; +} + using Vec2i = Vec2; using Vec2u = Vec2; using Vec2f = Vec2; @@ -58,6 +88,11 @@ using Vec3u = Vec3; using Vec3f = Vec3; using Vec3d = Vec3; +using Vec4i = Vec4; +using Vec4u = Vec4; +using Vec4f = Vec4; +using Vec4d = Vec4; + using Color = Vec3; } // namespace td diff --git a/include/misc/Maths.h b/include/misc/Maths.h new file mode 100644 index 0000000..3c60557 --- /dev/null +++ b/include/misc/Maths.h @@ -0,0 +1,113 @@ +#pragma once + +#include "Defines.h" +#include + +namespace td { +namespace maths { + +////////////////////////////////////////////////////////////////// +// Vectors // +////////////////////////////////////////////////////////////////// + +template +Vec3 operator- (const Vec3& vect) { + return { -vect.x, -vect.y, -vect.z }; +} + +template +Vec3 operator+ (const Vec3& vect, const Vec3& other) { + return { vect.x + other.x, vect.y + other.y, vect.z + other.y }; +} + +template +Vec3 operator- (const Vec3& vect, const Vec3& other) { + return vect + (-other); +} + +template +Vec3 Normalize(const Vec3& vect) { + T length = std::sqrt(vect.x * vect.x + vect.y * vect.y + vect.z * vect.z); + + return { vect.x / length, vect.y / length, vect.z / length }; +} + +template +T Dot(const Vec3& vect, const Vec3& other) { + return vect.x * other.x + vect.y * other.y + vect.z * other.z; +} + +template +Vec3 Cross(const Vec3& vect, const Vec3& other) { + return { + vect.y * other.z - vect.z * other.y, + vect.z * other.x - vect.x * other.z, + vect.x * other.y - vect.y * other.x, + }; +} + + + +////////////////////////////////////////////////////////////////// +// Matricies // +////////////////////////////////////////////////////////////////// + +template +struct Mat4 { + T x0, x1, x2, x3; + T y0, y1, y2, y3; + T z0, z1, z2, z3; + T w0, w1, w2, w3; + + T operator[] (std::size_t offset) const { + return reinterpret_cast(this)[offset]; + } + + T& operator[] (std::size_t offset) { + return reinterpret_cast(this)[offset]; + } +}; + +typedef Mat4 Mat4f; +typedef Mat4 Mat4i; +typedef Mat4 Mat4d; + +Mat4f Perspective(float fovY, float aspectRatio, float zNear, float zFar); +Mat4f LookAt(const Vec3f& eye, const Vec3f& center, const Vec3f& up); + +Mat4f Dot(const Mat4f& mat, const Mat4f& other); + +template +Mat4 Identity() { + Mat4 result{}; + + result.x0 = static_cast(1); + result.y1 = static_cast(1); + result.z2 = static_cast(1); + result.w3 = static_cast(1); + + return result; +} + +template +Mat4 Transpose(const Mat4& mat) { + Mat4 result; + + result.x1 = mat.y0; + result.x2 = mat.z0; + result.x3 = mat.w0; + result.y0 = mat.x1; + result.y2 = mat.z1; + result.y3 = mat.w1; + result.z0 = mat.x2; + result.z1 = mat.y2; + result.z3 = mat.w2; + result.w0 = mat.x3; + result.w1 = mat.y3; + result.w2 = mat.z3; + + return result; +} + +} // namespace maths +} // namespace td diff --git a/src/misc/Maths.cpp b/src/misc/Maths.cpp new file mode 100644 index 0000000..a754d06 --- /dev/null +++ b/src/misc/Maths.cpp @@ -0,0 +1,58 @@ +#include "misc/Maths.h" + +namespace td { +namespace maths { + +Mat4f Perspective(float fovY, float aspectRatio, float zNear, float zFar) { + const float tanHalfFovy = std::tan(fovY / 2.0f); + + Mat4f result{}; + result.x0 = 1.0f / (aspectRatio * tanHalfFovy); + result.y1 = 1.0f / (tanHalfFovy); + result.z2 = -(zFar + zNear) / (zFar - zNear); + result.z3 = -1.0f; + result.w2 = -(2.0f * zFar * zNear) / (zFar - zNear); + + return result; +} + +Mat4f LookAt(const Vec3f& eye, const Vec3f& center, const Vec3f& up) { + const Vec3f f = Normalize(center - eye); + const Vec3f s = Normalize(Cross(f, up)); + const Vec3f u = Cross(s, f); + + Mat4f result = Identity(); + result.x0 = s.x; + result.y0 = s.y; + result.z0 = s.z; + result.x1 = u.x; + result.y1 = u.y; + result.z1 = u.z; + result.x2 = -f.x; + result.y2 = -f.y; + result.z2 = -f.z; + result.w0 = -Dot(s, eye); + result.w1 = -Dot(u, eye); + result.w2 = Dot(f, eye); + + return result; +} + +Mat4f Dot(const Mat4f& mat, const Mat4f& other) { + Mat4f result {}; + + static const int MAT_SIZE = 4; + + for (int i = 0; i < MAT_SIZE; i++) { + for (int j = 0; j < MAT_SIZE; j++) { + for (int k = 0; k < MAT_SIZE; k++) { + result[i * MAT_SIZE + j] += mat[i * MAT_SIZE + k] * other[k * MAT_SIZE + j]; + } + } + } + + return result; +} + +} // namespace maths +} // namespace td