From 35ad6e7497711657e9bcd7fcd5fbc23bdd52e35f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 13 Aug 2022 11:07:07 +0000 Subject: [PATCH] Get camera working --- include/Orange/Graphics/Camera.h | 39 +++++++++++++++-------------- include/Orange/Math/Angle.h | 32 ++++++++++++++---------- include/Orange/Math/Matrix.h | 15 ++++++++---- include/Orange/Math/Quaternion.h | 33 ++++++++++++++++--------- include/Orange/Math/Swizzle.h | 7 ------ include/Orange/Math/Transform.h | 12 ++++----- include/Orange/Math/Unit.h | 42 ++++++++++++++++---------------- include/Orange/Math/Vector.h | 12 +++++++++ src/Apps/Tools/CubeTest.cpp | 12 +++++++-- 9 files changed, 118 insertions(+), 86 deletions(-) diff --git a/include/Orange/Graphics/Camera.h b/include/Orange/Graphics/Camera.h index 1816475..b5f4597 100644 --- a/include/Orange/Graphics/Camera.h +++ b/include/Orange/Graphics/Camera.h @@ -14,30 +14,30 @@ namespace orange struct Camera { - void lookAt(const vec3& position, const vec3& up = {0, 1, 0}) + void lookAt(const vec3& position, const vec3& up = {0.0f, 1.0f, 0.0f}) { transform.orientation = - conjugate(Math::lookAt(transform.position, position, up)); + conjugate(Math::lookAt(transform.position, position, up)); } void offsetOrientation(const Radian& yaw, const Radian& pitch) { - constexpr Quaternion yawRot{angleAxis(yaw, {0, 1, 0})}; - constexpr Quaternion pitchRot{angleAxis(pitch, right())}; + const quat yawRot = angleAxis(yaw, vec3{0.0f, 1.0f, 0.0f}); + const quat pitchRot = angleAxis(pitch, right()); transform.orientation = yawRot * pitchRot * transform.orientation; } - vec3 forward() const { return transform.orientation * Vector3{0, 0, -1}; } - vec3 backward() const { return transform.orientation * Vector3{0, 0, +1}; } + vec3 forward() const { return transform.orientation * vec3{0.0f, 0.0f, -1.0f}; } + vec3 backward() const { return transform.orientation * vec3{0.0f, 0.0f, +1.0f}; } - vec3 right() const { return transform.orientation * Vector3{+1, 0, 0}; } - vec3 left() const { return transform.orientation * Vector3{-1, 0, 0}; } + vec3 right() const { return transform.orientation * vec3{+1.0f, 0.0f, 0.0f}; } + vec3 left() const { return transform.orientation * vec3{-1.0f, 0.0f, 0.0f}; } - vec3 up() const { return transform.orientation * Vector3{0, +1, 0}; } - vec3 down() const { return transform.orientation * Vector3{0, -1, 0}; } + vec3 up() const { return transform.orientation * vec3{0.0f, +1.0f, 0.0f}; } + vec3 down() const { return transform.orientation * vec3{0.0f, -1.0f, 0.0f}; } - mat4 matrix() const { return getProjection() * getView(); } + mat4 matrix() const { return projection() * view(); } mat4 projection() const { if (projectionType == ProjectionType::Perspective) @@ -53,21 +53,20 @@ namespace orange else if (projectionType == ProjectionType::Orthographic) { const float distance = 0.5f * (farPlane - nearPlane); - return Math::ortho(-orthoScale * viewportAspectRatio, - orthoScale * viewportAspectRatio, - -orthoScale, - orthoScale, - -distance, - distance); + return Math::ortho( + -orthoScale * viewportAspectRatio, + orthoScale * viewportAspectRatio, + -orthoScale, orthoScale, + -distance, distance); } return mat4{}; } mat4 view() const { - return Math::scale(Vector3(1) / transform.scale) * - quaternionToMatrix4(conjugate(transform.orientation)) * - Math::translate(-transform.position); + return Math::scale(vec3{1.0f} / transform.scale) * + quaternionToMatrix4(conjugate(transform.orientation)) * + Math::translate(-transform.position); } diff --git a/include/Orange/Math/Angle.h b/include/Orange/Math/Angle.h index 5e56b30..5f46acb 100644 --- a/include/Orange/Math/Angle.h +++ b/include/Orange/Math/Angle.h @@ -14,25 +14,25 @@ namespace orange class Degree : public Unit { public: - Degree() {} + constexpr Degree() {} - explicit Degree(T value) + constexpr explicit Degree(T value) : Unit(value) { } - Degree(Unit value) + constexpr Degree(Unit value) : Unit(value) { } - template - explicit Degree(Unit value) + template + constexpr explicit Degree(Unit value) : Unit(value) { } - Degree(Unit value); + constexpr Degree(Unit value); }; template @@ -41,32 +41,32 @@ namespace orange public: Radian() {} - explicit Radian(T value) + constexpr explicit Radian(T value) : Unit(value) { } - Radian(Unit value) + constexpr Radian(Unit value) : Unit(value) { } - template - explicit Radian(Unit value) + template + constexpr explicit Radian(Unit value) : Unit(value) { } - Radian(Unit value); + constexpr Radian(Unit value); }; template - Degree::Degree(Unit value) + constexpr Degree::Degree(Unit value) : Unit(T(360) * T(value) / Math::Tau) { } template - Radian::Radian(Unit value) + constexpr Radian::Radian(Unit value) : Unit(T(value) * Math::Tau / T(360)) { } @@ -74,4 +74,10 @@ namespace orange using Radian = detail::Radian; using Degree = detail::Degree; + + constexpr Radian operator"" _rad(long double value) { return Radian{static_cast(value)}; } + constexpr Radian operator"" _rad(unsigned long long value) { return Radian{static_cast(value)}; } + + constexpr Degree operator"" _deg(long double value) { return Degree{static_cast(value)}; } + constexpr Degree operator"" _deg(unsigned long long value) { return Degree{static_cast(value)}; } } \ No newline at end of file diff --git a/include/Orange/Math/Matrix.h b/include/Orange/Math/Matrix.h index 9676301..f17d078 100644 --- a/include/Orange/Math/Matrix.h +++ b/include/Orange/Math/Matrix.h @@ -158,14 +158,19 @@ namespace orange } // Real matrix operations - + // TODO: Handle mixing-matching column counts constexpr Matrix operator*(const Matrix& other) const { - Matrix out; - for (size_t r = 0; r < Rows; r++) + const Matrix &us = *this; + + Matrix out{0.0f}; + for (size_t i = 0; i < Rows; i++) { - for (size_t c = 0; c < Columns; c++) - out[r][c] = (*this)[r][c] * other[c][r]; + for (size_t j = 0; j < Columns; j++) + { + for (size_t k = 0; k < Columns; k++) + out[i][j] += other[i][k] * us[k][j]; + } } return out; } diff --git a/include/Orange/Math/Quaternion.h b/include/Orange/Math/Quaternion.h index f93e4fe..22c2aec 100644 --- a/include/Orange/Math/Quaternion.h +++ b/include/Orange/Math/Quaternion.h @@ -10,7 +10,7 @@ namespace orange struct Quaternion : public Vec { constexpr Quaternion() - : Vec{ } { } + : Vec{ T{ 0 }, T{ 0 }, T{ 0 }, T{ 1 } } { } constexpr Quaternion(T x, T y, T z, T w) : Vec{ x, y, z, w } { } @@ -26,10 +26,10 @@ namespace orange const Quaternion& a = *this; return Quaternion { - a[3] * b[0] + a[0] * b[3] + a[1] * b[2] - a[2] * b[1], - a[3] * b[1] - a[0] * b[2] + a[1] * b[3] + a[2] * b[0], - a[3] * b[2] + a[0] * b[1] - a[1] * b[0] + a[2] * b[3], - a[3] * b[3] - a[0] * b[0] - a[1] * b[1] - a[2] * b[2] + a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y, + a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x, + a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w, + a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z }; } @@ -67,17 +67,26 @@ namespace orange constexpr Quaternion& operator/=(const Quaternion& other) = delete; - - constexpr Vec vector() const + // TODO: This sucks! Make this cleaner + // We should get a proper subclass thing + constexpr const Vec& vector() const { - const Quaternion& q = *this; - return Vec{ q[0], q[1], q[2] }; + return *reinterpret_cast*>(this); } - constexpr T scalar() const + constexpr Vec& vector() + { + return *reinterpret_cast*>(this); + } + + constexpr const T& scalar() const { - const Quaternion& q = *this; - return q[3]; + return (*this)[3]; + } + + constexpr T& scalar() + { + return (*this)[3]; } }; diff --git a/include/Orange/Math/Swizzle.h b/include/Orange/Math/Swizzle.h index 2664dfe..717ef76 100644 --- a/include/Orange/Math/Swizzle.h +++ b/include/Orange/Math/Swizzle.h @@ -54,13 +54,6 @@ namespace orange Copy(&components[0], &components[1], data.begin()); } - template - constexpr Swizzle(const Args&... args) - : data {{ args... }} - { - static_assert(sizeof...(Args) == 1); - } - constexpr Swizzle(const Swizzle& other) = default; }; diff --git a/include/Orange/Math/Transform.h b/include/Orange/Math/Transform.h index 505df04..82eb32b 100644 --- a/include/Orange/Math/Transform.h +++ b/include/Orange/Math/Transform.h @@ -36,7 +36,7 @@ namespace orange return Transform { - .position = (parentConjugate * (world.position - parent.position)) / parent.scale; + .position = (parentConjugate * (world.position - parent.position)) / parent.scale, .orientation = (parentConjugate * world.orientation), .scale = (parentConjugate * (world.scale / parent.scale)), }; @@ -69,16 +69,16 @@ namespace orange bool identity(const Transform& t) { return t.position == vec3{0.0f} && - t.orientation == Quaternion{} && - t.scale == vec3{1.0f}; + t.orientation == quat{} && + t.scale == vec3{1.0f}; } // TODO: - Matrix4 transformMatrix4(const Transform& t) + mat4 transformMatrix4(const Transform& t) { return Math::translate(t.position) * - quaternionToMatrix4(t.orientation) * - Math::scale(t.scale); + quaternionToMatrix4(t.orientation) * + Math::scale(t.scale); } } diff --git a/include/Orange/Math/Unit.h b/include/Orange/Math/Unit.h index 5beaa80..23f1a7a 100644 --- a/include/Orange/Math/Unit.h +++ b/include/Orange/Math/Unit.h @@ -12,99 +12,99 @@ namespace orange public: using Type = T; - Unit() + constexpr Unit() : m_value{T{0}} { } - explicit Unit(T value) + constexpr explicit Unit(T value) : m_value{value} { } template - explicit Unit(Unit value) + constexpr explicit Unit(Unit value) : m_value{T{value.m_value}} { } - explicit operator T() const { return m_value; } + constexpr explicit operator T() const { return m_value; } - bool operator==(Unit other) const + constexpr bool operator==(Unit other) const { return m_value == other.m_value; } - bool operator!=(Unit other) const { return !operator==(other); } + constexpr bool operator!=(Unit other) const { return !operator==(other); } - bool operator<(Unit other) const + constexpr bool operator<(Unit other) const { return m_value < other.m_value; } - bool operator>(Unit other) const + constexpr bool operator>(Unit other) const { return m_value > other.m_value; } - bool operator<=(Unit other) const { return !operator>(other); } + constexpr bool operator<=(Unit other) const { return !operator>(other); } - bool operator>=(Unit other) const { return !operator<(other); } + constexpr bool operator>=(Unit other) const { return !operator<(other); } - Unit operator-() const { return Unit{-m_value}; } + constexpr Unit operator-() const { return Unit{-m_value}; } - Unit& operator+=(Unit other) + constexpr Unit& operator+=(Unit other) { m_value += other.m_value; return *this; } - Unit operator+(Unit other) const + constexpr Unit operator+(Unit other) const { return Unit{m_value + other.m_value}; } - Unit& operator-=(Unit other) + constexpr Unit& operator-=(Unit other) { m_value -= other.m_value; return *this; } - Unit operator-(Unit other) const + constexpr Unit operator-(Unit other) const { return Unit{m_value - other.m_value}; } - Unit& operator*=(T number) + constexpr Unit& operator*=(T number) { m_value *= number; return *this; } - Unit operator*(T number) const + constexpr Unit operator*(T number) const { return Unit{m_value * number}; } - Unit& operator/=(T number) + constexpr Unit& operator/=(T number) { m_value /= number; return *this; } - Unit operator/(T number) const + constexpr Unit operator/(T number) const { return Unit{m_value / number}; } - T operator/(Unit other) const { return m_value / other.value; } + constexpr T operator/(Unit other) const { return m_value / other.value; } private: T m_value; }; template