Index: source/gui/ObjectTypes/CMiniMap.cpp =================================================================== --- source/gui/ObjectTypes/CMiniMap.cpp +++ source/gui/ObjectTypes/CMiniMap.cpp @@ -608,7 +608,7 @@ // Move the minimap to it's final location. unitMatrix.Translate(x, y, 0.0f); // Apply the gui matrix. - unitMatrix *= GetDefaultGuiMatrix(); + unitMatrix.Concatenate(GetDefaultGuiMatrix()); // Load the transform into the shader. shader->Uniform(str_transform, unitMatrix); Index: source/lib/self_test.h =================================================================== --- source/lib/self_test.h +++ source/lib/self_test.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -24,8 +24,9 @@ #define INCLUDED_SELF_TEST // for convenience, to avoid having to include all of these manually -#include "lib/status.h" +#include "lib/lib.h" #include "lib/os_path.h" +#include "lib/status.h" #include "lib/posix/posix.h" #define CXXTEST_HAVE_EH @@ -147,6 +148,14 @@ #define TS_ASSERT_VECTOR_EQUALS_ARRAY(vec1, array) TS_ASSERT_EQUALS(vec1, ts_make_vector((array), sizeof(array))) #define TS_ASSERT_VECTOR_CONTAINS(vec1, element) TS_ASSERT(std::find((vec1).begin(), (vec1).end(), element) != (vec1).end()); +#define TS_ASSERT_MATRIX_EQUALS_DELTA(m1, m2, size, epsilon) \ + for (int j = 0; j < size; ++j) \ + TS_ASSERT_DELTA(m1._data[j], m2._data[j], epsilon); + +#define TS_ASSERT_MATRIX_DIFFERS_DELTA(m1, m2, size, epsilon) \ + for (int j = 0; j < size; ++j) \ + TS_ASSERT(!feq(m1._data[j], m2._data[j], epsilon)); + class ScriptInterface; // Script-based testing setup (defined in test_setup.cpp). Defines TS_* functions. void ScriptTestSetup(const ScriptInterface&); Index: source/maths/Matrix3D.h =================================================================== --- source/maths/Matrix3D.h +++ source/maths/Matrix3D.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -126,8 +126,7 @@ // matrix multiplication/assignment CMatrix3D& operator*=(const CMatrix3D &matrix) { - Concatenate(matrix); - return *this; + return *this = *this * matrix; } // matrix scaling Index: source/maths/tests/test_Matrix3d.h =================================================================== --- source/maths/tests/test_Matrix3d.h +++ source/maths/tests/test_Matrix3d.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -50,6 +50,44 @@ } } + void test_compoundMultiplication() + { + const float EPS = 2e-4f; + float invertibleData[16] = { + 2.f, -3.f, 0.f, 1.f, + -2.f, 3.f, 0.f, 0.f, + 1.f, -2.f, 1.f, 0.f, + 1.f, -1.f, 0.f, 0.f + }; + + // Invertible matrix. + CMatrix3D a(invertibleData); + CMatrix3D n; + a.GetInverse(n); + a *= n; + CMatrix3D a2(invertibleData); + n *= a2; + + + TS_ASSERT_MATRIX_EQUALS_DELTA(a, n, 16, EPS); + + // Non invertible matrix. + float nonInvertibleData[16] = { + 2.f, -3.f, 0.f, 1.f, + -2.f, 3.f, 0.f, 0.f, + 1.f, -2.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 0.f + }; + + CMatrix3D b(nonInvertibleData); + b.GetInverse(n); + b *= n; + CMatrix3D b2(nonInvertibleData); + n *= b2; + + TS_ASSERT_MATRIX_DIFFERS_DELTA(b, n, 16, EPS); + } + void test_quats() { srand(0);