Square matrices already had that, (dual) quaternions too, making that
the default also with complex numbers. Updated the documentation to
reflect that.
It is now possible to implicitly create one-element Vector and also
explicitly fill more-element Vector with one value without any ambiguous
overload conflicts:
Vector<1, int> a1 = 1; // calls implicit constructor
//Vector<3, int> a3 = 1; // error!
Vector<1, int> b1(1); // still calls the implicit constructor, the
// explicit is disabled for one-element vector
Vector<3, int> b3(1); // calls the explicit "filling" constructor,
// the implicit is disabled for only one argument
The downside of this is that now specifying improper element count in
constructor doesn't lead to static_assert with human readable error, but
rather cryptic "no match" error.
The comparisons have also SIMD instructions returning bool vector, this
future-proofs them. Also it isn't confusing anymore (a < b is true when
all are less or just one?).
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.
* Added math equations to Quaternion, Vector and Matrix method
documentation.
* Removed confusing Quat*=Quat operator overload, as it isn't exactly
clear from which side the non-commutative multiplication is done:
Quaternion a;
a *= b; // eh?
a = a*b; // okay!
For similar reason this operator wasn't present in RectangularMatrix
either.
* Unified documentation of expected vector/quaternion normalization
state. Now it is not "assumed" but "expected", because failing to do
so results in assertion failure.
It prevents unwanted implicit conversions from e.g. nullptr to Camera,
Vector2 to Physics::Point etc. By making all the constructors explicit
it is easier to routinely add the keyword to all new classes instead of
thinking about cases when to add and when not to.
Optimalizations in Corrade::TestSuite and Corrade::Utility::Debug leaded
to significant reduction of compilation time - on my machine it was
~5:38 before with building of unit tests enabled, now only ~5:00.
Lowecase didn't prove to be better, because Doxygen cannot implicitly
link to it and it collides with non-type template parameters and private
variables.
Loop unrolling is better to leave up to the compiler, as it will do it
automatically and it doesn't add any maintenance burden. Constexpr
addition, multiplication etc. of Vector would be nice, but will that be
really useful? Maybe once if at all?