public override void OnParticlesActivated(Span <int> particlesIndex) { if (ParticleEngine.NativeEnabled) { return; } fixed(Particle *particleArr = Emitter.Particles) { for (int i = 0; i < particlesIndex.Length; i++) { Particle *particle = &particleArr[particlesIndex[i]]; startColors[particle->ID] = particle->Color; if (!IsRandom) { continue; } randEndColors[particle->ID] = new Vector4( Between(end1.X, end2.X, Random.Next(0.0f, 1.0f)), Between(end1.Y, end2.Y, Random.Next(0.0f, 1.0f)), Between(end1.Z, end2.Z, Random.Next(0.0f, 1.0f)), Between(end1.W, end2.W, Random.Next(0.0f, 1.0f))); } } }
/// <summary> /// Processes the particles. /// </summary> /// <param name="dt">Elapsed time in whole and fractional seconds.</param> /// <param name="particleArray">A pointer to an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float dt, Particle *particleArray, int count) { // Create the transformation matrix... float h = ((this.HueShift * dt) * Calculator.Pi) / 180f; float u = Calculator.Cos(h); float w = Calculator.Sin(h); Matrix hueTransform = new Matrix(1f, 0f, 0f, 0f, 0f, u, -w, 0f, 0f, w, u, 0f, 0f, 0f, 0f, 1f); for (int i = 0; i < count; i++) { Particle *particle = (particleArray + i); Vector4 colour; // Convert the current colour of the particle to YIQ colour space... Vector4.Transform(ref particle->Colour, ref HueShiftModifier.YIQTransformMatrix, out colour); // Transform the colour in YIQ space... Vector4.Transform(ref colour, ref hueTransform, out colour); // Convert the colour back to RGB... Vector4.Transform(ref colour, ref HueShiftModifier.RGBTransformMatrix, out colour); // And apply back to the particle... particle->Colour.X = colour.X; particle->Colour.Y = colour.Y; particle->Colour.Z = colour.Z; } }
private static void UpdateParticleGravity(Frame f, ulong e, Particle *particle, ECSConfig config) { particle->Position += particle->Velocity * config.deltaTime; var particleFilter = f.Filter <Particle>(); while (particleFilter.Next(out var otherEntity, out var otherParticle)) { if (otherEntity == e) { continue; } var toOther = otherParticle->Position - particle->Position; var sqrMagnitude = toOther.SqrMagnitude; if (sqrMagnitude <= Fix64.Zero) { continue; } if (sqrMagnitude >= config.halfRange * config.halfRange) { continue; } var forceGravity = (config.g * particle->Mass * otherParticle->Mass) / sqrMagnitude; particle->Velocity += toOther.Normalized * forceGravity * config.deltaTime; } }
public unsafe void Update(float amount, Particle *particle) { particle->Color = new HslColor( amount * _delta + StartValue, particle->Color.S, particle->Color.L); }
/// <summary> /// Processes the particles. /// </summary> /// <param name="dt">Elapsed time in whole and fractional seconds.</param> /// <param name="particleArray">A pointer to an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float dt, Particle *particleArray, int count) { this.TotalSeconds += dt; float deltaAmp = this.Amplitude * dt; for (int i = 0; i < count; i++) { Particle *particle = (particleArray + i); float secondsAlive = (float)(this.TotalSeconds - particle->Inception); float sin = Calculator.Cos(secondsAlive * this.Frequency); Vector2 force = new Vector2(sin, 0f); force.X = ((force.X * this.AngleCos) + (force.Y * -this.AngleSin)); force.Y = ((force.X * this.AngleSin) + (force.Y * this.AngleCos)); force.X *= deltaAmp; force.Y *= deltaAmp; particle->Velocity.X += force.X; particle->Velocity.Y += force.Y; } }
/// <summary> /// Processes the particles. /// </summary> /// <param name="dt">Elapsed time in whole and fractional seconds.</param> /// <param name="particleArray">A pointer to an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float dt, Particle *particleArray, int count) { float deltaForceX = this.Force.X * (this.Strength * dt); float deltaForceY = this.Force.Y * (this.Strength * dt); for (int i = 0; i < count; i++) { Particle *particle = (particleArray + i); if (particle->Position.X > this.Left) { if (particle->Position.X < this.Right) { if (particle->Position.Y > this.Top) { if (particle->Position.Y < this.Bottom) { particle->Velocity.X += deltaForceX; particle->Velocity.Y += deltaForceY; } } } } } }
public unsafe int UpdateBuffer() { int quadIndex = 0; fixed(ParticleVertex *pQuads = _quads) { fixed(Particle *pParticles = _particlesBuffer) { for (int i = 0, len = _particlesBuffer.Length; i < len; i++) { int k = 4 * quadIndex++; Particle *ptc = pParticles + i; for (int j = 0; j < 4; j++) { ParticleVertex *vertex = pQuads + k + j; vertex->PositionPtc = ptc->GlobalPosition; vertex->Alpha = ptc->Alpha; vertex->Color = ptc->Color; vertex->Size = ptc->Size; } } } _vb.Write(_quads); } return(quadIndex); }
/// <summary> /// Processes the particles. /// </summary> /// <param name="dt">Elapsed time in whole and fractional seconds.</param> /// <param name="particle">A pointer to an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float dt, Particle *particle, int count) { for (int i = 0; i < count; i++) { Particle *previousParticle = particle - 1; if (particle->Momentum == previousParticle->Momentum) { particle->Rotation = previousParticle->Rotation; continue; } float rads = Calculator.Atan2(particle->Momentum.Y, particle->Momentum.X); particle->Rotation = (rads + this.RotationOffset); if (particle->Rotation > Calculator.Pi) { particle->Rotation -= Calculator.TwoPi; } else if (particle->Rotation < -Calculator.Pi) { particle->Rotation += Calculator.TwoPi; } particle++; } }
/// <inheritdoc/> protected override unsafe void OnUpdate(float elapsedSeconds, Particle *particle, int count) { while (count-- > 0) { if (particle->Position.X < Container.Left) { particle->Position.X = Container.Left; particle->Velocity.X = -particle->Velocity.X * RestitutionCoefficient; } else if (particle->Position.X > Container.Right) { particle->Position.X = Container.Right; particle->Velocity.X = -particle->Velocity.X * RestitutionCoefficient; } if (particle->Position.Y < Container.Top) { particle->Position.Y = Container.Top; particle->Velocity.Y = -particle->Velocity.Y * RestitutionCoefficient; } else if (particle->Position.Y > Container.Bottom) { particle->Position.Y = Container.Bottom; particle->Velocity.Y = -particle->Velocity.Y * RestitutionCoefficient; } particle++; } }
/// <summary> /// Updates the given gameTime. /// </summary> /// <param name="gameTime"> The game time. </param> public void Update(GameTime gameTime) { if (_buffer.Count <= 0) { return; } _secondsSinceLastReclaim += gameTime.DeltaTimeS; if (_secondsSinceLastReclaim > _reclaimCycleTime) { ReclaimExpiredParticles(); _secondsSinceLastReclaim -= _reclaimCycleTime; } if (_buffer.Count > 0) { Particle *particle = _buffer.Pointer; int count = _buffer.Count; while (count-- > 0) { particle->LifeTime += gameTime.DeltaTimeS; particle->Age = particle->LifeTime / _lifespan; particle->Position += particle->Velocity * gameTime.DeltaTimeS; particle++; } _modifierExecutionStrategy.ExecuteModifiers( _modifiers, gameTime.DeltaTimeS, _buffer.Pointer, _buffer.Count); } }
public override unsafe void Update(float amount, Particle *particle) { particle->Color = new HslColor( (EndValue - StartValue) * amount + StartValue, particle->Color.S, particle->Color.L); }
/// <summary> /// Processes the particles. /// </summary> /// <param name="dt">Elapsed time in whole and fractional seconds.</param> /// <param name="particleArray">A pointer to an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float dt, Particle *particleArray, int count) { for (int i = 0; i < count; i++) { Particle *particle = (particleArray + i); Particle *previousParticle = (particle - 1); if (particle->Age == previousParticle->Age) { particle->Scale = previousParticle->Scale; continue; } if (particle->Age < this.MiddlePosition) { particle->Scale = particle->InitialScale * (this.InitialScale + ((this.MiddleScale - this.InitialScale) * (particle->Age / this.MiddlePosition))); } else { particle->Scale = particle->InitialScale * (this.MiddleScale + ((this.FinalScale - this.MiddleScale) * ((particle->Age - this.MiddlePosition) / (1f - this.MiddlePosition)))); } } }
/// <summary> /// Processes the particles. /// </summary> /// <param name="elapsedSeconds">Elapsed time in whole and fractional seconds.</param> /// <param name="particle">A pointer to the first item in an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float elapsedSeconds, Particle *particle, int count) { particle->Colour.X = (this.InitialColour.X + ((this.UltimateColour.X - this.InitialColour.X) * particle->Age)); particle->Colour.Y = (this.InitialColour.Y + ((this.UltimateColour.Y - this.InitialColour.Y) * particle->Age)); particle->Colour.Z = (this.InitialColour.Z + ((this.UltimateColour.Z - this.InitialColour.Z) * particle->Age)); Particle *previousParticle = particle; particle++; for (int i = 1; i < count; i++) { if (particle->Age < previousParticle->Age) { particle->Colour.X = (this.InitialColour.X + ((this.UltimateColour.X - this.InitialColour.X) * particle->Age)); particle->Colour.Y = (this.InitialColour.Y + ((this.UltimateColour.Y - this.InitialColour.Y) * particle->Age)); particle->Colour.Z = (this.InitialColour.Z + ((this.UltimateColour.Z - this.InitialColour.Z) * particle->Age)); } else { particle->Colour.X = previousParticle->Colour.X; particle->Colour.Y = previousParticle->Colour.Y; particle->Colour.Z = previousParticle->Colour.Z; } previousParticle++; particle++; } }
/// <summary> /// Causes all Modifiers in the collection to process the particles. /// </summary> internal unsafe void RunProcessors(float dt, Particle *particleArray, int count) { for (int i = 0; i < this.Count; i++) { this[i].Process(dt, particleArray, count); } }
/// <summary> /// Processes the particles. /// </summary> /// <param name="dt">Elapsed time in whole and fractional seconds.</param> /// <param name="particleArray">A pointer to an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float dt, Particle *particleArray, int count) { Vector2 distance; float strengthDelta = this.Strength * dt; float deltaForceX = this.Force.X * strengthDelta; float deltaForceY = this.Force.Y * strengthDelta; for (int i = 0; i < count; i++) { Particle *particle = (particleArray + i); // Calculate the distance between the Particle and the center of the force... distance.X = (float)(this.Position.X - particle->Position.X); distance.Y = (float)(this.Position.Y - particle->Position.Y); float squareDistance = ((distance.X * distance.X) + (distance.Y * distance.Y)); // Check to see if the Particle is within range of the force... if (squareDistance < this.SquareRadius) { // Adjust the force vector based on the strength of the force and the time delta... particle->Velocity.X += deltaForceX; particle->Velocity.Y += deltaForceY; } } }
/// <summary> /// Processes the particles. /// </summary> /// <param name="dt">Elapsed time in whole and fractional seconds.</param> /// <param name="particleArray">A pointer to an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float dt, Particle *particleArray, int count) { float left = this.Position.X; float right = this.Position.X + this.Width; float top = this.Position.Y; float bottom = this.Position.Y + this.Height; for (int i = 0; i < count; i++) { Particle *particle = (particleArray + i); float halfScale = particle->Scale * 0.5f; if (particle->Position.X < left) { particle->Position.X = left; float momentumDelta = this.RestitutionCoefficient.Sample(); //momentumDelta = momentumDelta > 1f ? 1f : momentumDelta; //momentumDelta = momentumDelta < 0f ? 0f : momentumDelta; particle->Momentum.X *= -momentumDelta; } else if (particle->Position.X > right) { particle->Position.X = right; float momentumDelta = this.RestitutionCoefficient.Sample(); //momentumDelta = momentumDelta > 1f ? 1f : momentumDelta; //momentumDelta = momentumDelta < 0f ? 0f : momentumDelta; particle->Momentum.X *= -momentumDelta; } if (particle->Position.Y < top) { particle->Position.Y = top; float momentumDelta = this.RestitutionCoefficient.Sample(); //momentumDelta = momentumDelta > 1f ? 1f : momentumDelta; //momentumDelta = momentumDelta < 0f ? 0f : momentumDelta; particle->Momentum.Y *= -momentumDelta; } else if (particle->Position.Y > bottom) { particle->Position.Y = bottom; float momentumDelta = this.RestitutionCoefficient.Sample(); //momentumDelta = momentumDelta > 1f ? 1f : momentumDelta; //momentumDelta = momentumDelta < 0f ? 0f : momentumDelta; particle->Momentum.Y *= -momentumDelta; } } }
/// <inheritdoc /> protected override unsafe void OnUpdate(float elapsedSeconds, Particle *particle, int count) { while (count-- > 0) { particle->Opacity = (_deltaOpacity * particle->Age) + _initialOpacity; particle++; } }
/// <inheritdoc /> protected override unsafe void OnUpdate(float elapsedSeconds, Particle *particle, int count) { while (count-- > 0) { particle->Opacity = 1.0f - particle->Age; particle++; } }
/// <inheritdoc /> protected override unsafe void OnUpdate(float elapsedSeconds, Particle *particle, int count) { while (count-- > 0) { particle->Scale = (_deltaScale * particle->Age) + _initialScale; particle++; } }
/// <summary> /// Processes the particles. /// </summary> /// <param name="dt">Elapsed time in whole and fractional seconds.</param> /// <param name="particleArray">A pointer to an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float dt, Particle *particleArray, int count) { for (int i = 0; i < count; i++) { Particle *particle = (particleArray + i); particle->Colour.W = 1f - particle->Age; } }
/// <summary> /// Processes the particles. /// </summary> /// <param name="dt">Elapsed time in whole and fractional seconds.</param> /// <param name="particleArray">A pointer to an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float dt, Particle *particleArray, int count) { for (int i = 0; i < count; i++) { Particle *particle = (particleArray + i); particle->Colour.W = (this.Initial + ((this.Ultimate - this.Initial) * particle->Age)); } }
/// <summary> /// Processes the particles. /// </summary> /// <param name="dt">Elapsed time in whole and fractional seconds.</param> /// <param name="particle">A pointer to an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float dt, Particle *particle, int count) { for (int i = 0; i < count; i++) { particle->Scale = particle->InitialScale * (this.InitialScale + ((this.UltimateScale - this.InitialScale) * particle->Age)); particle++; } }
/// <summary> /// Allocate particles. /// </summary> /// <param name="quantity"> The quantity. </param> /// <param name="first"> [in,out] Pointer to the first particle which can be used. </param> /// <returns> /// The count of particles to release. /// </returns> public int Allocate(int quantity, out Particle *first) { //_size - _tail = Available int numToRelease = Math.Min(quantity, _size - _tail); first = _pointer + _tail; _tail += numToRelease; return(numToRelease); }
/// <summary> /// Initializes a new instance of the <see cref="ParticleBuffer" /> class. /// </summary> /// <param name="size"> The size. </param> public ParticleBuffer(int size) { _size = size; _nativePointer = Marshal.AllocHGlobal(SizeInBytes); _pointer = (Particle *)_nativePointer; GC.AddMemoryPressure(SizeInBytes); }
/// <summary> /// Processes active particles. /// </summary> /// <param name="deltaSeconds">Elapsed time in whole and fractional seconds.</param> /// <param name="particle">A pointer to the first element in an array of particles.</param> /// <param name="count">The number of particles which need to be processed.</param> protected internal override unsafe void Process(float deltaSeconds, Particle *particle, int count) { for (int i = 0; i < count; i++) { // TODO modifier logic... particle++; } }
public unsafe void Reclaim(int number) { Count -= number; Head += number; if (Head >= BufferEnd) { Head -= Size + 1; } }
/// <summary> /// Executes the update action. /// </summary> /// <param name="elapsedSeconds"> The elapsed in seconds. </param> /// <param name="particle"> [in,out] If non-, the particle. </param> /// <param name="count"> Number of. </param> protected override unsafe void OnUpdate(float elapsedSeconds, Particle *particle, int count) { Vector2 v = Direction * (Strength * elapsedSeconds); while (count-- > 0) { particle->Velocity += v * particle->Mass; particle++; } }
/// <inheritdoc/> protected override unsafe void OnUpdate(float elapsedSeconds, Particle *particle, int count) { float drag = -DragCoefficient * Density * elapsedSeconds; while (count-- > 0) { particle->Velocity += particle->Velocity * drag * particle->Mass; particle++; } }
/// <inheritdoc /> protected override unsafe void OnUpdate(float elapsedSeconds, Particle *particle, int count) { float delta = RotationRate * elapsedSeconds; while (count-- > 0) { particle->Rotation += delta; particle++; } }
public override void OnUpdate(float deltaTime, Particle *arrayPtr, int length) { if (ParticleEngine.NativeEnabled) { return; } Particle *tail = arrayPtr + length; switch (transitionType) { case TransitionType.Constant: { for (Particle *particle = arrayPtr; particle < tail; particle++) { particle->SpriteRotation += start * deltaTime; } } break; case TransitionType.Lerp: { for (Particle *particle = arrayPtr; particle < tail; particle++) { float angleDelta = ParticleMath.Lerp( start, end, particle->TimeAlive / particle->InitialLife); particle->SpriteRotation += angleDelta * deltaTime; } } break; case TransitionType.Curve: { for (Particle *particle = arrayPtr; particle < tail; particle++) { particle->SpriteRotation += curve.Evaluate(particle->TimeAlive / particle->InitialLife) * deltaTime; } } break; case TransitionType.RandomConstant: { for (Particle *particle = arrayPtr; particle < tail; particle++) { particle->SpriteRotation += Between(start, end, rand[particle->ID]) * deltaTime; } } break; case TransitionType.RandomCurve: { for (Particle *particle = arrayPtr; particle < tail; particle++) { particle->SpriteRotation += curve.Evaluate(rand[particle->ID]) * deltaTime; } } break; default: throw new ArgumentOutOfRangeException(); } }
/// <summary> /// Release the given number of particles or the most available. /// Returns a started iterator to iterate over the new particles. /// </summary> public unsafe ParticleIterator Release(int releaseQuantity) { var numToRelease = Math.Min(releaseQuantity, Available); var prevCount = Count; Count += numToRelease; Tail += numToRelease; if (Tail >= BufferEnd) Tail -= Size + 1; return Iterator.Reset(prevCount); }
internal unsafe ParticleIterator Reset(int offset) { Total = _buffer.Count; _current = _buffer.Head + offset; if (_current >= _buffer.BufferEnd) _current -= _buffer.Size + 1; return this; }
public unsafe ParticleIterator Reset() { _current = _buffer.Head; Total = _buffer.Count; return this; }
public unsafe Particle* Next() { var p = _current; _current++; if (_current == _buffer.BufferEnd) _current = (Particle*)_buffer._nativePointer; return p; }