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.
Will allow for more convenient usage of e.g. ShapeGroup operators:
Physics::ObjectShape3D* shape;
shape->setShape(Physics::Sphere3D({}, 0.75f) ||
Physics::AxisAlignedBox3D({}, {3.0f, 1.5f, 2.0f}));
All rendering code computed the transformation/projection matrix the
same way, resulting in redundant calculations. Also the
`transformationMatrix` parameter of internal draw() function was never
used.
FeatureGroup shouldn't delete the features, as all features are deleted
in Object destructor anyway and no feature can be created without
explicitly attaching it to some Object (and it also cannot be detached).
Moreover, when the group contains two features belogning to one object
and one feature is added using multiple inheritance, on group
destruction the object gets deleted along with the feature, removing
also the other feature, which breaks the for cycle in group destructor.
In most cases the names aren't even supported/used and thus it is
wasteful to have them in all *Data classes. If the importer wants to
support them, it would reimplement *name() functions instead.