Remove redundant code from quaternion class

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3699 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2011-05-04 15:09:43 +00:00
parent ba7ea55a6f
commit 2f8b537d25
2 changed files with 105 additions and 26 deletions

View File

@ -120,7 +120,10 @@ class quaternion
//! Inverts this quaternion
quaternion& makeInverse();
//! Set this quaternion to the result of the interpolation between two quaternions
//! Set this quaternion to the result of the linear interpolation between two quaternions
quaternion& quaternion::lerp(quaternion q1, quaternion q2, f32 time);
//! Set this quaternion to the result of the spherical interpolation between two quaternions
quaternion& slerp( quaternion q1, quaternion q2, f32 interpolate );
//! Create quaternion from rotation angle and rotation axis.
@ -490,43 +493,37 @@ inline quaternion& quaternion::normalize()
}
// set this quaternion to the result of the linear interpolation between two quaternions
inline quaternion& quaternion::lerp(quaternion q1, quaternion q2, f32 time)
{
const f32 scale = 1.0f - time;
const f32 invscale = time;
return (*this = (q1*scale) + (q2*invscale));
}
// set this quaternion to the result of the interpolation between two quaternions
inline quaternion& quaternion::slerp(quaternion q1, quaternion q2, f32 time)
{
f32 angle = q1.dotProduct(q2);
// make sure we use the short rotation
if (angle < 0.0f)
{
q1 *= -1.0f;
angle *= -1.0f;
}
f32 scale;
f32 invscale;
if ((angle + 1.0f) > 0.05f)
{
if ((1.0f - angle) >= 0.05f) // spherical interpolation
if (angle <= 0.95f) // spherical interpolation
{
const f32 theta = acosf(angle);
const f32 invsintheta = reciprocal(sinf(theta));
scale = sinf(theta * (1.0f-time)) * invsintheta;
invscale = sinf(theta * time) * invsintheta;
const f32 scale = sinf(theta * (1.0f-time)) * invsintheta;
const f32 invscale = sinf(theta * time) * invsintheta;
return (*this = (q1*scale) + (q2*invscale));
}
else // linear interploation
{
scale = 1.0f - time;
invscale = time;
}
}
else
{
q2.set(-q1.Y, q1.X, -q1.W, q1.Z);
scale = sinf(PI * (0.5f - time));
invscale = sinf(PI * time);
}
return (*this = (q1*scale) + (q2*invscale));
return lerp(q1,q2,time);
}

View File

@ -133,6 +133,88 @@ bool testRotationFromTo()
}
return result;
}
bool testInterpolation()
{
bool result=true;
core::quaternion q(1.f,2.f,3.f,4.f);
core::quaternion q2;
q2.lerp(q,q,0);
if (q != q2)
{
logTestString("Quaternion lerp with same quaternion did not yield same quaternion back (with t==0).\n");
result = false;
}
q2.lerp(q,q,0.5f);
if (q != q2)
{
logTestString("Quaternion lerp with same quaternion did not yield same quaternion back (with t==0.5).\n");
result = false;
}
q2.lerp(q,q,1);
if (q != q2)
{
logTestString("Quaternion lerp with same quaternion did not yield same quaternion back (with t==1).\n");
result = false;
}
q2.lerp(q,q,0.2345f);
if (q != q2)
{
logTestString("Quaternion lerp with same quaternion did not yield same quaternion back (with t==0.2345).\n");
result = false;
}
q2.slerp(q,q,0);
if (q != q2)
{
logTestString("Quaternion slerp with same quaternion did not yield same quaternion back (with t==0).\n");
result = false;
}
q2.slerp(q,q,0.5f);
if (q != q2)
{
logTestString("Quaternion slerp with same quaternion did not yield same quaternion back (with t==0.5).\n");
result = false;
}
q2.slerp(q,q,1);
if (q != q2)
{
logTestString("Quaternion slerp with same quaternion did not yield same quaternion back (with t==1).\n");
result = false;
}
q2.slerp(q,q,0.2345f);
if (q != q2)
{
logTestString("Quaternion slerp with same quaternion did not yield same quaternion back (with t==0.2345).\n");
result = false;
}
core::quaternion q3(core::vector3df(45,135,85)*core::DEGTORAD);
q.set(core::vector3df(35,125,75)*core::DEGTORAD);
q2.slerp(q,q3,0);
if (q != q2)
{
logTestString("Quaternion slerp with different quaternions did not yield first quaternion back (with t==0).\n");
result = false;
}
q2.slerp(q,q3,1);
if (q3 != q2)
{
logTestString("Quaternion slerp with different quaternions did not yield second quaternion back (with t==1).\n");
result = false;
}
q2.slerp(q,q3,0.5);
if (!q2.equals(core::quaternion(-0.437f,0.742f,0.017f,0.506f),0.001f))
{
logTestString("Quaternion slerp with different quaternions did not yield correct result (with t==0.5).\n");
result = false;
}
q2.slerp(q,q3,0.2345f);
if (!q2.equals(core::quaternion(-0.4202f,0.7499f,0.03814f,0.5093f),0.0007f))
{
logTestString("Quaternion slerp with different quaternions did not yield correct result (with t==0.2345).\n");
result = false;
}
return result;
}
}
bool testQuaternion(void)
@ -172,7 +254,7 @@ bool testQuaternion(void)
}
result &= testRotationFromTo();
result &= testInterpolation();
result &= testEulerConversion();
return result;