Previously it was possible to access internal transformation
implementation from Transformation and thus also from Object, e.g.:
typedef SceneGraph::Object<SceneGraph::MatrixTransformation2D> Object2D;
Object2D o;
o.fromMatrix(...); // What does this here and why it returns matrix?!
Now everything is hidden in Implementation namespace and all
traces of previous code are removed from documentation. It might now be
slightly harder for users to implement their own transformation
implementations, but it wasn't easy before either. The widely used ones
are already implemented, so it shouldn't be too much of a problem.
Similarly for potential backward compatibility issues, I assume nobody
needed to implement their own transformation yet.
Makes some cases less consistent (and some convenience shortcuts
impossible), but goes well with the attitude "don't use pointer when it
can't be null".
Until now, all calls to e.g. `Object::translate()` were virtual, which
is _very_ bad for performance. The virtual call is only needed when
setting the transformation via some interface, e.g.
`AbstractTranslationRotation3D`, as the caller doesn't know which
transformation implementation is used.
Now all public-facing transformation methods are inline non-virtual
functions, which are in most cases calling directly the transformation
implementation. In `Abstract*` transformation interfaces these functions
call private virtual `do*()` implementations, which are (re)implemented
in subclasses, but aren't used anywhere except when transforming
directly through the `Abstract*` interfaces. This should have good
impact on performance when doing many transformations in every frame
(although I can't verify it anywhere, as I don't have any significantly
large animated demo). Except of course when doing it through the virtual
interfaces.
As the public-facing transformation methods are now non-virtual, there
are now no "covariant return" issues and they can now return proper
`Object<*Transformation*>` type instead of just `*Transformation*`,
which makes full non-WTF method chaining possible:
Object2D* obj2;
obj2->translate({0.5f, -1.0f}) // Transformation method
->setParentKeepTransformation(obj1); // Object method
Or even this:
Object2D* obj = (new Object2D)->rotate(-15.0_degf);