# Quaternion problem (with exe)

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

## Recommended Posts

I recently finished doing skeletal animation, but every once in awhile, there will be bones which dont seem to animate the way they should. In other words, they dont take the path they should and rotate weirdly. Example Here Click on the Skeletal.zip link. [Edited by - GamerSg on September 23, 2004 1:55:44 AM]

##### Share on other sites
Odd, looks like your getting scaling with the rotation. Can't help you much without some code though....

##### Share on other sites
There is totally no scaling/translation in my code, so im only doing rotation via quaternions. As you can see, it works normally for all the other bones, but screws up for the right hand.

##### Share on other sites
Maybe your animation matrices do not match with the amount of reference matrices.

In other words:
if your reference mesh has 25 BONES and your animation does not,
every time you transform the inverted world vertices wia tha animation world matrix, you have to check if it is the same, for example:

for ( i=every bone in reference mesh )
for ( j=every bone in animation mesh )
if ( ref_bone.name == anim_bone.name )
do transform
else
keep reference bone.

##### Share on other sites
I was thinking the problem lies more with my Quaternion Interpolation, if you observe the animation closely, the figure is doing a jumping jack (couldnt think of any other animation) which goes something like this (in keyframes)
1) o|  | ||2)__ o __  | |  / \ 3) o|  | ||4) \ o /  | |  /

If you notice, the right hand does reach the keyframes. The problem lies with the path it takes to reach the next keyframe. For some reason, the left hand seems to work well.

##### Share on other sites
Perhaps you need to normalize some quaternions somewhere... like after transforming a child bone's rotation by a parent bone's? (Your download link didnt work when I tried so couldn't get a better look)

I've had some pretty interesting looking animations before when I forgot to normalize.

##### Share on other sites

Is it a must to normalize?
When should i normalise?
Obviously normalizing every quaternion is going to result in quite a hit in performance?

##### Share on other sites
You certainly need to normalise before you build a rotation matrix from your quaternion (unless your quat to matrix routine auto-normalises), otherwise you'll get shearing or scaling problems.
You don't need to normalise every time you multiply quaternions together.

##### Share on other sites
Hmm i just looked through my code and realised that i am not doing the rotation multiplication with quaternions, instead im converting a bone's quaternion to a matrix first, before multiplying the matrix with the parents matrix.

Also, all my quaternions are normalised before they are exported.

##### Share on other sites
Still stuck with no clues.

Here is my quaternion interpolation code which i had obtained from the quaternion article on gamasutra.
void Math::InterpolateQuat(Quat& first,Quat& second,Quat& result,float time){	//Interpolates between 2 quaternions based on time factor ranging from 0-1	//Variables	double cosine;	Quat temp;	//temp quaternion	float scale0,scale1;	//dot product between the 2 quats			cosine = first.x * second.x + first.y * second.y + first.z * second.z + first.w * second.w;		if(cosine<0.0)		{			//if it is negative, make it positive			cosine = -cosine;			temp.x = -second.x;			temp.y = -second.y;			temp.z = -second.z;			temp.w = -second.w;		}		else		{			temp.x = second.x;			temp.y = second.y;			temp.z = second.z;			temp.w = second.w;		}		if ( (1.0 - cosine) > 0.0001 ) {			double omega, sinom;			// standard case (slerp)			omega = acos(cosine);			sinom = sin(omega);			scale0 = static_cast<float>(sin((1.0 - time) * omega) / sinom);			scale1 = static_cast<float>(sin(time * omega) / sinom);		}		else {//else do LERP			scale0 = 1.0f - time;			scale1 = time;				}		result.x = first.x * scale0 + second.x * scale1;	result.y = first.y * scale0 + second.y * scale1;	result.z = first.z * scale0 + second.z * scale1;	result.w = first.w * scale0 + second.w * scale1;}

• 17
• 10
• 21
• 16
• 9