#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, }; } template T Dot(const Vec4& vect, const Vec4& other) { return vect.x * other.x + vect.y * other.y + vect.z * other.z + vect.w * other.w; } ////////////////////////////////////////////////////////////////// // Matricies // ////////////////////////////////////////////////////////////////// template struct Mat4 { static const std::size_t MATRIX_SIZE = 4; 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]; } T at(std::size_t row, std::size_t column) const { return operator[](row * MATRIX_SIZE + column); } T& at(std::size_t row, std::size_t column) { return operator[](row * MATRIX_SIZE + column); } }; typedef Mat4 Mat4f; typedef Mat4 Mat4i; typedef Mat4 Mat4d; template Vec4 Dot(const Mat4& mat, const Vec4& vect) { return { Dot(*reinterpret_cast*>(&mat), vect), Dot(*reinterpret_cast*>(&mat[Mat4::MATRIX_SIZE]), vect), Dot(*reinterpret_cast*>(&mat[2 * Mat4::MATRIX_SIZE]), vect), Dot(*reinterpret_cast*>(&mat[3 * Mat4::MATRIX_SIZE]), vect), }; } template Mat4 Dot(const Mat4& mat, const Mat4& other) { Mat4 result {}; for (std::size_t i = 0; i < Mat4::MATRIX_SIZE; i++) { for (std::size_t j = 0; j < Mat4::MATRIX_SIZE; j++) { for (std::size_t k = 0; k < Mat4::MATRIX_SIZE; k++) { result.at(i, j) = mat.at(i, k) * other.at(k, j); } } } return result; } 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; } Mat4f Perspective(float fovY, float aspectRatio, float zNear, float zFar); Mat4f Look(const Vec3f& eye, const Vec3f& center, const Vec3f& up); Mat4f Inverse(const Mat4f& mat); } // namespace maths } // namespace td