/*
* ParticleEngine.cs
* Authors: Brian Murphy
* Copyright (c) 2007-2008 Cornell University
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using tAC_Engine.Graphics.Cameras;
using TACParticleEngine.Emitters;
using Util;
namespace TACParticleEngine.Particles
{
///
/// Handles creation, updating, and rendering of all emitters associtied with it
///
public class ParticleEngine : DrawableGameScreenComponent, ICloneable
{
#region Fields
// Whether to draw using GPU or CPU
private bool mGPURendering;
// Current sprite batch renderer
private SpriteBatch mSpriteBatch;
// Current active camera
private Camera mActiveCamera;
// Current viewport used for rendering to
private Viewport mViewport;
// Current content manager used in managing content
private ContentManager mContent;
// Boolean value to let the particle manager know when to dispose of this
private bool mToDestroy;
// List of emitters
private readonly List mEmitterList;
#endregion
#region Properties
///
/// Sets whether or not the engine will draw using GPU or CPU rendering
///
public bool GPURendering { set { mGPURendering = value; } }
///
/// Sets the SpriteBatch object to be used in CPU rendering
///
public SpriteBatch SpriteBatch { set { mSpriteBatch = value; } }
///
/// Sets the active camera that is used for rendering
///
public Camera ActiveCamera { set { mActiveCamera = value; } }
///
/// Sets the viewport to draw within for CPU rendering
///
public Viewport Viewport { set { mViewport = value; } }
///
/// Gets/Sets whether this should be destroyed
///
public bool ToDestory
{
get { return mToDestroy; }
set { mToDestroy = value; }
}
///
/// Sets the current content manager used for content management
///
public ContentManager Content { set { mContent = value; } }
///
/// Gets the list of emitters within the particle engine
///
public List Emitters { get { return mEmitterList; } }
///
/// True if any of the emitters in the engine are still active
/// *Note* active means that it is still able to draw while alive
///
public bool EmitterActive
{
get
{
foreach (Emitter emitter in mEmitterList)
{
if (emitter.IsActive)
{
return true;
}
}
return false;
}
}
///
/// True if any of the emitters are alive
/// *Note* alive means that it's lifetime has not been exceeded
///
public bool EmitterAlive
{
get
{
foreach (Emitter emitter in mEmitterList)
{
if (emitter.Alive)
{
return true;
}
}
return false;
}
}
///
/// True if all of the particles in all emitters are finished drawing
/// *Note* that this is typically for when an emitter is no longer alive
///
public bool EmitterParticlesDone
{
get
{
foreach (Emitter emitter in mEmitterList)
{
if (!emitter.ParticlesDone)
{
return false;
}
}
return true;
}
}
///
/// Used for clearing out unused particle engines
///
public static readonly Predicate NotAlive = delegate(ParticleEngine engine)
{
return (engine.mToDestroy && !engine.EmitterActive);
};
#endregion
#region Creation
///
/// Particle Engine constuctor which sets its list of emitters to the given list
///
/// The list of emitters the particle engine will use
public ParticleEngine(List emitterList)
{
mEmitterList = emitterList;
mToDestroy = false;
}
///
/// Returns a copy of this particle engine
///
/// A cloned copy of this particle engine
public object Clone()
{
List emitters = new List();
foreach (Emitter emitter in Emitters)
{
emitters.Add((Emitter)emitter.Clone());
}
return new ParticleEngine(emitters);
}
#endregion
#region File I/O
///
/// Reads in a xml particle file and stores it as a new particle effect
///
/// The name of the particle file to read in
/// A new particle engine created for the read in file
public static ParticleEngine LoadFromFile(string filename)
{
System.Xml.XmlDocument xml = new System.Xml.XmlDocument();
xml.Load(filename);
ParticleCompiled ret = new ParticleCompiled();
foreach (System.Xml.XmlNode node in xml.GetElementsByTagName("particle")[0].ChildNodes)
{
EmitterInfo emitter = new EmitterInfo();
foreach (System.Xml.XmlNode info in node.ChildNodes)
{
if (info.Name.Equals("type"))
emitter.Type = info.InnerText;
if (info.Name.Equals("textureName"))
emitter.TextureName = info.InnerText;
if (info.Name.Equals("blendEffect"))
emitter.BlendEffect = (SpriteBlendMode)Enum.Parse(emitter.BlendEffect.GetType(), info.InnerText, true);
if (info.Name.Equals("positions"))
{
List vertices = new List();
String[] dots = info.InnerText.TrimStart('(').TrimEnd(')').Replace(")(", " ").Split(' ');
foreach (String point in dots)
{
String[] vertex = point.Split(',');
vertices.Add(new Vector3(float.Parse(vertex[0]), float.Parse(vertex[1]), float.Parse(vertex[2])));
}
emitter.Positions = vertices;
}
if (info.Name.Equals("sprayRange"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.SprayRange = new Vector3(
float.Parse(component[0]),
float.Parse(component[1]),
float.Parse(component[2]));
}
if (info.Name.Equals("direction"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.Direction = new Vector3(
float.Parse(component[0]),
float.Parse(component[1]),
float.Parse(component[2]));
}
if (info.Name.Equals("minVel"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.MinVel = new Vector3(
float.Parse(component[0]),
float.Parse(component[1]),
float.Parse(component[2]));
}
if (info.Name.Equals("maxVel"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.MaxVel = new Vector3(
float.Parse(component[0]),
float.Parse(component[1]),
float.Parse(component[2]));
}
if (info.Name.Equals("emitLifetime"))
emitter.EmitLifetime = float.Parse(info.InnerText);
if (info.Name.Equals("particlesPerSec"))
emitter.ParticlePersSec = int.Parse(info.InnerText);
if (info.Name.Equals("particleLifetime"))
emitter.ParticleLifetime = float.Parse(info.InnerText);
if (info.Name.Equals("particleAmount"))
emitter.ParticleAmount = int.Parse(info.InnerText);
if (info.Name.Equals("minStartSpeed"))
emitter.MinStartSpeed = float.Parse(info.InnerText);
if (info.Name.Equals("maxStartSpeed"))
emitter.MaxStartSpeed = float.Parse(info.InnerText);
if (info.Name.Equals("minEndSpeed"))
emitter.MinEndSpeed = float.Parse(info.InnerText);
if (info.Name.Equals("maxEndSpeed"))
emitter.MaxEndSpeed = float.Parse(info.InnerText);
if (info.Name.Equals("minStartColor"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.MinStartColor = new Vector4(
float.Parse(component[0]),
float.Parse(component[1]),
float.Parse(component[2]),
float.Parse(component[3]));
}
if (info.Name.Equals("maxStartColor"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.MaxStartColor = new Vector4(
float.Parse(component[0]),
float.Parse(component[1]),
float.Parse(component[2]),
float.Parse(component[3]));
}
if (info.Name.Equals("minEndColor"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.MinEndColor = new Vector4(
float.Parse(component[0]),
float.Parse(component[1]),
float.Parse(component[2]),
float.Parse(component[3]));
}
if (info.Name.Equals("maxEndColor"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.MaxEndColor = new Vector4(
float.Parse(component[0]),
float.Parse(component[1]),
float.Parse(component[2]),
float.Parse(component[3]));
}
if (info.Name.Equals("minStartSize"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.MinStartSize = new Vector2(
float.Parse(component[0]),
float.Parse(component[1]));
}
if (info.Name.Equals("maxStartSize"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.MaxStartSize = new Vector2(
float.Parse(component[0]),
float.Parse(component[1]));
}
if (info.Name.Equals("minEndSize"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.MinEndSize = new Vector2(
float.Parse(component[0]),
float.Parse(component[1]));
}
if (info.Name.Equals("maxEndSize"))
{
String[] component = info.InnerText.TrimStart('(').TrimEnd(')').Split(',');
emitter.MaxEndSize = new Vector2(
float.Parse(component[0]),
float.Parse(component[1]));
}
if (info.Name.Equals("scale"))
{
emitter.Scale = float.Parse(info.InnerText);
}
if (info.Name.Equals("scaleSpeed"))
{
emitter.ScaleSpeed = float.Parse(info.InnerText);
}
}
ret.EmitterInfoList.Add(emitter);
}
List emitterInfoList = ret.EmitterInfoList;
List emitters = new List();
foreach (EmitterInfo info in emitterInfoList)
{
if (info.Type.Equals("SplineEmitter"))
{
emitters.Add(new SplineEmitter(info.Positions.ToArray(), info.Scale, info.ScaleSpeed,
info.BlendEffect, info.TextureName, info.ParticlePersSec, info.ParticleAmount,
info.EmitLifetime, info.ParticleLifetime, info.MinStartSize, info.MaxStartSize,
info.MinEndSize, info.MaxEndSize, info.MinStartSpeed, info.MaxStartSpeed, info.MinEndSpeed,
info.MaxEndSpeed, info.MinStartColor, info.MaxStartColor, info.MinEndColor, info.MaxEndColor));
}
else if (info.Type.Equals("PointEmitter"))
{
emitters.Add(new PointEmitter(info.Positions[0],
info.BlendEffect, info.TextureName, info.ParticlePersSec, info.ParticleAmount,
info.EmitLifetime, info.ParticleLifetime, info.MinStartSize, info.MaxStartSize,
info.MinEndSize, info.MaxEndSize, info.MinStartSpeed, info.MaxStartSpeed, info.MinEndSpeed,
info.MaxEndSpeed, info.MinStartColor, info.MaxStartColor, info.MinEndColor, info.MaxEndColor));
}
else if (info.Type.Equals("SprayEmitter"))
{
emitters.Add(new SprayEmitter(info.Positions[0], info.SprayRange, info.Direction,
info.BlendEffect, info.TextureName, info.ParticlePersSec, info.ParticleAmount,
info.EmitLifetime, info.ParticleLifetime, info.MinStartSize, info.MaxStartSize,
info.MinEndSize, info.MaxEndSize, info.MinStartSpeed, info.MaxStartSpeed,
info.MinEndSpeed, info.MaxEndSpeed, info.MinStartColor, info.MaxStartColor,
info.MinEndColor, info.MaxEndColor));
}
else if (info.Type.Equals("DirectionalEmitter"))
{
emitters.Add(new DirectionalEmitter(info.Positions[0], info.MinVel, info.MaxVel,
info.BlendEffect, info.TextureName, info.ParticlePersSec, info.ParticleAmount,
info.EmitLifetime, info.ParticleLifetime, info.MinStartSize, info.MaxStartSize,
info.MinEndSize, info.MaxEndSize, info.MinStartSpeed, info.MaxStartSpeed, info.MinEndSpeed,
info.MaxEndSpeed, info.MinStartColor, info.MaxStartColor, info.MinEndColor, info.MaxEndColor));
}
}
return new ParticleEngine(emitters);
}
///
/// Saves all the information of the particle effect into an xml file of the given name
///
/// The name of the xml file to save to
public void SaveToFile(string filename)
{
System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(filename, null);
writer.WriteStartDocument();
writer.WriteComment(filename.Substring(filename.LastIndexOf("\\") + 1) + "\nCopyright (c) 2008 Cornell University\n\n" +
"This program is free software; you can redistribute it and/or\n" +
"modify it under the terms of the GNU General Public License\n" +
"as published by the Free Software Foundation; either version 2\n" +
"of the License, or (at your option) any later version.\n\n" +
"This program is distributed in the hope that it will be useful,\n" +
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +
"GNU General Public License for more details.\n\n" +
"You should have received a copy of the GNU General Public License\n" +
"along with this program; if not, write to the Free Software\n" +
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.");
writer.WriteWhitespace("\n\n");
writer.WriteStartElement("particle");
writer.WriteWhitespace("\n");
foreach (Emitter emitter in mEmitterList)
{
writer.WriteStartElement("emitter");
writer.WriteWhitespace("\n");
if (emitter is DirectionalEmitter)
{
writer.WriteStartElement("type");
writer.WriteString("DirectionalEmitter");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("positions");
writer.WriteString("(" + emitter.EmitterPosition.X + "," + emitter.EmitterPosition.Y + "," + emitter.EmitterPosition.Z + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("minVel");
writer.WriteString("(" + ((DirectionalEmitter)emitter).MinVel.X + "," + ((DirectionalEmitter)emitter).MinVel.Y + "," + ((DirectionalEmitter)emitter).MinVel.Z + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("maxVel");
writer.WriteString("(" + ((DirectionalEmitter)emitter).MaxVel.X + "," + ((DirectionalEmitter)emitter).MaxVel.Y + "," + ((DirectionalEmitter)emitter).MaxVel.Z + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
}
if (emitter is PointEmitter)
{
writer.WriteStartElement("type");
writer.WriteString("PointEmitter");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("positions");
writer.WriteString("(" + emitter.EmitterPosition.X + "," + emitter.EmitterPosition.Y + "," + emitter.EmitterPosition.Z + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
}
if (emitter is SplineEmitter)
{
writer.WriteStartElement("type");
writer.WriteString("SplineEmitter");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("positions");
string tempStr = "";
Vector3[] tempArr = ((SplineEmitter)emitter).EmitterPositions;
for (int i = tempArr.Length - 1; i >= 0; --i)
{
tempStr += "(" + tempArr[i].X + "," + tempArr[i].Y + "," + tempArr[i].Z + ")";
}
writer.WriteString(tempStr);
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("direction");
writer.WriteString("(" + emitter.Direction.X + "," + emitter.Direction.Y + "," + emitter.Direction.Z + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("scale");
writer.WriteString(((SplineEmitter)emitter).Scale.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("scaleSpeed");
writer.WriteString(((SplineEmitter)emitter).ScaleSpeed.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n");
}
if (emitter is SprayEmitter)
{
writer.WriteStartElement("type");
writer.WriteString("SprayEmitter");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("positions");
writer.WriteString("(" + emitter.EmitterPosition.X + "," + emitter.EmitterPosition.Y + "," + emitter.EmitterPosition.Z + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("direction");
writer.WriteString("(" + emitter.Direction.X + "," + emitter.Direction.Y + "," + emitter.Direction.Z + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("sprayRange");
writer.WriteString("(" + ((SprayEmitter)emitter).SprayRange.X + "," + ((SprayEmitter)emitter).SprayRange.Y + "," + ((SprayEmitter)emitter).SprayRange.Z + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
}
writer.WriteStartElement("textureName");
writer.WriteString(emitter.TextureName);
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("blendEffect");
writer.WriteString(emitter.BlendEffect.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("emitLifetime");
writer.WriteString(emitter.EmitLifetime.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("particlesPerSec");
writer.WriteString(emitter.ParticlesPerSec.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("particleAmount");
writer.WriteString(emitter.PaticleAmount.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("particleLifetime");
writer.WriteString(emitter.ParticleLifetime.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n\n");
writer.WriteStartElement("minStartSpeed");
writer.WriteString(emitter.MinStartSpeed.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("maxStartSpeed");
writer.WriteString(emitter.MaxStartSpeed.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("minEndSpeed");
writer.WriteString(emitter.MinEndSpeed.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("maxStartSpeed");
writer.WriteString(emitter.MaxEndSpeed.ToString());
writer.WriteEndElement();
writer.WriteWhitespace("\n\n");
writer.WriteComment(" (r,g,b,a) range 0.0-1.0 ");
writer.WriteWhitespace("\n");
writer.WriteStartElement("minStartColor");
writer.WriteString("(" + emitter.MinStartColor.X + "," + emitter.MinStartColor.Y + "," + emitter.MinStartColor.Z + "," + emitter.MinStartColor.W + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("maxStartColor");
writer.WriteString("(" + emitter.MaxStartColor.X + "," + emitter.MaxStartColor.Y + "," + emitter.MaxStartColor.Z + "," + emitter.MaxStartColor.W + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("minEndColor");
writer.WriteString("(" + emitter.MinEndColor.X + "," + emitter.MinEndColor.Y + "," + emitter.MinEndColor.Z + "," + emitter.MinEndColor.W + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("maxEndColor");
writer.WriteString("(" + emitter.MaxEndColor.X + "," + emitter.MaxEndColor.Y + "," + emitter.MaxEndColor.Z + "," + emitter.MaxEndColor.W + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n\n");
writer.WriteComment(" (x,y) ");
writer.WriteWhitespace("\n");
writer.WriteStartElement("minstartSize");
writer.WriteString("(" + emitter.MinStartSize.X + "," + emitter.MinStartSize.Y + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("maxStartSize");
writer.WriteString("(" + emitter.MaxStartSize.X + "," + emitter.MaxStartSize.Y + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("minEndSize");
writer.WriteString("(" + emitter.MinEndSize.X + "," + emitter.MinEndSize.Y + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteStartElement("maxEndSize");
writer.WriteString("(" + emitter.MaxEndSize.X + "," + emitter.MaxEndSize.Y + ")");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
writer.WriteEndElement();
writer.WriteWhitespace("\n");
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
}
#endregion
#region Management
///
/// Reloads in content that we are using whenever the graphics device loses focus so as to not crash program
///
public void Load()
{
for (int i = mEmitterList.Count - 1; i >= 0; i--)
{
mEmitterList[i].Content = mContent;
mEmitterList[i].LoadContent();
}
}
///
/// Unloads content so as to not take up too much memory. Primarily used for minigames.
///
public void Unload()
{
for (int i = mEmitterList.Count - 1; i >= 0; i--)
{
mEmitterList[i].UnloadContent();
}
}
///
/// Disposes necessary objects.
///
/// Whether or not this is currently being disposed of
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (mEmitterList.Count > 0)
{
for (int i = mEmitterList.Count - 1; i >= 0; --i)
{
mEmitterList[i].Dispose();
mEmitterList[i] = null;
}
mEmitterList.Clear();
}
}
base.Dispose(disposing);
}
#endregion
#region Render
///
/// Handles all rendering of particles using GPU or CPU rendering
///
/// The total game time
public override void Draw(GameTime gameTime)
{
if (EmitterActive)
{
if (mGPURendering)
{
// Set point sprite values
Game.GraphicsDevice.RenderState.PointSpriteEnable = true;
Game.GraphicsDevice.RenderState.PointSizeMax = 256;
// Set the alpha blend mode
Game.GraphicsDevice.RenderState.AlphaBlendEnable = true;
Game.GraphicsDevice.RenderState.AlphaBlendOperation = BlendFunction.Add;
Game.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
// Set the alpha test mode
Game.GraphicsDevice.RenderState.AlphaTestEnable = true;
Game.GraphicsDevice.RenderState.AlphaFunction = CompareFunction.Greater;
Game.GraphicsDevice.RenderState.ReferenceAlpha = 0;
// Enable the depth buffer (so particles will not be visible through
// solid objects like the ground plane), but disable depth writes
// (so particles will not obscure other particles).
Game.GraphicsDevice.RenderState.DepthBufferEnable = true;
Game.GraphicsDevice.RenderState.DepthBufferWriteEnable = false;
// Do the actually rendering
for (int i = mEmitterList.Count - 1; i >= 0; --i)
{
mEmitterList[i].RenderGPU(mActiveCamera);
}
// Reset a couple of the more unusual renderstates that we changed,
// so as not to mess up any other subsequent drawing.
Game.GraphicsDevice.RenderState.PointSpriteEnable = false;
Game.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;
}
else
{
for (int i = mEmitterList.Count - 1; i >= 0; --i)
{
mEmitterList[i].RenderCPU(mSpriteBatch, mActiveCamera, mViewport);
}
}
}
}
#endregion
#region Update
///
/// Updates all emitters inside of engine
///
/// The time since last call cycle
public void Update(float elapsedTime)
{
for (int i = mEmitterList.Count - 1; i >= 0; i--)
{
mEmitterList[i].Update(elapsedTime);
}
}
#endregion
#region Modifiers
///
/// Sets the scale size for a spline emitter
/// *Note* has no effect on a non-spline emitter
///
/// The size the emitter will scale by
public void SetSplineScale(float scale)
{
foreach (Emitter emitter in mEmitterList)
{
if (emitter is SplineEmitter)
{
((SplineEmitter)emitter).Scale = scale;
}
}
}
///
/// Sets the specified particle engine to either active or inactive
///
/// True to activate the particle engine, false to deactivate it
public void SetActive(bool isActive)
{
foreach (Emitter emitter in mEmitterList)
{
emitter.IsActive = isActive;
}
}
///
/// Sets the positions of all the points of all spline emitters within the particle engine
///
/// The new positions to put the spline points at
public void SetEnginePositions(Vector3[] Positions)
{
foreach (Emitter emitter in mEmitterList)
{
if (emitter is SplineEmitter)
{
(emitter as SplineEmitter).EmitterPositions = Positions;
}
}
}
///
/// Sets the position of all the emitters within the particle engine
///
/// The new position to put the particle at
public void SetEnginePosition(Vector3 Position)
{
foreach (Emitter emitter in mEmitterList)
{
emitter.EmitterPosition = Position;
}
}
///
/// Sets the color of all the emitters within the particle engine
///
/// The new color to set the particle to
/// Whether the new speed remains constant or decays
public void SetEngineColor(Vector4 Color, bool Constant)
{
if (Constant)
{
foreach (Emitter emitter in mEmitterList)
{
emitter.StartColor = Color;
emitter.EndColor = Color;
}
}
else
{
foreach (Emitter emitter in mEmitterList)
{
emitter.StartColor = Color;
}
}
}
///
/// Sets the size of all the emitters within the particle engine
///
/// The new size to set the particle to
public void SetEngineSize(Vector2 Size)
{
foreach (Emitter emitter in mEmitterList)
{
emitter.Size = Size;
}
}
///
/// Sets the speed of all emitters within the particle engine
///
/// The new speed to set the particle to
/// Whether the new speed remains constant or decays
public void SetEngineSpeed(float Speed, bool Constant)
{
if (Constant)
{
foreach (Emitter emitter in mEmitterList)
{
emitter.StartSpeed = Speed;
emitter.EndSpeed = Speed;
}
}
else
{
foreach (Emitter emitter in mEmitterList)
{
emitter.StartSpeed = Speed;
}
}
}
///
/// Sets the direction of all emitters within the particle engine
///
/// The new direction to set the particle to
public void SetEngineDirection(Vector3 Direction)
{
foreach (Emitter emitter in mEmitterList)
{
emitter.Direction = Direction;
}
}
///
/// Sets the lifetime of all particles in all emitters within the particle engine
///
/// The new lifetime to set the particle to
public void SetEngineParticleLifetime(float Lifetime)
{
foreach (Emitter emitter in mEmitterList)
{
emitter.ParticleLifetime = Lifetime;
}
}
///
/// Sets the amount of particles to be active at one time.
///
/// The amount of particles
public void SetEngineParticles(float Num)
{
foreach (Emitter emitter in mEmitterList)
{
emitter.ParticlesPerSec = Num / emitter.ParticleLifetime;
}
}
///
/// Sets the amount of particles created per second
///
/// The amount of particles created per second
public void SetEngineParticlesPerSec(float NumPerSec)
{
foreach (Emitter emitter in mEmitterList)
{
emitter.ParticlesPerSec = NumPerSec;
}
}
///
/// Sets whether or not particles directions will be random
///
/// Whether or not particles will move in a random direction
public void SetRandomDirection(bool Random)
{
foreach (Emitter emitter in mEmitterList)
{
emitter.RandomDirection = Random;
}
}
#endregion
}
}