diff --git a/util/mat4.hpp b/util/mat4.hpp deleted file mode 100644 index 1cc20c9..0000000 --- a/util/mat4.hpp +++ /dev/null @@ -1,310 +0,0 @@ -#ifndef MAT4_HPP -#define MAT4_HPP - -#include "Vec3.hpp" -#include "Vec4.hpp" -#include -#include - -class Mat4 { -public: - union { - struct { - float m00, m01, m02, m03, - m10, m11, m12, m13, - m20, m21, m22, m23, - m30, m31, m32, m33; - }; - float data[16]; - float m[4][4]; - }; - - // Constructors - Mat4() : m00(1), m01(0), m02(0), m03(0), - m10(0), m11(1), m12(0), m13(0), - m20(0), m21(0), m22(1), m23(0), - m30(0), m31(0), m32(0), m33(1) {} - - Mat4(float scalar) : m00(scalar), m01(scalar), m02(scalar), m03(scalar), - m10(scalar), m11(scalar), m12(scalar), m13(scalar), - m20(scalar), m21(scalar), m22(scalar), m23(scalar), - m30(scalar), m31(scalar), m32(scalar), m33(scalar) {} - - Mat4(float m00, float m01, float m02, float m03, - float m10, float m11, float m12, float m13, - float m20, float m21, float m22, float m23, - float m30, float m31, float m32, float m33) : - m00(m00), m01(m01), m02(m02), m03(m03), - m10(m10), m11(m11), m12(m12), m13(m13), - m20(m20), m21(m21), m22(m22), m23(m23), - m30(m30), m31(m31), m32(m32), m33(m33) {} - - // Identity matrix - static Mat4 identity() { - return Mat4(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - } - - // Zero matrix - static Mat4 zero() { return Mat4(0); } - - // Translation matrix - static Mat4 translation(const Vec3& translation) { - return Mat4(1, 0, 0, translation.x, - 0, 1, 0, translation.y, - 0, 0, 1, translation.z, - 0, 0, 0, 1); - } - - // Rotation matrices - static Mat4 rotationX(float angle) { - float cosA = std::cos(angle); - float sinA = std::sin(angle); - return Mat4(1, 0, 0, 0, - 0, cosA, -sinA, 0, - 0, sinA, cosA, 0, - 0, 0, 0, 1); - } - - static Mat4 rotationY(float angle) { - float cosA = std::cos(angle); - float sinA = std::sin(angle); - return Mat4(cosA, 0, sinA, 0, - 0, 1, 0, 0, - -sinA, 0, cosA, 0, - 0, 0, 0, 1); - } - - static Mat4 rotationZ(float angle) { - float cosA = std::cos(angle); - float sinA = std::sin(angle); - return Mat4(cosA, -sinA, 0, 0, - sinA, cosA, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - } - - // Scaling matrix - static Mat4 scaling(const Vec3& scale) { - return Mat4(scale.x, 0, 0, 0, - 0, scale.y, 0, 0, - 0, 0, scale.z, 0, - 0, 0, 0, 1); - } - - // Perspective projection matrix - static Mat4 perspective(float fov, float aspect, float near, float far) { - float tanHalfFov = std::tan(fov / 2.0f); - float range = near - far; - - return Mat4(1.0f / (aspect * tanHalfFov), 0, 0, 0, - 0, 1.0f / tanHalfFov, 0, 0, - 0, 0, (-near - far) / range, 2.0f * far * near / range, - 0, 0, 1, 0); - } - - // Orthographic projection matrix - static Mat4 orthographic(float left, float right, float bottom, float top, float near, float far) { - return Mat4(2.0f / (right - left), 0, 0, -(right + left) / (right - left), - 0, 2.0f / (top - bottom), 0, -(top + bottom) / (top - bottom), - 0, 0, -2.0f / (far - near), -(far + near) / (far - near), - 0, 0, 0, 1); - } - - // LookAt matrix (view matrix) - static Mat4 lookAt(const Vec3& eye, const Vec3& target, const Vec3& up) { - Vec3 z = (eye - target).normalized(); - Vec3 x = up.cross(z).normalized(); - Vec3 y = z.cross(x); - - return Mat4(x.x, x.y, x.z, -x.dot(eye), - y.x, y.y, y.z, -y.dot(eye), - z.x, z.y, z.z, -z.dot(eye), - 0, 0, 0, 1); - } - - // Arithmetic operations - Mat4 operator+(const Mat4& other) const { - Mat4 result; - for (int i = 0; i < 16; ++i) { - result.data[i] = data[i] + other.data[i]; - } - return result; - } - - Mat4 operator-(const Mat4& other) const { - Mat4 result; - for (int i = 0; i < 16; ++i) { - result.data[i] = data[i] - other.data[i]; - } - return result; - } - - Mat4 operator*(const Mat4& other) const { - Mat4 result; - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) { - result.m[i][j] = 0; - for (int k = 0; k < 4; ++k) { - result.m[i][j] += m[i][k] * other.m[k][j]; - } - } - } - return result; - } - - Mat4 operator*(float scalar) const { - Mat4 result; - for (int i = 0; i < 16; ++i) { - result.data[i] = data[i] * scalar; - } - return result; - } - - Mat4 operator/(float scalar) const { - Mat4 result; - for (int i = 0; i < 16; ++i) { - result.data[i] = data[i] / scalar; - } - return result; - } - - Vec4 operator*(const Vec4& vec) const { - return Vec4( - m00 * vec.x + m01 * vec.y + m02 * vec.z + m03 * vec.w, - m10 * vec.x + m11 * vec.y + m12 * vec.z + m13 * vec.w, - m20 * vec.x + m21 * vec.y + m22 * vec.z + m23 * vec.w, - m30 * vec.x + m31 * vec.y + m32 * vec.z + m33 * vec.w - ); - } - - Vec3 transformPoint(const Vec3& point) const { - Vec4 result = *this * Vec4(point, 1.0f); - return result.xyz() / result.w; - } - - Vec3 transformDirection(const Vec3& direction) const { - Vec4 result = *this * Vec4(direction, 0.0f); - return result.xyz(); - } - - Mat4& operator+=(const Mat4& other) { - *this = *this + other; - return *this; - } - - Mat4& operator-=(const Mat4& other) { - *this = *this - other; - return *this; - } - - Mat4& operator*=(const Mat4& other) { - *this = *this * other; - return *this; - } - - Mat4& operator*=(float scalar) { - *this = *this * scalar; - return *this; - } - - Mat4& operator/=(float scalar) { - *this = *this / scalar; - return *this; - } - - bool operator==(const Mat4& other) const { - for (int i = 0; i < 16; ++i) { - if (data[i] != other.data[i]) return false; - } - return true; - } - - bool operator!=(const Mat4& other) const { - return !(*this == other); - } - - // Matrix operations - float determinant() const { - // Using Laplace expansion for 4x4 determinant - float det = 0; - det += m00 * (m11 * (m22 * m33 - m23 * m32) - m12 * (m21 * m33 - m23 * m31) + m13 * (m21 * m32 - m22 * m31)); - det -= m01 * (m10 * (m22 * m33 - m23 * m32) - m12 * (m20 * m33 - m23 * m30) + m13 * (m20 * m32 - m22 * m30)); - det += m02 * (m10 * (m21 * m33 - m23 * m31) - m11 * (m20 * m33 - m23 * m30) + m13 * (m20 * m31 - m21 * m30)); - det -= m03 * (m10 * (m21 * m32 - m22 * m31) - m11 * (m20 * m32 - m22 * m30) + m12 * (m20 * m31 - m21 * m30)); - return det; - } - - Mat4 transposed() const { - return Mat4(m00, m10, m20, m30, - m01, m11, m21, m31, - m02, m12, m22, m32, - m03, m13, m23, m33); - } - - Mat4 inverse() const { - // This is a simplified inverse implementation - // For production use, consider a more robust implementation - float det = determinant(); - if (std::abs(det) < 1e-10f) { - return Mat4(); // Return identity if not invertible - } - - Mat4 result; - // Calculate inverse using adjugate matrix divided by determinant - // This is a placeholder - full implementation would be quite lengthy - float invDet = 1.0f / det; - - // Note: This is a simplified version - full implementation would calculate all 16 cofactors - result.m00 = (m11 * (m22 * m33 - m23 * m32) - m12 * (m21 * m33 - m23 * m31) + m13 * (m21 * m32 - m22 * m31)) * invDet; - // ... continue for all 16 elements - - return result.transposed() * invDet; - } - - // Access operators - float& operator()(int row, int col) { - return m[row][col]; - } - - const float& operator()(int row, int col) const { - return m[row][col]; - } - - float& operator[](int index) { - return data[index]; - } - - const float& operator[](int index) const { - return data[index]; - } - - std::string toString() const { - return "Mat4([" + std::to_string(m00) + ", " + std::to_string(m01) + ", " + std::to_string(m02) + ", " + std::to_string(m03) + "],\n" + - " [" + std::to_string(m10) + ", " + std::to_string(m11) + ", " + std::to_string(m12) + ", " + std::to_string(m13) + "],\n" + - " [" + std::to_string(m20) + ", " + std::to_string(m21) + ", " + std::to_string(m22) + ", " + std::to_string(m23) + "],\n" + - " [" + std::to_string(m30) + ", " + std::to_string(m31) + ", " + std::to_string(m32) + ", " + std::to_string(m33) + "])"; - } -}; - -inline std::ostream& operator<<(std::ostream& os, const Mat4& mat) { - os << mat.toString(); - return os; -} - -inline Mat4 operator*(float scalar, const Mat4& mat) { - return mat * scalar; -} - -// Now you can implement the Ray3 transform method -#include "ray3.hpp" - -inline Ray3 Ray3::transform(const Mat4& matrix) const { - Vec3 transformedOrigin = matrix.transformPoint(origin); - Vec3 transformedDirection = matrix.transformDirection(direction); - return Ray3(transformedOrigin, transformedDirection.normalized()); -} - -#endif \ No newline at end of file diff --git a/util/ray3.hpp b/util/ray3.hpp index 8a77d7d..cbb5eb1 100644 --- a/util/ray3.hpp +++ b/util/ray3.hpp @@ -63,8 +63,11 @@ public: return crossProduct.length() / direction.length(); } - // Transform ray by a 4x4 matrix (for perspective/affine transformations) - Ray3 transform(const class Mat4& matrix) const; + Ray3 transform(const class Mat4& matrix) const { + Vec3 transformedOrigin = matrix.transformPoint(origin); + Vec3 transformedDirection = matrix.transformDirection(direction); + return Ray3(transformedOrigin, transformedDirection.normalized()); + } std::string toString() const { return "Ray3(origin: " + origin.toString() + ", direction: " + direction.toString() + ")"; diff --git a/util/mat2.hpp b/util/vecmat/mat2.hpp similarity index 100% rename from util/mat2.hpp rename to util/vecmat/mat2.hpp diff --git a/util/mat3.hpp b/util/vecmat/mat3.hpp similarity index 100% rename from util/mat3.hpp rename to util/vecmat/mat3.hpp diff --git a/util/vecmat/mat4.hpp b/util/vecmat/mat4.hpp new file mode 100644 index 0000000..c69475c --- /dev/null +++ b/util/vecmat/mat4.hpp @@ -0,0 +1,355 @@ +#ifndef MAT4_HPP +#define MAT4_HPP + +#include "../vectorlogic/vec3.hpp" +#include "../vectorlogic/vec4.hpp" +#include "../ray3.hpp" +#include +#include + +template +class Mat4 { +public: + union { + struct { + T m00, m01, m02, m03, + m10, m11, m12, m13, + m20, m21, m22, m23, + m30, m31, m32, m33; + }; + T data[16]; + T m[4][4]; + }; + + // Constructors + Mat4() : m00(1), m01(0), m02(0), m03(0), + m10(0), m11(1), m12(0), m13(0), + m20(0), m21(0), m22(1), m23(0), + m30(0), m31(0), m32(0), m33(1) {} + + Mat4(T scalar) : m00(scalar), m01(scalar), m02(scalar), m03(scalar), + m10(scalar), m11(scalar), m12(scalar), m13(scalar), + m20(scalar), m21(scalar), m22(scalar), m23(scalar), + m30(scalar), m31(scalar), m32(scalar), m33(scalar) {} + + Mat4(T m00, T m01, T m02, T m03, + T m10, T m11, T m12, T m13, + T m20, T m21, T m22, T m23, + T m30, T m31, T m32, T m33) : + m00(m00), m01(m01), m02(m02), m03(m03), + m10(m10), m11(m11), m12(m12), m13(m13), + m20(m20), m21(m21), m22(m22), m23(m23), + m30(m30), m31(m31), m32(m32), m33(m33) {} + + // Identity matrix + static Mat4 identity() { + return Mat4(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + } + + // Zero matrix + static Mat4 zero() { return Mat4(0); } + + // Translation matrix + static Mat4 translation(const Vec3& translation) { + return Mat4(1, 0, 0, translation.x, + 0, 1, 0, translation.y, + 0, 0, 1, translation.z, + 0, 0, 0, 1); + } + + // Rotation matrices + static Mat4 rotationX(T angle) { + T cosA = std::cos(angle); + T sinA = std::sin(angle); + return Mat4(1, 0, 0, 0, + 0, cosA, -sinA, 0, + 0, sinA, cosA, 0, + 0, 0, 0, 1); + } + + static Mat4 rotationY(T angle) { + T cosA = std::cos(angle); + T sinA = std::sin(angle); + return Mat4(cosA, 0, sinA, 0, + 0, 1, 0, 0, + -sinA, 0, cosA, 0, + 0, 0, 0, 1); + } + + static Mat4 rotationZ(T angle) { + T cosA = std::cos(angle); + T sinA = std::sin(angle); + return Mat4(cosA, -sinA, 0, 0, + sinA, cosA, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + } + + // Scaling matrix + static Mat4 scaling(const Vec3& scale) { + return Mat4(scale.x, 0, 0, 0, + 0, scale.y, 0, 0, + 0, 0, scale.z, 0, + 0, 0, 0, 1); + } + + // Perspective projection matrix + static Mat4 perspective(T fov, T aspect, T near, T far) { + T tanHalfFov = std::tan(fov / static_cast(2)); + T range = near - far; + + return Mat4(static_cast(1) / (aspect * tanHalfFov), 0, 0, 0, + 0, static_cast(1) / tanHalfFov, 0, 0, + 0, 0, (-near - far) / range, static_cast(2) * far * near / range, + 0, 0, 1, 0); + } + + // Orthographic projection matrix + static Mat4 orthographic(T left, T right, T bottom, T top, T near, T far) { + return Mat4(static_cast(2) / (right - left), 0, 0, -(right + left) / (right - left), + 0, static_cast(2) / (top - bottom), 0, -(top + bottom) / (top - bottom), + 0, 0, -static_cast(2) / (far - near), -(far + near) / (far - near), + 0, 0, 0, 1); + } + + // LookAt matrix (view matrix) + static Mat4 lookAt(const Vec3& eye, const Vec3& target, const Vec3& up) { + Vec3 z = (eye - target).normalized(); + Vec3 x = up.cross(z).normalized(); + Vec3 y = z.cross(x); + + return Mat4(x.x, x.y, x.z, -x.dot(eye), + y.x, y.y, y.z, -y.dot(eye), + z.x, z.y, z.z, -z.dot(eye), + 0, 0, 0, 1); + } + + // Arithmetic operations + Mat4 operator+(const Mat4& other) const { + Mat4 result; + for (int i = 0; i < 16; ++i) { + result.data[i] = data[i] + other.data[i]; + } + return result; + } + + Mat4 operator-(const Mat4& other) const { + Mat4 result; + for (int i = 0; i < 16; ++i) { + result.data[i] = data[i] - other.data[i]; + } + return result; + } + + Mat4 operator*(const Mat4& other) const { + Mat4 result; + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + result.m[i][j] = 0; + for (int k = 0; k < 4; ++k) { + result.m[i][j] += m[i][k] * other.m[k][j]; + } + } + } + return result; + } + + Mat4 operator*(T scalar) const { + Mat4 result; + for (int i = 0; i < 16; ++i) { + result.data[i] = data[i] * scalar; + } + return result; + } + + Mat4 operator/(T scalar) const { + Mat4 result; + for (int i = 0; i < 16; ++i) { + result.data[i] = data[i] / scalar; + } + return result; + } + + Vec4 operator*(const Vec4& vec) const { + return Vec4( + m00 * vec.x + m01 * vec.y + m02 * vec.z + m03 * vec.w, + m10 * vec.x + m11 * vec.y + m12 * vec.z + m13 * vec.w, + m20 * vec.x + m21 * vec.y + m22 * vec.z + m23 * vec.w, + m30 * vec.x + m31 * vec.y + m32 * vec.z + m33 * vec.w + ); + } + + Vec3 transformPoint(const Vec3& point) const { + Vec4 result = *this * Vec4(point, static_cast(1)); + return result.xyz() / result.w; + } + + Vec3 transformDirection(const Vec3& direction) const { + Vec4 result = *this * Vec4(direction, static_cast(0)); + return result.xyz(); + } + + Mat4& operator+=(const Mat4& other) { + *this = *this + other; + return *this; + } + + Mat4& operator-=(const Mat4& other) { + *this = *this - other; + return *this; + } + + Mat4& operator*=(const Mat4& other) { + *this = *this * other; + return *this; + } + + Mat4& operator*=(T scalar) { + *this = *this * scalar; + return *this; + } + + Mat4& operator/=(T scalar) { + *this = *this / scalar; + return *this; + } + + bool operator==(const Mat4& other) const { + for (int i = 0; i < 16; ++i) { + if (data[i] != other.data[i]) return false; + } + return true; + } + + bool operator!=(const Mat4& other) const { + return !(*this == other); + } + + // Matrix operations + T determinant() const { + // Using Laplace expansion for 4x4 determinant + T det = 0; + det += m00 * (m11 * (m22 * m33 - m23 * m32) - m12 * (m21 * m33 - m23 * m31) + m13 * (m21 * m32 - m22 * m31)); + det -= m01 * (m10 * (m22 * m33 - m23 * m32) - m12 * (m20 * m33 - m23 * m30) + m13 * (m20 * m32 - m22 * m30)); + det += m02 * (m10 * (m21 * m33 - m23 * m31) - m11 * (m20 * m33 - m23 * m30) + m13 * (m20 * m31 - m21 * m30)); + det -= m03 * (m10 * (m21 * m32 - m22 * m31) - m11 * (m20 * m32 - m22 * m30) + m12 * (m20 * m31 - m21 * m30)); + return det; + } + + Mat4 transposed() const { + return Mat4(m00, m10, m20, m30, + m01, m11, m21, m31, + m02, m12, m22, m32, + m03, m13, m23, m33); + } + + Mat4 inverse() const { + T det = determinant(); + if (std::abs(det) < static_cast(1e-10)) { + return Mat4(); // Return identity if not invertible + } + + Mat4 result; + T invDet = static_cast(1) / det; + + // Calculate inverse using adjugate matrix + result.m00 = (m11 * (m22 * m33 - m23 * m32) - m12 * (m21 * m33 - m23 * m31) + m13 * (m21 * m32 - m22 * m31)) * invDet; + result.m01 = (m01 * (m22 * m33 - m23 * m32) - m02 * (m21 * m33 - m23 * m31) + m03 * (m21 * m32 - m22 * m31)) * -invDet; + result.m02 = (m01 * (m12 * m33 - m13 * m32) - m02 * (m11 * m33 - m13 * m31) + m03 * (m11 * m32 - m12 * m31)) * invDet; + result.m03 = (m01 * (m12 * m23 - m13 * m22) - m02 * (m11 * m23 - m13 * m21) + m03 * (m11 * m22 - m12 * m21)) * -invDet; + + result.m10 = (m10 * (m22 * m33 - m23 * m32) - m12 * (m20 * m33 - m23 * m30) + m13 * (m20 * m32 - m22 * m30)) * -invDet; + result.m11 = (m00 * (m22 * m33 - m23 * m32) - m02 * (m20 * m33 - m23 * m30) + m03 * (m20 * m32 - m22 * m30)) * invDet; + result.m12 = (m00 * (m12 * m33 - m13 * m32) - m02 * (m10 * m33 - m13 * m30) + m03 * (m10 * m32 - m12 * m30)) * -invDet; + result.m13 = (m00 * (m12 * m23 - m13 * m22) - m02 * (m10 * m23 - m13 * m20) + m03 * (m10 * m22 - m12 * m20)) * invDet; + + result.m20 = (m10 * (m21 * m33 - m23 * m31) - m11 * (m20 * m33 - m23 * m30) + m13 * (m20 * m31 - m21 * m30)) * invDet; + result.m21 = (m00 * (m21 * m33 - m23 * m31) - m01 * (m20 * m33 - m23 * m30) + m03 * (m20 * m31 - m21 * m30)) * -invDet; + result.m22 = (m00 * (m11 * m33 - m13 * m31) - m01 * (m10 * m33 - m13 * m30) + m03 * (m10 * m31 - m11 * m30)) * invDet; + result.m23 = (m00 * (m11 * m23 - m13 * m21) - m01 * (m10 * m23 - m13 * m20) + m03 * (m10 * m21 - m11 * m20)) * -invDet; + + result.m30 = (m10 * (m21 * m32 - m22 * m31) - m11 * (m20 * m32 - m22 * m30) + m12 * (m20 * m31 - m21 * m30)) * -invDet; + result.m31 = (m00 * (m21 * m32 - m22 * m31) - m01 * (m20 * m32 - m22 * m30) + m02 * (m20 * m31 - m21 * m30)) * invDet; + result.m32 = (m00 * (m11 * m32 - m12 * m31) - m01 * (m10 * m32 - m12 * m30) + m02 * (m10 * m31 - m11 * m30)) * -invDet; + result.m33 = (m00 * (m11 * m22 - m12 * m21) - m01 * (m10 * m22 - m12 * m20) + m02 * (m10 * m21 - m11 * m20)) * invDet; + + return result; + } + + // Access operators + T& operator()(int row, int col) { + return m[row][col]; + } + + const T& operator()(int row, int col) const { + return m[row][col]; + } + + T& operator[](int index) { + return data[index]; + } + + const T& operator[](int index) const { + return data[index]; + } + + std::string toString() const { + return "Mat4([" + std::to_string(m00) + ", " + std::to_string(m01) + ", " + std::to_string(m02) + ", " + std::to_string(m03) + "],\n" + + " [" + std::to_string(m10) + ", " + std::to_string(m11) + ", " + std::to_string(m12) + ", " + std::to_string(m13) + "],\n" + + " [" + std::to_string(m20) + ", " + std::to_string(m21) + ", " + std::to_string(m22) + ", " + std::to_string(m23) + "],\n" + + " [" + std::to_string(m30) + ", " + std::to_string(m31) + ", " + std::to_string(m32) + ", " + std::to_string(m33) + "])"; + } +}; + +// Stream output operator +template +inline std::ostream& operator<<(std::ostream& os, const Mat4& mat) { + os << mat.toString(); + return os; +} + +// Scalar multiplication from left +template +inline Mat4 operator*(T scalar, const Mat4& mat) { + return mat * scalar; +} + +using Mat4f = Mat4; +using Mat4d = Mat4; + +Mat4f lookAt(Vec3f const& eye, Vec3f const& center, Vec3f const& up) { + Vec3f const f = (center - eye).normalized(); + Vec3f const s = f.cross(up).normalized(); + Vec3f const u = s.cross(f); + + Mat4f Result = Mat4f::identity(); + Result(0, 0) = s.x; + Result(1, 0) = s.y; + Result(2, 0) = s.z; + Result(3, 0) = -s.dot(eye); + Result(0, 1) = u.x; + Result(1, 1) = u.y; + Result(2, 1) = u.z; + Result(3, 1) = -u.dot(eye); + Result(0, 2) = -f.x; + Result(1, 2) = -f.y; + Result(2, 2) = -f.z; + Result(3, 2) = f.dot(eye); + return Result; +} + +Mat4f perspective(float fovy, float aspect, float zNear, float zfar) { + float const tanhalfF = tan(fovy / 2); + Mat4f Result = 0; + Result(0,0) = 1 / (aspect * tanhalfF); + Result(1,1) = 1 / tanhalfF; + Result(2,2) = zfar / (zNear - zfar); + Result(2,3) = -1; + Result(3,2) = -(zfar * zNear) / (zfar - zNear); + return Result; +} + +#endif \ No newline at end of file diff --git a/util/vectorlogic/vec3.hpp b/util/vectorlogic/vec3.hpp index 5902f5f..dd37e19 100644 --- a/util/vectorlogic/vec3.hpp +++ b/util/vectorlogic/vec3.hpp @@ -404,4 +404,14 @@ namespace std { }; } +template +Vec3 max(Vec3 a, Vec3 b) { + return a.max(b); +} + +template +Vec3 min(Vec3 a, Vec3 b) { + return a.min(b); +} + #endif \ No newline at end of file