From db41d43345ea73cf7c1bbb29448e52ffb822e3e0 Mon Sep 17 00:00:00 2001 From: vimene Date: Tue, 13 Jan 2026 02:04:52 +0100 Subject: added textures for the hardware renderer - removed "using" directive in .hpp - reverse order of arguments for quaternion rotation, i.e. q.rot(v) instead of v.rot(q), where q is a quaterinon and v a vector - pass the inverse of the view matrix to render_and_present_frame, to allow light calculation in shaders (we used to just pass the matrix of the quaternion of the transformation, i.e. discard scaling and translations) - added another mesh and texture (viking_room) for testing purposes - added transparent background option - added Quaternion::look_towards(), which is the equivalent of Matrix4::look_at() but only for rotations - various improvement to .obj parsing - load texture coordinates from .obj file - merged duplicate vertices in Mesh::linearize_indices() --- src/math/mat4.hpp | 1 + src/math/quat.hpp | 26 ++++++++++++++++++++++++++ src/math/utils.hpp | 24 ++++++++++++++++++++++++ src/math/vector.hpp | 26 ++++++++++++++------------ 4 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 src/math/utils.hpp (limited to 'src/math') diff --git a/src/math/mat4.hpp b/src/math/mat4.hpp index 6a215d3..b25dbd4 100644 --- a/src/math/mat4.hpp +++ b/src/math/mat4.hpp @@ -4,6 +4,7 @@ #include #include #include "math/vector.hpp" +#include "math/quat.hpp" namespace engine::math { diff --git a/src/math/quat.hpp b/src/math/quat.hpp index 51392e7..9687c98 100644 --- a/src/math/quat.hpp +++ b/src/math/quat.hpp @@ -2,6 +2,7 @@ #define MATH_QUAT_HPP #include +#include "math/vector.hpp" namespace engine::math { @@ -30,6 +31,23 @@ struct Quaternion { return {std::cos(a / 2.f), 0.f, std::sin(a / 2.f), 0.f}; } + static constexpr Quaternion look_towards(const Vector3& dir, const Vector3& up) { + // TODO: extract common code between Matrix4::look_at and this. We should have something + // similar to a function returning a 3x3 matrix which does: + // e_x -> up.cross(-dir).normalize() + // e_y -> (-dir).cross(e_x).normalize() + // e_z -> (-dir).normalize() + Vector3 new_x = up.cross(-dir).normalize(); + Vector3 new_y = (-dir).cross(new_x).normalize(); + Vector3 new_z = (-dir).normalize(); + return { + std::sqrt(std::max(0.f, new_x.x + new_y.y + new_z.z + 1.f)) / 2.f, + std::copysign(std::sqrt(std::max(0.f, new_x.x - new_y.y - new_z.z + 1.f)) / 2.f, new_y.z - new_z.y), + std::copysign(std::sqrt(std::max(0.f, -new_x.x + new_y.y - new_z.z + 1.f)) / 2.f, new_z.x - new_x.z), + std::copysign(std::sqrt(std::max(0.f, -new_x.x - new_y.y + new_z.z + 1.f)) / 2.f, new_x.y - new_y.x), + }; + } + float w, x, y, z; constexpr Quaternion() {} @@ -71,6 +89,14 @@ struct Quaternion { constexpr Quaternion conjugate() const & { return {w, -x, -y, -z}; } + + constexpr Vector3 rot(const Vector3& v) const & { + return { + (2.f * (w * w + x * x) - 1.f) * v.x + (2.f * (x * y - w * z) ) * v.y + (2.f * (x * z + w * y) ) * v.z, + (2.f * (x * y + w * z) ) * v.x + (2.f * (w * w + y * y) - 1.f) * v.y + (2.f * (y * z - w * x) ) * v.z, + (2.f * (x * z - w * y) ) * v.x + (2.f * (y * z + w * x) ) * v.y + (2.f * (w * w + z * z) - 1.f) * v.z, + }; + } }; } diff --git a/src/math/utils.hpp b/src/math/utils.hpp new file mode 100644 index 0000000..5ec5959 --- /dev/null +++ b/src/math/utils.hpp @@ -0,0 +1,24 @@ +#ifndef MATH_UTILS_HPP +#define MATH_UTILS_HPP + +#include +#include +#include "math/vector.hpp" + +namespace engine::math::utils { + +template struct Vector; +template<> struct Vector<2> { using type = engine::math::Vector2; }; +template<> struct Vector<3> { using type = engine::math::Vector3; }; +template<> struct Vector<4> { using type = engine::math::Vector4; }; + +template +constexpr Vector::type array_to_vec(const std::array& coords) { + return [&](std::index_sequence) constexpr -> Vector::type { + return { coords[i] ... }; + }(std::make_index_sequence()); +} + +} + +#endif // MATH_UTILS_HPP diff --git a/src/math/vector.hpp b/src/math/vector.hpp index e836e0d..471f30d 100644 --- a/src/math/vector.hpp +++ b/src/math/vector.hpp @@ -2,11 +2,20 @@ #define MATH_VECTOR_HPP #include -#include "math/quat.hpp" namespace engine::math { +struct Vector2; +constexpr Vector2 operator*(float n, const Vector2& other); +constexpr Vector2 operator/(const Vector2& other, float n); + struct Vector2 { + static constexpr size_t size = 2; + + static constexpr Vector2 bilerp(const Vector2& v1, const Vector2& v2, const Vector2& v3, float b0, float b1) { + return b0 * v1 + b1 * v2 + (1.f - b0 - b1) * v3; + } + float x, y; constexpr bool operator==(const Vector2& other) const & { @@ -77,6 +86,8 @@ constexpr Vector3 operator*(float n, const Vector3& other); constexpr Vector3 operator/(const Vector3& other, float n); struct Vector3 { + static constexpr size_t size = 3; + static constexpr Vector3 bilerp(const Vector3& v1, const Vector3& v2, const Vector3& v3, float b0, float b1) { return b0 * v1 + b1 * v2 + (1.f - b0 - b1) * v3; } @@ -126,14 +137,6 @@ struct Vector3 { }; } - constexpr Vector3 rot(const Quaternion& q) const & { - return { - (2.f * (q.w * q.w + q.x * q.x) - 1.f) * x + (2.f * (q.x * q.y - q.w * q.z) ) * y + (2.f * (q.x * q.z + q.w * q.y) ) * z, - (2.f * (q.x * q.y + q.w * q.z) ) * x + (2.f * (q.w * q.w + q.y * q.y) - 1.f) * y + (2.f * (q.y * q.z - q.w * q.x) ) * z, - (2.f * (q.x * q.z - q.w * q.y) ) * x + (2.f * (q.y * q.z + q.w * q.x) ) * y + (2.f * (q.w * q.w + q.z * q.z) - 1.f) * z, - }; - } - constexpr float dot(const Vector3& other) const & { return x * other.x + y * other.y + z * other.z; } @@ -168,15 +171,14 @@ constexpr Vector3 operator/(const Vector3& other, float n) { } struct Vector4 { + static constexpr size_t size = 4; + float x, y, z, w; constexpr Vector4() {} constexpr Vector4(float x, float y, float z, float w) : x{x}, y{y}, z{z}, w{w} {} - constexpr Vector4(float x, float y, float z) : x{x}, y{y}, z{z}, w{1.f} {} constexpr Vector4(const Vector2& v, float z, float w) : x{v.x}, y{v.y}, z{z}, w{w} {} - constexpr Vector4(const Vector2& v, float z) : x{v.x}, y{v.y}, z{z}, w{1.f} {} constexpr Vector4(const Vector3& v, float w) : x{v.x}, y{v.y}, z{v.z}, w{w} {} - constexpr Vector4(const Vector3& v) : x{v.x}, y{v.y}, z{v.z}, w{1.f} {} constexpr bool operator==(const Vector4& other) const & { return x == other.x && y == other.y && z == other.z && w == other.w; -- cgit v1.2.3