Useful for squeezing out last bits of performance, e.g. in this case:
Vector3 a;
a[0] = something++;
a[1] = something++;
a[2] = something++;
In the code all elements are first zeroed out and then overwritten
later, thus it might be good to avoid the zero-initialization:
Vector3 a{Math::NoInit};
a[0] = something++;
a[1] = something++;
a[2] = something++;
This will of course be more useful in far larger data types and arrays
of these.
Some classes are by default constructed zero-filled while other are set
to identity and the only way to to check this is to look into the
documentation. This changes the default constructor of all classes to
take an optional "tag" which acts as documentation about how the type is
constructed. Note that this result in no behavioral changes, just
ability to be more explicit when writing the code. Example:
// These two are equivalent
Quaternion q1;
Quaternion q2{Math::IdentityInit};
// These two are equivalent
Vector4 vec1;
Vector4 vec2{Math::ZeroInit};
Matrix4 a{Math::IdentityInit, 2}; // 2 on diagonal
Matrix4 b{Math::ZeroInit}; // all zero
This functionality was already present in some ugly form in Matrix,
Matrix3 and Matrix4 classes. It was long and ugly to write, so it is
now generalized into the new Math::IdentityInit and Math::ZeroInit tags,
the original Matrix::IdentityType, Matrix::Identity, Matrix::ZeroType
and Matrix::Zero are deprecated and will be removed in the future
release.
Math::Matrix<7, Int> m{Math::Matrix<7, Int>::Identity}; // before
Math::Matrix<7, Int> m{Math::IdentityInit}; // now
The only places where they aren't absolute are:
- when header is included from corresponding source file
- when including headers which are not part of final installation (e.g.
test-specific configuration, headers from Implementation/)
Everything what was in src/ is now in src/Corrade, everything from
src/Plugins is now in src/MagnumPlugins, everything from external/ is in
src/MagnumExternal. Added new CMakeLists.txt file and updated the other
ones for the moves, no other change was made. If MAGNUM_BUILD_DEPRECATED
is set, everything compiles and installs like previously except for the
plugins, which are now in MagnumPlugins and not in Magnum/Plugins.
Besides all the good things it is now possible to do even more insane
and useless constexpr-fu:
constexpr auto a = Math::Matrix3x3<Int>::fromDiagonal({1, 3, 2});
/* 7 0
0 7 */
constexpr Math::Matrix<a.diagonal()[2], Int> c(7);
The pointer conversion can be done only explicitly, thus the users will
always know what they are doing. With that change, perfectly valid
things like this couldn't be done (the result of a + b is kept until the
semicolon):
Vector3 a, b;
void foo(float* data);
foo((a + b).data());
Moreover this conversion wasn't even properly tested, leading to issues
as in mosra/corrade@781f5df38a7b1b366f3de477dd5fe641eca6ed20.
This reverts commit add989703e.
There are more cases that should be fixed, but this is the most
problematic one, as this might look completely innocent:
Vector2 a, b;
float* c = (a + b).data();
Unlike this, which looks suspicious:
Vector2& c = a + b;
They were already in Magnum namespace for floats and doubles, now they
can be used also for generic type (e.g. use `Math::Matrix2x3<T>` instead
of overly verbose `Math::RectangularMatrix<2, 3, T>`). GCC 4.7+ only.
We would need to duplicate all the functionality found in Vector, which
I don't think is needed at all. If anyone needs to do this, it is
possible to "linearize" the matrix into long vector and do the
operations on it.
Also updated subclass operator implementation, added tests for it, both
for proper returned value and proper result type.
Also fixed unary RectangularMatrix::operator-() and Vector::operator-()
documentation (was stating that the operation is done in-place, which is
impossible.
First, removed functions which can be done with Vector's member
functions and functions from Functions.h. More flexibility and less
redundant code which leads to easier SIMD implementation later.
Vector4 a;
Float b = a.maxAbs(); // before
Float b = Math::abs(a).max(); // now
Second, removed all functions from RectangularMatrix which are
implemented in Vector and added conversion from RectangularMatrix to
Vector and back. Also for more flexibility and less redundant code (i.e.
reusing SIMD-optimized Vector::max() instead of writing it again).
Matrix4x3 a;
Float b = a.max(); // before
Float b = a.toVector().max(); // now
It does too much harm on GCC 4.6 (all these constexpr constructors are
not constexpr now). We can disable that `-pedantic` warning for GCC 4.6
only and live with that.
This reverts commit 2d92d497d9.
Awesome bug. In GCC 4.6 it throws plenty of ungoogleable `-pedantic`
warnings and in GCC 4.5 it fails directly with "error: bad array
initializer". Fallback to initialization using for-cycle.
Hello, performance? You can go home now.
Also updated all dependent classes to follow the change, such as Color
and Rectangle. Backwards compatibility for GCC 4.6 (with lack of support
for delegating constructors) will be done as non-constexpr constructor
using operator=().
Overall architecture is simplififed with this change and also it's not
needed to use reinterpret_cast in matrix internals anymore, thus there
is no need for operator() and [][] works now always as expected without
any risk of GCC misoptimizations.
On the other side, constructing matrix from list of elements is not
possible anymore. You have to specify the elements as list of
column vectors, which might be less convenient to write, but it helps to
distinguish what is column and what is row:
Matrix<2, int> a(1, 2, // before
3, 4);
Matrix<2, int> a(Vector<2, int>(1, 2), // now
Vector<2, int>(3, 4));
For some matrix specializations (i.e. Matrix3 and Matrix4) it is
possible to use list-initialization instead of explicit type
specification:
Matrix<3, int>({1, 2, 3},
{4, 5, 6},
{7, 8, 9});
I didn't yet figure out how to properly implement the general
(constexpr) constructor to also take lists, so it's a bit ugly for now.
Matrix operations are now done column-wise, which should help with
future SIMD implementations, documentation is also updated accordingly.
I also removed forgotten remains of matrix/matrix operator*=(), which
can be confusing, as the multiplication is not commutative. Why it is
not present is explained in d9c900f076.
Removed workarounds for alias templates, variadic templates and
anonymous enums, but 1.8.2 has some bug with forward declarations
causing classes to appear in default namespace, breaking
cross-references.