#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2009 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
This library 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
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#endregion
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
namespace Nuclex.Graphics.SpecialEffects.Particles {
/// Simulates the effects of gravity on particles
/// Data type of the particles
public class GravityAffector : IParticleAffector {
/// Average gravity on earth in meters per squared second
public const float StandardEarthGravity = 9.80665f;
/// Initializes a new gravity affector
///
/// Modifier through which the particles' properties will be changed
///
public GravityAffector(IParticleModifier modifier) :
this(modifier, StandardEarthGravity) { }
///
/// Initializes a new gravity affector with a custom gravity constant
///
///
/// Modifier through which the particles' properties will be changed
///
///
/// Gravity constant that will be applied to the particles
///
public GravityAffector(IParticleModifier modifier, float gravity) :
this(modifier, new Vector3(0.0f, -gravity, 0.0f)) { }
///
/// Initializes a new gravity affector with a custom gravity vector
///
///
/// Modifier through which the particles' properties will be changed
///
/// Gravity vector that will be applied to the particles
public GravityAffector(IParticleModifier modifier, Vector3 gravity) {
this.modifier = modifier;
this.Gravity = gravity;
}
///
/// Whether the affector can do multiple updates in a single step without
/// changing the outcome of the simulation
///
public bool IsCoalescable { get { return false; } }
/// Applies the affector's effect to a series of particles
/// Particles the affector will be applied to
/// Index of the first particle that will be affected
/// Number of particles that will be affected
/// Number of updates to perform in the affector
///
/// Contrary to general-purpose particle systems like we might find in expensive
/// animation packages, we don't update particles based on time but instead
/// use the simplified approach of updating particles in simulation steps.
/// This simplifies the implementation and matches a game's architecture where
/// the simulation is updated in steps as well to have a predictable outcome.
///
public void Affect(ParticleType[] particles, int start, int count, int updates) {
if(this.modifier.HasVelocity) {
float seconds = (float)updates / UpdatesPerSecond;
Vector3 accumulatedVelocity = this.Gravity * seconds;
this.modifier.AddToVelocity(particles, start, count, ref accumulatedVelocity);
}
}
/// XNA's standard update frequency
///
/// Can be adjusted if your simulation runs at a different speed to ensure that
/// the gravity constant is still expressed in m/s^2
///
public float UpdatesPerSecond = 60.0f;
/// Gravity in m/s^2 that will be applied to the particles
public Vector3 Gravity;
/// Particle modifier used to apply gravity to the particles
private IParticleModifier modifier;
}
} // namespace Nuclex.Graphics.SpecialEffects.Particles