//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
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;
#endregion
using DarkWynter.Stream.PhysicsGpu;
using DarkWynter.Stream;
///
/// GpuObjectList contains a list of GpuObjects.
/// It takes an object at a time and holds it till ConvertToVariables is called, at which time it transfers converts the data into textures.
/// After this initialization, GpuObjects can still be added by using ConvertSubsetToVariables.
///
public class GpuObjectList
{
// Type information
private string type;
///
/// A list of GpuVariables used in our algorithm.
///
public List variables = new List();
public List _variables { get { return variables; } set { variables = value; } }
///
/// GpuProcessor is used to process each gpu object each pass
///
public GpuProcessor gpu_Processor { get { return _gpu_Processor; } set { _gpu_Processor = value; } }
public GpuProcessor _gpu_Processor;
/////
///// List of mass objects being converted to GpuVariables.
/////
//public List masses { get { return _masses; } set { _masses = value; } }
//private List _masses = new List();
///
/// A forceMap simulating wind currents.
///
public GpuWindMap windMap { get { return _windMap; } set { _windMap = value; } }
private GpuWindMap _windMap = new GpuWindMap();
///
/// Spacial Data Structure used in Gpu Collision algorithm.
///
public SpatialMap locationMap { get { return _locationMap; } set { _locationMap = value; } }
public SpatialMap _locationMap;
public Draw draw { get { return _draw; } set { _draw = value; } }
public Draw _draw;
// The instance data itself
private List instanceList;
private List removeObjects;
private List storeObjects;
public bool runLoad { get { return _runLoad; } set { _runLoad = value; } }
private bool _runLoad = false;
///
/// GpuObjectList constructor.
/// Creates a list of GpuVariables used in Physics and Collision.
///
public GpuObjectList(GraphicsDevice gd, XmlNode objectNode, Vector3 startingLocation)
{
gpu_Processor = new GpuProcessor(gd);
// Create Location Map
//locationMap = new SpatialMap(gd, "SpatialMain", ShaderParameters.UpdateFX.LocationMap,true, 0, 100);
// Create Variables and add to the Object
variables.Add(new Vec3(gd, "TotalForce", ShaderParameters.UpdateFX.TotalForce, true, 0, 100));
variables.Add(new Vec3(gd, "Acceleration", ShaderParameters.UpdateFX.Acceleration, true, 0, 100));
variables.Add(new Vec3(gd, "Velocity", ShaderParameters.UpdateFX.Velocity, true, 0, 100));
variables.Add(new Quat(gd, "Rotation", ShaderParameters.UpdateFX.Rotation, true, -100, 100));
variables.Add(new Vec3(gd, "CurrentPosition", ShaderParameters.UpdateFX.CurrentPosition, true, 0, 100));
variables.Add(new Vec3(gd, "Dummy", ShaderParameters.UpdateFX.Dummy, true, 0, 100));
variables.Add(new Vec1(gd, "", ShaderParameters.UpdateFX.Radius, false, 0, 100));
variables.Add(new Vec1(gd, "", ShaderParameters.UpdateFX.Scale, false, 0, 100));
variables.Add(new Vec1(gd, "", ShaderParameters.UpdateFX.Mass, false, 0, 100));
removeObjects = new List();
storeObjects = new List();
}
///
/// Override load function, parses and loads xml data.
///
/// ObjectLibrary that this list belongs to.
/// True if load was successful
public bool Load(GraphicsDevice gd)
{
//draw = new Draw(Draw.DrawMethod.GPUObjectList_Draw, "GPUPhysixInstancedShaderMain");
//draw.vertexDeclaration = new VertexDeclaration(gd, draw.FBTDElements);
//if (masses.Count > 0)
//{
// // Add a list of CPU Objects to the GPU Object
// ConvertToVariables();
// draw.textureList = masses[0].gameObjectPointer.draw.textureList;
// draw.model = masses[0].gameObjectPointer.draw.model;
// instanceList = new List();
// for (int i = 0; i < masses.Count; i++)
// {
// instanceList.Add(masses[i].gameObjectPointer.staticObjectValues);
// }
// draw.instanceDataFBTD = new VertexFogBinormalTangentDepth[instanceList.Count];
// instanceList.CopyTo(draw.instanceDataFBTD);
// draw.vertexBuffer = new VertexBuffer(Statics_Stream.RenderSettings.graphics.GraphicsDevice,
// typeof(VertexFogBinormalTangentDepth),
// draw.instanceDataFBTD.Length,
// BufferUsage.WriteOnly);
// draw.vertexBuffer.SetData(draw.instanceDataFBTD);
//}
//// Add Wind Map
//windMap.Load(node.Attributes["windMap"].Value, Statics_Engine.SystemSettings.content);
// Set Wind Map handle in shader
windMap.SetWindMap(ShaderParameters.UpdateFX.WindMap);
//// Set Scale and Min Value range
//ShaderParameters.DrawFX.scaleRange.SetValue(variables[4].scaleRange);
//ShaderParameters.DrawFX.minimumValue.SetValue(variables[4].minimumValue);
ShaderParameters.UpdateFX.cpScaleRangeY.SetValue(variables[4].scaleRange);
ShaderParameters.UpdateFX.cpScaleMinY.SetValue(variables[4].minimumValue);
//ShaderParameters.UpdateFX.scaleMinY.SetValue(objectLibrary.terrain.terrainScaleMinY);
//ShaderParameters.UpdateFX.scaleRangeY.SetValue(objectLibrary.terrain.terrainScaleMaxY - objectLibrary.terrain.terrainScaleMinY);
//// Set HeightMap, NormalMap, ForceMap, and Scale Values
//ShaderParameters.UpdateFX.TerrainHeightMap.SetValue(objectLibrary.terrain.heightMapTexture);
//ShaderParameters.UpdateFX.TerrainNormalMap.SetValue(objectLibrary.terrain.normalMapTexture);
//ShaderParameters.UpdateFX.gpuObjectScale.SetValue(Statics_Engine.TerrainSettings.collisionMapSize);
return true;
}
/////
///// Adds a mass object to be converted to a GpuObject.
///// Used by attack methods.
/////
///// Game object being added.
//public void AddNewObject(GameObject gameObject, bool convertNow)
//{
// masses.Add(gameObject.mass);
// variables[0].AddProperty(gameObject.mass.totalForce);
// variables[1].AddProperty(gameObject.mass.acceleration);
// variables[2].AddProperty(gameObject.mass.velocity);
// variables[3].AddProperty(gameObject.mass.currentRotation);
// variables[4].AddProperty(gameObject.mass.currentPosition);
// variables[5].AddProperty(gameObject.mass.totalForce); // Dummy Texture
// variables[6].AddProperty(gameObject.mass.boundingVolume.radius);
// variables[7].AddProperty(gameObject.mass.scale);
// variables[8].AddProperty(gameObject.mass.mass);
// int i = masses.Count - 1;
// Matrix matrix = Matrix.CreateScale(gameObject.mass.scale) *
// Matrix.CreateFromQuaternion(gameObject.mass.currentRotation);
// gameObject.staticObjectValues = new VertexFogBinormalTangentDepth();
// 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);
// masses[i].gameObjectPointer.staticObjectValues.Depth = new Vector4((float)i % 256 / 256, (float)((int)i / 256) / 256, 0, matrix.M44);
// if (convertNow)
// {
// if (masses.Count == 1)
// {
// runLoad = true;
// }
// storeObjects.Add(gameObject.staticObjectValues);
// ConvertSubsetToVariables(i, 1);
// }
//}
/////
///// Adds a List of mass objects to be converted to a GpuObject.
///// Used by attack methods.
/////
///// List of Mass objects being added.
//public void AddMass(List massList)
//{
// if (masses.Count == 0)
// {
// runLoad = true;
// }
// // Get insertion point
// int startIndex = masses.Count;
// int massCount = massList.Count;
// for (int i = 0; i < massList.Count; i++)
// {
// masses.Add(massList[i]);
// variables[0].AddProperty(massList[i].totalForce);
// variables[1].AddProperty(massList[i].acceleration);
// variables[2].AddProperty(massList[i].velocity);
// variables[3].AddProperty(massList[i].currentRotation);
// variables[4].AddProperty(massList[i].currentPosition);
// variables[5].AddProperty(massList[i].totalForce); // Dummy Texture
// variables[6].AddProperty(massList[i].boundingVolume.radius);
// variables[7].AddProperty(massList[i].scale);
// variables[8].AddProperty(massList[i].mass);
// int massNum = masses.Count - 1;
// Matrix matrix = Matrix.CreateScale(massList[i].scale) *
// Matrix.CreateFromQuaternion(massList[i].currentRotation);
// massList[i].gameObjectPointer.staticObjectValues.Fog = new Vector4(matrix.M11, matrix.M12, matrix.M13, matrix.M14);
// massList[i].gameObjectPointer.staticObjectValues.Binormal = new Vector4(matrix.M21, matrix.M22, matrix.M23, matrix.M24);
// massList[i].gameObjectPointer.staticObjectValues.Tangent = new Vector4(matrix.M31, matrix.M32, matrix.M33, matrix.M34);
// massList[i].gameObjectPointer.staticObjectValues.Depth = new Vector4((float)massNum % 256 / 256, (float)((int)massNum / 256) / 256, 0, matrix.M44);
// storeObjects.Add(massList[i].gameObjectPointer.staticObjectValues);
// }
// ConvertSubsetToVariables(startIndex, massCount);
//}
/////
///// Remove a mass object from the GpuObjectList.
/////
///// Mass to be removed.
//public void RemoveMass(Mass mass)
//{
// int index;
// index = masses.IndexOf(mass);
// masses.Remove(mass);
// removeObjects.Add(mass.gameObjectPointer.staticObjectValues);
// variables[0].ClearProperty(index);
// variables[1].ClearProperty(index);
// variables[2].ClearProperty(index);
// variables[3].ClearProperty(index);
// variables[4].ClearProperty(index);
// variables[5].ClearProperty(index); // Dummy Texture
// variables[6].ClearProperty(index);
// variables[7].ClearProperty(index);
// variables[8].ClearProperty(index);
// ConvertSubsetToVariables(index, 1);
//}
///
/// Convert a list of GameObjects into a Gpu Object
///
private void ConvertToVariables()
{
variables[0].SetTexData(); // totalForce
variables[1].SetTexData(); // acceleration
variables[2].SetTexData(); // velocity
variables[3].SetTexData(); // rotation
variables[4].SetTexData(); // currentPosition
variables[5].SetTexData(); // dummy
variables[6].SetTexData(); // radius
variables[7].SetTexData(); // scale
variables[8].SetTexData(); // mass
}
private void ConvertSubsetToVariables(int index, int count)
{
variables[0].SetSubTexData(index, count); // totalForce
variables[1].SetSubTexData(index, count); // acceleration
variables[2].SetSubTexData(index, count); // velocity
variables[3].SetSubTexData(index, count); // rotation
variables[4].SetSubTexData(index, count); // currentPosition
variables[5].SetSubTexData(index, count); // dummy
variables[6].SetSubTexData(index, count); // radius
variables[7].SetSubTexData(index, count); // scale
variables[8].SetSubTexData(index, count); // mass
}
//private void RetrieveValues()
//{
// // Unscale the Gpu Objectvariables
// for (int variableCount = 0; variableCount < variables.Count; variableCount++)
// {
// variables[variableCount].UnScale();
// }
// // Get current position for each object
// for (int massCount = 0; massCount < masses.Count; massCount++)
// {
// masses[massCount].totalForce = new Vector3(variables[0].properties[massCount].X,
// variables[0].properties[massCount].Y,
// variables[0].properties[massCount].Z);
// masses[massCount].acceleration = new Vector3(variables[1].properties[massCount].X,
// variables[1].properties[massCount].Y,
// variables[1].properties[massCount].Z);
// masses[massCount].velocity = new Vector3(variables[2].properties[massCount].X,
// variables[2].properties[massCount].Y,
// variables[2].properties[massCount].Z);
// masses[massCount].currentRotation = new Quaternion(variables[3].properties[massCount].X,
// variables[3].properties[massCount].Y,
// variables[3].properties[massCount].Z,
// variables[3].properties[massCount].W);
// masses[massCount].currentPosition = new Vector3(variables[4].properties[massCount].X,
// variables[4].properties[massCount].Y,
// variables[4].properties[massCount].Z);
// masses[massCount].scale = new Vector3(variables[7].properties[massCount].X);
// masses[massCount].mass = variables[8].properties[massCount].X;
// }
//}
///
/// Update using GpuProcessor.
///
/// ObjectLibrary that this list belongs to.
public void Update(GraphicsDevice gd, float dt)
{
if (runLoad)
{
runLoad = false;
Load(gd);
}
//// Calc the player's current position
//Vector2 playerPos2d =
// new Vector2(Statics_Engine.PlayerSettings.playerPosition.X, Statics_Engine.PlayerSettings.playerPosition.Y ) /
// new Vector2(Statics_Engine.TerrainSettings.collisionMapSize) / new Vector2(2.0f) + new Vector2(0.5f);
//ShaderParameters.UpdateFX.playerPosition.SetValue(playerPos2d);
// Set Change in Time
ShaderParameters.UpdateFX.dt.SetValue(dt);
//gpu_Processor.ExecuteRTT(gd, locationMap, variables);
}
///
/// Override Draw function
///
public Draw Draw(GraphicsDevice gd)
{
//if (masses.Count == 0)
//{
// return null;
//}
#if !XBOX360
// Transfer Current Position Reference from Update Effect to Draw Effect
//ShaderParameters.DrawFX.CurrentPosition.SetValue(variables[4]._read);
if (removeObjects.Count != 0)
{
for (int i = 0; i < removeObjects.Count; i++)
{
instanceList.Remove(removeObjects[i]);
}
instanceList.CopyTo(draw.instanceDataFBTD);
draw.vertexBuffer = new VertexBuffer(gd,
typeof(VertexFogBinormalTangentDepth),
draw.instanceDataFBTD.Length,
BufferUsage.WriteOnly);
draw.vertexBuffer.SetData(draw.instanceDataFBTD);
removeObjects.Clear();
}
if (storeObjects.Count != 0)
{
for (int i = 0; i < storeObjects.Count; i++)
{
instanceList.Add(storeObjects[i]);
}
draw.instanceDataFBTD = new VertexFogBinormalTangentDepth[instanceList.Count];
instanceList.CopyTo(draw.instanceDataFBTD);
draw.vertexBuffer = new VertexBuffer(gd,
typeof(VertexFogBinormalTangentDepth),
draw.instanceDataFBTD.Length,
BufferUsage.WriteOnly);
draw.vertexBuffer.SetData(draw.instanceDataFBTD);
storeObjects.Clear();
}
return draw;
#endif
}
}
}