Click here to Skip to main content
15,861,168 members
Articles / Programming Languages / C#
Tip/Trick

XNA C# Rotation About 3 Axis

Rate me:
Please Sign up or sign in to vote.
4.20/5 (2 votes)
8 Sep 2013CPOL1 min read 14.6K   332   2   1
XNA - rotate model about each axis without gimbal lock

Introduction

XNA is a great platform for hobby graphics programming. I wanted a ship to move through space and rotate independently about each axis. This is simple once you know how, but my first few attempts did not work.

Background

I wanted to have a ship move through space and be able to use a separate control to rotate on each axis: x,y, z. My first attempt worked fine for one axis at a time, but once I rotate about one axis, the other axis got rotated and then I was rotating about some random axis. And I ran into gimbal lock: the math would stop working if I was vertical or tried to rotate too far one way.

A bit of research told me that the answer is matrices. Don't try to do the math by hand with trigonometry, use the built in XNA functions that handle model rotations. It took a bit of fiddling about, but here is the surprisingly simple control code:

C#
protected void UpdateInput()
{
// lets do some 90 turns and short moves with the keyboard
KeyboardState keys = Keyboard.GetState();
// only move once per key press, not constantly
if (keys.IsKeyDown(Keys.X) && !oldState.IsKeyDown(Keys.X) )
	{
	// rotate 90 degrees on X axis of the model
	modelRotation *= Matrix.CreateFromAxisAngle(modelRotation.Left, MathHelper.PiOver2);
	}
else
	{
	if (keys.IsKeyDown(Keys.Y) && !oldState.IsKeyDown(Keys.Y) )
		{
		modelRotation *= Matrix.CreateFromAxisAngle(modelRotation.Up,
			MathHelper.PiOver2);
		}
	else
		{
		if (keys.IsKeyDown(Keys.Z) && !oldState.IsKeyDown(Keys.Z))
			{
			modelRotation *= Matrix.CreateFromAxisAngle
			(modelRotation.Forward, MathHelper.PiOver2);
			}
		else
			{
			if (keys.IsKeyDown(Keys.B) && !oldState.IsKeyDown(Keys.B))
				{
				// move forward
				modelPosition += modelRotation.Forward * 500;
				}
			else
				{
				if (keys.IsKeyDown(Keys.D0) && !oldState.IsKeyDown(Keys.D0))
					{
					modelPosition = Vector3.Zero;
					modelRotation = Matrix.Identity;
					}
				}
			}
		}
	}
	oldState = keys;
} 

Using the Code

This code can be easily updated to support smooth movement. Right now it makes the model jump, with each key press, but it shows the basic technique.

Points of Interest

XNA has lots of built in functions that make doing directX very simple. If you want to play with graphics, or learn it in a higher level platform, XNA is the way to go.

History

  • Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Canada Canada
Professional Programmer living in Beautiful Vancouver, BC, Canada.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Volynsky Alex9-Sep-13 7:59
professionalVolynsky Alex9-Sep-13 7:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.