/* Sparx * Copyright August Zinsser 2007 * This program is distributed under the terms of the GNU General Public License */ using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Storage; using Microsoft.Xna.Framework.Graphics; namespace Pina3D.Particles { public abstract class Emission : SparxMortalEntity { protected Vector3 mPosition; protected Vector3 mVelocity; protected List mMyModifiers; protected List mMyForces; protected bool mVisible; protected Matrix mTransform; protected float mRenderScale; protected float mRenderRotation; public bool Visible { set { mVisible = value; } get { return mVisible; } } public Vector2 Position2D { set { mPosition = new Vector3(value.X, value.Y, mPosition.Z); } get { return new Vector2(mPosition.X, mPosition.Y); } } public Vector3 Position3D { set { mPosition = value; } get { return mPosition; } } public Vector2 Velocity2D { set { mVelocity = new Vector3(value.X, value.Y, mVelocity.Z); } get { return new Vector2(mVelocity.X, mVelocity.Y); } } public Vector3 Velocity3D { set { mVelocity = new Vector3(value.X, value.Y, value.Z); } get { return mVelocity; } } public float X { set { mPosition.X = value; } get { return mPosition.X; } } public float Y { set { mPosition.Y = value; } get { return mPosition.Y; } } public float Z { set { mPosition.Z = value; } get { return mPosition.Z; } } public float DX { set { mVelocity.X = value; } get { return mVelocity.X; } } public float DY { set { mVelocity.Y = value; } get { return mVelocity.Y; } } public float DZ { set { mVelocity.Z = value; } get { return mVelocity.Z; } } public List Modifiers { get { return mMyModifiers; } } /// /// Applies a local space transformation to this emission and all spawns if it is an emitter. Transformations do NOT multiply down. Setting the /// transform of an particle will cause it to ignore the transform of its emitter unless that emitter's transform is updated. /// public virtual Matrix Transform { set { mTransform = value; } get { return mTransform; } } /// /// Scales all particles at render time. Render positions will not be affected by scale. /// public virtual float RenderScale { set { mRenderScale = value; } get { return mRenderScale; } } /// /// Rotates all particles (in screen space) at render time. Render not positions will be affected. /// public virtual float RenderRotation { set { mRenderRotation = value; } get { return mRenderRotation; } } public abstract int ParticleCount { get;} public abstract int EmitterCount { get;} /// /// Specifies inital values /// /// Where the emitter is located /// True if the emission does not implicitly die, false if it should die after the specified lifespan /// Ignored if immortal == true public Emission(string name, Vector3 position, bool immortal, float lifeSpan) : base (name, lifeSpan, immortal) { mPosition = position; mVelocity = Vector3.Zero; mMyModifiers = new List(); mMyForces = new List(); mTransform = Matrix.Identity; mRenderScale = 1f; mRenderRotation = 0f; } protected Emission() { } /// /// Tells this emission to be affected by the specified Modifier. If it is already subscribed, then do nothing. /// /// public virtual void SubscribeToModifier(Modifier modifier) { if (!mMyModifiers.Contains(modifier)) mMyModifiers.Add(modifier); } /// /// Removes the effects of the specified Modifier. If already unsubscribed, do nothing. /// /// public virtual void UnsubscribeFromModifier(Modifier modifier) { if (mMyModifiers.Contains(modifier)) mMyModifiers.Remove(modifier); } /// /// Forces this emission to be affected by the specified Force. If it is already subscribed, then do nothing. /// /// public virtual void SubscribeToForce(Force force) { if (!mMyForces.Contains(force)) mMyForces.Add(force); } /// /// Removes the effects of the specified Force. If already unsubscribed, do nothing. /// /// public virtual void UnsubscribeFromForce(Force force) { if (mMyForces.Contains(force)) mMyForces.Remove(force); } public override void Update() { base.Update(); // Regular movement mPosition += mVelocity * Pina.ElapsedSeconds; // Forces for (int i = 0; i < mMyForces.Count; i++) { mMyForces[i].Update(this); } } } }