Get camera working

This commit is contained in:
Joshua Ashton 2022-08-13 11:07:07 +00:00
parent 4ca37f3d5c
commit 35ad6e7497
9 changed files with 118 additions and 86 deletions

View File

@ -14,30 +14,30 @@ namespace orange
struct Camera 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 = transform.orientation =
conjugate(Math::lookAt<Quaternion>(transform.position, position, up)); conjugate(Math::lookAt<quat>(transform.position, position, up));
} }
void offsetOrientation(const Radian& yaw, const Radian& pitch) void offsetOrientation(const Radian& yaw, const Radian& pitch)
{ {
constexpr Quaternion yawRot{angleAxis(yaw, {0, 1, 0})}; const quat yawRot = angleAxis(yaw, vec3{0.0f, 1.0f, 0.0f});
constexpr Quaternion pitchRot{angleAxis(pitch, right())}; const quat pitchRot = angleAxis(pitch, right());
transform.orientation = yawRot * pitchRot * transform.orientation; transform.orientation = yawRot * pitchRot * transform.orientation;
} }
vec3 forward() 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 * Vector3{0, 0, +1}; } vec3 backward() const { return transform.orientation * vec3{0.0f, 0.0f, +1.0f}; }
vec3 right() 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 * Vector3{-1, 0, 0}; } vec3 left() const { return transform.orientation * vec3{-1.0f, 0.0f, 0.0f}; }
vec3 up() 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 * Vector3{0, -1, 0}; } 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 mat4 projection() const
{ {
if (projectionType == ProjectionType::Perspective) if (projectionType == ProjectionType::Perspective)
@ -53,21 +53,20 @@ namespace orange
else if (projectionType == ProjectionType::Orthographic) else if (projectionType == ProjectionType::Orthographic)
{ {
const float distance = 0.5f * (farPlane - nearPlane); const float distance = 0.5f * (farPlane - nearPlane);
return Math::ortho(-orthoScale * viewportAspectRatio, return Math::ortho(
orthoScale * viewportAspectRatio, -orthoScale * viewportAspectRatio,
-orthoScale, orthoScale * viewportAspectRatio,
orthoScale, -orthoScale, orthoScale,
-distance, -distance, distance);
distance);
} }
return mat4{}; return mat4{};
} }
mat4 view() const mat4 view() const
{ {
return Math::scale(Vector3(1) / transform.scale) * return Math::scale(vec3{1.0f} / transform.scale) *
quaternionToMatrix4(conjugate(transform.orientation)) * quaternionToMatrix4(conjugate(transform.orientation)) *
Math::translate(-transform.position); Math::translate(-transform.position);
} }

View File

@ -14,25 +14,25 @@ namespace orange
class Degree : public Unit<Degree, T> class Degree : public Unit<Degree, T>
{ {
public: public:
Degree() {} constexpr Degree() {}
explicit Degree(T value) constexpr explicit Degree(T value)
: Unit<orange::detail::Degree, T>(value) : Unit<orange::detail::Degree, T>(value)
{ {
} }
Degree(Unit<orange::detail::Degree, T> value) constexpr Degree(Unit<orange::detail::Degree, T> value)
: Unit<orange::detail::Degree, T>(value) : Unit<orange::detail::Degree, T>(value)
{ {
} }
template <class U> template <typename U>
explicit Degree(Unit<orange::detail::Degree, U> value) constexpr explicit Degree(Unit<orange::detail::Degree, U> value)
: Unit<orange::detail::Degree, T>(value) : Unit<orange::detail::Degree, T>(value)
{ {
} }
Degree(Unit<Radian, T> value); constexpr Degree(Unit<Radian, T> value);
}; };
template <typename T> template <typename T>
@ -41,32 +41,32 @@ namespace orange
public: public:
Radian() {} Radian() {}
explicit Radian(T value) constexpr explicit Radian(T value)
: Unit<orange::detail::Radian, T>(value) : Unit<orange::detail::Radian, T>(value)
{ {
} }
Radian(Unit<orange::detail::Radian, T> value) constexpr Radian(Unit<orange::detail::Radian, T> value)
: Unit<orange::detail::Radian, T>(value) : Unit<orange::detail::Radian, T>(value)
{ {
} }
template <class U> template <typename U>
explicit Radian(Unit<orange::detail::Radian, U> value) constexpr explicit Radian(Unit<orange::detail::Radian, U> value)
: Unit<orange::detail::Radian, T>(value) : Unit<orange::detail::Radian, T>(value)
{ {
} }
Radian(Unit<Degree, T> value); constexpr Radian(Unit<Degree, T> value);
}; };
template <typename T> template <typename T>
Degree<T>::Degree(Unit<Radian, T> value) constexpr Degree<T>::Degree(Unit<Radian, T> value)
: Unit<orange::detail::Degree, T>(T(360) * T(value) / Math::Tau) : Unit<orange::detail::Degree, T>(T(360) * T(value) / Math::Tau)
{ {
} }
template <typename T> template <typename T>
Radian<T>::Radian(Unit<Degree, T> value) constexpr Radian<T>::Radian(Unit<Degree, T> value)
: Unit<orange::detail::Radian, T>(T(value) * Math::Tau / T(360)) : Unit<orange::detail::Radian, T>(T(value) * Math::Tau / T(360))
{ {
} }
@ -74,4 +74,10 @@ namespace orange
using Radian = detail::Radian<float>; using Radian = detail::Radian<float>;
using Degree = detail::Degree<float>; using Degree = detail::Degree<float>;
constexpr Radian operator"" _rad(long double value) { return Radian{static_cast<float>(value)}; }
constexpr Radian operator"" _rad(unsigned long long value) { return Radian{static_cast<float>(value)}; }
constexpr Degree operator"" _deg(long double value) { return Degree{static_cast<float>(value)}; }
constexpr Degree operator"" _deg(unsigned long long value) { return Degree{static_cast<float>(value)}; }
} }

View File

@ -158,14 +158,19 @@ namespace orange
} }
// Real matrix operations // Real matrix operations
// TODO: Handle mixing-matching column counts
constexpr Matrix operator*(const Matrix& other) const constexpr Matrix operator*(const Matrix& other) const
{ {
Matrix out; const Matrix &us = *this;
for (size_t r = 0; r < Rows; r++)
Matrix out{0.0f};
for (size_t i = 0; i < Rows; i++)
{ {
for (size_t c = 0; c < Columns; c++) for (size_t j = 0; j < Columns; j++)
out[r][c] = (*this)[r][c] * other[c][r]; {
for (size_t k = 0; k < Columns; k++)
out[i][j] += other[i][k] * us[k][j];
}
} }
return out; return out;
} }

View File

@ -10,7 +10,7 @@ namespace orange
struct Quaternion : public Vec<T, 4> struct Quaternion : public Vec<T, 4>
{ {
constexpr Quaternion() constexpr Quaternion()
: Vec<T, 4>{ } { } : Vec<T, 4>{ T{ 0 }, T{ 0 }, T{ 0 }, T{ 1 } } { }
constexpr Quaternion(T x, T y, T z, T w) constexpr Quaternion(T x, T y, T z, T w)
: Vec<T, 4>{ x, y, z, w } { } : Vec<T, 4>{ x, y, z, w } { }
@ -26,10 +26,10 @@ namespace orange
const Quaternion<T>& a = *this; const Quaternion<T>& a = *this;
return Quaternion<T> return Quaternion<T>
{ {
a[3] * b[0] + a[0] * b[3] + a[1] * b[2] - a[2] * b[1], a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
a[3] * b[1] - a[0] * b[2] + a[1] * b[3] + a[2] * b[0], a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,
a[3] * b[2] + a[0] * b[1] - a[1] * b[0] + a[2] * b[3], a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w,
a[3] * b[3] - a[0] * b[0] - a[1] * b[1] - a[2] * b[2] a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z
}; };
} }
@ -67,17 +67,26 @@ namespace orange
constexpr Quaternion<T>& operator/=(const Quaternion<T>& other) = delete; constexpr Quaternion<T>& operator/=(const Quaternion<T>& other) = delete;
// TODO: This sucks! Make this cleaner
constexpr Vec<T, 3> vector() const // We should get a proper subclass thing
constexpr const Vec<T, 3>& vector() const
{ {
const Quaternion<T>& q = *this; return *reinterpret_cast<const Vec<T, 3>*>(this);
return Vec<T, 3>{ q[0], q[1], q[2] };
} }
constexpr T scalar() const constexpr Vec<T, 3>& vector()
{
return *reinterpret_cast<Vec<T, 3>*>(this);
}
constexpr const T& scalar() const
{ {
const Quaternion<T>& q = *this; return (*this)[3];
return q[3]; }
constexpr T& scalar()
{
return (*this)[3];
} }
}; };

View File

@ -54,13 +54,6 @@ namespace orange
Copy(&components[0], &components[1], data.begin()); Copy(&components[0], &components[1], data.begin());
} }
template <typename... Args>
constexpr Swizzle(const Args&... args)
: data {{ args... }}
{
static_assert(sizeof...(Args) == 1);
}
constexpr Swizzle(const Swizzle& other) = default; constexpr Swizzle(const Swizzle& other) = default;
}; };

View File

@ -36,7 +36,7 @@ namespace orange
return Transform return Transform
{ {
.position = (parentConjugate * (world.position - parent.position)) / parent.scale; .position = (parentConjugate * (world.position - parent.position)) / parent.scale,
.orientation = (parentConjugate * world.orientation), .orientation = (parentConjugate * world.orientation),
.scale = (parentConjugate * (world.scale / parent.scale)), .scale = (parentConjugate * (world.scale / parent.scale)),
}; };
@ -69,16 +69,16 @@ namespace orange
bool identity(const Transform& t) bool identity(const Transform& t)
{ {
return t.position == vec3{0.0f} && return t.position == vec3{0.0f} &&
t.orientation == Quaternion{} && t.orientation == quat{} &&
t.scale == vec3{1.0f}; t.scale == vec3{1.0f};
} }
// TODO: // TODO:
Matrix4 transformMatrix4(const Transform& t) mat4 transformMatrix4(const Transform& t)
{ {
return Math::translate(t.position) * return Math::translate(t.position) *
quaternionToMatrix4(t.orientation) * quaternionToMatrix4(t.orientation) *
Math::scale(t.scale); Math::scale(t.scale);
} }
} }

View File

@ -12,99 +12,99 @@ namespace orange
public: public:
using Type = T; using Type = T;
Unit() constexpr Unit()
: m_value{T{0}} : m_value{T{0}}
{ {
} }
explicit Unit(T value) constexpr explicit Unit(T value)
: m_value{value} : m_value{value}
{ {
} }
template <typename U> template <typename U>
explicit Unit(Unit<Derived, U> value) constexpr explicit Unit(Unit<Derived, U> value)
: m_value{T{value.m_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<Derived, T> other) const constexpr bool operator==(Unit<Derived, T> other) const
{ {
return m_value == other.m_value; return m_value == other.m_value;
} }
bool operator!=(Unit<Derived, T> other) const { return !operator==(other); } constexpr bool operator!=(Unit<Derived, T> other) const { return !operator==(other); }
bool operator<(Unit<Derived, T> other) const constexpr bool operator<(Unit<Derived, T> other) const
{ {
return m_value < other.m_value; return m_value < other.m_value;
} }
bool operator>(Unit<Derived, T> other) const constexpr bool operator>(Unit<Derived, T> other) const
{ {
return m_value > other.m_value; return m_value > other.m_value;
} }
bool operator<=(Unit<Derived, T> other) const { return !operator>(other); } constexpr bool operator<=(Unit<Derived, T> other) const { return !operator>(other); }
bool operator>=(Unit<Derived, T> other) const { return !operator<(other); } constexpr bool operator>=(Unit<Derived, T> other) const { return !operator<(other); }
Unit<Derived, T> operator-() const { return Unit<Derived, T>{-m_value}; } constexpr Unit<Derived, T> operator-() const { return Unit<Derived, T>{-m_value}; }
Unit<Derived, T>& operator+=(Unit<Derived, T> other) constexpr Unit<Derived, T>& operator+=(Unit<Derived, T> other)
{ {
m_value += other.m_value; m_value += other.m_value;
return *this; return *this;
} }
Unit<Derived, T> operator+(Unit<Derived, T> other) const constexpr Unit<Derived, T> operator+(Unit<Derived, T> other) const
{ {
return Unit<Derived, T>{m_value + other.m_value}; return Unit<Derived, T>{m_value + other.m_value};
} }
Unit<Derived, T>& operator-=(Unit<Derived, T> other) constexpr Unit<Derived, T>& operator-=(Unit<Derived, T> other)
{ {
m_value -= other.m_value; m_value -= other.m_value;
return *this; return *this;
} }
Unit<Derived, T> operator-(Unit<Derived, T> other) const constexpr Unit<Derived, T> operator-(Unit<Derived, T> other) const
{ {
return Unit<Derived, T>{m_value - other.m_value}; return Unit<Derived, T>{m_value - other.m_value};
} }
Unit<Derived, T>& operator*=(T number) constexpr Unit<Derived, T>& operator*=(T number)
{ {
m_value *= number; m_value *= number;
return *this; return *this;
} }
Unit<Derived, T> operator*(T number) const constexpr Unit<Derived, T> operator*(T number) const
{ {
return Unit<Derived, T>{m_value * number}; return Unit<Derived, T>{m_value * number};
} }
Unit<Derived, T>& operator/=(T number) constexpr Unit<Derived, T>& operator/=(T number)
{ {
m_value /= number; m_value /= number;
return *this; return *this;
} }
Unit<Derived, T> operator/(T number) const constexpr Unit<Derived, T> operator/(T number) const
{ {
return Unit<Derived, T>{m_value / number}; return Unit<Derived, T>{m_value / number};
} }
T operator/(Unit<Derived, T> other) const { return m_value / other.value; } constexpr T operator/(Unit<Derived, T> other) const { return m_value / other.value; }
private: private:
T m_value; T m_value;
}; };
template <template <typename> class Derived, typename T> template <template <typename> class Derived, typename T>
Unit<Derived, T> operator*(typename std::common_type<T>::type number, constexpr Unit<Derived, T> operator*(typename std::common_type<T>::type number,
const Unit<Derived, T>& value) const Unit<Derived, T>& value)
{ {
return value * number; return value * number;

View File

@ -267,6 +267,18 @@ namespace orange
using vec3 = Vec<float, 3>; using vec3 = Vec<float, 3>;
using vec4 = Vec<float, 4>; using vec4 = Vec<float, 4>;
constexpr vec1 operator"" _vec1(long double value) { return vec1{static_cast<float>(value)}; }
constexpr vec1 operator"" _vec1(unsigned long long value) { return vec1{static_cast<float>(value)}; }
constexpr vec2 operator"" _vec2(long double value) { return vec2{static_cast<float>(value)}; }
constexpr vec2 operator"" _vec2(unsigned long long value) { return vec2{static_cast<float>(value)}; }
constexpr vec3 operator"" _vec3(long double value) { return vec3{static_cast<float>(value)}; }
constexpr vec3 operator"" _vec3(unsigned long long value) { return vec3{static_cast<float>(value)}; }
constexpr vec4 operator"" _vec4(long double value) { return vec4{static_cast<float>(value)}; }
constexpr vec4 operator"" _vec4(unsigned long long value) { return vec4{static_cast<float>(value)}; }
float cross(const vec2& a, const vec2& b) float cross(const vec2& a, const vec2& b)
{ {
return a.x * b.y - b.x * a.y; return a.x * b.y - b.x * a.y;

View File

@ -14,6 +14,8 @@
#include <Orange/Render/Swapchain.h> #include <Orange/Render/Swapchain.h>
#include <Orange/Render/VulkanHelpers.h> #include <Orange/Render/VulkanHelpers.h>
#include <Orange/Graphics/Camera.h>
#include <vs_Mesh.h> #include <vs_Mesh.h>
#include <fs_DebugVertColor.h> #include <fs_DebugVertColor.h>
@ -545,10 +547,16 @@ int main(int argc, char** argv)
mat4 view; mat4 view;
}; };
Camera camera;
camera.transform.position = vec3{0.0f, 0.0f, 80.0f};
camera.viewportAspectRatio = 16.0f / 9.0f;
camera.offsetOrientation(10_deg, 0_deg);
//camera.lookAt(vec3{40.0f, 40.0f, 0.0f});
UniformData uniformData UniformData uniformData
{ {
.projection = Math::perspective(Degree(90.0f), 16.0f / 9.0f, 0.01f, 1024.0f), .projection = camera.projection(),
.view = Math::translate(vec3{0.0f, 0.0f, -80.0f}), .view = camera.view(),
}; };
auto pooler = MemoryPool{ *r_buffer }; auto pooler = MemoryPool{ *r_buffer };