123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- using System;
- using System.Collections.Generic;
- using FarseerPhysics.Dynamics;
- namespace FarseerPhysics.Controllers
- {
- /// <summary>
- /// Put a limit on the linear (translation - the movespeed) and angular (rotation) velocity
- /// of bodies added to this controller.
- /// </summary>
- public class VelocityLimitController : Controller
- {
- public bool LimitAngularVelocity = true;
- public bool LimitLinearVelocity = true;
- private List<Body> _bodies = new List<Body>();
- private float _maxAngularSqared;
- private float _maxAngularVelocity;
- private float _maxLinearSqared;
- private float _maxLinearVelocity;
- /// <summary>
- /// Initializes a new instance of the <see cref="VelocityLimitController"/> class.
- /// Sets the max linear velocity to Settings.MaxTranslation
- /// Sets the max angular velocity to Settings.MaxRotation
- /// </summary>
- public VelocityLimitController()
- : base(ControllerType.VelocityLimitController)
- {
- MaxLinearVelocity = Settings.MaxTranslation;
- MaxAngularVelocity = Settings.MaxRotation;
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="VelocityLimitController"/> class.
- /// Pass in 0 or float.MaxValue to disable the limit.
- /// maxAngularVelocity = 0 will disable the angular velocity limit.
- /// </summary>
- /// <param name="maxLinearVelocity">The max linear velocity.</param>
- /// <param name="maxAngularVelocity">The max angular velocity.</param>
- public VelocityLimitController(float maxLinearVelocity, float maxAngularVelocity)
- : base(ControllerType.VelocityLimitController)
- {
- if (maxLinearVelocity == 0 || maxLinearVelocity == float.MaxValue)
- LimitLinearVelocity = false;
- if (maxAngularVelocity == 0 || maxAngularVelocity == float.MaxValue)
- LimitAngularVelocity = false;
- MaxLinearVelocity = maxLinearVelocity;
- MaxAngularVelocity = maxAngularVelocity;
- }
- /// <summary>
- /// Gets or sets the max angular velocity.
- /// </summary>
- /// <value>The max angular velocity.</value>
- public float MaxAngularVelocity
- {
- get { return _maxAngularVelocity; }
- set
- {
- _maxAngularVelocity = value;
- _maxAngularSqared = _maxAngularVelocity * _maxAngularVelocity;
- }
- }
- /// <summary>
- /// Gets or sets the max linear velocity.
- /// </summary>
- /// <value>The max linear velocity.</value>
- public float MaxLinearVelocity
- {
- get { return _maxLinearVelocity; }
- set
- {
- _maxLinearVelocity = value;
- _maxLinearSqared = _maxLinearVelocity * _maxLinearVelocity;
- }
- }
- public override void Update(float dt)
- {
- foreach (Body body in _bodies)
- {
- if (!IsActiveOn(body))
- continue;
- if (LimitLinearVelocity)
- {
- //Translation
- // Check for large velocities.
- float translationX = dt * body.LinearVelocityInternal.X;
- float translationY = dt * body.LinearVelocityInternal.Y;
- float result = translationX * translationX + translationY * translationY;
- if (result > dt * _maxLinearSqared)
- {
- float sq = (float)Math.Sqrt(result);
- float ratio = _maxLinearVelocity / sq;
- body.LinearVelocityInternal.X *= ratio;
- body.LinearVelocityInternal.Y *= ratio;
- }
- }
- if (LimitAngularVelocity)
- {
- //Rotation
- float rotation = dt * body.AngularVelocityInternal;
- if (rotation * rotation > _maxAngularSqared)
- {
- float ratio = _maxAngularVelocity / Math.Abs(rotation);
- body.AngularVelocityInternal *= ratio;
- }
- }
- }
- }
- public void AddBody(Body body)
- {
- _bodies.Add(body);
- }
- public void RemoveBody(Body body)
- {
- _bodies.Remove(body);
- }
- }
- }
|