Square matrices already had that, (dual) quaternions too, making that
the default also with complex numbers. Updated the documentation to
reflect that.
It's now possible to conveniently transform 2D vectors and points with
3x3 matrices and 3D vectors/points with 4x4 matrices. Previous most
low-level solution:
Matrix4 m;
Vector3 v;
Vector3 a = (m*Vector4(v, 1.0f)).xyz();
Vector4 b = (m*Vector4(v, 0.0f)).xyz();
Another, more generalized solution for points was with Point2D/Point3D,
adding a lot of confusion (what is that class and what does .vector()?):
Vector3 a = (m*Point3D(v)).vector();
And the worst solution was with generic 2D/3D code (WTF!):
auto a = (m*typename DimensionTraits::PointType(v)).vector();
Now it is just this, similar for both dimensions:
Vector3 a = m.transformPoint(v);
Vector3 b = m.transformVector(v);
Note that transformation three-component vectors with 3x3 matrices or
four-component vectors with 4x4 matrices is easy enough so it doesn't
need any special convenience functions whatsoever:
Vector3 c = m.rotation()*v;
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.
Long-standing TODO, can be used for in-game mirrors etc. I give up with
shearing, as I think that it makes sense only in 2D and I can't find any
reasonable use case for that yet.
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.
Now whole Magnum, Magnum::SceneGraph and Magnum::Math namespaces are
fully documented -- each class has at least "getting started"
documentation, larger modules are documented on separate pages.
Matrix3 is for 2D affine transformations, while Matrix4 is for 3D.
Returning Matrix3 would allow doing this, which isn't meaningful
operation at all:
Matrix4 transformation;
Vector2 wtf = transformation.rotationScaling().translation();
Currently moved only non-square functionality from Matrix there. Also
static constant members such as row/column count and size are now
lowercase, as they are variables, not types.