The perf cost is just too great for these to be enabled always. The only
place where the assertions are kept always is in the batch APIs -- there
it's assumed the function is called on large enough data to offset this
overhead, plus since it's often dealing with large blocks of data the
memory safety is more important than various FP drifts which were the
usual case why other assertions were firing.
And update docs in Matrix[34]::rotation() and related functions to note
this. This is a breaking change that may cause existing code to start
asserting.
The old one is deprecated, and will be removed in a future release.
Unfortunately, to avoid deprecation warnings, all use of NoInit in the
Math library temporarily have to be Magnum::NoInit This will be cleaned
up when the deprecated alias is removed.
Turns out this seriously broke properites that should always hold, such
as that R*S = M for a R and S extracted out of M. Another way to fix
this would be flipping signs in the rotation() / rotationShear() / ...
queries as well, but that adds extra operations to both rotation() and
scaling() and at that point it's just better to do what was done the
whole decade before.
To ensure this doesn't happen again and doesn't cost me a whole day of
debugging in an end-user app (SceneGraph TRS transformations got broken
because those assume that rotation() and scaling() *do* combine back,
which is a reasonable thing to assume), the docs are extended to note
this and there's an explicit test for both negative scale and large
angle corner cases as well.
This reverts commit 9aa68715db.
This is a breaking change, but I think it is worth doing. Because now
Matrix4::scaling(vec).scaling() == vec
which was true also for translation and other.
Important: the rotation() accessor now allows non-uniform scaling but
expects orthogonality (previously it allowed non-orthogonal rotation
axes but disallowed non-uniform scaling).
Documentation of all these accessors is further improved now as well.
The compiler does that for us. Probably a brain fart from 2010. On the
other hand, the ConfigurationValue specializations need to be there,
because the type is used explicitly as template parameter.
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.