123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- using System;
- using System.Collections.Generic;
- using FarseerPhysics.Dynamics;
- using Microsoft.Xna.Framework;
- namespace FarseerPhysics.Controllers
- {
- public enum GravityType
- {
- Linear,
- DistanceSquared
- }
- public class GravityController : Controller
- {
- public List<Body> Bodies = new List<Body>();
- public List<Vector2> Points = new List<Vector2>();
- public GravityController(float strength)
- : base(ControllerType.GravityController)
- {
- Strength = strength;
- MaxRadius = float.MaxValue;
- }
- public GravityController(float strength, float maxRadius, float minRadius)
- : base(ControllerType.GravityController)
- {
- MinRadius = minRadius;
- MaxRadius = maxRadius;
- Strength = strength;
- }
- public float MinRadius { get; set; }
- public float MaxRadius { get; set; }
- public float Strength { get; set; }
- public GravityType GravityType { get; set; }
- public override void Update(float dt)
- {
- Vector2 f = Vector2.Zero;
- foreach (Body body1 in World.BodyList)
- {
- if (!IsActiveOn(body1))
- continue;
- foreach (Body body2 in Bodies)
- {
- if (body1 == body2 || (body1.IsStatic && body2.IsStatic) || !body2.Enabled)
- continue;
- Vector2 d = body2.WorldCenter - body1.WorldCenter;
- float r2 = d.LengthSquared();
- if (r2 < Settings.Epsilon)
- continue;
- float r = d.Length();
- if (r >= MaxRadius || r <= MinRadius)
- continue;
- switch (GravityType)
- {
- case GravityType.DistanceSquared:
- f = Strength / r2 / (float)Math.Sqrt(r2) * body1.Mass * body2.Mass * d;
- break;
- case GravityType.Linear:
- f = Strength / r2 * body1.Mass * body2.Mass * d;
- break;
- }
- body1.ApplyForce(ref f);
- Vector2.Negate(ref f, out f);
- body2.ApplyForce(ref f);
- }
- foreach (Vector2 point in Points)
- {
- Vector2 d = point - body1.Position;
- float r2 = d.LengthSquared();
- if (r2 < Settings.Epsilon)
- continue;
- float r = d.Length();
- if (r >= MaxRadius || r <= MinRadius)
- continue;
- switch (GravityType)
- {
- case GravityType.DistanceSquared:
- f = Strength / r2 / (float)Math.Sqrt(r2) * body1.Mass * d;
- break;
- case GravityType.Linear:
- f = Strength / r2 * body1.Mass * d;
- break;
- }
- body1.ApplyForce(ref f);
- }
- }
- }
- public void AddBody(Body body)
- {
- Bodies.Add(body);
- }
- public void AddPoint(Vector2 point)
- {
- Points.Add(point);
- }
- }
- }
|