Root/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | using System.Collections.Generic; using FarseerPhysics.Collision; using FarseerPhysics.Collision.Shapes; using FarseerPhysics.Dynamics; using Microsoft.Xna.Framework; namespace FarseerPhysics.Controllers { public sealed class BuoyancyController : Controller { /// <summary> /// Controls the rotational drag that the fluid exerts on the bodies within it. Use higher values will simulate thick fluid, like honey, lower values to /// simulate water-like fluids. /// </summary> public float AngularDragCoefficient; /// <summary> /// Density of the fluid. Higher values will make things more buoyant, lower values will cause things to sink. /// </summary> public float Density; /// <summary> /// Controls the linear drag that the fluid exerts on the bodies within it. Use higher values will simulate thick fluid, like honey, lower values to /// simulate water-like fluids. /// </summary> public float LinearDragCoefficient; /// <summary> /// Acts like waterflow. Defaults to 0,0. /// </summary> public Vector2 Velocity; private AABB _container; private Vector2 _gravity; private Vector2 _normal; private float _offset; private Dictionary< int , Body> _uniqueBodies = new Dictionary< int , Body>(); /// <summary> /// Initializes a new instance of the <see cref="BuoyancyController"/> class. /// </summary> /// <param name="container">Only bodies inside this AABB will be influenced by the controller</param> /// <param name="density">Density of the fluid</param> /// <param name="linearDragCoefficient">Linear drag coefficient of the fluid</param> /// <param name="rotationalDragCoefficient">Rotational drag coefficient of the fluid</param> /// <param name="gravity">The direction gravity acts. Buoyancy force will act in opposite direction of gravity.</param> public BuoyancyController(AABB container, float density, float linearDragCoefficient, float rotationalDragCoefficient, Vector2 gravity) : base (ControllerType.BuoyancyController) { Container = container; _normal = new Vector2(0, 1); Density = density; LinearDragCoefficient = linearDragCoefficient; AngularDragCoefficient = rotationalDragCoefficient; _gravity = gravity; } public AABB Container { get { return _container; } set { _container = value; _offset = _container.UpperBound.Y; } } public override void Update( float dt) { _uniqueBodies.Clear(); World.QueryAABB(fixture => { if (fixture.Body.IsStatic || !fixture.Body.Awake) return true ; if (!_uniqueBodies.ContainsKey(fixture.Body.BodyId)) _uniqueBodies.Add(fixture.Body.BodyId, fixture.Body); return true ; }, ref _container); foreach (KeyValuePair< int , Body> kv in _uniqueBodies) { Body body = kv.Value; Vector2 areac = Vector2.Zero; Vector2 massc = Vector2.Zero; float area = 0; float mass = 0; for ( int j = 0; j < body.FixtureList.Count; j++) { Fixture fixture = body.FixtureList[j]; if (fixture.Shape.ShapeType != ShapeType.Polygon && fixture.Shape.ShapeType != ShapeType.Circle) continue ; Shape shape = fixture.Shape; Vector2 sc; float sarea = shape.ComputeSubmergedArea(_normal, _offset, body.Xf, out sc); area += sarea; areac.X += sarea * sc.X; areac.Y += sarea * sc.Y; mass += sarea * shape.Density; massc.X += sarea * sc.X * shape.Density; massc.Y += sarea * sc.Y * shape.Density; } areac.X /= area; areac.Y /= area; massc.X /= mass; massc.Y /= mass; if (area < Settings.Epsilon) continue ; //Buoyancy Vector2 buoyancyForce = -Density * area * _gravity; body.ApplyForce(buoyancyForce, massc); //Linear drag Vector2 dragForce = body.GetLinearVelocityFromWorldPoint(areac) - Velocity; dragForce *= -LinearDragCoefficient * area; body.ApplyForce(dragForce, areac); //Angular drag body.ApplyTorque(-body.Inertia / body.Mass * area * body.AngularVelocity * AngularDragCoefficient); } } } } |
Source at commit 187feef47cf4 created 12 years 7 months ago. By Nathan Adams, Added tag Version 1.0.1.5 for changeset cbfc9f26b2d0 |
---|