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); }