Archived

This topic is now archived and is closed to further replies.

Mesh Rotation problems

This topic is 5012 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

Hi all, I am trying to rotate a mesh using quaternions. The mesh rotates to follow the way the camera is pointing.It works well apart from when the mesh rotates from 0 to <360 and from 360 to >0. Whenever this happens the mesh rotates all the way around again, instead of just rotating the short way. I'm sure its pretty easy to get around this but I just can't sort my head out over it. Any help much appreciated Code below. Cheers Drb2k2
VOID CMediumObjectDetails::CalculateMeshRotation(D3DXVECTOR3 CameraPosition)
{
	CameraPosition.z = CameraPosition.z - this->m_vCurrentPosition.z;
	CameraPosition.x = CameraPosition.x - this->m_vCurrentPosition.x;
	D3DXVECTOR3 TempMeshPos = this->m_vCurrentPosition;
	TempMeshPos.z = 0.0f;
	TempMeshPos.x = 0.0f; // = 0


	// get the vector of a position on the far side of mesh

	D3DXVECTOR3 Line;
	D3DXVec3Subtract(&Line, &TempMeshPos, &CameraPosition);
	D3DXVec3Add(&Line, &Line, &TempMeshPos);
	Line.y = 0;
	D3DXVec3Normalize(&Line,&Line);
	D3DXVECTOR3 LookingAt(0,0,-1);
	D3DXVec3Normalize(&LookingAt, &LookingAt);

	//check to see which direction to rotate in

	D3DXVECTOR3 Cross;
	float dotproduct;
	dotproduct = D3DXVec3Dot(&Line, &LookingAt);
	D3DXVec3Cross(&Cross,&Line,&LookingAt);

	//calculate angle in degrees

	dotproduct = (float)acos(dotproduct);
	dotproduct = D3DXToDegree(dotproduct);
	//convert to 360 degrees

	if(Cross.y >=0.0f)
		this->m_vRequiredRotation.y = 360.0f-dotproduct;
	else
		this->m_vRequiredRotation.y =  dotproduct;

	// now see if any rotation needs to be done

	if(this->m_vRequiredRotation != this->m_vCurrentRotation)
	{

		// now calculate the quaternion rotation

		D3DXQUATERNION Current,Required;
		Current.x = this->m_vCurrentRotation.x;
		Current.y = this->m_vCurrentRotation.y;
		Current.z = this->m_vCurrentRotation.z;
		Required.x = -this->m_vRequiredRotation.x;
		Required.y = -this->m_vRequiredRotation.y;
		Required.z = -this->m_vRequiredRotation.z;


		D3DXQUATERNION Result;
		D3DXQuaternionSlerp(&Result, &Current, &Required, 0.5f);
			this->m_vCurrentRotation.x = Result.x;
			this->m_vCurrentRotation.y = Result.y;
			this->m_vCurrentRotation.z = Result.z;
	}

}
[edited by - drb2k2 on March 25, 2004 10:20:56 AM]

Share this post


Link to post
Share on other sites
If you just want the values to stay between 360 just prevent them yourself...

(Angle>360)Angle-=360;
(Angle<360)Angle+=360;

This works since 10 is the same as 370 and -10 is the same as 360... So now your values willl stay between 0 - 360. Nice little code example too for smooth camera movement, hehe there is an easier way but it should work, just manually prevent the angles to stay between 0-360 and you should be ok...

Also when adding or subtracting vectors DX has the operators already predefined for that.

D3DXVECTOR3 Line = TempMeshPos - CameraPosition;
Will work the same.

Also this isn''t necessary at all. Just do the math.
LookingAt/=sqrt(0*0+0*0+-1*1);
Will always return LookingAt(0,0,-1);

So get this out.
D3DXVECTOR3 LookingAt(0,0,-1);
D3DXVec3Normalize(&LookingAt, &LookingAt);

Why not do this though, take both your camera rotation matrix, and your tempmesh rotation matrix and just turn those into quaternions? Maybe even make a class for camera followed objects to always have a member quaternion. Then all you gotta due is start updating it as it is camera followed.

Share this post


Link to post
Share on other sites
Hi jimmynelson,
thanks for the reply. Cheers for the tip regarding subtracting the vectors, I will make amends. I''m not sure that the angle ever goes above 360 degrees though. It just seems that slerp cannot do a rotation from around 0 -> around 360 and vice versa. I don''t know how to get around this since the slerp function is sadly over my head. Can slerp actuall do this calculation and therefore my code is wrong?
cheers
DRb2k

Share this post


Link to post
Share on other sites