//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
#define GPUInstancing
namespace DarkWynter.Engine.ObjectLib
{
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using System.Xml;
using System.Diagnostics;
using Xclna.Xna.Animation.Content;
using Xclna.Xna.Animation;
#endregion
using Globals;
using GameObjects;
using DarkWynter.Engine.Init;
using DarkWynter.Stream;
///
/// Contains a list of Generic Props.
/// Locations of these props are loaded from a LocationMap, listed in the Prop xml data for the level.
/// Generic Props use instancing, and consequently draw much faster than stand alone GameObjects.
///
public class PropList : GameObject
{
// Type information
private string type;
public List gameObjectList; // CpuObjects run physics and collision on the cpu
///
/// Constructor for a PropList.
///
public PropList(Load gameObjectLoader)
: base(gameObjectLoader)
{
// Create a GameObject list
gameObjectList = new List();
}
///
/// Loads a prop for each xml defined color in the xml defined LocationMap image.
///
/// ObjectLibrary that these props belong to.
/// True if load was successful
public override bool Load(ObjectLibrary objectLibrary)
{
bool success = base.LoadModel(load.node);
int response = int.Parse(load.node.Attributes["collisionResponse"].Value);
Enums_Engine.CollisionResponses currentResponse;
if (response == 4)
{
currentResponse = Enums_Engine.CollisionResponses.NONE;
}
else if (response == 3)
{
currentResponse = Enums_Engine.CollisionResponses.MANNALOSS;
}
else if (response == 2)
{
currentResponse = Enums_Engine.CollisionResponses.MANNABONUS;
}
else if (response == 1)
{
currentResponse = Enums_Engine.CollisionResponses.HEALTHLOSS;
}
else
{
currentResponse = Enums_Engine.CollisionResponses.HEALTHBONUS;
}
float collisionMultiplier = float.Parse(load.node.Attributes["collisionMultiplier"].Value);
// Return unsuccessfully if can't load user supplied XML data
if (!success) { return false; }
string value = load.node.Attributes["animated"].Value;
if (value == "Yes")
{
modelAnimated = true;
draw.drawMethod = Enums_Stream.DrawMethod.PropListAnimated_Draw;
draw.technique = "InstancedAnimation";
draw.vertexDeclaration = new VertexDeclaration(Statics_Stream.RenderSettings.graphics.GraphicsDevice, draw.InstAnimElements);
// Create Animators
animator = new ModelAnimator(draw.model);
idle = new AnimationController(animator.Animations["idle"]);
RunController(idle);
}
else
{
modelAnimated = false;
draw.drawMethod = Enums_Stream.DrawMethod.PropList_Draw;
draw.technique = "BasicLightingInstancedShaderMain";
draw.vertexDeclaration = new VertexDeclaration(Statics_Stream.RenderSettings.graphics.GraphicsDevice, draw.FBTDElements);
}
// Check to see if list is empty
// Happens if XML color value is not found
if (gameObjectList.Count <= 0)
return false;
else
{
draw.instanceDataFBTD = new VertexFogBinormalTangentDepth[gameObjectList.Count];
for (int i = 0; i < gameObjectList.Count; i++)
{
// gameObjectList[i].draw.instanceDataFBTD = new VertexFogBinormalTangentDepth[16];
draw.instanceDataFBTD[i] = gameObjectList[i].staticObjectValues;
//gameObjectList[i].draw.instanceDataFBTD[i] = gameObjectList[i].staticObjectValues;
}
draw.vertexBuffer = new VertexBuffer(Statics_Stream.RenderSettings.graphics.GraphicsDevice,
typeof(VertexFogBinormalTangentDepth),
draw.instanceDataFBTD.Length,
BufferUsage.WriteOnly);
draw.vertexBuffer.SetData(draw.instanceDataFBTD);
return true;
}
}
public void AddNewObject(GameObject gameObject)
{
// Instancing
gameObject.staticObjectValues = new VertexFogBinormalTangentDepth();
Matrix matrix = Matrix.CreateScale(gameObject.mass.scale) *
Matrix.CreateFromQuaternion(gameObject.mass.currentRotation) *
Matrix.CreateTranslation(gameObject.mass.currentPosition);
gameObject.staticObjectValues.Fog = new Vector4(matrix.M11, matrix.M12, matrix.M13, matrix.M14);
gameObject.staticObjectValues.Binormal = new Vector4(matrix.M21, matrix.M22, matrix.M23, matrix.M24);
gameObject.staticObjectValues.Tangent = new Vector4(matrix.M31, matrix.M32, matrix.M33, matrix.M34);
gameObject.staticObjectValues.Depth = new Vector4(matrix.M41, matrix.M42, matrix.M43, matrix.M44);
// Add the prop to the prop list
gameObjectList.Add(gameObject);
}
///
/// Updates this list of props.
///
/// ObjectLibrary which these props belong to.
public override void Update(ref ObjectLibrary objectLibrary)
{
// Physics?
// Collision?
// Use booleans loaded from xml...
}
///
/// Manages drawing all the props in this list.
///
public override Draw Draw()
{
if (gameObjectList.Count == 0)
{
return null;
}
#if !XBOX360
GraphicsDevice gd = Statics_Stream.RenderSettings.graphics.GraphicsDevice;
if (modelAnimated)
{
currentAnimation.Update(Statics_Engine.SystemSettings.elementalGameTime);
draw.animator = animator;
}
return draw;
#endif
}
}
}
// Legacy Code :)
// public void DrawShadow(ModelManager modelManager)
// {
// if (instanceData.Length == 0)
// {
// return;
// }
//#if !XBOX360
// GetUpdatedInstanceData();
// ModelInfo modelInfo = new ModelInfo();
// modelInfo = modelManager.GetModelInfo(type);
// // Set the values of the shader
// ShaderParameters.DrawFX.modelTexture1.SetValue(modelInfo.currentTexture);
// ShaderParameters.DrawFX.bumpTexture1.SetValue(modelInfo.bumpTexture);
// ShaderParameters.DrawFX.World.SetValue(Matrix.Identity);
// // Set the vertex declaration
// Statics.SystemSettings.graphics.GraphicsDevice.VertexDeclaration = vertexDeclaration;
// Statics.SystemSettings.graphics.GraphicsDevice.Vertices[0].SetFrequencyOfIndexData(instanceData.Length);
// Statics.SystemSettings.graphics.GraphicsDevice.Vertices[1].SetFrequencyOfInstanceData(1);
// // Tell the GPU how many times to run through the instance data and set the stream.
// Statics.SystemSettings.graphics.GraphicsDevice.Vertices[1].SetSource(instanceBuffer, 0, vertexDeclaration.GetVertexStrideSize(1));
// // Draw the model
// foreach (ModelMesh mesh in modelInfo.model.Meshes)
// {
// // Set the index buffer
// Statics.SystemSettings.graphics.GraphicsDevice.Indices = mesh.IndexBuffer;
// // Tell the GPU how many times to run through the vertex data and set the stream.
// Statics.SystemSettings.graphics.GraphicsDevice.Vertices[0].SetSource(mesh.VertexBuffer, 0, vertexDeclaration.GetVertexStrideSize(0));
// foreach (ModelMeshPart part in mesh.MeshParts)
// {
// part.Effect.CurrentTechnique = part.Effect.Techniques["InstancedShadowMap"];
// part.Effect.Begin();
// for (int k = 0; k < part.Effect.CurrentTechnique.Passes.Count; k++)
// {
// EffectPass pass = part.Effect.CurrentTechnique.Passes[k];
// pass.Begin();
// Statics.SystemSettings.graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,
// part.BaseVertex,
// 0,
// part.NumVertices,
// part.StartIndex,
// part.PrimitiveCount);
// pass.End();
// }
// part.Effect.End();
// }
// }
//#endif
// }