2014/09/16
1
Peter Wentworth
We don't build game objects by hand‐programming the meshes, textures, colours, and effects.
Instead, we use a 3D Modelling package or find some pre‐built models from various repositories, or we buy models.
Each model comes with its meshes, normals, colours, texture mapping, textures, basic effects, (and more), already built in.
The programmer now needs six steps:
1. Add the model to our Contentproject
2. At game intialization time, Loadthe pre‐built model 3. Fit and orient it appropriately to the rest of our scene 4. Move it around: either keep (YPR, Position), or a Worldmatrix.
5. Play its animations (e.g. by moving its bones) (not in this lecture) 6. Render it.
Models have meshes
A model usually has many meshes for “parts” of the object, e.g.
cockpit, wings, propellor, head, torso, arms.
Meshes tend to be organized to logically break the model into parts that require different shading, textures, and lighting.
This vulture came with 11 meshes, e.g. Body, Nose, Eyes, Innermouth, left arm, right arm, left toes, etc.
Models have multiple meshes, and a skeleton with a root bone.
Each mesh has its own effects: colours, vertices, shading options, texture, transparency, etc. The mesh is the "unit of drawing calls" to the GPU.
If you want animation that can move meshes in relation to one another, (e.g. spin the propellor of the plane, or move the arm at the shoulder), you need to rig the model. (rig??)
Some models are rigged ‐‐ they have a non‐trivial skeleton.
The vertex positions of each mesh are defined relative to a parent bone.
Bones are organized in a tree hierarchy, (a skeleton, or in Blender, called an armature) rooted at Root.
We retro‐fitted this skeleton to the Vulture using a tool called MilkShape.
In a simple (unrigged) model, all vertices are defined as offsets from the single Root bone.
Models have their root (Pelvis) at (0,0,0) in model space.
Pelvis is the Root here
2014/09/16
2
So before tweaking, Louie's pelvis will coincide with and be drawn at the world origin.
XNA supports only two model formats out‐
of‐the‐box :
Microsoft's own .X format.
Autodesk’s .fbxformat. Many third‐party tools have decent .fbxexporters.
There are a large number of different model formats.
Users seem to have endless issues: see questions about models in the XNA Creator’s / Indie Club.
(This may have improved since time of first writing…)
XNA has an extensible Content Pipeline...
XNA content (textures, models, sounds, etc.) is always pre‐
compiled on a Windows platform into an internal (serialized and zipped) version of what it needs at run time. These .xnb files are deployed to the XBox, or to Windows Phone, or to the PC.
You can provide your own processor, writerand reader
the content processoris used at compile time to read and process the raw model into your custom data structures,
your writerwill serialize your custom data structures so that they can be packed into and shipped as part of the .xnb).
Your matching reader, shipped with the game, will be used at run time to deserialize your custom data structures.
In principle, then, XNA could cater for any model format, if you are willing to do it all yourself.
But in practice, very little seems to be available.
1 of 6: Add your model to your Content project.
You’ll have a Content project node that does a separate compilation step during the build.
You might also have a Content folder.
Don't confuse them: you have to get your model into the Content projectin order to have it precompiled! (The icon for a folder is different!)
The model may also need external textures …
2 of 6: How to load the model
Use your game's ContentManager. It will read and deserialize the precompiled file, send the mesh and textures to the GPU, and will ensure that the GPU resources are released when the game terminates.
Model louie; // class-level declaration
// In LoadContent
louie = Content.Load<Model>(“StaticVulture");
3 of 5: Fit the model to your world!
Every Modelhas a Roottransform.
You should reserve the use of this transform for one and only one purpose: fitting the model to your scene. Don’t follow bad practice of using the World matrix for this.
This might involve scaling, rotations and translations so that your model is not lying flat on his face, and he has his feet on the floor. If needed, do this directly after you load the model, once only.
louie.Root.Transform = // Pick up the model off his face.
Matrix.CreateRotationX(- MathHelper.PiOver2);
2014/09/16
3 4 of 6: In Update(), manipulate your model's
World matrix, (or his Position and YPR from which you'll later rebuild a World matrix)
You did declare a separate World matrix (or separate Position and YPR) for each model you loaded, didn't you?
if (blah blah...) // turn him by tweaking his world matrix louieWorld *= Matrix.CreateRotationY(0.04f);
5 of 6: Animation (move his bones)
Deferred until another time…
6 of 6: Drawing the model
To compute the composite transform applicable to vertices in a mesh, we need to walk the skeleton tree from Rootand multiply together all the (relative) transforms on the path, to compute the complete, absolute transform.
TheCopyAbsoluteBoneTransformsTo method does it all for us!
public void draw(ICamera theCam)
{ // Allocate an array of transform matrices, one per bone, Matrix [ ] bonesNow = new Matrix [ louie.Bones.Count ];
// Traverse the skeleton tree to set them all up…
louie.CopyAbsoluteBoneTransformsTo( bonesNow );
…
6 of 6: Drawing the model ...
foreach (ModelMesh mesh in louie.Meshes)
{ foreach (BasicEffect be in mesh.Effects) // set up args on each effect { be.World = bonesNow [ mesh.ParentBone.Index ] * louieWorld;
be.View = theCam.View;
be.Projection = theCam.Projection;
}mesh.Draw(); // let the GPU to do its thing for this mesh } } // end of Draw()
• Each mesh has its own effects built it.
• A mesh knows its parent bone index – this lets us pick up the correct transform from the array.
Summary and Key Ideas
Model parsing, conversion to internal run‐time structures, serialization and compression is done in the Content Pipeline Processor, only when compiling your game, only on a Windows PC.
The run‐time platforms for Windows, XBox, Windows Phone, etc. can deserialize and use the data structures at game time.
Only .X and .fbxmodel formats are directly supported.
Not all features of these formats are supported, e.g.
loading animations and skeletons is notnatively supported.
The Content Pipeline Processor is extensible, though.
Summary and Key Ideas ...
A model comprises multiple meshes.
Positions in each mesh are defined relative to its parent bone, but some unrigged models only have a root bone.
In rigged models, bones form a hierarchy and contain transforms relative to their parent bones.
To render the mesh you first need to accumulate all the transforms, starting at Root, that impact the mesh, then also accumulate your own world transforms!
A single method call does the hard work of accumulating the composite transform matrices from the model!