Skip to content

Commit

Permalink
move matrix back into hpp/cpp, add filesystem.exists
Browse files Browse the repository at this point in the history
  • Loading branch information
TurtleP committed Nov 18, 2023
1 parent 98a550f commit 09820d4
Show file tree
Hide file tree
Showing 20 changed files with 637 additions and 529 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ target_sources(${PROJECT_NAME} PRIVATE
source/common/data.cpp
source/common/exception.cpp
source/common/luax.cpp
source/common/matrix.cpp
source/common/module.cpp
source/common/object.cpp
source/common/pixelformat.cpp
Expand Down
2 changes: 1 addition & 1 deletion include/common/drawable.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "matrix.tcc"
#include "matrix.hpp"
#include "object.hpp"

namespace love
Expand Down
192 changes: 192 additions & 0 deletions include/common/matrix.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#pragma once

#include "console.hpp"
#include "math.hpp"
#include "vector.hpp"

#include "utilities/driver/renderer/vertex.hpp"

#include <cstring>
#include <ranges>
#include <utility>

#include <span>

namespace love
{
template<typename R, typename T>
concept ValidTransformRange =
std::ranges::random_access_range<R> &&
(std::is_same_v<std::remove_cvref_t<std::ranges::range_value_t<R>>,
std::remove_cvref_t<T>> ||
(std::is_same_v<std::remove_cvref_t<T>, Vector3> &&
std::is_same_v<std::remove_cvref_t<std::ranges::range_value_t<R>>, vertex::Vertex>));

template<typename R>
concept Vector3TransformRange = ValidTransformRange<R, Vector3>;

template<typename R>
concept Vector2TransformRange = ValidTransformRange<R, Vector2>;

template<typename R>
concept VectorAtLeast2TransformRange =
ValidTransformRange<R, Vector2> || ValidTransformRange<R, Vector3>;

class Matrix4
{
protected:
template<VectorAtLeast2TransformRange R>
static auto DeVertexize(R&& r) -> decltype(auto)
{
if constexpr (std::is_same_v<std::remove_cvref_t<std::ranges::range_value_t<R>>,
vertex::Vertex>)
{
return r | std::views::transform([](auto&& e) -> auto& { return e.position; });
}
else
{
return std::forward<decltype(r)>(r);
}
}

static void Multiply(const Matrix4& a, const Matrix4& b, float t[0x10]);

public:
static void Multiply(const Matrix4& a, const Matrix4& b, Matrix4& result);

Matrix4();

Matrix4(float t00, float t10, float t01, float t11, float x, float y);

Matrix4(const float elements[0x10]);

Matrix4(const Matrix4& a, const Matrix4& b);

Matrix4(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx,
float ky);

Matrix4 operator*(const Matrix4& other) const;

void operator*=(const Matrix4& other);

const float* GetElements() const
{
return this->matrix;
}

void SetRow(int row, const Vector4& vector);

Vector4 GetRow(int row);

void SetColumn(int column, const Vector4& vector);

Vector4 GetColumn(int column);

void SetIdentity();

void SetTranslation(float x, float y);

void SetRotation(float rotation);

void SetScale(float sx, float sy);

void SetShear(float kx, float ky);

void GetApproximateScale(float& sx, float& sy) const;

void SetRawTransformation(float t00, float t10, float t01, float t11, float x, float y);

void SetTransformation(float x, float y, float angle, float sx, float sy, float ox,
float oy, float kx, float ky);

void Translate(float x, float y);

void Rotate(float rotation);

void Scale(float sx, float sy);

void Shear(float kx, float ky);

bool IsAffine2DTransform() const;

bool IsAffine3DTransform() const;

template<Vector3TransformRange Vdst, VectorAtLeast2TransformRange Vsrc>
void TransformXY0(Vdst&&, const Vsrc&&, int size) const;

template<VectorAtLeast2TransformRange Vdst, VectorAtLeast2TransformRange Vsrc>
/* transform Vector2 src into Vector2 dst */
void TransformXY(Vdst&& dst, Vsrc&& src) const
{
if constexpr (std::is_same_v<std::remove_cvref_t<std::ranges::range_value_t<Vdst>>,
vertex::Vertex> ||
std::is_same_v<std::remove_cvref_t<std::ranges::range_value_t<Vsrc>>,
vertex::Vertex>)
{
TransformXY(DeVertexize(dst), DeVertexize(src));
return;
}
else
{
// This might need to be an assert; jury's out
// static_assert(std::ranges::size(dst) == std::ranges::size(src));

for (size_t i = 0; i < std::ranges::size(dst); i++)
{
float x = (this->matrix[0] * src[i].x) + (this->matrix[4] * src[i].y) + (0) +
(this->matrix[12]);

float y = (this->matrix[1] * src[i].x) + (this->matrix[5] * src[i].y) + (0) +
(this->matrix[13]);

dst[i].x = x;
dst[i].y = y;
}
}
}

template<Vector3TransformRange Vdst, Vector3TransformRange Vsrc>
/* transform Vector3 src into Vector3 dst */
void TransformXYZ(Vdst&& dst, Vsrc&& src) const
{
if constexpr (std::is_same_v<std::remove_cvref_t<std::ranges::range_value_t<Vdst>>,
vertex::Vertex> ||
std::is_same_v<std::remove_cvref_t<std::ranges::range_value_t<Vsrc>>,
vertex::Vertex>)
{
TransformXYZ(DeVertexize(dst), DeVertexize(src));
return;
}
else
{
// static_assert(std::ranges::size(dst) == std::ranges::size(src));

for (size_t i = 0; i < std::ranges::size(dst); i++)
{
float x = (this->matrix[0] * src[i].x) + (this->matrix[4] * src[i].y) +
(this->matrix[8] * src[i].z) + (this->matrix[12]);

float y = (this->matrix[1] * src[i].x) + (this->matrix[5] * src[i].y) +
(this->matrix[9] * src[i].z) + (this->matrix[13]);

float z = (this->matrix[2] * src[i].x) + (this->matrix[6] * src[i].y) +
(this->matrix[10] * src[i].z) + (this->matrix[14]);

dst[i].x = x;
dst[i].y = y;
dst[i].z = z;
}
}
}

Matrix4 Inverse() const;

static Matrix4 Ortho(float left, float right, float bottom, float top, float near,
float far);

static Matrix4 Perspective(float verticalfov, float aspect, float near, float far);

protected:
float matrix[0x10];
};
} // namespace love
Loading

0 comments on commit 09820d4

Please sign in to comment.