diff --git a/CMakeLists.txt b/CMakeLists.txt
index f8ce8e4..33d905d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -108,14 +108,14 @@ add_library(fennec STATIC
include/fennec/math/trigonometric.h
include/fennec/math/relational.h
+ include/fennec/math/ext/constants.h
+
include/fennec/math/detail/__fwd.h
include/fennec/math/detail/__math.h
include/fennec/math/detail/__matrix.h
include/fennec/math/detail/__types.h
include/fennec/math/detail/__vector_traits.h
- include/fennec/math/ext/constants.h
-
# FPROC ================================================================================================================
# Strings
@@ -128,6 +128,7 @@ add_library(fennec STATIC
# Filesystem
include/fennec/fproc/filesystem/file.h source/fproc/filesystem/file.cpp
include/fennec/fproc/filesystem/path.h source/fproc/filesystem/path.cpp
+ include/fennec/math/ext/transform.h
)
# add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled
diff --git a/include/fennec/fproc/filesystem/path.h b/include/fennec/fproc/filesystem/path.h
index 7528a24..c03d4c8 100644
--- a/include/fennec/fproc/filesystem/path.h
+++ b/include/fennec/fproc/filesystem/path.h
@@ -26,6 +26,9 @@ namespace fennec
///
/// \brief struct for handling file paths
+///
+/// \details This structure makes no guarantees about the validity of a path.
+/// Operations do not examine the system's file structure.
struct path
{
public:
diff --git a/include/fennec/math/ext/transform.h b/include/fennec/math/ext/transform.h
new file mode 100644
index 0000000..eadf4c4
--- /dev/null
+++ b/include/fennec/math/ext/transform.h
@@ -0,0 +1,198 @@
+// =====================================================================================================================
+// fennec, a free and open source game engine
+// Copyright © 2025 Medusa Slockbower
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+// =====================================================================================================================
+
+#ifndef FENNEC_MATH_EXT_TRANSFORM_H
+#define FENNEC_MATH_EXT_TRANSFORM_H
+
+#include
+#include
+#include
+
+namespace fennec
+{
+
+///
+/// \brief Create a 2d translation matrix
+/// \param x a vector containing the position
+/// \returns An identity matrix with the last column set to x
+template
+constexpr mat translation(const vec& x) {
+ return mat(
+ 1, 0, 0
+ , 0, 1, 0
+ , x, 1
+ );
+}
+
+///
+/// \brief Create a 3d translation matrix
+/// \param x a vector containing the position
+/// \returns An identity matrix with the last column set to x
+template
+constexpr mat translation(const vec& x) {
+ return mat(
+ 1, 0, 0, 0
+ , 0, 1, 0, 0
+ , 0, 0, 1, 0
+ , x, 1
+ );
+}
+
+///
+/// \brief Create a 2d scaling matrix
+/// \param x a vector containing the scale for each axis
+/// \returns A diagonal matrix with the terms of x
+template
+constexpr mat scaling(const vec& x) {
+ return mat(
+ x.x, 0, 0
+ , 0, x.y, 0
+ , 0, 0, 1
+ );
+}
+
+///
+/// \brief Create a 3d scaling matrix
+/// \param x a vector containing the scale for each axis
+/// \returns A diagonal matrix with the terms of x
+template
+constexpr mat scaling(const vec& x) {
+ return mat(
+ x.x, 0, 0, 0
+ , 0, x.y, 0, 0
+ , 0, 0, x.z, 0
+ , 0, 0, 0, 1
+ );
+}
+
+///
+/// \brief Create a 2d rotation matrix
+/// \param a the angle of the rotation in radians
+/// \returns A rotation matrix that rotates about the "z-axis"
+template
+constexpr mat rotation(const genType a) {
+
+ // Calculate sin and cos terms
+ const genType c = fennec::cos(a);
+ const genType s = fennec::sin(a);
+
+ // Calculate the matrix
+ return mat(
+ c, -s, 0
+ , s, c, 0
+ , 0, 0, 1
+ );
+}
+
+///
+/// \brief Create a 3d rotation matrix from axis-angle
+/// \param A The axis vector
+/// \param a The rotation about the axis in radians
+/// \returns A rotation matrix about A
+template
+constexpr mat rotation(const vec& A, genType a) {
+ // https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
+
+ // Calculate sin and cos terms
+ const genType c = fennec::cos(a);
+ const genType s = fennec::sin(a);
+
+ // Calculate axis term
+ const vec u = (fennec::one() - c) * A;
+ const vec v = s * A;
+
+ // Calculate the Matrix
+ return mat(
+ A.x * u.x + c, A.x * u.y + v.z, A.x * u.z - v.y, 0
+ , A.x * u.y - v.z, A.y * u.y + c, A.y * u.z + v.x, 0
+ , A.x * u.z + v.y, A.y * u.z - v.x, A.z * u.z + c, 0
+ , 0, 0, 0, 1
+ );
+}
+
+template
+constexpr mat rotation_x(genType a) {
+
+ // Calculate sin and cos terms
+ const genType c = fennec::cos(a);
+ const genType s = fennec::sin(a);
+
+ // Calculate the matrix
+ return mat(
+ 1, 0, 0, 0
+ , 0, c, -s, 0
+ , 0, s, c, 0
+ , 0, 0, 0, 1
+ );
+}
+
+template
+constexpr mat rotation_y(genType a) {
+
+ // Calculate sin and cos terms
+ const genType c = fennec::cos(a);
+ const genType s = fennec::sin(a);
+
+ // Calculate the matrix
+ return mat(
+ c, 0, s, 0
+ , 0, 0, 0, 0
+ , -s, 0, c, 0
+ , 0, 0, 0, 1
+ );
+}
+
+template
+constexpr mat rotation_z(const genType a) {
+
+ // Calculate sin and cos terms
+ const genType c = fennec::cos(a);
+ const genType s = fennec::sin(a);
+
+ // Calculate the matrix
+ return mat(
+ c, -s, 0, 0
+ , s, c, 0, 0
+ , 0, 0, 1, 0
+ , 0, 0, 0, 1
+ );
+}
+
+template
+constexpr mat rotation(const vec& E) {
+
+ // Calculate sin and cos terms
+ const genType ca = fennec::cos(E.x);
+ const genType sa = fennec::sin(E.x);
+ const genType cb = fennec::cos(E.y);
+ const genType sb = fennec::sin(E.y);
+ const genType cg = fennec::cos(E.z);
+ const genType sg = fennec::sin(E.z);
+
+ // Calculate the matrix
+ return mat(
+ ca*cb, sa*sb, -sb, 0
+ , ca*sb*sg - sa*cg, sa*sb*sg + ca*cg, cb*sg, 0
+ , ca*sb*cg + sa*sg, sa*sb*cg - ca*sg, cb*cg, 0
+ , 0, 0, 0, 1
+ );
+}
+
+}
+
+#endif // FENNEC_MATH_EXT_TRANSFORM_H
diff --git a/source/fproc/filesystem/file.cpp b/source/fproc/filesystem/file.cpp
index bb1e10a..4f033ba 100644
--- a/source/fproc/filesystem/file.cpp
+++ b/source/fproc/filesystem/file.cpp
@@ -52,11 +52,11 @@ constexpr const cstring fmode_translate(uint8_t mode) {
// and editor assets, which require a complete read of the file before any writing is done
case fmode_read | fmode_write: return "r+";
- case fmode_write | fmode_trunc: return "w";
- case fmode_read | fmode_write | fmode_trunc: return "w+";
+ case fmode_write | fmode_trunc: return "w";
+ case fmode_read | fmode_write | fmode_trunc: return "w+";
- case fmode_write | fmode_trunc | fmode_exclusive: return "wx";
- case fmode_read | fmode_write | fmode_trunc | fmode_exclusive: return "wx+";
+ case fmode_write | fmode_trunc | fmode_exclusive: return "wx";
+ case fmode_read | fmode_write | fmode_trunc | fmode_exclusive: return "wx+";
// Binary Files
case fmode_binary | fmode_read: return "rb";