/// <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; }
/// <summary> /// Finds a new target for AI component /// </summary> /// <param name="ai"></param> /// <param name="location"></param> /// <returns></returns> private Body _FindNewTarget(AI ai, Body location) { //find all fixtures in world around the location. AABB aabb = new AABB(location.Position, ai.SearchRadius, ai.SearchRadius); #if WINDOWS HashSet<PhysicsBody> bodies = new HashSet<PhysicsBody>(); #else List<PhysicsBody> bodies = new List<PhysicsBody>(); #endif world.QueryAABB(x => { if (x.Body.BodyId != location.BodyId) { if ((string.IsNullOrEmpty(ai.TargetGroup) || ai.TargetGroup.Equals((x.Body.UserData as Entity).Group)) && !(world.GetEntity((x.Body.UserData as Entity).Id) == null || ( world.GetEntity((x.Body.UserData as Entity).Id) != null && world.GetEntity((x.Body.UserData as Entity).Id).GetComponent<Body>() != null && !world.GetEntity((x.Body.UserData as Entity).Id).GetComponent<Body>().Equals(x.Body)))) { bodies.Add(x.Body); } } return true; }, ref aabb); if (bodies.Count > 0) //IF BODIES IN SEARCH RADIUS. { PhysicsBody[] list = new PhysicsBody[bodies.Count]; bodies.CopyTo(list); Entity ent = (location.UserData as Entity); //SORT BY TARGETING TYPE. switch (ai.Targeting) { case Targeting.Closest: return ClosestEntity(location.Position, list).GetComponent<Body>(); case Targeting.Strongest: return StrongestEntity(list).GetComponent<Body>(); case Targeting.Weakest: return WeakestEntity(list).GetComponent<Body>(); case Targeting.None: return null; default: return null; } } else return null; }
/// <summary> /// Query the world for all fixtures that potentially overlap the /// provided AABB. /// /// Inside the callback: /// Return true: Continues the query /// Return false: Terminate the query /// </summary> /// <param name="callback">A user implemented callback class.</param> /// <param name="aabb">The aabb query box.</param> public void QueryAABB(Func<Fixture, bool> callback, ref AABB aabb) { ContactManager.BroadPhase.Query(proxyId => { FixtureProxy proxy = ContactManager.BroadPhase.GetProxy(proxyId); return callback(proxy.Fixture); }, ref aabb); }
public PhysicsWorld(Vector2 gravity, AABB span) : this() { Gravity = gravity; ContactManager = new ContactManager(new QuadTreeBroadPhase(span)); }
/// <summary> /// Get all intersections between a line segment and an AABB. /// </summary> /// <param name="point1">The first point of the line segment to test</param> /// <param name="point2">The second point of the line segment to test.</param> /// <param name="aabb">The AABB that is used for testing intersection.</param> /// <param name="intersectionPoints">An list of intersection points. Any intersection points found will be added to this list.</param> public static void LineSegmentAABBIntersect(ref Vector2 point1, ref Vector2 point2, AABB aabb, ref List<Vector2> intersectionPoints) { LineSegmentVerticesIntersect(ref point1, ref point2, aabb.Vertices, ref intersectionPoints); }
/// <summary> /// Regenerate the terrain. /// </summary> public void RegenerateTerrain() { //iterate effected cells var gx0 = (int)(_dirtyArea.LowerBound.X / CellSize); var gx1 = (int)(_dirtyArea.UpperBound.X / CellSize) + 1; if (gx0 < 0) gx0 = 0; if (gx1 > _xnum) gx1 = _xnum; var gy0 = (int)(_dirtyArea.LowerBound.Y / CellSize); var gy1 = (int)(_dirtyArea.UpperBound.Y / CellSize) + 1; if (gy0 < 0) gy0 = 0; if (gy1 > _ynum) gy1 = _ynum; for (int gx = gx0; gx < gx1; gx++) { for (int gy = gy0; gy < gy1; gy++) { //remove old terrain object at grid cell if (_bodyMap[gx, gy] != null) { for (int i = 0; i < _bodyMap[gx, gy].Count; i++) { World.RemoveBody(_bodyMap[gx, gy][i]); } } _bodyMap[gx, gy] = null; //generate new one GenerateTerrain(gx, gy); } } _dirtyArea = new AABB(new Vector2(float.MaxValue, float.MaxValue), new Vector2(float.MinValue, float.MinValue)); }
/// <summary> /// Get the fixture's AABB. This AABB may be enlarge and/or stale. /// If you need a more accurate AABB, compute it using the Shape and /// the body transform. /// </summary> /// <param name="aabb">The aabb.</param> /// <param name="childIndex">Index of the child.</param> public void GetAABB(out AABB aabb, int childIndex) { Debug.Assert(0 <= childIndex && childIndex < ProxyCount); aabb = Proxies[childIndex].AABB; }
public MSTerrain(PhysicsWorld world, AABB area) { World = world; Width = area.Extents.X * 2; Height = area.Extents.Y * 2; Center = area.Center; }
/// <summary> /// Initialize the terrain for use. /// </summary> public void Initialize() { // find top left of terrain in world space _topLeft = new Vector2(Center.X - (Width * 0.5f), Center.Y - (-Height * 0.5f)); // convert the terrains size to a point cloud size _localWidth = Width * PointsPerUnit; _localHeight = Height * PointsPerUnit; _terrainMap = new sbyte[(int)_localWidth + 1, (int)_localHeight + 1]; for (int x = 0; x < _localWidth; x++) { for (int y = 0; y < _localHeight; y++) { _terrainMap[x, y] = 1; } } _xnum = (int)(_localWidth / CellSize); _ynum = (int)(_localHeight / CellSize); _bodyMap = new List<PhysicsBody>[_xnum, _ynum]; // make sure to mark the dirty area to an infinitely small box _dirtyArea = new AABB(new Vector2(float.MaxValue, float.MaxValue), new Vector2(float.MinValue, float.MinValue)); }
/// <summary> /// Does this aabb contain the provided AABB. /// </summary> /// <param name="aabb">The aabb.</param> /// <returns> /// <c>true</c> if it contains the specified aabb; otherwise, <c>false</c>. /// </returns> public bool Contains(ref AABB aabb) { bool result = true; result = result && LowerBound.X <= aabb.LowerBound.X; result = result && LowerBound.Y <= aabb.LowerBound.Y; result = result && aabb.UpperBound.X <= UpperBound.X; result = result && aabb.UpperBound.Y <= UpperBound.Y; return result; }
/// <summary> /// Combine two AABBs into this one. /// </summary> /// <param name="aabb1">The aabb1.</param> /// <param name="aabb2">The aabb2.</param> public void Combine(ref AABB aabb1, ref AABB aabb2) { LowerBound = Vector2.Min(aabb1.LowerBound, aabb2.LowerBound); UpperBound = Vector2.Max(aabb1.UpperBound, aabb2.UpperBound); }
/// <summary> /// Combine an AABB into this one. /// </summary> /// <param name="aabb">The aabb.</param> public void Combine(ref AABB aabb) { LowerBound = Vector2.Min(LowerBound, aabb.LowerBound); UpperBound = Vector2.Max(UpperBound, aabb.UpperBound); }
public static bool TestOverlap(ref AABB a, ref AABB b) { Vector2 d1 = b.LowerBound - a.UpperBound; Vector2 d2 = a.LowerBound - b.UpperBound; if (d1.X > 0.0f || d1.Y > 0.0f) return false; if (d2.X > 0.0f || d2.Y > 0.0f) return false; return true; }
public static bool TestOverlap(AABB a, AABB b) { return TestOverlap(ref a, ref b); }