Sign in to follow this  

Extracting directional vectors from quaternions

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

After spending some time with my newly learned knowledge of quaternions and integrating them into my engine, I've started to put together a first-person simulation. All rotations and animations look good, except for what I try to clamp my direction. My SetDirection() and other functions that set the orientation don't seem to be working correctly. There's a couple ways I tried to do this but none have worked... Here's what I have so far: Using the vector direction and creating a rotation matrix
void Update()
{
// ...
if ( fabs(m_camera.GetDirection().Y) > 0.8f )
{
	Vector3 dir = m_camera.GetDirection();
	if ( dir.Y > 0 )
		dir.Y = 0.8f;
	else
		dir.Y = -0.8f;
	dir.Normalize();
	Vector3 right = dir ^ Vector3(0.0f, 1.0f, 0.0f);
	Vector3 up = right ^ dir;
	m_camera.SetOrientation(Quaternion(right,up,dir)); // calls Quaternion::SetFromAxes()
}
// ...
}

Vector3 Camera::GetDirection() const
{
	return GetOrientation().Rotate(Vector3(0.0f, 0.0f, -1.0f));
}
Vector3 Quaternion::Rotate(const Vector3 & vec) const
{
	Quaternion v(0.0f,vec);
	return Quaternion(*this * v * this->operator~()).vec;
}
void Quaternion::SetFromAxes(
    const Vector3 & xAxis,
    const Vector3 & yAxis,
    const Vector3 & zAxis)
{
	Matrix3 mat;

	mat[0] = xAxis.X;
	mat[1] = xAxis.Y;
	mat[2] = xAxis.Z;

	mat[3] = yAxis.X;
	mat[4] = yAxis.Y;
	mat[5] = yAxis.Z;

	mat[6] = zAxis.X;
	mat[7] = zAxis.Y;
	mat[8] = zAxis.Z;

	SetFromRotationMatrix(mat);
}
void Quaternion::SetFromRotationMatrix( const Matrix3 & m ) // from Ogre3D
{
	float trace = m[0] + m[4] + m[8];
	float root;

        // 'w' is the real part and 'vec' is a Vector3 of the imaginary components
	if ( trace > 0.0f )
	{
		root = sqrtf(trace + 1.0f);
		w = 0.5f * root;
		root = 0.5f / root;
		vec.X = (m[7] - m[5]) * root;
		vec.Y = (m[2] - m[6]) * root;
		vec.Z = (m[3] - m[1]) * root;
	}
	else
	{
		static long s_iNext[3] = { 1,2,0 };
		long i = 0;
		if ( m[4] > m[0] )
			i = 1;
		if ( m[8] > m[i*3+i] )
			i = 2;
		long j = s_iNext[i];
		long k = s_iNext[j];

		root = sqrtf(m[i*3+i] - m[j*3+j] - m[k*3+k] + 1.0f);
		float * quat[3] = {&vec.X, &vec.Y, &vec.Z};

		*quat[i] = 0.5f * root;
		root = 0.5f / root;
		w = (m[k*3+j] - m[j*3+k]) * root;
		*quat[j] = (m[j*3+i] + m[i*3+j]) * root;
		*quat[k] = (m[k*3+i] + m[i*3+k]) * root;
	}
}



Use cached out angle values
if ( fabs(m_camera.GetPitch()) > 3.14f/3.0f )
{
	if ( m_camera.GetOrientation().GetPitch() > 0 )
		m_camera.SetPitch(3.14f/3.0f);
	else
		m_camera.SetPitch(-3.14f/3.0f);
 
}
void Camera::Pitch( float angle )
{
	Quaternion q;
	Vector3 axis;
	axis = GetOrientation().Rotate(Vector3(1.0f, 0.0f, 0.0f));
	q.SetFromAxis( angle, axis );
	q.Normalize();
	IncOrientation(q);
	SetOrientation(GetOrientation().Normalized());
}
void Camera::SetPitch( float angle )
{
	float a = m_orientation.GetPitch();
	Pitch( angle - a );
}			
float sWQuaternion::GetPitch() const
{
	Vector3 yAxis = GetYAxis();
	return atan2(yAxis.X, yAxis.Y);
}
sWVector3D sWQuaternion::GetYAxis() const
{
	// 'w' is real part, 'vec' is a Vector3 of imaginary part in this quat
	float fTx  = 2.0f*vec.X;
	float fTy  = 2.0f*vec.Y;
	float fTz  = 2.0f*vec.Z;
	float fTwx = fTx*w;
	float fTwz = fTz*w;
	float fTxx = fTx*vec.X;
	float fTxy = fTy*vec.X;
	float fTyz = fTz*vec.Y;
	float fTzz = fTz*vec.Z;

	return Vector3(fTxy-fTwz, 1.0f-(fTxx+fTzz), fTyz+fTwx);
}


Is there anything noticeably wrong with my code? Using either method?

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

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