Jump to content
  • Advertisement
Sign in to follow this  
BloodLust666

Extracting directional vectors from quaternions

This topic is 3170 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;
		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 = 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
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!