Skip to main content
gamedev.net
🔒 Locked 🎮 Unity

Rotation Problem

Started by jpmcmu Dec 19, 2008 at 12:52 AM 4 replies 1.4k views
Original Post
jpmcmu
jpmcmu
I am trying to rotate an object toward a location in space. I have the math for rotating one vector towards another down just fine, and it all works. However, when I multiple the resulting rotation on to the matrix stack, the resulting rotation is not what I expected. The rotations come out as a left-handed rotation and what seems to be local rotations. The object is original facing the -z axis (0.0,0.0,-1.0). I rotate the object to face the positive y axis (0.0,1.0,0.0). The heading vector says its facing the positive y axis but the object ends up facing the -y axis. If I then rotate it to face the negative x axis the object ends up rotating around the y axis, but the heading vector ends up facing the correct position. Any help would be greatly appreciated. Create rotation to turn one vector into another

// TODO: needs optimizing 
quaternion::quaternion(const vec3d& from, const vec3d& to)
{
	vec3d current = from;
	vec3d target = to;
	
	target.normalize();
	current.normalize();
	
	double angle = acos( current.dot(target) ) * TO_DEGREES;
	vec3d axis = current.cross(target);
	
	if ( fabs(angle) <= 0.00001)
	{
		*this = quaternion();
		return;
	}
	
	if ( fabs(angle -180.0) <= 0.00001 )
	{
		vec3d temp;
		if( fabs(from.i) < fabs(from.j) )
		{
			if( fabs(from.i) < fabs(from.k) )
				temp.set(1.0,0.0,0.0);
			else
				temp.set(0.0,0.0,1.0);
		}
		else if( fabs( from.j) < fabs(from.k) )
			temp.set(0.0,1.0,0.0);
		else
			temp.set(0.0,0.0,1.0);
			
		axis = from.cross(temp);
	}
	
	*this = quaternion(angle,axis);
}

Quaternion to matrix code

matrix quaternion::toMatrix() const
{
	matrix _matrix;
	
	// Pre-compute quat combinations
	double xw = _quat[1]*_quat[0],
		   xx = _quat[1]*_quat[1],
	       xy = _quat[1]*_quat[2],
	       xz = _quat[1]*_quat[3],
	       
	       yw = _quat[2]*_quat[0],
	       yy = _quat[2]*_quat[2],
	       yz = _quat[2]*_quat[3],
	       
	       zw = _quat[3]*_quat[0],
	       zz = _quat[3]*_quat[3];
	
	// Apply quat combinations
	_matrix[0] = 1.0-2.0*(yy + zz);
	_matrix[1] = 2.0*(xy - zw);
	_matrix[2] = 2.0*(xz + yw);
	_matrix[3] = 0.0;
	_matrix[4] = 2.0*(xy + zw);
	_matrix[5] = 1.0-2.0*(xx + zz);
	_matrix[6] = 2.0*(yz - xw);
	_matrix[7] = 0.0;
	_matrix[8] = 2.0*(xz - yw);
	_matrix[9] = 2.0*(yz + xw);
	_matrix[10] =1.0 -2.0*(xx + yy);
	_matrix[11] = 0.0;
	_matrix[12] = 0.0;
	_matrix[13] = 0.0;
	_matrix[14] = 0.0;
	_matrix[15] = 1.0;
	
	return _matrix;
}

What I do with the code above

_rotation = quaternion(heading,target) * _rotation;

glPushMatrix();
glMultMatrixd( _rotation.toMatrix() );
glPopMatrix();

Sleep is for the weak, or at least that is what I tell myself every morning.
alvaro
alvaro
It looks to me like you want to do
_rotation = _rotation * quaternion(heading,target);


EDIT: If that doesn't fix your problem, I suggest you run it through a debugger and check the intermediate results. You can also simply add a bunch of print statements while you debug the problem.

[Edited by - alvaro on December 19, 2008 10:24:02 AM]
jpmcmu
jpmcmu
Thanks for the reply. _rotation is a quaternion, and quaternion multiplication is not commutative so it should be _rotation = new_quat * _old_quat; I have been running through a debugger and the resulting rotation is correct. When I rotate a vector with the resulting rotation it faces the point I want.

I just can't seem to find out why the object in the game is not rotated correctly. As far as I can tell the toMatrix() code is correct. Since the rotation can rotate a heading vector towards the correct position, doesn't this mean that the same rotation can rotate an object towards that point? Instead of converting the quaternion to a matrix should I be using it to rotate heading, up, and right vectors and then create a matrix from those? I guess ill try this later, off to work.. hobbies don't pay bills..
Sleep is for the weak, or at least that is what I tell myself every morning.
alvaro
alvaro
Quote:
Original post by jpmcmu
Thanks for the reply. _rotation is a quaternion, and quaternion multiplication is not commutative so it should be _rotation = new_quat * _old_quat; I have been running through a debugger and the resulting rotation is correct. When I rotate a vector with the resulting rotation it faces the point I want.


I just can't seem to find out why the object in the game is not rotated correctly.

So what you are saying is that your problem is that you have a quaternion that represents some rotation, but when you try to use it to set up the matrix in OpenGL, the object is not displayed the way you want it. In that case you should concentrate on that problem, and not complicate matters telling us about how you are composing rotations to make the object look somewhere.

You should be able to rotate each individual vertex using the quaternion, or have OpenGL do the rotations for you, and get the same results. I would try to make a simple program that does just that; if there is something about setting up the matrix stack in OpenGL that you don't understand, writing this simple program will help you identify what it is and fix it.

swiftcoder
swiftcoder
Quote:
Original post by jpmcmu
Instead of converting the quaternion to a matrix should I be using it to rotate heading, up, and right vectors and then create a matrix from those?
Try writing a test program that transforms a vector by your quaternion, and then transforms a vector by the matrix, and compares the results.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
jpmcmu
jpmcmu
I implemented a different method to convert to the quaternion to a matrix and that solved the problem. The above code works but it results in left-handed rotations. I need to figure out why that is later. Anyway, thanks for the help guys.
Sleep is for the weak, or at least that is what I tell myself every morning.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.