public void UpdatePhysics(ParticleJobSchedule schedule)
        {
            var particle = schedule.Particle;
            var velocity = new Vector2();

            foreach (var otherParticle in schedule.SpaceSnapshot.AllParticles)
            {
                if (particle.Id == otherParticle.Id)
                {
                    continue;
                }

                var a = particle.Position;
                var b = otherParticle.Position;

                var sqrDistance = (a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y);
                //var sqrDistance = particle.Position.DistanceSquared(otherParticle.Position);
                if (sqrDistance > MAXIMUM_DISTANCE)
                {
                    continue;
                }

                var delta               = (particle.Position - otherParticle.Position).Normalize();
                var particleData        = particle.GetParticleData <ParticleLifeParticleData>().ParticleType;
                var interactionConstant = particleData.ParticleInteractions[particleData.Id]
                                          .GetInteraction(sqrDistance);

                if (delta == Vector2.Zero || delta.IsNaN())
                {
                    if (particle.Id > otherParticle.Id)
                    {
                        delta = RNG.RandomBool() ? new Vector2(-1, 0) : RNG.RandomBool() ? new Vector2(-1, -1) : new Vector2(-1, 1);
                    }
                    else
                    {
                        delta = RNG.RandomBool() ? new Vector2(1, 0) : RNG.RandomBool() ? new Vector2(1, 1) : new Vector2(1, -1);
                    }
                }

                delta     = delta * interactionConstant;
                velocity += delta;
            }

            particle.Velocity = velocity.Average(particle.Velocity);

            particle.Velocity           = particle.Velocity.Lerp(Vector2.Zero, 0.05f); // Friction
            particle.ScheduledPosition += particle.Velocity * LogicTimer.DeltaTime * 50;
        }
        public ParticleJobSchedule ScheduleParticleJob(Particle particle, Space space)
        {
            if (!didRunCache)
            {
                physicsUpdater.CacheParticleData(space.CurrentSpaceSnapshot);
                didRunCache = true;
            }

            var schedule = new ParticleJobSchedule()
            {
                Particle      = particle,
                SpaceSnapshot = space.CurrentSpaceSnapshot
            };

            return(schedule);
        }
        public void UpdatePhysics(ParticleJobSchedule schedule)
        {
            var particle = schedule.Particle;
            var velocity = new Vector2();

            var particleData = particleDataCache[particle.Id];

            foreach (var otherParticle in schedule.SpaceSnapshot.AllParticles)
            {
                if (particle.Id == otherParticle.Id)
                {
                    continue;
                }

                var otherParticleData = particleDataCache[otherParticle.Id];

                var a = particle.Position;
                var b = otherParticle.Position;

                var sqrDistance = (a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y);


                var mass1   = particleData.Mass; // particle.GetParticleData<GravityParticleData>().Mass;
                var radius1 = particleData.Radius;

                var mass2   = otherParticleData.Mass; //otherParticle.GetParticleData<GravityParticleData>().Mass;
                var radius2 = otherParticleData.Radius;

                var force        = G * mass1 * mass2 / sqrDistance; // Calculate Force by Newton's formula
                var acceleration = force / mass1;

                if (float.IsNaN(force))
                {
                    continue;
                }

                if (IsColliding(sqrDistance, radius1, radius2))
                {
                    var overlap = radius1 + radius2 - sqrDistance.Sqrt();

                    if (overlap.IsNaN())
                    {
                        overlap = 0;
                    }

                    if (particleData.Mass <= otherParticleData.Mass)
                    {
                        particle.ScheduledPosition += (a - b).Normalize() * overlap; // Go back a little if we are interlapping
                    }
                    // Elastic collision formula
                    var newVelocity = (((mass1 - mass2) / (mass1 + mass2)) * particle.ScheduledVelocity + ((2 * mass2) / (mass1 + mass2)) * otherParticle.Velocity);

                    particle.ScheduledVelocity = newVelocity;
                }
                else
                {
                    velocity -= (a - b).Normalize() * acceleration;
                }
            }

            particle.ScheduledVelocity += velocity;
            particle.ScheduledPosition += particle.ScheduledVelocity * LogicTimer.DeltaTime;
        }
 /// <summary>
 /// Update particle with given ParticleJobSchedule
 /// </summary>
 public void UpdateParticle(ParticleJobSchedule schedule)
 {
     physicsUpdater.UpdatePhysics(schedule);
 }