#region Copyright
/*
--------------------------------------------------------------------------------
This source file is part of Xenocide
by Project Xenocide Team
For the latest info on Xenocide, see http://www.projectxenocide.com/
This work is licensed under the Creative Commons
Attribution-NonCommercial-ShareAlike 2.5 License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/2.5/
or send a letter to Creative Commons, 543 Howard Street, 5th Floor,
San Francisco, California, 94105, USA.
--------------------------------------------------------------------------------
*/
/*
* @file CombatantMeshes.cs
* @date Created: 2008/01/06
* @author File creator: David Teviotdale
* @author Credits: none
*/
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using ProjectXenocide.Utils;
using ProjectXenocide.Model.Battlescape;
using ProjectXenocide.Model.Battlescape.Combatants;
using ProjectXenocide.Model.StaticData;
using XnaModel = Microsoft.Xna.Framework.Graphics.Model;
#endregion
namespace ProjectXenocide.UI.Scenes.Battlescape
{
///
/// the set of 3D models for the various combatants
///
public class CombatantMeshes
{
///
/// Load models for all the combatants on the battlescape
///
/// content manager that fetches the content
/// the battlescape
public void LoadContent(ContentManager content, Battle battlescape)
{
// Draw combatants
foreach (Team team in battlescape.Teams)
{
foreach (Combatant combatant in team.Combatants)
{
string modelName = combatant.Graphic.Model;
if (!models.ContainsKey(modelName))
{
XnaModel model = content.Load("Content\\Models\\" + modelName);
models.Add(modelName, new ModelInfo(model, combatant.Graphic));
}
}
}
}
///
/// Render the combatant
///
/// combatant to render
/// effect to use to draw the combatant
/// is X-Corp supposed to be able to see this combatant?
public void Draw(Combatant combatant, BasicEffect basicEffect, bool visible)
{
// fetch model
ModelInfo modelInfo = models[combatant.Graphic.Model];
// set up world matrix to position object in world
Matrix world = modelInfo.scalingMatrix;
//... if combatant is dead or stunned, plant model face down on ground
if (combatant.CanTakeOrders)
{
world *= Matrix.CreateRotationY(combatant.Heading);
}
else
{
world *= Matrix.CreateRotationZ(-MathHelper.PiOver2) * Matrix.CreateTranslation(-0.5f, 0, 0);
}
world *= Matrix.CreateTranslation(BattlescapeScene.CellToWorld(combatant.Position));
// draw the model
//...Copy any parent transforms
Matrix[] transforms = new Matrix[modelInfo.model.Bones.Count];
modelInfo.model.CopyAbsoluteBoneTransformsTo(transforms);
//...Draw the model, a model can have multiple meshes, so loop
foreach (ModelMesh mesh in modelInfo.model.Meshes)
{
//This is where the mesh orientation is set, as well as our camera and projection
foreach (BasicEffect effect in mesh.Effects)
{
effect.LightingEnabled = false;
effect.World = transforms[mesh.ParentBone.Index] * world;
effect.View = basicEffect.View;
effect.Projection = basicEffect.Projection;
effect.Alpha = visible ? 1.0f : 0.5f ;
}
//Draw the mesh, will use the effects set above.
mesh.Draw();
}
}
#region Fields
///
/// Hold the data on a combatant's 3D model
///
private struct ModelInfo
{
///
/// Ctor
///
/// The model
/// Scaling and orientation information for model
public ModelInfo(XnaModel model, Graphic graphic)
{
this.model = model;
// compute matrix to put model to scale and default orientation
BoundingSphere sphere = Util.CalcBoundingSphere(model);
// Scaling factor for model, use value from graphic, or scale to bounding sphere if none supplied
float scale = graphic.Scale;
if (0 == scale)
{
scale = (1.0f / sphere.Radius);
}
scalingMatrix = Matrix.CreateScale(scale) * graphic.InitialRotation;
// adjust for origin of model not being centered correctly in XZ plane
Vector3 displacement = Vector3.Transform(sphere.Center, scalingMatrix);
scalingMatrix *= Matrix.CreateTranslation(-displacement.X, 0, -displacement.Z);
}
public XnaModel model;
public Matrix scalingMatrix;
}
/// The models
private Dictionary models = new Dictionary();
#endregion Fields
}
}