Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Phone

Developing for Windows Phone and Xbox Live : Camera Types & Models

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
5/30/2011 11:48:56 AM

Camera Types

Although any individual game probably has only a single type of camera, there are a wide variety that can be used—cameras that follow the players, cameras that never move, and cameras that change depending on the circumstances...the possibilities are endless.

Static Cameras

The easiest camera to think about is a static camera. As the name implies, a static camera doesn’t move. It sits there and just looks out.Let’s create a helper class that is your camera type. Right-click your project, select Add->New Item, choose Game Component (calling it CameraComponent.cs) and add the following variables to it:

protected Matrix view;
protected Matrix proj;

You need a way to get these values back from your component, so add two property getters for them now:

public Matrix View
{
get
{
return view;
}
}
public Matrix Projection
{
get
{
return proj;
}
}

You also need to initialize these to something reasonable, so in your Initialize overload, add the following:

view = Matrix.CreateLookAt(new Vector3(0, 0,-16),
Vector3.Zero, Vector3.Up);
proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
Game.GraphicsDevice.Viewport.AspectRatio, 1.0f, 100.0f);

With that, you’ve made yourself a fixed static camera. Let’s modify the game to use this camera instead. Add a new variable to your Game class to hold the camera:

CameraComponent camera;

Then, in your game’s Initialize overload, add this component to your game’s component list:

Components.Add(camera = new CameraComponent(this));

Then finally, switch your call to Draw on the model to use this camera component:

model.Draw(Matrix.CreateTranslation(pos), camera.View, camera.Projection);

If you run the application now, you see a slightly different view because your camera is in a different location. This camera can be extended to support different types of cameras, which you should experiment with.

Models

What Is a Model?

A model is essentially a collection of geometry that is rendered together to form an object in the world.

If you use a Digital Content Creation (DCC) package, such as SoftImage Mod Tool (see Figure 1), to create your objects, when you export those creations to a file (such as an .fbx file or an .x file), you can add these to your content projects to use the Model content importer. These are loaded into the Model class.

Figure 1. A DCC package creating a model

Models

The first method you can look at on the Model class is the Draw method. This method (as the name implies) draws the model using the supplied transform with the provided view and projection matrices and with the defaults for everything else. It is a quick and easy way to show something onscreen as you’ve seen so far.

A Tag property can also be used to store any type of data. Many content importers also include extra information in this object for the game to use. Let’s take a look at the Meshes property next.

Meshes

The Meshes property returns a collection of ModelMesh objects. Although that is the simplest form of a model, models can be extremely complex. Imagine a model that represents a city. The city would have roads, buildings, and signs. Each of these objects can be represented by a different model mesh, whereas the combined set of meshes is the full model.

Each mesh also has a Draw method that can be used to render the mesh separately, but notice that this method has no parameters. This does the rendering of the mesh, but it does so with the current settings of the effects rather than setting the world, view, and projection matrices that the model’s Draw method does. This is because there is extra information inherent to each mesh that might change where it is in the world.

Another piece of information found on the mesh is the BoundingSphere property, which describes a sphere that encompasses the entire mesh. The bounding sphere object has a few fields and methods that are used for a variety of reasons. The Center and Radius fields are used to describe the sphere, whereas there are a few helper methods such as Contains and Intersects used to detect objects in the sphere. You can also Transform the sphere using that helper method.

Each mesh can also have a Name (that can be set by your code or set during content importing and loading) and Tag similarly to the model itself. Aside from the bones (which are discussed in a moment), the last two properties on the mesh are Effects and MeshParts, which are interrelated. The Effects collection is the collection of effects that is associated with each mesh part and controls how the mesh parts are rendered. The number of effects and mesh parts is identical, and you can update or modify the effects for any of the mesh parts you’d like.


Each mesh part is the portion of the model that is actually rendered. Notice that one of the properties it has is the Effect that this part uses. Changing this property also affects the Effects property on the mesh at the same index this mesh part exists at. The rest of the properties contain the information about the geometry and gives you the information you need to draw the mesh part with the DrawIndexedPrimitives method. You can see the IndexBuffer and VertexBuffer properties that hold the index and vertex data and the PrimitiveCount to dictate how many triangles to draw. When drawing data using this information, you can always use a primitive type PrimitiveType.TriangleList.

A few other pieces of information on the mesh part can be used when setting the vertex buffer and index buffer to the device, such as NumVertices (which is the number of vertices in the buffer), VertexOffset (which is the number of vertices to skip before getting to the vertices required for this mesh part), and StartIndexModel and ModelMesh before it, this also includes a Tag (which is the number of indices to skip before getting to the first index required by this mesh part). Like the property.

Normally each mesh part is separated from the other portions of the mesh based on the material it uses to render itself. You see the term material used often in DCC packages and throughout literature on this subject.

For example, in the imaginary city model, you can also imagine that the road portions of the model are all one mesh. If you had three different kinds of roads, such as a paved street, a gravel road, and a dirt road, you would potentially use different textures and possibly even different effects for those, so your roads mesh would have three different mesh parts: one for the paved street, one for the gravel roads, and a final one for the dirt roads.

See Figure 2 for an example of how models, meshes, and mesh parts are all interrelated.

Figure 2. Models, meshes, and mesh parts


Throughout the discussions of models, you didn’t about one particular type of object, so let’s take a look at it now.

Bones

The ModelMesh has a property ParentBone that you skipped, and the model itself had quite a few methods and properties that deal with bones. What exactly are bones (aside from things like a femur or a song by Alice in Chains)? At a high level, bones are what connect each mesh to every other mesh. See Figure 3 for an example of a simple model with three meshes.

Figure 3. A model with three meshes

Let’s assume you want to build a model of a person, and what is in Figure 3 is what you have so far. You have the sphere representing the head, a cylinder representing the neck, and a cube representing the torso. Each of these body parts can be considered a mesh in the larger full model, and bones are what tie these together. Each bone tells you the relationship between itself, its parent, and its children.

One of the meshes in the model is the root bone. This is the mesh that is the root of the other meshes and is accessed via the Root property on the model, which returns a ModelBone object. These objects have a few different properties to help explain the relationship of that particular bone to the others in the model. First, it has the Children property that is a collection of ModelBone objects that define the children of this bone. You can also get the Parent (again, as a ModelBone) of this bone. Like the mesh, you can also get the Name of this bone, which can be set during content import and creation.

You also see the Index property, which is the index of this bone in the model’s Bones collection (which is the entire collection of bones for the model). Finally, you see the Transform property, which is the transform of this bone in relation to its parent. Let’s look at an example.

In the model in Figure 3, you can imagine that the torso would be the root bone with a single child being the cylinder forming the neck, which in turn, has a single child as the sphere forming the head. If the model had arms and the torso was the root, you could extrapolate out that it would have multiple children for the neck, arms, and legs.

Now, assume that the torso has a transformation of Matrix.Identity. It has no scale or rotation and it is located at the origin (0,0,0). However, the neck is approximately three units above that, so the Transform property of the neck bone is Matrix.CreateTranslation(0,3,0). You can see that the head is even higher, yet approximately three units above its parent, the neck, so its Transform property would be Matrix.CreateTranslation(0,3,0), even though it is approximately six units above the torso! If your head was slightly turned, you could instead have its Transform property be Matrix.CreateRotationX(MathHelper.PiOver4) * Matrix.CreateTranslation(0,3,0). The transform is always based on the parent bone and not the model itself. This is especially useful for animated characters because like in this example, you can easily have your head turn side to side by simply changing the rotation transform on a single bone, rather than repositioning the entire set of geometry.

There are also three methods on the Model class you can use to get or set these transforms. You can use the CopyBoneTransformsTo method to create a copy of the transforms each bone has into a new array of matrices (for example, what you might want to pass into an effect). You can also use the similar (but opposite order) method of CopyBoneTransformsFrom to update all the bones with these new transforms. There is also another helper method called CopyAbsoluteBoneTransformsTo, which like the nonabsolute one, copies all the transforms into an array of matrices. The difference is this one combines each child’s transform with all of its parent transforms.

What this means, in the previous example, by using CopyBoneTransformsTo you would have an array of three matrices: the first member having Matrix.Identity and the second two members having Matrix.CreateTranslation(0,3,0). However, if you use CopyAbsoluteBoneTransformsTo, you would have the same array of three matrices with the first two members remaining the same, but the third member would instead be Matrix.CreateTranslation(0,6,0) because it combines the transform with its parents transforms.

Rendering Models

Enough of all this text—’let’s actually use the model class to draw some stuff onscreen! Create a new Windows Game project and add any model you’d like from the downloadable examples. Now, get ready to do some rendering. You need to add a variable for your model, such as:

Model model;

Next, update your LoadContent method to get the object instantiated:

model = Content.Load("YourModel");
foreach (ModelMesh mm in model.Meshes)
{
foreach (Effect e in mm.Effects)
{

IEffectLights iel = e as IEffectLights;
if (iel != null)
{
iel.EnableDefaultLighting();
}
}
}

Naturally, you need to replace the YourModel with whatever model you picked. Although you haven’t gotten to the effects yet, the next section of code enables default lights for all portions of the model that have it.

Next, because you’ve picked any random model you wanted, and models can be of a wide variety of sizes, you need to add a helper method to get the size of the largest mesh in the model, so you can scale it correctly. In a real game, you never have to do this trickery because you control the scale and size of the models, but here, it’s a quick operation to have a good guess. Add this private function to your game class:

private float GetMaxMeshRadius(Model m)
{
float radius = 0.0f;
foreach (ModelMesh mm in m.Meshes)
{
if (mm.BoundingSphere.Radius > radius)
{
radius = mm.BoundingSphere.Radius;
}
}
return radius;
}

This goes through each mesh and finds the one with the largest bounding radius and returns the largest radius it finds. Now you can add another helper method to draw the model, which you’ update a few times over the next few pages to see the various ways of rendering the model. The first one is the easiest:

private void DrawModel(Model m, float radius, Matrix proj, Matrix view)
{
m.Draw(Matrix.CreateScale(1.0f / radius), view, proj);
}

The only thing interesting you use for the model is the world matrix. You create a scale that makes the model approximately 1.0f units. This enables you to use a static camera regardless of model size and still see it in its entirety.

Finally, you need to do the actual rendering. Replace your Draw method with the following:

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
float radius = GetMaxMeshRadius(model);
Matrix proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
GraphicsDevice.Viewport.AspectRatio, 1.0f, 100.0f);
Matrix view = Matrix.CreateLookAt(new Vector3(2, 3, 4), Vector3.Zero, Vector3.Up);
DrawModel(model, radius, proj, view);
base.Draw(gameTime);
}


Notice here that you’re positioning the camera slightly offset from the model and four units away. This is possible only because of the scaling done in the DrawModel call; otherwise, you have to base your camera size on the size of the model. Nothing here is exactly new, though, and running the application shows your model rendered on screen.

Next, let’s add the new method DrawModelViaMeshes to use the meshes instead of the single Draw method on model. Add the following method and update your DrawModel call to use this one instead:

private void DrawModelViaMeshes(Model m, float radius, Matrix proj, Matrix view)
{

Matrix world = Matrix.CreateScale(1.0f / radius);
foreach (ModelMesh mm in model.Meshes)
{
foreach (Effect e in mm.Effects)
{
IEffectMatrices iem = e as IEffectMatrices;
if (iem != null)
{
iem.World = GetParentTransform(m, mm.ParentBone) * world;
iem.Projection = proj;
iem.View = view;
}
}
mm.Draw();
}
}


This also needs a helper method to get the parent bone transform, so add this, too:

private Matrix GetParentTransform(Model m, ModelBone mb)
{
return (mb == m.Root) ? mb.Transform :
mb.Transform * GetParentTransform(m, mb.Parent);
}

So, what is going on here? You set the initial world matrix you want to use as the basis for everything, much like you did in the previous one-line call, but after that, things seem to get much more complicated! In reality, this is straightforward. For every mesh in your model, you go through the effects and set the matrices each needs. The view and projection matrices are the same for every effect (because you don’t want the camera moving around based on which portion of the model you’ render); however, the world matrix is vastly different.

Each mesh sets its world matrix to the parent’s world matrix combined with the constant world matrix for the model. Notice that the helper method to get the parent’s world matrix is recursive. Because each bone’s transform is relative to its parent’s transform, to get the full transform for any bone in the model, you need to combine its transform with all of its parents, which is what the helper method does. It stops when it gets to the root bone because it has no parent and simply returns the root bone’s transform.

Note

In a real game, you do not want to use this recursive function every single frame as you did here to get the bone transforms. You would instead cache them (and use perhaps the CopyAbsoluteBoneTransformsTo helper method), but it was done this way to illustrate the concept.


If you want even more control, however, you can render everything in the model exclusively through the device methods without ever calling one of the helper Draw methods. Add yet another helper method to draw the model via the vertex data itself and update your DrawModel call to use this one instead:

private void DrawModelViaVertexBuffer(Model m, float radius, Matrix proj, Matrix view)
{

Matrix world = Matrix.CreateScale(1.0f / radius);
foreach (ModelMesh mm in model.Meshes)
{
foreach(ModelMeshPart mmp in mm.MeshParts)
{
IEffectMatrices iem = mmp.Effect as IEffectMatrices;
if ( (mmp.Effect != null) && (iem != null) )
{
iem.World = GetParentTransform(m, mm.ParentBone) * world;
iem.Projection = proj;
iem.View = view;
GraphicsDevice.SetVertexBuffer(mmp.VertexBuffer, mmp.VertexOffset);
GraphicsDevice.Indices = mmp.IndexBuffer;
foreach (EffectPass ep in mmp.Effect.CurrentTechnique.Passes)
{
ep.Apply();
GraphicsDevice.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0,
mmp.NumVertices, mmp.StartIndex, mmp.PrimitiveCount);
}
}
}
}
}


Notice the similarities between this one and the last one. You still need to enumerate through each of the meshes; however, instead of calling the Draw method on the meshes, enumerate through each of the mesh parts. You set the world, view, and projection matrices as you did before, although the actual rendering is done much differently.

You can see that the data needed to do the rendering is on the ModelMeshPart class. You need to set the vertex and index buffers to the device, which are on the part, and then the data needed to make the DrawIndexedPrimitives call are also there. By default, models loaded via the built-in importers from the content pipeline require the primitive type to be TriangleList, although creating your own importers can change this if you want to change it.

Other -----------------
- Developing for Windows Phone and Xbox Live : Projection Matrix
- Developing for Windows Phone and Xbox Live : View Matrix
- Programming Windows Phone 7 : Pivot and Panorama - The XNA Music Classes: MediaPlayer
- Programming Windows Phone 7 : Pivot and Panorama - Displaying the Albums
- Programming Windows Phone 7 : Pivot and Panorama - The XNA Music Classes: MediaLibrary
- Programming Windows Phone 7 : Pivot and Panorama - The XNA Connection
- Programming Windows Phone 7 : Pivot and Panorama - Music by Composer
- Programming Windows Phone 7 : Pivot and Panorama - Compare and Contrast
- Programming Windows Phone 7 : Elements and Properties - Modes of Opacity
- Programming Windows Phone 7 : Elements and Properties - Non-Tiled Tile Brushes & Playing Movies
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us
Popular tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 windows Phone 7 windows Phone 8
programming4us programming4us
 
programming4us
Natural Miscarriage
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Game Trailer