using System; using System.Collections.Generic; using OpenTK; using SM.Base.Contexts; using SM.Base.Scene; using SM.Base.Time; using SM.Base.Types; using SM.OGL.Shaders; namespace SM.Base.Drawing.Particles { /// /// The (drawing) basis for particles /// public abstract class ParticleDrawingBasis : DrawingBasis, IScriptable where TTransform : GenericTransformation, new() where TDirection : struct { /// /// This contains all important information for each particle. /// protected ParticleStruct[] particleStructs; /// /// This contains the different instances for the particles. /// protected List instances; /// /// The stopwatch of the particles. /// protected Timer timer; /// /// The amount of particles /// public int Amount = 32; /// /// The maximum speed of the particles /// public float MaxSpeed = 1; /// /// Get/Sets the state of pausing. /// public bool Paused { get => timer.Paused; set => timer.Paused = value; } /// /// Controls the movement of each particles. /// public abstract Func MovementCalculation { get; set; } protected ParticleDrawingBasis(TimeSpan duration) { timer = new Timer(duration); } /// /// Triggers the particles. /// public void Trigger() { timer.Start(); CreateParticles(); } /// public void Update(UpdateContext context) { if (!timer.Running) return; ParticleContext particleContext = new ParticleContext() { Timer = timer, }; for (int i = 0; i < Amount; i++) { particleContext.Speed = particleStructs[i].Speed; instances[i].ModelMatrix = CreateMatrix(particleStructs[i], MovementCalculation(particleStructs[i].Direction, particleContext)); } } /// protected override void DrawContext(ref DrawContext context) { if (!timer.Active) return; base.DrawContext(ref context); context.Instances = instances; context.Shader.Draw(context); } /// /// Creates the particles. /// protected virtual void CreateParticles() { particleStructs = new ParticleStruct[Amount]; instances = new List(); for (int i = 0; i < Amount; i++) { particleStructs[i] = CreateObject(i); instances.Add(new Instance()); } } /// /// Creates a particle. /// protected abstract ParticleStruct CreateObject(int index); /// /// Generates the desired matrix for drawing. /// protected abstract Matrix4 CreateMatrix(ParticleStruct Struct, TDirection relativePosition); } }