Sign in to follow this  
quasar3d

quaternions?

Recommended Posts

quasar3d    814
I am trying to use quaternions for my animations, but I can't really get them working correctly. I made a plugin for maya, which gets the quaternion from the items transformation matrix. Most of the time this seems to work fine, but especially if I try to blend between multiply animations, it sometimes gives very weird results. I think the problem has something to do with the fact that you can represent each rotation by 2 diffent quaternions. I did a little test with a cube which rotates only around it's x axis. This is a part of the quaternion keyframes I got, and there is indead a flip of signs: <key t = "5" value = ".7330, -.6801, 0, 0"/> <key t = "6" value = ".6234, -.7818, 0, 0"/> <key t = "7" value = "-.4999, .8660, 0, 0"/> <key t = "8" value = "-.3653, .9308, 0, 0"/> Is there a way to get the quaternions in a way that those sign flips won't occur? This is my matrix to quaternion code
Quaternion Matrix4::ToQuaternion() const
{
	float trace = m[0][0] + m[1][1] + m[2][2];
	
	if(trace > 0)
	{
		float root = sqrtf(trace + 1);

		Quaternion ret;
		ret.w = root * .5f;
		root = .5f / root;
		ret.x = (m[2][1] - m[1][2]) * root;
		ret.y = (m[0][2] - m[2][0]) * root;
		ret.z = (m[1][0] - m[0][1]) * root;
		ret.Normalize();
		return ret;
	}
	else
	{
		const int next[] = {1,2,0};
		int i = 0;
		if(m[1][1] > m[0][0])
			i = 1;
		if(m[2][2] > m[i][i])
			i = 2;
		int j = next[i];
		int k = next[j];

		float root = sqrtf(m[i][i] - m[j][j] - m[k][k] + 1);

		Quaternion ret;
		ret.vec[i] = root * .5f;
		root = .5f / root;
		ret.w = (m[k][j] - m[j][k]) * root;
		ret.vec[j] = (m[j][i] + m[i][j]) * root;
		ret.vec[k] = (m[k][i] + m[i][k]) * root;
		ret.Normalize();
		return ret;
	}
}


Share this post


Link to post
Share on other sites
Fruny    1658
Quote:
Is there a way to get the quaternions in a way that those sign flips won't occur?


Negating the quaternion when necessary to keep the w coordinate always positive should work OK.

Share this post


Link to post
Share on other sites
Dave Eberly    1173
Quote:
Original post by Fruny
Quote:
Is there a way to get the quaternions in a way that those sign flips won't occur?


Negating the quaternion when necessary to keep the w coordinate always positive should work OK.


Actually, no (from experience trying this with real data sets). What you need to do is make sure the angle between consecutive quaternions is acute. If q0 and q1 are those quaternions, if Dot(q0,q1) >= 0 then interpolate q0 and q1. If Dot(q0,q1) < 0 then interpolate q0 and -q1. In my own applications, I preprocess quaternion sequences so that the dot product is always nonnegative, thus avoiding the dot-product test at run time.

Share this post


Link to post
Share on other sites
quasar3d    814
Quote:
Original post by Dave Eberly
Quote:
Original post by Fruny
Quote:
Is there a way to get the quaternions in a way that those sign flips won't occur?


Negating the quaternion when necessary to keep the w coordinate always positive should work OK.


Actually, no (from experience trying this with real data sets). What you need to do is make sure the angle between consecutive quaternions is acute. If q0 and q1 are those quaternions, if Dot(q0,q1) >= 0 then interpolate q0 and q1. If Dot(q0,q1) < 0 then interpolate q0 and -q1. In my own applications, I preprocess quaternion sequences so that the dot product is always nonnegative, thus avoiding the dot-product test at run time.


Thanks alot man, this works perfectly.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this