// Project: XnaGraphicEngine, File: Model.cs // Namespace: XnaGraphicEngine.Graphics, Class: Model // Path: C:\code\XnaBook\XnaGraphicEngine\Graphics, Author: Abi // Code lines: 36, Size of file: 900 Bytes // Creation date: 27.11.2006 03:27 // Last modified: 27.11.2006 03:50 // Generated with Commenter by abi.exDream.com #region Using directives using System; using System.Collections.Generic; using System.Text; using XnaModel = Microsoft.Xna.Framework.Graphics.Model; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework; using XnaGraphicEngine.Game; using XnaGraphicEngine.Helpers; #endregion namespace XnaGraphicEngine.Graphics { /// /// Model /// public class Model : IGraphicContent { #region Variables /// /// Name of this model, also used to load it from the content system. /// string name = ""; /// /// Underlying xna model object. Loaded with the content system. /// XnaModel xnaModel = null; /// /// Transform matrices for each mesh part, we only have to get them once /// if the model is not animated. /// Matrix[] transforms = null; /// /// Scaling of model. Used to create objecMatrix. /// float scaling = 1.0f; /// /// Default object matrix to fix models from 3ds max to our engine! /// Matrix objectMatrix = Matrix.CreateRotationX(MathHelper.Pi / 2.0f); #endregion #region Properties /// /// Name for this model, this is the content name. /// /// String public string Name { get { return name; } // get } // Name /// /// Xna model /// public XnaModel XnaModel { get { return xnaModel; } // get } // XnaModel #endregion #region Constructor /// /// Create model /// /// Device /// Filename public Model(string setModelName) { name = setModelName; Load(); BaseGame.RegisterGraphicContentObject(this); // Get matrices for each mesh part transforms = new Matrix[xnaModel.Bones.Count]; xnaModel.CopyAbsoluteBoneTransformsTo(transforms); // Calculate scaling for this object, used for rendering. scaling = xnaModel.Meshes[0].BoundingSphere.Radius * transforms[0].Right.Length(); if (scaling == 0) scaling = 0.0001f; // Apply scaling to objectMatrix to rescale object to size of 1.0 objectMatrix *= Matrix.CreateScale(1.0f / scaling); } // Model(device, filename) #endregion #region Load public void Load() { if (xnaModel == null) xnaModel = BaseGame.Content.Load( @"Content\" + name); } // Load() #endregion #region Dispose public void Dispose() { xnaModel = null; } // Dispose() #endregion #region Render /// /// Render /// /// Render matrix public void Render(Matrix renderMatrix) { if (xnaModel == null) return; // Apply objectMatrix renderMatrix = objectMatrix * renderMatrix; // Go through all meshes in the model foreach (ModelMesh mesh in xnaModel.Meshes) { // Assign world matrix for each used effect BaseGame.WorldMatrix = transforms[mesh.ParentBone.Index] * renderMatrix; // And for each effect this mesh uses (usually just 1, multimaterials // are nice in 3ds max, but not efficiently for rendering stuff). foreach (Effect effect in mesh.Effects) { // Set technique (not done automatically by XNA framework). effect.CurrentTechnique = effect.Techniques["Specular20"]; // Set matrices, we use world, viewProj and viewInverse in // the ParallaxMapping.fx shader effect.Parameters["world"].SetValue( BaseGame.WorldMatrix); // Note: these values should only be set once every frame! // to improve performance again, also we should access them // with EffectParameter and not via name (which is slower)! // For more information see Chapter 6 and 7. effect.Parameters["viewProj"].SetValue( BaseGame.ViewProjectionMatrix); effect.Parameters["viewInverse"].SetValue( BaseGame.InverseViewMatrix); // Also set light direction (not really used here, but later) effect.Parameters["lightDir"].SetValue( BaseGame.LightDirection); } // foreach (effect) // Render with help of the XNA ModelMesh Draw method, which just goes // through all mesh parts and renders them (with vertex and index // buffers). mesh.Draw(); } // foreach (mesh) } // Render(renderMatrix) /// /// Render /// /// Render position public void Render(Vector3 renderPos) { Render(Matrix.CreateTranslation(renderPos)); } // Render(renderPos) #endregion #region Unit Testing #if DEBUG public static void TestRenderModel() { Model testModel = null; TestGame.Start("TestRenderModel", delegate { testModel = new Model("Apple"); }, delegate { testModel.Render(Matrix.CreateScale(10)); }); } // TestRenderModel() #endif #endregion } // class Model } // namespace XnaGraphicEngine.Graphics