Friday, February 19, 2010

XNA 3D Cheat Sheet

A cheat sheet in technology is something that can get you from A to B very quickly. This cheat sheet will get you from scratch of having no 3D in your XNA application to having a full 3D model displayed on your screen and rotate very quickly. then models and model bones will be touched off just to give you an idea.

Hope this helps.


*I'm assuming you have a new XNA project open and are ready to start working and some working knowledge of XNA

Basics of 3D

Required System Statements:

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Content;

using Microsoft.Xna.Framework.Graphics;

For user input use:

using Microsoft.Xna.Framework.Input;

For more advanced functionality such as controlling digital media such as Video and Audio different system ‘using’ statements can be added to the list.

Useful 3D model data types:

GraphicsDeviceManagerFor managing graphics 3D / 2D

Model – for loading and using a 3D model

ModleBone – for programatically manipulating a 3D model skeleton structure

Matrixused for gettin projection, view and rotation

Vector3 - used for storing X,Y,Z axis with floating point numbers


Displaying a model to the screen:

- Load the model in the main Load Method

public void Load(ContentManager content)

{

// Load the model from the ContentManager.Basically the content manager knows where your content is stored and loads it in from there see the screen shot below.

mymodel = content.Load<Model>("fbxmodel");

}

Draw the model to the screen

public void Draw(Matrix world, Matrix view, Matrix projection)

{

// Set the world matrix as the root transform of the model.

mymodel.Root.Transform = world;

foreach (ModelMesh mesh in mymodel.Meshes)

{

foreach (BasicEffect effect in mesh.Effects)

{

effect.World = boneTransforms[mesh.ParentBone.Index];

effect.View = view;

effect.Projection = projection;

effect.EnableDefaultLighting();

}

mesh.Draw();

}

}

*Note the next two sections ultise the Update() Method

Adding Basic Rotation:

First step to get some movement to a 3D model would be to get it to spin on the spot. Casting the the gameTime milliseconds multiplied by a radian value is the simplest method for doing this.

float modelRotation = 0.0f;

protected override void Update(GameTime gameTime)

{

modelRotation += (float)gameTime.ElapsedGameTime.TotalMilliseconds * MathHelper.ToRadians(0.1f);

}

Adding movement to 3D model bones:

This is a lot more complex than simply getting an entire model to move. It requires some extra properties for holding information on the bones of the 3D model. The following code is from Tank Simple Animation exaple from the XNA website - link http://creators.xna.com/en-GB/sample/simpleanimation

The code is broken down into easily digestable chunks

Model variable to load the 3D model into

Model tankModel;

ModelBone variable to hold the Turret part of the model

ModelBone turretBone;

Matrix variable will be used to calculate the rotation of the turret

Matrix turretTransform;

Used to store the current animation position of the turret

float turretRotationValue;

The following property is used to get and set the turret rotation value

public float TurretRotation

{

get { return turretRotationValue; }

set { turretRotationValue = value; }

}

The next step is to load in the model and the model bones into variables so they can be used later on it other methods. The turretBone loads in the bone value from the tankModel variable and matrices of the model bone is passed to the turretTransform variable

public void Load(ContentManager content)

{

// Load the tank model from the ContentManager.

tankModel = content.Load<Model>("tank");

turretBone = tankModel.Bones["turret_geo"];

turretTransform = turretBone.Transform;

}

The model is then drawn to the screen and its rotation and transformation is started by applying matrices to the model bone.

public void Draw(Matrix world, Matrix view, Matrix projection)

{

// Set the world matrix as the root transform of the model.

tankModel.Root.Transform = world;

Matrix turretRotation = Matrix.CreateRotationY(turretRotationValue);

turretBone.Transform = turretRotation * turretTransform;

tankModel.CopyAbsoluteBoneTransformsTo(boneTransforms);

// Draw the model.

foreach (ModelMesh mesh in tankModel.Meshes)

{

foreach (BasicEffect effect in mesh.Effects)

{

effect.World = boneTransforms[mesh.ParentBone.Index];

effect.View = view;

effect.Projection = projection;

effect.EnableDefaultLighting();

}

mesh.Draw();

}

}

The update method is responsible for applying the calculations to the the matrices values, so that the turret on the tank turns. You will notice that the gameTime value is used.

protected override void Update(GameTime gameTime)

{

float time = (float)gameTime.TotalGameTime.TotalSeconds;

tankModel.TurretRotation = (float)Math.Sin(time * 0.333f) * 1.25f;

base.Update(gameTime);

}