When rotation is identical, the rotation of the first dual quaternion is
returned instead, together with the linearly interpolated translation of
both (lerp of the vectors of the dual part). The additional include is
needed for `Math::lerp(Vector<3, T>, Vector<3, T>, T)`.
Signed-off-by: Squareys <Squareys@googlemail.com>
If and only if the quaternions to interpolate are equal, the angle between
them is 0.0 and we therefore cannot safely divide by the sin of that angle.
Credits to @wivlaro for finding this one.
Fixes#117.
Signed-off-by: Squareys <Squareys@googlemail.com>
Making use of sincos() for Dual numbers, constructing DualQuaternion
from dual vector and scalar parts and using
DualQuaternion::isNormalized(). Also updated the math equation to be
consistent with conventions elsewhere.
Mainly a convenience function in case you want to compute sin and cos of
the same, potentially longer expression, and you don't want to have
repeated code or temporary variables. On some architectures might use
faster instruction that computes both values in one shot.
- Use explicit conversion to `T`
- Use `std::` for `acos, cos, sin` to avoid use of double only functions
- Do not mutate variables in math code to avoid confusion
Signed-off-by: Squareys <Squareys@googlemail.com>
Should help people understand the code and counteracts the unreadability
caused by the optimization commit at least a bit.
Signed-off-by: Squareys <Squareys@googlemail.com>
Optimized with simple code tricks, some very complex math (like `2*0.5=1`),
and principal of locality. Things the compiler would probably do for me
anyway. Was able to remove about 6 useless float multiplications.
Signed-off-by: Squareys <Squareys@googlemail.com>
Now works both ways. The base class works with virtually any combination
that is supported by the underlying types, so e.g. Dual<Matrix3<T>>
could be multiplied/divided with Vector3<T> (result is Vector3<T>), with
Matrix3<T> (result is Matrix3<T>) or with T (result is Matrix3<T>).
The macros, on the other hand, because they are there only to help with
implementation of *my* subclasses, restrict that to the two only cases I
need (i.e. multiplication with Dual<T> and Dual<T::Type> and nothing
else). Could be extended in the future if it needs to be.
It worked flawlessly when crosscompiled from Linux, but compiling that
natively causes the linker to loudly complain about undefined references
to ConfigurationValue structs. I think it worked well under 4.9.2 (but
that mess had a slew of other ugly problems, such as complete inability
to produce non-crashing C++11 code under x64). The linker error is
caused only because I tried to reduce binary bloat, so I'm just
disabling that for MinGW and screw that. No problem under MSVC.