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
{
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<Quaternion>(transform.position, position, up));
conjugate(Math::lookAt<quat>(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);
}

View File

@ -14,25 +14,25 @@ namespace orange
class Degree : public Unit<Degree, T>
{
public:
Degree() {}
constexpr Degree() {}
explicit Degree(T value)
constexpr explicit 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)
{
}
template <class U>
explicit Degree(Unit<orange::detail::Degree, U> value)
template <typename U>
constexpr explicit Degree(Unit<orange::detail::Degree, U> value)
: Unit<orange::detail::Degree, T>(value)
{
}
Degree(Unit<Radian, T> value);
constexpr Degree(Unit<Radian, T> value);
};
template <typename T>
@ -41,32 +41,32 @@ namespace orange
public:
Radian() {}
explicit Radian(T value)
constexpr explicit 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)
{
}
template <class U>
explicit Radian(Unit<orange::detail::Radian, U> value)
template <typename U>
constexpr explicit Radian(Unit<orange::detail::Radian, U> value)
: Unit<orange::detail::Radian, T>(value)
{
}
Radian(Unit<Degree, T> value);
constexpr Radian(Unit<Degree, T> value);
};
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)
{
}
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))
{
}
@ -74,4 +74,10 @@ namespace orange
using Radian = detail::Radian<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
// 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;
}

View File

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

View File

@ -54,13 +54,6 @@ namespace orange
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;
};

View File

@ -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);
}
}

View File

@ -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 <typename U>
explicit Unit(Unit<Derived, U> value)
constexpr explicit Unit(Unit<Derived, U> 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;
}
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;
}
bool operator>(Unit<Derived, T> other) const
constexpr bool operator>(Unit<Derived, T> other) const
{
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;
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};
}
Unit<Derived, T>& operator-=(Unit<Derived, T> other)
constexpr Unit<Derived, T>& operator-=(Unit<Derived, T> other)
{
m_value -= other.m_value;
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};
}
Unit<Derived, T>& operator*=(T number)
constexpr Unit<Derived, T>& operator*=(T number)
{
m_value *= number;
return *this;
}
Unit<Derived, T> operator*(T number) const
constexpr Unit<Derived, T> operator*(T number) const
{
return Unit<Derived, T>{m_value * number};
}
Unit<Derived, T>& operator/=(T number)
constexpr Unit<Derived, T>& operator/=(T number)
{
m_value /= number;
return *this;
}
Unit<Derived, T> operator/(T number) const
constexpr Unit<Derived, T> operator/(T number) const
{
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:
T m_value;
};
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)
{
return value * number;

View File

@ -267,6 +267,18 @@ namespace orange
using vec3 = Vec<float, 3>;
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)
{
return a.x * b.y - b.x * a.y;

View File

@ -14,6 +14,8 @@
#include <Orange/Render/Swapchain.h>
#include <Orange/Render/VulkanHelpers.h>
#include <Orange/Graphics/Camera.h>
#include <vs_Mesh.h>
#include <fs_DebugVertColor.h>
@ -545,10 +547,16 @@ int main(int argc, char** argv)
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
{
.projection = Math::perspective(Degree(90.0f), 16.0f / 9.0f, 0.01f, 1024.0f),
.view = Math::translate(vec3{0.0f, 0.0f, -80.0f}),
.projection = camera.projection(),
.view = camera.view(),
};
auto pooler = MemoryPool{ *r_buffer };