# Quaternions has a 90 deg dead angle

This topic is 4766 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi I am using quaternions for both animations and my camera and I am encountering the same problem in both cases. It seems like the quaternions have a dead angle of 90 degrees. Passing that angle will either make the quaternion roll around rotating the other direction, or break it. By break it I mean that any rotation matrix made from the quaternion ends up havid bad right, up, and at vectors causing the entire frustum to collapse in the camera case. In the animations some joints sometime flip around an entire lap and get twisted. Here are the funcitons I use. Sorry if its a lot of code I'm kind of new to quaternions so go easy on me please // SLERP void SiCQuaternion::Slerp(const SiVector4T *pQuaternion1, const SiVector4T *pQuaternion2, float fDelta) { SiVector4T v4Quat2 = *pQuaternion2; float fDot = pQuaternion1->Dot(*pQuaternion2); if( fDot < 0.0f ) { fDot =-fDot; v4Quat2.fX = -v4Quat2.fX; v4Quat2.fY = -v4Quat2.fY; v4Quat2.fZ = -v4Quat2.fZ; v4Quat2.fW = -v4Quat2.fW; } if (fDot <= 1.f && fDot > 0.999f) { Lerp(pQuaternion1, &v4Quat2, fDelta); return; } float fTheta = acosf(fDot); float fT = 1.f / sinf(fTheta); m_v4Quaternion.Add(*pQuaternion1 * sinf( (1.f - fDelta) * fTheta), v4Quat2 * sinf(fDelta * fTheta)); m_v4Quaternion = m_v4Quaternion * fT; } // BUILD ROTATION MATRIX float fWX, fWY, fWZ, fXX, fYY, fZZ, fYZ, fXY, fXZ, fX2, fY2, fZ2; // Clean the matrix memset(pOutMatrix, 0, sizeof(SiMatrix4T)); pOutMatrix->_44 = 1.0f; fX2 = m_v4Quaternion.fX + m_v4Quaternion.fX; fY2 = m_v4Quaternion.fY + m_v4Quaternion.fY; fZ2 = m_v4Quaternion.fZ + m_v4Quaternion.fZ; fXX = m_v4Quaternion.fX * fX2; fYY = m_v4Quaternion.fY * fY2; fZZ = m_v4Quaternion.fZ * fZ2; fXY = m_v4Quaternion.fX * fY2; fXZ = m_v4Quaternion.fX * fZ2; fYZ = m_v4Quaternion.fY * fZ2; fWX = m_v4Quaternion.fW * fX2; fWY = m_v4Quaternion.fW * fY2; fWZ = m_v4Quaternion.fW * fZ2; pOutMatrix->_11 = 1.f - (fYY + fZZ); pOutMatrix->_12 = fXY - fWZ; pOutMatrix->_13 = fXZ + fWY; pOutMatrix->_21 = fXY + fWZ; pOutMatrix->_22 = 1.f - (fXX + fZZ); pOutMatrix->_23 = fYZ - fWX; pOutMatrix->_31 = fXZ - fWY; pOutMatrix->_32 = fYZ + fWX; pOutMatrix->_33 = 1.f - (fXX + fYY); } // And finally build from matrix. This can not be the problem in the animation case since I export quaternions from maya { float fTemp = pMatrix->_11 + pMatrix->_22 + pMatrix->_33 + pMatrix->_44; float fFour; int i,j,k; if (fTemp >= 1.f) { fFour = 2.f * sqrt(fTemp); m_v4Quaternion.fW = fFour * 0.25f; m_v4Quaternion.fX = (pMatrix->_32 - pMatrix->_23) / fFour; m_v4Quaternion.fY = (pMatrix->_13 - pMatrix->_31) / fFour; m_v4Quaternion.fZ = (pMatrix->_21 - pMatrix->_12) / fFour; } else { if (pMatrix->_11 > pMatrix->_22) { i = 0; } else { i = 1; } if (pMatrix->_33 > pMatrix->fMatrix[i * 4 + 4]) { i = 2; } j = (i+1)%3; k = (j+1)%3; fFour = 2.f * sqrt(pMatrix->fMatrix[i * 4 + i] - pMatrix->fMatrix[i * 4 + i] - pMatrix->fMatrix[k * 4 + k] + 1.f); m_v4Quaternion.fVec = fFour * 0.25f; m_v4Quaternion.fVec[j] = (pMatrix->fMatrix[j* 4 + i] + pMatrix->fMatrix[i* 4 + j]) / fFour; m_v4Quaternion.fVec[k] = (pMatrix->fMatrix[k* 4 + i] + pMatrix->fMatrix[i* 4 + k]) / fFour; m_v4Quaternion.fW = (pMatrix->fMatrix[j * 4 + k] - pMatrix->fMatrix[k * 4 + j]) / fFour; } Thanks

##### Share on other sites
Quote:
 Original post by tealrabbit// And finally build from matrix. This can not be the problem in the animation case since I export quaternions from maya

and
Quote:
 fFour = 2.f * sqrt(pMatrix->fMatrix[i * 4 + i] - pMatrix->fMatrix[i * 4 + i] - pMatrix->fMatrix[k * 4 + k] + 1.f);

Is this correct?

##### Share on other sites
In addition to the line Dave pointed out, I think you may also have a problem in this line:

if (pMatrix->_33 > pMatrix->fMatrix[i * 4 + 4])

Also it seems that your slerp function could fail if the two input quaternions are very close to equal. To avoid this I would change this line:

if (fDot <= 1.f && fDot > 0.999f)

To:

if (fDot > 0.999f)

##### Share on other sites
Thanks a lot for the quick answers. You where both right. Those two fixes took care of the quaternions breaking and making bad matrices. The only problem now is that the quaternions still seems to switch direction when they hit a certain angle and get "inverted".

This is in the Lerp or Slerp I am pretty sure.

Thanks for the help. I'm sure I'll figure this out.

##### Share on other sites
Quote:
 Original post by tealrabbitThe only problem now is that the quaternions still seems to switch direction when they hit a certain angle and get "inverted".This is in the Lerp or Slerp I am pretty sure.

This is fairly common with Lerp and Slerp algorithms, it happens whenever the quaternions are are at such a rotation that any axis will do for the rotation. My fix was to use the first quaternions up vector as the axis for the rotation, if any axis is acceptable.

Sorry if that isn't very clear,

SwiftCoder

##### Share on other sites
regarding the "switching directions" on your interpolation.
i'm imagining that you have these keyframes:

time 0: 0 degrees
time 30: 90 degrees
time 60: 0 degrees.

at time 31, there is nothing in the slerp math that can tell which direction you want to go in -- it can't tell whether 91 or 89 degrees is the right answer for frame 31..

the solution is to have your artist put in keyframes at, say, time 45..
or to put them in programmaticall as you are pulling the animation out of maya.

that's what we do where i work.

1. 1
2. 2
Rutin
19
3. 3
JoeJ
16
4. 4
5. 5

• 35
• 23
• 13
• 13
• 17
• ### Forum Statistics

• Total Topics
631701
• Total Posts
3001810
×