Domanda

I'm essentially working on a function for slerping and while it kinda works, it's having a weird perspective warping issue that I'm stuck trying to work out right now.

Quaternion sLerp(Quaternion start, Quaternion end, float s)
{
    float dot = qDot(start, end);
    float theta = std::acos(dot);
    float sTheta = std::sin(theta);

    float w1 = sin((1.0f-s)*theta) / sTheta;
    float w2 = sin(s*theta) / sTheta;

    Quaternion Temp(0,0,0,0);

    Temp = start*w1 + end*w2;

    return Temp;
}

Essentially what it's doing (or should be doing) is just slerping between two values to provide a rotation, and the result from this is being converted to a rotation matrix. But what's going wrong is a horribly, horribly stretched view... for some reason during the rotation it stretched everything, starting with everything too long / thin and reaching a midpoint of being much shorter before starting to go back to being thin. Any help would be great.

È stato utile?

Soluzione

Your slerp code seems fine, although one would normally make sure that dot>=0 because otherwise, you're rotating the long way around the circle. In general, it's also important to make sure that dot!=1 because you'll run into divide-by-zero problems.

A proper quaternion should never stretch the view. Either you're passing in non-unit-length quaternions for start or end, or your quaternion-to-matrix code is suspect (or you're getting funky behavior because the angle between the two quaternions is very small and you're dividing by almost zero).


My code for converting from quaternion to a matrix for use in OpenGL:

// First row
glMat[ 0] = 1.0f - 2.0f * ( q[1] * q[1] + q[2] * q[2] );
glMat[ 1] = 2.0f * (q[0] * q[1] + q[2] * q[3]);
glMat[ 2] = 2.0f * (q[0] * q[2] - q[1] * q[3]);
glMat[ 3] = 0.0f;

// Second row
glMat[ 4] = 2.0f * ( q[0] * q[1] - q[2] * q[3] );
glMat[ 5] = 1.0f - 2.0f * ( q[0] * q[0] + q[2] * q[2] );
glMat[ 6] = 2.0f * (q[2] * q[1] + q[0] * q[3] );
glMat[ 7] = 0.0f;

// Third row
glMat[ 8] = 2.0f * ( q[0] * q[2] + q[1] * q[3] );
glMat[ 9] = 2.0f * ( q[1] * q[2] - q[0] * q[3] );
glMat[10] = 1.0f - 2.0f * ( q[0] * q[0] + q[1] * q[1] );
glMat[11] = 0.0f;

// Fourth row
glMat[12] = 0.0;
glMat[13] = 0.0;
glMat[14] = 0.0;
glMat[15] = 1.0f;

Altri suggerimenti

Do you need to normalise the quaternion?

I think the following:

float sTheta = std::sin(theta);

should be:

float sTheta = sqrt(1.0f - sqr(theta));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top