Optimization in quaternion::rotationFromTo from Robert Eisele

Turns out we can avoid a square root and a division.
Patch comes even with proof: https://raw.org/proof/quaternion-from-two-vectors
(I also tested it a while and indeed got same results)

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6511 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2023-07-30 16:34:24 +00:00 committed by sfan5
parent 2c086e5fdc
commit fbdc4ee8d5

@ -720,6 +720,8 @@ inline core::quaternion& quaternion::makeIdentity()
inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const vector3df& to) inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const vector3df& to)
{ {
// Based on Stan Melax's article in Game Programming Gems // Based on Stan Melax's article in Game Programming Gems
// Optimized by Robert Eisele: https://raw.org/proof/quaternion-from-two-vectors
// Copy, since cannot modify local // Copy, since cannot modify local
vector3df v0 = from; vector3df v0 = from;
vector3df v1 = to; vector3df v1 = to;
@ -744,10 +746,8 @@ inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const
return set(axis.X, axis.Y, axis.Z, 0).normalize(); return set(axis.X, axis.Y, axis.Z, 0).normalize();
} }
const f32 s = sqrtf( (1+d)*2 ); // optimize inv_sqrt const vector3df c = v0.crossProduct(v1);
const f32 invs = 1.f / s; return set(c.X, c.Y, c.Z, 1 + d).normalize();
const vector3df c = v0.crossProduct(v1)*invs;
return set(c.X, c.Y, c.Z, s * 0.5f).normalize();
} }