summaryrefslogtreecommitdiff
path: root/Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers
diff options
context:
space:
mode:
Diffstat (limited to 'Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers')
-rw-r--r--Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/CircleContainerModifier.cs52
-rw-r--r--Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/RectangleContainerModifier.cs59
-rw-r--r--Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/RectangleLoopContainerModifier.cs42
3 files changed, 153 insertions, 0 deletions
diff --git a/Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/CircleContainerModifier.cs b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/CircleContainerModifier.cs
new file mode 100644
index 0000000..30d2802
--- /dev/null
+++ b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/CircleContainerModifier.cs
@@ -0,0 +1,52 @@
+using System;
+using Microsoft.Xna.Framework;
+
+namespace MonoGame.Extended.Particles.Modifiers.Containers
+{
+ public class CircleContainerModifier : Modifier
+ {
+ public float Radius { get; set; }
+ public bool Inside { get; set; } = true;
+ public float RestitutionCoefficient { get; set; } = 1;
+
+ public override unsafe void Update(float elapsedSeconds, ParticleBuffer.ParticleIterator iterator)
+ {
+ var radiusSq = Radius*Radius;
+ while (iterator.HasNext)
+ {
+ var particle = iterator.Next();
+ var localPos = particle->Position - particle->TriggerPos;
+
+ var distSq = localPos.LengthSquared();
+ var normal = localPos;
+ normal.Normalize();
+
+ if (Inside)
+ {
+ if (distSq < radiusSq) continue;
+
+ SetReflected(distSq, particle, normal);
+ }
+ else
+ {
+ if (distSq > radiusSq) continue;
+
+ SetReflected(distSq, particle, -normal);
+ }
+ }
+ }
+
+ private unsafe void SetReflected(float distSq, Particle* particle, Vector2 normal)
+ {
+ var dist = (float) Math.Sqrt(distSq);
+ var d = dist - Radius; // how far outside the circle is the particle
+
+ var twoRestDot = 2*RestitutionCoefficient*
+ Vector2.Dot(particle->Velocity, normal);
+ particle->Velocity -= twoRestDot*normal;
+
+ // exact computation requires sqrt or goniometrics
+ particle->Position -= normal*d;
+ }
+ }
+} \ No newline at end of file
diff --git a/Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/RectangleContainerModifier.cs b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/RectangleContainerModifier.cs
new file mode 100644
index 0000000..a56e072
--- /dev/null
+++ b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/RectangleContainerModifier.cs
@@ -0,0 +1,59 @@
+using Microsoft.Xna.Framework;
+
+namespace MonoGame.Extended.Particles.Modifiers.Containers
+{
+ public sealed class RectangleContainerModifier : Modifier
+ {
+ public int Width { get; set; }
+ public int Height { get; set; }
+ public float RestitutionCoefficient { get; set; } = 1;
+
+ public override unsafe void Update(float elapsedSeconds, ParticleBuffer.ParticleIterator iterator)
+ {
+ while (iterator.HasNext)
+ {
+ var particle = iterator.Next();
+
+ var left = particle->TriggerPos.X + Width*-0.5f;
+ var right = particle->TriggerPos.X + Width*0.5f;
+ var top = particle->TriggerPos.Y + Height*-0.5f;
+ var bottom = particle->TriggerPos.Y + Height*0.5f;
+
+ var xPos = particle->Position.X;
+ var xVel = particle->Velocity.X;
+ var yPos = particle->Position.Y;
+ var yVel = particle->Velocity.Y;
+
+ if ((int) particle->Position.X < left)
+ {
+ xPos = left + (left - xPos);
+ xVel = -xVel*RestitutionCoefficient;
+ }
+ else
+ {
+ if (particle->Position.X > right)
+ {
+ xPos = right - (xPos - right);
+ xVel = -xVel*RestitutionCoefficient;
+ }
+ }
+
+ if (particle->Position.Y < top)
+ {
+ yPos = top + (top - yPos);
+ yVel = -yVel*RestitutionCoefficient;
+ }
+ else
+ {
+ if ((int) particle->Position.Y > bottom)
+ {
+ yPos = bottom - (yPos - bottom);
+ yVel = -yVel*RestitutionCoefficient;
+ }
+ }
+ particle->Position = new Vector2(xPos, yPos);
+ particle->Velocity = new Vector2(xVel, yVel);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/RectangleLoopContainerModifier.cs b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/RectangleLoopContainerModifier.cs
new file mode 100644
index 0000000..4da6efa
--- /dev/null
+++ b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Particles/Modifiers/Containers/RectangleLoopContainerModifier.cs
@@ -0,0 +1,42 @@
+using Microsoft.Xna.Framework;
+
+namespace MonoGame.Extended.Particles.Modifiers.Containers
+{
+ public class RectangleLoopContainerModifier : Modifier
+ {
+ public int Width { get; set; }
+ public int Height { get; set; }
+
+ public override unsafe void Update(float elapsedSeconds, ParticleBuffer.ParticleIterator iterator)
+ {
+ while (iterator.HasNext)
+ {
+ var particle = iterator.Next();
+ var left = particle->TriggerPos.X + Width*-0.5f;
+ var right = particle->TriggerPos.X + Width*0.5f;
+ var top = particle->TriggerPos.Y + Height*-0.5f;
+ var bottom = particle->TriggerPos.Y + Height*0.5f;
+
+ var xPos = particle->Position.X;
+ var yPos = particle->Position.Y;
+
+ if ((int) particle->Position.X < left)
+ xPos = particle->Position.X + Width;
+ else
+ {
+ if ((int) particle->Position.X > right)
+ xPos = particle->Position.X - Width;
+ }
+
+ if ((int) particle->Position.Y < top)
+ yPos = particle->Position.Y + Height;
+ else
+ {
+ if ((int) particle->Position.Y > bottom)
+ yPos = particle->Position.Y - Height;
+ }
+ particle->Position = new Vector2(xPos, yPos);
+ }
+ }
+ }
+} \ No newline at end of file