Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

Quaternion Warping

Started by Riraito Jul 3, 2009 at 2:56 PM 3 replies 1.3k views
Original Post
Riraito
Riraito
I've run into some trouble with my Quaternion based camera movement. At the moment I am getting yaw and pitch values from the mouse, and then converting them to quaternions and then to a matrix. The problem is occurring when the yaw gets close to 180 degrees, any change in the pitch causes strange warping instead of rotation I suspect It has something to do with either my quaternion concat code or my quaternion to matrix code. Unfortunately my knowledge of this math is quite limited so I was wondering if anyone sees anything overtly wrong with this code, or has any other ideas about what might be wrong.

Quaternion rot = Quaternion(Vector3f(1.0f, 0.0f, 0.0f), pitch) * Quaternion(Vector3f(0.0f, 1.0f, 0.0f), yaw);


Matrix.h
class Matrix4x4 {
	float m_[16];
	
	...
	
	void setRotation( const Quaternion& quat ) {
		float xx = 2 * quat.x * quat.x;
		float xy = 2 * quat.x * quat.y;
		float xz = 2 * quat.x * quat.z;
		float xw = 2 * quat.x * quat.w;

		float yy = 2 * quat.y * quat.y;
		float yz = 2 * quat.y * quat.z;
		float yw = 2 * quat.y * quat.w;

		float zz = 2 * quat.z * quat.z;
		float zw = 2 * quat.z * quat.w;


		m_[0] = 1 - (yy + zz);	m_[4] =     (xy + zw);	m_[ 8] =     (xz - yw);
		m_[1] =     (xy - zw);	m_[5] = 1 - (xx + zz);	m_[ 9] =	 (xy + xw);
		m_[2] =     (xz + yw);	m_[6] =     (yz - xw);	m_[10] = 1 - (xx + yy);
	}
}


class Quaternion {
	float w, x, y, z;

	...

	inline Quaternion operator*(const Quaternion& q) const {
		Quaternion ret(
			(w*q.w) - (x*q.x) - (y*q.y) - (z*q.z),
			(w*q.x) + (x*q.w) + (y*q.z) - (z*q.y),
			(w*q.y) + (y*q.w) + (z*q.x) - (x*q.z),
			(w*q.z) + (z*q.w) + (x*q.y) - (y*q.x)
		);
		return ret;
	}
}

Zakwayda
Zakwayda
Can you post the constructor for the quaternion class?

Also, it looks like you're only modifying the upper-left 3x3 part of the matrix in your 'set rotation' function. Do you set the matrix to identity prior to building the rotation transform? (Maybe that's what the ellipsis is...)
Riraito
Riraito
Quote:
Original post by jyk
Can you post the constructor for the quaternion class?

Also, it looks like you're only modifying the upper-left 3x3 part of the matrix in your 'set rotation' function. Do you set the matrix to identity prior to building the rotation transform? (Maybe that's what the ellipsis is...)


Yep the default constructor sets it to an identity matrix, and I dont do anything besides call setRotation.

Heres the quaternion constructor for axis angle

	inline Quaternion(Vector3f axis, float angle) {		axis.normalize();		double rads = angle * PI / 180.0f;		double s = sin(rads * 0.5f);		x = axis.x * s; y = axis.y * s; z = axis.z * s;		w = cos(rads * 0.5f);	}


Edit: also this is for opengl, and the matrix is column major, if that makes any difference
Zakwayda
Zakwayda
I think element 9 of your rotation matrix might be wrong - you might double-check it.
Riraito
Riraito
aha, brilliant, it should have been

m_[9] = (yz + xw);

instead of

m_[9] = (xy + xw);

I would have never caught that, thank you so much!!

Topic Locked

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

Sign in to reply to this topic.