using System; using System.Drawing; using Azimuth; using Blacklight.Core; using Blacklight.Core.Drawables; using Prism; namespace Konis.Blacklight { /// /// Writes a standard emitter's particles into the entries of a sprite batch, so Blacklight can draw them. /// public static class ParticleSpriteWriter { private const SpriteBatch.Varying WrittenColumns = SpriteBatch.Varying.TintColor | SpriteBatch.Varying.Transform; /// /// Writes one entry per live particle, in the order the emitter keeps them, and returns how many that was. /// /// /// A batch drawing the entries must vary and . A particle's size is the width in world units it draws at, and its /// rotation turns the way an turns for a positive angle. /// /// The emitter whose particles are written. /// How the emitter's three-dimensional positions land on the screen. /// The sprite every particle draws, which is centered on the particle. /// /// The set to write into. It grows to fit, and gains the columns the writer fills if it lacks them. /// public static int Write( StandardEmitter emitter, ViewProjection projection, in SpriteSource source, SpriteBatch.EntrySet entries) { Particle[] particles = emitter.Store.Items; int count = emitter.Store.Count; entries.EnsureCapacity(count); entries.AddColumns(WrittenColumns); Size size = source.Size; var destination = new SpriteDestination(new Vector(size.Width / 2.0, size.Height / 2.0), size); var entry = new SpriteBatch.Entry(in source, in destination); Vector3 origin = emitter.Position; for (int i = 0; i < count; i++) { var position = new Vector3( origin.X + particles[i].PositionX, origin.Y + particles[i].PositionY, origin.Z + particles[i].PositionZ); double angle = emitter.RotationOf(i) * 2.0 * Math.PI; double scale = emitter.SizeOf(i) / (double)size.Width; entries.Entries[i] = entry; entries.Transforms[i] = new AffineMatrix(angle, projection.Project(position), scale); entries.TintColors[i] = Prism.Color.FromArgb(emitter.TintOf(i)); } return count; } } }