Kajetan Johannes Hammerle 3 maanden geleden
bovenliggende
commit
2faa1bb228
8 gewijzigde bestanden met toevoegingen van 229 en 579 verwijderingen
  1. 2 2
      CMakeLists.txt
  2. 28 23
      include/core/Matrix.hpp
  3. 0 134
      old/Matrix.cpp
  4. 0 38
      old/Matrix.hpp
  5. 0 176
      old/MatrixTests.cpp
  6. 95 94
      src/Matrix.cpp
  7. 1 1
      test/Main.cpp
  8. 103 111
      test/modules/MatrixTests.cpp

+ 2 - 2
CMakeLists.txt

@@ -12,7 +12,7 @@ set(SRC
     #"src/Frustum.cpp"
     #"src/HashMap.cpp"
     "src/Logger.cpp"
-    #"src/Matrix.cpp"
+    "src/Matrix.cpp"
     #"src/Plane.cpp"
     "src/Quaternion.cpp"
     #"src/Random.cpp"
@@ -38,7 +38,7 @@ set(SRC_TESTS
     #"test/modules/FrustumTests.cpp"
     #"test/modules/HashMapTests.cpp"
     #"test/modules/ListTests.cpp"
-    #"test/modules/MatrixTests.cpp"
+    "test/modules/MatrixTests.cpp"
     #"test/modules/PlaneTests.cpp"
     "test/modules/QuaternionTests.cpp"
     #"test/modules/QueueTests.cpp"

+ 28 - 23
include/core/Matrix.hpp

@@ -2,31 +2,36 @@
 #define CORE_MATRIX_H
 
 #include "core/Quaternion.hpp"
-#include "core/Vector.hpp"
 
-typedef struct {
-    Vector4 data[4];
-} Matrix;
+namespace Core {
+    class Matrix final {
+        Vector4 data[4];
 
-#define ZERO_MATRIX ((Matrix){0})
-#define UNIT_MATRIX \
-    ((Matrix){{{{1, 0, 0, 0}}, {{0, 1, 0, 0}}, {{0, 0, 1, 0}}, {{0, 0, 0, 1}}}})
+    public:
+        Matrix();
+        Matrix& unit();
+        Matrix& set(size_t index, const Vector4& v);
+        Matrix transpose() const;
+        const float* getValues() const;
+        Matrix& operator*=(const Matrix& other);
+        Matrix operator*(const Matrix& other) const;
+        Vector3 operator*(const Vector3& v) const;
+        Matrix& scale(const Vector3& v);
+        Matrix& scale(float f);
+        Matrix& translate(const Vector3& v);
+        Matrix& translateX(float tx);
+        Matrix& translateY(float ty);
+        Matrix& translateZ(float tz);
+        Matrix& translateTo(const Vector3& v);
+        Matrix& rotateX(float radians);
+        Matrix& rotateY(float radians);
+        Matrix& rotateZ(float radians);
+        Matrix& rotate(const Quaternion& q);
+        size_t toString(char* s, size_t n) const;
 
-Matrix* transposeMatrix(Matrix* m);
-Matrix* mulSetMatrix(Matrix* m, const Matrix* a);
-Matrix* mulMatrix(Matrix* m, const Matrix* a, const Matrix* b);
-Vector3* mulMatrixV3(Vector3* v, const Matrix* m, const Vector3* a);
-Matrix* scaleMatrix(Matrix* m, const Vector3* v);
-Matrix* scaleMatrixF(Matrix* m, float f);
-Matrix* translateMatrix(Matrix* m, const Vector3* v);
-Matrix* translateMatrixX(Matrix* m, float tx);
-Matrix* translateMatrixY(Matrix* m, float ty);
-Matrix* translateMatrixZ(Matrix* m, float tz);
-Matrix* translateMatrixTo(Matrix* m, const Vector3* v);
-Matrix* rotateMatrixX(Matrix* m, float radians);
-Matrix* rotateMatrixY(Matrix* m, float radians);
-Matrix* rotateMatrixZ(Matrix* m, float radians);
-Matrix* rotateMatrix(Matrix* m, const Quaternion* q);
-size_t toStringMatrix(const Matrix* m, char* buffer, size_t n);
+    private:
+        Matrix& rotate(float degrees, int a, int b);
+    };
+}
 
 #endif

+ 0 - 134
old/Matrix.cpp

@@ -1,134 +0,0 @@
-#include "core/math/Matrix.hpp"
-
-#include "core/math/Math.hpp"
-
-Core::Matrix::Matrix() {
-    unit();
-}
-
-Core::Matrix& Core::Matrix::unit() {
-    return translateTo(Vector3(0.0f, 0.0f, 0.0f));
-}
-
-Core::Matrix& Core::Matrix::set(size_t index, const Vector4& v) {
-    data[index] = v;
-    return *this;
-}
-
-Core::Matrix Core::Matrix::transpose() {
-    Matrix m;
-    for(size_t x = 0; x < 4; x++) {
-        for(size_t y = 0; y < 4; y++) {
-            m.data[x][y] = data[y][x];
-        }
-    }
-    return m;
-}
-
-const float* Core::Matrix::getValues() const {
-    return &(data[0][0]);
-}
-
-Core::Matrix& Core::Matrix::operator*=(const Matrix& m) {
-    data[0] = data[0][0] * m.data[0] + data[0][1] * m.data[1] +
-              data[0][2] * m.data[2] + data[0][3] * m.data[3];
-    data[1] = data[1][0] * m.data[0] + data[1][1] * m.data[1] +
-              data[1][2] * m.data[2] + data[1][3] * m.data[3];
-    data[2] = data[2][0] * m.data[0] + data[2][1] * m.data[1] +
-              data[2][2] * m.data[2] + data[2][3] * m.data[3];
-    data[3] = data[3][0] * m.data[0] + data[3][1] * m.data[1] +
-              data[3][2] * m.data[2] + data[3][3] * m.data[3];
-    return *this;
-}
-
-Core::Matrix Core::Matrix::operator*(const Matrix& other) const {
-    Matrix m = *this;
-    m *= other;
-    return m;
-}
-
-Core::Vector3 Core::Matrix::operator*(const Vector3& v) const {
-    Vector4 v4(v[0], v[1], v[2], 1.0f);
-    return Vector3(data[0].dot(v4), data[1].dot(v4), data[2].dot(v4)) *
-           (1.0f / data[3].dot(v4));
-}
-
-Core::Matrix& Core::Matrix::scale(const Vector3& v) {
-    data[0] *= v[0];
-    data[1] *= v[1];
-    data[2] *= v[2];
-    return *this;
-}
-
-Core::Matrix& Core::Matrix::scale(float s) {
-    return scale(Vector3(s, s, s));
-}
-
-Core::Matrix& Core::Matrix::translate(const Vector3& v) {
-    return translateX(v[0]).translateY(v[1]).translateZ(v[2]);
-}
-
-Core::Matrix& Core::Matrix::translateX(float tx) {
-    data[0] += data[3] * tx;
-    return *this;
-}
-
-Core::Matrix& Core::Matrix::translateY(float ty) {
-    data[1] += data[3] * ty;
-    return *this;
-}
-
-Core::Matrix& Core::Matrix::translateZ(float tz) {
-    data[2] += data[3] * tz;
-    return *this;
-}
-
-Core::Matrix& Core::Matrix::translateTo(const Vector3& v) {
-    data[0] = Vector4(1.0f, 0.0f, 0.0f, v[0]);
-    data[1] = Vector4(0.0f, 1.0f, 0.0f, v[1]);
-    data[2] = Vector4(0.0f, 0.0f, 1.0f, v[2]);
-    data[3] = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
-    return *this;
-}
-
-Core::Matrix& Core::Matrix::rotate(float degrees, int a, int b) {
-    float sin = 0.0f;
-    float cos = 0.0f;
-    sincosf(Core::Math::degreeToRadian(degrees), &sin, &cos);
-    Vector4 v = data[a];
-    data[a] = cos * data[a] - sin * data[b];
-    data[b] = sin * v + cos * data[b];
-    return *this;
-}
-
-Core::Matrix& Core::Matrix::rotateX(float degrees) {
-    return rotate(degrees, 1, 2);
-}
-
-Core::Matrix& Core::Matrix::rotateY(float degrees) {
-    return rotate(-degrees, 0, 2);
-}
-
-Core::Matrix& Core::Matrix::rotateZ(float degrees) {
-    return rotate(degrees, 0, 1);
-}
-
-Core::Matrix& Core::Matrix::rotate(const Quaternion& q) {
-    Vector3 a = q * Vector3(data[0][0], data[1][0], data[2][0]);
-    Vector3 b = q * Vector3(data[0][1], data[1][1], data[2][1]);
-    Vector3 c = q * Vector3(data[0][2], data[1][2], data[2][2]);
-    Vector3 d = q * Vector3(data[0][3], data[1][3], data[2][3]);
-    set(0, Vector4(a[0], b[0], c[0], d[0]));
-    set(1, Vector4(a[1], b[1], c[1], d[1]));
-    set(2, Vector4(a[2], b[2], c[2], d[2]));
-    return *this;
-}
-
-void Core::Matrix::toString(BufferString& s) const {
-    s.append('[');
-    s.append(data[0]).append(", ");
-    s.append(data[1]).append(", ");
-    s.append(data[2]).append(", ");
-    s.append(data[3]);
-    s.append("]");
-}

+ 0 - 38
old/Matrix.hpp

@@ -1,38 +0,0 @@
-#ifndef CORE_MATRIX_HPP
-#define CORE_MATRIX_HPP
-
-#include "core/math/Quaternion.hpp"
-#include "core/utils/ArrayString.hpp"
-
-namespace Core {
-    class Matrix final {
-        Vector4 data[4];
-
-    public:
-        Matrix();
-        Matrix& unit();
-        Matrix& set(size_t index, const Vector4& v);
-        Matrix transpose();
-        const float* getValues() const;
-        Matrix& operator*=(const Matrix& other);
-        Matrix operator*(const Matrix& other) const;
-        Vector3 operator*(const Vector3& v) const;
-        Matrix& scale(const Vector3& v);
-        Matrix& scale(float f);
-        Matrix& translate(const Vector3& v);
-        Matrix& translateX(float tx);
-        Matrix& translateY(float ty);
-        Matrix& translateZ(float tz);
-        Matrix& translateTo(const Vector3& v);
-        Matrix& rotateX(float degrees);
-        Matrix& rotateY(float degrees);
-        Matrix& rotateZ(float degrees);
-        Matrix& rotate(const Quaternion& q);
-        void toString(BufferString& s) const;
-
-    private:
-        Matrix& rotate(float degrees, int a, int b);
-    };
-}
-
-#endif

+ 0 - 176
old/MatrixTests.cpp

@@ -1,176 +0,0 @@
-#include "../Tests.hpp"
-#include "core/math/Matrix.hpp"
-
-using V3 = Core::Vector3;
-
-static void testInit() {
-    Core::Matrix m;
-    const float* data = m.getValues();
-    for(int i = 0; i < 16; i++) {
-        int x = i % 4;
-        int y = i / 4;
-        CORE_TEST_FLOAT(x == y, data[i], 0.0f);
-    }
-}
-
-static void testTranspose() {
-    Core::Matrix m;
-    m.set(0, Core::Vector4(1.0f, 2.0f, 3.0f, 4.0f));
-    m.set(1, Core::Vector4(5.0f, 6.0f, 7.0f, 8.0f));
-    m.set(2, Core::Vector4(9.0f, 10.0f, 11.0f, 12.0f));
-    m.set(3, Core::Vector4(13.0f, 14.0f, 15.0f, 16.0f));
-    Core::Matrix t = m.transpose();
-    Core::Matrix m2 = t.transpose();
-
-    const float* mp = m.getValues();
-    const float* tp = t.getValues();
-    for(int x = 0; x < 4; x++) {
-        for(int y = 0; y < 4; y++) {
-            CORE_TEST_FLOAT(mp[y * 4 + x], tp[x * 4 + y], 0.0f);
-        }
-    }
-    const float* mp2 = m2.getValues();
-    for(int i = 0; i < 16; i++) {
-        CORE_TEST_FLOAT(mp[i], mp2[i], 0.0f);
-    }
-}
-
-static void testScale() {
-    Core::Matrix m;
-    m.scale(V3(2.0f, 3.0f, 4.0f));
-    CORE_TEST_VECTOR(V3(-8.0f, 18.0f, 28.0f), m * V3(-4.0f, 6.0f, 7.0f));
-}
-
-static void testUniformScale() {
-    Core::Matrix m;
-    m.scale(2.0f);
-    CORE_TEST_VECTOR(V3(-8.0f, 12.0f, 14.0f), m * V3(-4.0f, 6.0f, 7.0f));
-}
-
-static void testTranslateX() {
-    Core::Matrix m;
-    m.translateX(5.0f);
-    CORE_TEST_VECTOR(V3(1.0f, 6.0f, 7.0f), m * V3(-4.0f, 6.0f, 7.0f));
-}
-
-static void testTranslateY() {
-    Core::Matrix m;
-    m.translateY(6.0f);
-    CORE_TEST_VECTOR(V3(-4.0f, 12.0f, 7.0f), m * V3(-4.0f, 6.0f, 7.0f));
-}
-
-static void testTranslateZ() {
-    Core::Matrix m;
-    m.translateZ(7.0f);
-    CORE_TEST_VECTOR(V3(-4.0f, 6.0f, 14.0f), m * V3(-4.0f, 6.0f, 7.0f));
-}
-
-static void testTranslate() {
-    Core::Matrix m;
-    m.translate(V3(1.0f, 2.0f, 3.0f));
-    CORE_TEST_VECTOR(V3(-3.0f, 8.0f, 10.0f), m * V3(-4.0f, 6.0f, 7.0f));
-}
-
-static void testCombination() {
-    Core::Matrix m;
-    m.scale(2.0f);
-    m.translateX(1.0f);
-    m.translateY(2.0f);
-    m.translateZ(3.0f);
-    m.translate(V3(-4.0f, 2.0f, 3.0f));
-    m.scale(V3(2.0f, 3.0f, 4.0f));
-    m.scale(0.5f);
-    CORE_TEST_VECTOR(V3(-1.0f, 9.0f, 16.0f), m * V3(1.0f, 1.0f, 1.0f));
-}
-
-static void testMatrixCombination() {
-    Core::Matrix a;
-    a.scale(2.0f);
-    a.translate(V3(1.0f, 2.0f, 3.0f));
-
-    Core::Matrix b;
-    b.scale(3.0f);
-    b.translate(V3(1.0f, 1.0f, 1.0f));
-
-    Core::Matrix c;
-    c.translate(V3(-1.0f, -2.0f, -3.0f));
-    c *= b * a;
-
-    CORE_TEST_VECTOR(V3(9.0f, 11.0f, 13.0f), c * V3(1.0f, 1.0f, 1.0f));
-}
-
-static void testRotateX() {
-    Core::Matrix m;
-    m.rotateX(90);
-    CORE_TEST_VECTOR(V3(1.0f, 0.0f, 0.0f), m * V3(1.0f, 0.0f, 0.0f));
-    CORE_TEST_VECTOR(V3(0.0f, 0.0f, 1.0f), m * V3(0.0f, 1.0f, 0.0f));
-    CORE_TEST_VECTOR(V3(0.0f, -1.0f, 0.0f), m * V3(0.0f, 0.0f, 1.0f));
-}
-
-static void testRotateY() {
-    Core::Matrix m;
-    m.rotateY(90);
-    CORE_TEST_VECTOR(V3(0.0f, 0.0f, -1.0f), m * V3(1.0f, 0.0f, 0.0f));
-    CORE_TEST_VECTOR(V3(0.0f, 1.0f, 0.0f), m * V3(0.0f, 1.0f, 0.0f));
-    CORE_TEST_VECTOR(V3(1.0f, 0.0f, 0.0f), m * V3(0.0f, 0.0f, 1.0f));
-}
-
-static void testRotateZ() {
-    Core::Matrix m;
-    m.rotateZ(90);
-    CORE_TEST_VECTOR(V3(0.0f, 1.0f, 0.0f), m * V3(1.0f, 0.0f, 0.0f));
-    CORE_TEST_VECTOR(V3(-1.0f, 0.0f, 0.0f), m * V3(0.0f, 1.0f, 0.0f));
-    CORE_TEST_VECTOR(V3(0.0f, 0.0f, 1.0f), m * V3(0.0f, 0.0f, 1.0f));
-}
-
-static void testToString() {
-    Core::ArrayString<1024> s;
-    Core::Matrix m;
-    m.set(0, Core::Vector4(1.0f, 2.0f, 3.0f, 4.0f));
-    m.set(1, Core::Vector4(5.0f, 6.0f, 7.0f, 8.0f));
-    m.set(2, Core::Vector4(9.0f, 10.0f, 11.0f, 12.0f));
-    m.set(3, Core::Vector4(13.0f, 14.0f, 15.0f, 16.0f));
-    s.append(m);
-    CORE_TEST_STRING(
-        "[[1.00, 2.00, 3.00, 4.00], [5.00, 6.00, 7.00, 8.00], "
-        "[9.00, 10.00, 11.00, 12.00], [13.00, 14.00, 15.00, 16.00]]",
-        s);
-}
-
-static void testQuaternionMatrix() {
-    Core::Quaternion q1(V3(1.0f, 0.0f, 0.0f), 48.0f);
-    Core::Quaternion q2(V3(0.0f, 1.0f, 0.0f), 52.0f);
-    Core::Quaternion q3(V3(0.0f, 0.0f, 1.0f), 60.0f);
-
-    Core::Matrix m;
-    m.translate(V3(1.0f, 2.0f, 3.0f));
-    m.rotate(q1).rotate(q2).rotate(q3);
-    m.translate(V3(1.0f, 2.0f, 3.0f));
-
-    Core::Matrix check;
-    check.translate(V3(1.0f, 2.0f, 3.0f));
-    check.rotateX(48.0f).rotateY(52.0f).rotateZ(60.0f);
-    check.translate(V3(1.0f, 2.0f, 3.0f));
-
-    for(int i = 0; i < 16; i++) {
-        CORE_TEST_FLOAT(check.getValues()[i], m.getValues()[i], 0.0001f);
-    }
-}
-
-void Core::testMatrix() {
-    testInit();
-    testScale();
-    testUniformScale();
-    testTranspose();
-    testTranslateX();
-    testTranslateY();
-    testTranslateZ();
-    testTranslate();
-    testCombination();
-    testMatrixCombination();
-    testRotateX();
-    testRotateY();
-    testRotateZ();
-    testToString();
-    testQuaternionMatrix();
-}

+ 95 - 94
src/Matrix.cpp

@@ -1,136 +1,137 @@
-#include <math.h>
-#include <stdio.h>
+#include "core/Matrix.hpp"
 
-#include "core/Generic.hpp"
-#include "core/ToString.hpp"
+Core::Matrix::Matrix() {
+    unit();
+}
+
+Core::Matrix& Core::Matrix::unit() {
+    return translateTo(Vector3(0.0f, 0.0f, 0.0f));
+}
 
-#define M(m, x, y) ((m)->data[x].data[y])
+Core::Matrix& Core::Matrix::set(size_t index, const Vector4& v) {
+    data[index] = v;
+    return *this;
+}
 
-Matrix* transposeMatrix(Matrix* m) {
-    Matrix c = ZERO_MATRIX;
+Core::Matrix Core::Matrix::transpose() const {
+    Matrix m;
     for(size_t x = 0; x < 4; x++) {
         for(size_t y = 0; y < 4; y++) {
-            M(&c, x, y) = M(m, y, x);
+            m.data[x][y] = data[y][x];
         }
     }
-    *m = c;
     return m;
 }
 
-Matrix* mulSetMatrix(Matrix* m, const Matrix* a) {
-    for(int i = 0; i < 4; i++) {
-        Vector4 d = VECTOR4;
-        addSet(&d, mul(a->data + 0, m->data[i].x));
-        addSet(&d, mul(a->data + 1, m->data[i].y));
-        addSet(&d, mul(a->data + 2, m->data[i].z));
-        addSet(&d, mul(a->data + 3, m->data[i].w));
-        m->data[i] = d;
-    }
-    return m;
+const float* Core::Matrix::getValues() const {
+    return &(data[0][0]);
+}
+
+Core::Matrix& Core::Matrix::operator*=(const Matrix& m) {
+    data[0] = data[0][0] * m.data[0] + data[0][1] * m.data[1] +
+              data[0][2] * m.data[2] + data[0][3] * m.data[3];
+    data[1] = data[1][0] * m.data[0] + data[1][1] * m.data[1] +
+              data[1][2] * m.data[2] + data[1][3] * m.data[3];
+    data[2] = data[2][0] * m.data[0] + data[2][1] * m.data[1] +
+              data[2][2] * m.data[2] + data[2][3] * m.data[3];
+    data[3] = data[3][0] * m.data[0] + data[3][1] * m.data[1] +
+              data[3][2] * m.data[2] + data[3][3] * m.data[3];
+    return *this;
 }
 
-Matrix* mulMatrix(Matrix* m, const Matrix* a, const Matrix* b) {
-    *m = *a;
-    mulSetMatrix(m, b);
+Core::Matrix Core::Matrix::operator*(const Matrix& other) const {
+    Matrix m = *this;
+    m *= other;
     return m;
 }
 
-Vector3* mulMatrixV3(Vector3* v, const Matrix* m, const Vector3* a) {
-    Vector4 v4 = V(a->x, a->y, a->z, 1.0f);
-    v->x = dot(m->data + 0, &v4);
-    v->y = dot(m->data + 1, &v4);
-    v->z = dot(m->data + 2, &v4);
-    mulSet(v, 1.0f / dot(m->data + 3, &v4));
-    return v;
+Core::Vector3 Core::Matrix::operator*(const Vector3& v) const {
+    Vector4 v4(v[0], v[1], v[2], 1.0f);
+    return Vector3(data[0].dot(v4), data[1].dot(v4), data[2].dot(v4)) *
+           (1.0f / data[3].dot(v4));
 }
 
-Matrix* scaleMatrix(Matrix* m, const Vector3* v) {
-    mulSet(m->data + 0, v->x);
-    mulSet(m->data + 1, v->y);
-    mulSet(m->data + 2, v->z);
-    return m;
+Core::Matrix& Core::Matrix::scale(const Vector3& v) {
+    data[0] *= v[0];
+    data[1] *= v[1];
+    data[2] *= v[2];
+    return *this;
 }
 
-Matrix* scaleMatrixF(Matrix* m, float f) {
-    return scaleMatrix(m, &V(f, f, f));
+Core::Matrix& Core::Matrix::scale(float s) {
+    return scale(Vector3(s, s, s));
 }
 
-Matrix* translateMatrix(Matrix* m, const Vector3* v) {
-    translateMatrixX(m, v->x);
-    translateMatrixY(m, v->y);
-    translateMatrixZ(m, v->z);
-    return m;
+Core::Matrix& Core::Matrix::translate(const Vector3& v) {
+    return translateX(v[0]).translateY(v[1]).translateZ(v[2]);
 }
 
-Matrix* translateMatrixX(Matrix* m, float tx) {
-    addSet(m->data + 0, mul(m->data + 3, tx));
-    return m;
+Core::Matrix& Core::Matrix::translateX(float tx) {
+    data[0] += data[3] * tx;
+    return *this;
 }
 
-Matrix* translateMatrixY(Matrix* m, float ty) {
-    addSet(m->data + 1, mul(m->data + 3, ty));
-    return m;
+Core::Matrix& Core::Matrix::translateY(float ty) {
+    data[1] += data[3] * ty;
+    return *this;
 }
 
-Matrix* translateMatrixZ(Matrix* m, float tz) {
-    addSet(m->data + 2, mul(m->data + 3, tz));
-    return m;
+Core::Matrix& Core::Matrix::translateZ(float tz) {
+    data[2] += data[3] * tz;
+    return *this;
 }
 
-Matrix* translateMatrixTo(Matrix* m, const Vector3* v) {
-    m->data[0] = V(1.0f, 0.0f, 0.0f, v->x);
-    m->data[1] = V(0.0f, 1.0f, 0.0f, v->y);
-    m->data[2] = V(0.0f, 0.0f, 1.0f, v->z);
-    m->data[3] = V(0.0f, 0.0f, 0.0f, 1.0f);
-    return m;
+Core::Matrix& Core::Matrix::translateTo(const Vector3& v) {
+    data[0] = Vector4(1.0f, 0.0f, 0.0f, v[0]);
+    data[1] = Vector4(0.0f, 1.0f, 0.0f, v[1]);
+    data[2] = Vector4(0.0f, 0.0f, 1.0f, v[2]);
+    data[3] = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
+    return *this;
 }
 
-static Matrix* rotate(Matrix* m, float radians, int a, int b) {
-    float sin = sinf(radians);
-    float cos = cosf(radians);
-    Vector4 v = m->data[a];
-    sub(m->data + a, mul(&v, cos), mul(m->data + b, sin));
-    add(m->data + b, mul(&v, sin), mul(m->data + b, cos));
-    return m;
+Core::Matrix& Core::Matrix::rotate(float radians, int a, int b) {
+    float sin = 0.0f;
+    float cos = 0.0f;
+    sincosf(radians, &sin, &cos);
+    Vector4 v = data[a];
+    data[a] = cos * v - sin * data[b];
+    data[b] = sin * v + cos * data[b];
+    return *this;
 }
 
-Matrix* rotateMatrixX(Matrix* m, float radians) {
-    return rotate(m, radians, 1, 2);
+Core::Matrix& Core::Matrix::rotateX(float degrees) {
+    return rotate(degrees, 1, 2);
 }
 
-Matrix* rotateMatrixY(Matrix* m, float radians) {
-    return rotate(m, -radians, 0, 2);
+Core::Matrix& Core::Matrix::rotateY(float degrees) {
+    return rotate(-degrees, 0, 2);
 }
 
-Matrix* rotateMatrixZ(Matrix* m, float radians) {
-    return rotate(m, radians, 0, 1);
+Core::Matrix& Core::Matrix::rotateZ(float degrees) {
+    return rotate(degrees, 0, 1);
 }
 
-Matrix* rotateMatrix(Matrix* m, const Quaternion* q) {
-    Vector3 a;
-    Vector3 b;
-    Vector3 c;
-    Vector3 d;
-    mul(&a, q, &V(M(m, 0, 0), M(m, 1, 0), M(m, 2, 0)));
-    mul(&b, q, &V(M(m, 0, 1), M(m, 1, 1), M(m, 2, 1)));
-    mul(&c, q, &V(M(m, 0, 2), M(m, 1, 2), M(m, 2, 2)));
-    mul(&d, q, &V(M(m, 0, 3), M(m, 1, 3), M(m, 2, 3)));
-    m->data[0] = V(a.x, b.x, c.x, d.x);
-    m->data[1] = V(a.y, b.y, c.y, d.y);
-    m->data[2] = V(a.z, b.z, c.z, d.z);
-    return m;
+Core::Matrix& Core::Matrix::rotate(const Quaternion& q) {
+    Vector3 a = q * Vector3(data[0][0], data[1][0], data[2][0]);
+    Vector3 b = q * Vector3(data[0][1], data[1][1], data[2][1]);
+    Vector3 c = q * Vector3(data[0][2], data[1][2], data[2][2]);
+    Vector3 d = q * Vector3(data[0][3], data[1][3], data[2][3]);
+    set(0, Vector4(a[0], b[0], c[0], d[0]));
+    set(1, Vector4(a[1], b[1], c[1], d[1]));
+    set(2, Vector4(a[2], b[2], c[2], d[2]));
+    return *this;
 }
 
-size_t toStringMatrix(const Matrix* m, char* buffer, size_t n) {
-    size_t w = 0;
-    stringAdd(&w, &buffer, &n, toString(buffer, n, "["));
-    stringAdd(&w, &buffer, &n, toStringV4(m->data + 0, buffer, n));
-    stringAdd(&w, &buffer, &n, toString(buffer, n, ", "));
-    stringAdd(&w, &buffer, &n, toStringV4(m->data + 1, buffer, n));
-    stringAdd(&w, &buffer, &n, toString(buffer, n, ", "));
-    stringAdd(&w, &buffer, &n, toStringV4(m->data + 2, buffer, n));
-    stringAdd(&w, &buffer, &n, toString(buffer, n, ", "));
-    stringAdd(&w, &buffer, &n, toStringV4(m->data + 3, buffer, n));
-    stringAdd(&w, &buffer, &n, toString(buffer, n, "]"));
-    return w;
+size_t Core::Matrix::toString(char* s, size_t n) const {
+    size_t total = 0;
+    addString("[", s, n, total);
+    addString(data[0], s, n, total);
+    addString(", ", s, n, total);
+    addString(data[1], s, n, total);
+    addString(", ", s, n, total);
+    addString(data[2], s, n, total);
+    addString(", ", s, n, total);
+    addString(data[3], s, n, total);
+    addString("]", s, n, total);
+    return total;
 }

+ 1 - 1
test/Main.cpp

@@ -73,7 +73,7 @@ int main(int argAmount, const char** args) {
     // testFrustum();
     // testHashMap(light);
     // testList(light);
-    // testMatrix();
+    testMatrix();
     // testPlane();
     testQuaternion();
     // testQueue();

+ 103 - 111
test/modules/MatrixTests.cpp

@@ -1,10 +1,13 @@
-#include "../Tests.h"
-#include "core/Generic.h"
-#include "core/Utility.h"
+#include "../Tests.hpp"
+#include "core/Matrix.hpp"
+#include "core/Test.hpp"
+
+using Core::Matrix;
+using V3 = Core::Vector3;
 
 static void testInit() {
-    Matrix m = UNIT_MATRIX;
-    const float* data = (float*)&m;
+    Matrix m;
+    const float* data = m.getValues();
     for(int i = 0; i < 16; i++) {
         int x = i % 4;
         int y = i / 4;
@@ -14,174 +17,163 @@ static void testInit() {
 
 static void testTranspose() {
     Matrix m;
-    float* data = (float*)&m;
-    for(int i = 0; i < 16; i++) {
-        data[i] = (float)(i + 1);
-    }
-    Matrix t = m;
-    transposeMatrix(&t);
-    Matrix m2 = t;
-    transposeMatrix(&m2);
-
-    const float* mp = (float*)&m;
-    const float* tp = (float*)&t;
+    m.set(0, Core::Vector4(1.0f, 2.0f, 3.0f, 4.0f));
+    m.set(1, Core::Vector4(5.0f, 6.0f, 7.0f, 8.0f));
+    m.set(2, Core::Vector4(9.0f, 10.0f, 11.0f, 12.0f));
+    m.set(3, Core::Vector4(13.0f, 14.0f, 15.0f, 16.0f));
+    Matrix t = m.transpose();
+    Matrix m2 = t.transpose();
+
+    const float* mp = m.getValues();
+    const float* tp = t.getValues();
     for(int x = 0; x < 4; x++) {
         for(int y = 0; y < 4; y++) {
             TEST_FLOAT(mp[y * 4 + x], tp[x * 4 + y], 0.0f);
         }
     }
-    const float* mp2 = (float*)&m2;
+    const float* mp2 = m2.getValues();
     for(int i = 0; i < 16; i++) {
         TEST_FLOAT(mp[i], mp2[i], 0.0f);
     }
 }
 
 static void testScale() {
-    Matrix m = UNIT_MATRIX;
-    scaleMatrix(&m, &V(2.0f, 3.0f, 4.0f));
-    TEST_V3(&V(-8.0f, 18.0f, 28.0f), mul(&m, &V(-4.0f, 6.0f, 7.0f)));
+    Core::Matrix m;
+    m.scale(V3(2.0f, 3.0f, 4.0f));
+    TEST(V3(-8.0f, 18.0f, 28.0f), m * V3(-4.0f, 6.0f, 7.0f));
 }
 
 static void testUniformScale() {
-    Matrix m = UNIT_MATRIX;
-    scaleMatrixF(&m, 2.0f);
-    TEST_V3(&V(-8.0f, 12.0f, 14.0f), mul(&m, &V(-4.0f, 6.0f, 7.0f)));
+    Core::Matrix m;
+    m.scale(2.0f);
+    TEST(V3(-8.0f, 12.0f, 14.0f), m * V3(-4.0f, 6.0f, 7.0f));
 }
 
 static void testTranslateX() {
-    Matrix m = UNIT_MATRIX;
-    translateMatrixX(&m, 5.0f);
-    TEST_V3(&V(1.0f, 6.0f, 7.0f), mul(&m, &V(-4.0f, 6.0f, 7.0f)));
+    Core::Matrix m;
+    m.translateX(5.0f);
+    TEST(V3(1.0f, 6.0f, 7.0f), m * V3(-4.0f, 6.0f, 7.0f));
 }
 
 static void testTranslateY() {
-    Matrix m = UNIT_MATRIX;
-    translateMatrixY(&m, 6.0f);
-    TEST_V3(&V(-4.0f, 12.0f, 7.0f), mul(&m, &V(-4.0f, 6.0f, 7.0f)));
+    Core::Matrix m;
+    m.translateY(6.0f);
+    TEST(V3(-4.0f, 12.0f, 7.0f), m * V3(-4.0f, 6.0f, 7.0f));
 }
 
 static void testTranslateZ() {
-    Matrix m = UNIT_MATRIX;
-    translateMatrixZ(&m, 7.0f);
-    TEST_V3(&V(-4.0f, 6.0f, 14.0f), mul(&m, &V(-4.0f, 6.0f, 7.0f)));
+    Core::Matrix m;
+    m.translateZ(7.0f);
+    TEST(V3(-4.0f, 6.0f, 14.0f), m * V3(-4.0f, 6.0f, 7.0f));
 }
 
 static void testTranslate() {
-    Matrix m = UNIT_MATRIX;
-    translateMatrix(&m, &V(1.0f, 2.0f, 3.0f));
-    TEST_V3(&V(-3.0f, 8.0f, 10.0f), mul(&m, &V(-4.0f, 6.0f, 7.0f)));
+    Core::Matrix m;
+    m.translate(V3(1.0f, 2.0f, 3.0f));
+    TEST(V3(-3.0f, 8.0f, 10.0f), m * V3(-4.0f, 6.0f, 7.0f));
 }
 
 static void testTranslateTo() {
-    char buffer[1024];
     Matrix m;
-    for(int i = 0; i < 16; i++) {
-        ((float*)&m)[i] = (float)i + 1.0f;
-    }
-    translateMatrixTo(&m, &V(6.0f, 8.0f, 9.0f));
-    toStringMatrix(&m, buffer, sizeof(buffer));
+    m.translateTo(V3(6.0f, 8.0f, 9.0f));
     TEST_STRING(
-        "[[1.000, 0.000, 0.000, 6.000], [0.000, 1.000, 0.000, 8.000], "
-        "[0.000, 0.000, 1.000, 9.000], [0.000, 0.000, 0.000, 1.000]]",
-        buffer);
+        "[[1.00, 0.00, 0.00, 6.00], [0.00, 1.00, 0.00, 8.00], "
+        "[0.00, 0.00, 1.00, 9.00], [0.00, 0.00, 0.00, 1.00]]",
+        m);
 }
 
 static void testCombination() {
-    Matrix m = UNIT_MATRIX;
-    scaleMatrixF(&m, 2.0f);
-    translateMatrixX(&m, 1.0f);
-    translateMatrixY(&m, 2.0f);
-    translateMatrixZ(&m, 3.0f);
-    translateMatrix(&m, &V(-4.0f, 2.0f, 3.0f));
-    scaleMatrix(&m, &V(2.0f, 3.0f, 4.0f));
-    scaleMatrixF(&m, 0.5f);
-    TEST_V3(&V(-1.0f, 9.0f, 16.0f), mul(&m, &V(1.0f, 1.0f, 1.0f)));
+    Matrix m;
+    m.scale(2.0f);
+    m.translateX(1.0f);
+    m.translateY(2.0f);
+    m.translateZ(3.0f);
+    m.translate(V3(-4.0f, 2.0f, 3.0f));
+    m.scale(V3(2.0f, 3.0f, 4.0f));
+    m.scale(0.5f);
+    TEST(V3(-1.0f, 9.0f, 16.0f), m * V3(1.0f, 1.0f, 1.0f));
 }
 
 static void testMatrixCombination() {
-    Matrix a = UNIT_MATRIX;
-    scaleMatrixF(&a, 2.0f);
-    translateMatrix(&a, &V(1.0f, 2.0f, 3.0f));
+    Matrix a;
+    a.scale(2.0f);
+    a.translate(V3(1.0f, 2.0f, 3.0f));
 
-    Matrix b = UNIT_MATRIX;
-    scaleMatrixF(&b, 3.0f);
-    translateMatrix(&b, &V(1.0f, 1.0f, 1.0f));
+    Matrix b;
+    b.scale(3.0f);
+    b.translate(V3(1.0f, 1.0f, 1.0f));
 
-    Matrix c = UNIT_MATRIX;
-    translateMatrix(&c, &V(-1.0f, -2.0f, -3.0f));
+    Matrix c;
+    c.translate(V3(-1.0f, -2.0f, -3.0f));
 
-    mulSet(&c, mul(&ZERO_MATRIX, &b, &a));
-
-    TEST_V3(&V(9.0f, 11.0f, 13.0f), mul(&c, &V(1.0f, 1.0f, 1.0f)));
+    c *= b * a;
+    TEST(V3(9.0f, 11.0f, 13.0f), c * V3(1.0f, 1.0f, 1.0f));
 }
 
 static void testRotateX() {
-    Matrix m = UNIT_MATRIX;
-    rotateMatrixX(&m, degreeToRadian(90.0f));
-    TEST_V3(&V(1.0f, 0.0f, 0.0f), mul(&m, &V(1.0f, 0.0f, 0.0f)));
-    TEST_V3(&V(0.0f, 0.0f, 1.0f), mul(&m, &V(0.0f, 1.0f, 0.0f)));
-    TEST_V3(&V(0.0f, -1.0f, 0.0f), mul(&m, &V(0.0f, 0.0f, 1.0f)));
+    Matrix m;
+    m.rotateX(Core::degreeToRadian(90.0f));
+    TEST(V3(1.0f, 0.0f, 0.0f), m * V3(1.0f, 0.0f, 0.0f));
+    TEST(V3(0.0f, 0.0f, 1.0f), m * V3(0.0f, 1.0f, 0.0f));
+    TEST(V3(0.0f, -1.0f, 0.0f), m * V3(0.0f, 0.0f, 1.0f));
 }
 
 static void testRotateY() {
-    Matrix m = UNIT_MATRIX;
-    rotateMatrixY(&m, degreeToRadian(90.0f));
-    TEST_V3(&V(0.0f, 0.0f, -1.0f), mul(&m, &V(1.0f, 0.0f, 0.0f)));
-    TEST_V3(&V(0.0f, 1.0f, 0.0f), mul(&m, &V(0.0f, 1.0f, 0.0f)));
-    TEST_V3(&V(1.0f, 0.0f, 0.0f), mul(&m, &V(0.0f, 0.0f, 1.0f)));
+    Matrix m;
+    m.rotateY(Core::degreeToRadian(90.0f));
+    TEST(V3(0.0f, 0.0f, -1.0f), m * V3(1.0f, 0.0f, 0.0f));
+    TEST(V3(0.0f, 1.0f, 0.0f), m * V3(0.0f, 1.0f, 0.0f));
+    TEST(V3(1.0f, 0.0f, 0.0f), m * V3(0.0f, 0.0f, 1.0f));
 }
 
 static void testRotateZ() {
-    Matrix m = UNIT_MATRIX;
-    rotateMatrixZ(&m, degreeToRadian(90.0f));
-    TEST_V3(&V(0.0f, 1.0f, 0.0f), mul(&m, &V(1.0f, 0.0f, 0.0f)));
-    TEST_V3(&V(-1.0f, 0.0f, 0.0f), mul(&m, &V(0.0f, 1.0f, 0.0f)));
-    TEST_V3(&V(0.0f, 0.0f, 1.0f), mul(&m, &V(0.0f, 0.0f, 1.0f)));
+    Matrix m;
+    m.rotateZ(Core::degreeToRadian(90.0f));
+    TEST(V3(0.0f, 1.0f, 0.0f), m * V3(1.0f, 0.0f, 0.0f));
+    TEST(V3(-1.0f, 0.0f, 0.0f), m * V3(0.0f, 1.0f, 0.0f));
+    TEST(V3(0.0f, 0.0f, 1.0f), m * V3(0.0f, 0.0f, 1.0f));
 }
 
 static void testQuaternionMatrix() {
-    Quaternion q1 = UNIT_QUATERNION;
-    axisAngleQ(&q1, &V(1.0f, 0.0f, 0.0f), degreeToRadian(48.0f));
-    Quaternion q2 = UNIT_QUATERNION;
-    axisAngleQ(&q2, &V(0.0f, 1.0f, 0.0f), degreeToRadian(52.0f));
-    Quaternion q3 = UNIT_QUATERNION;
-    axisAngleQ(&q3, &V(0.0f, 0.0f, 1.0f), degreeToRadian(60.0f));
-
-    Matrix m = UNIT_MATRIX;
-    translateMatrix(&m, &V(1.0f, 2.0f, 3.0f));
-    rotateMatrix(&m, &q1);
-    rotateMatrix(&m, &q2);
-    rotateMatrix(&m, &q3);
-    translateMatrix(&m, &V(1.0f, 2.0f, 3.0f));
-
-    Matrix check = UNIT_MATRIX;
-    translateMatrix(&check, &V(1.0f, 2.0f, 3.0f));
-    rotateMatrixX(&check, degreeToRadian(48.0f));
-    rotateMatrixY(&check, degreeToRadian(52.0f));
-    rotateMatrixZ(&check, degreeToRadian(60.0f));
-    translateMatrix(&check, &V(1.0f, 2.0f, 3.0f));
+    Core::Quaternion q1(V3(1.0f, 0.0f, 0.0f), Core::degreeToRadian(48.0f));
+    Core::Quaternion q2(V3(0.0f, 1.0f, 0.0f), Core::degreeToRadian(52.0f));
+    Core::Quaternion q3(V3(0.0f, 0.0f, 1.0f), Core::degreeToRadian(60.0f));
+
+    Matrix m;
+    m.translate(V3(1.0f, 2.0f, 3.0f));
+    m.rotate(q1);
+    m.rotate(q2);
+    m.rotate(q3);
+    m.translate(V3(1.0f, 2.0f, 3.0f));
+
+    Matrix check;
+    check.translate(V3(1.0f, 2.0f, 3.0f));
+    check.rotateX(Core::degreeToRadian(48.0f));
+    check.rotateY(Core::degreeToRadian(52.0f));
+    check.rotateZ(Core::degreeToRadian(60.0f));
+    check.translate(V3(1.0f, 2.0f, 3.0f));
 
     for(int i = 0; i < 16; i++) {
-        TEST_FLOAT(((float*)&check)[i], ((float*)&m)[i], 0.0001f);
+        TEST_FLOAT(check.getValues()[i], m.getValues()[i], 0.0001f);
     }
 }
 
 static void testToString() {
     Matrix m;
-    for(int i = 0; i < 16; i++) {
-        ((float*)&m)[i] = (float)i + 1.0f;
-    }
+    m.set(0, Core::Vector4(1.0f, 2.0f, 3.0f, 4.0f));
+    m.set(1, Core::Vector4(5.0f, 6.0f, 7.0f, 8.0f));
+    m.set(2, Core::Vector4(9.0f, 10.0f, 11.0f, 12.0f));
+    m.set(3, Core::Vector4(13.0f, 14.0f, 15.0f, 16.0f));
     char buffer[1024];
-    size_t n = toStringMatrix(&m, buffer, sizeof(buffer));
-    TEST_SIZE(127, n);
+    size_t n = toString(m, buffer, sizeof(buffer));
+    TEST(111, n);
     TEST_STRING(
-        "[[1.000, 2.000, 3.000, 4.000], [5.000, 6.000, 7.000, 8.000], "
-        "[9.000, 10.000, 11.000, 12.000], [13.000, 14.000, 15.000, 16.000]]",
+        "[[1.00, 2.00, 3.00, 4.00], [5.00, 6.00, 7.00, 8.00], "
+        "[9.00, 10.00, 11.00, 12.00], [13.00, 14.00, 15.00, 16.00]]",
         buffer);
-
-    n = toStringMatrix(&m, buffer, 20);
-    TEST_SIZE(127, n);
-    TEST_STRING("[[1.000, 2.000, 3.0", buffer);
+    n = toString(m, buffer, 20);
+    TEST(111, n);
+    TEST_STRING("[[1.00, 2.00, 3.00,", buffer);
 }
 
 void testMatrix() {