using System; using System.Collections.Generic; using FarseerPhysics.Collision.Shapes; using FarseerPhysics.Common; using FarseerPhysics.Common.Decomposition; using FarseerPhysics.Dynamics; using Microsoft.Xna.Framework; namespace FarseerPhysics.Factories { /// /// An easy to use factory for creating bodies /// public static class FixtureFactory { public static Fixture AttachEdge(Vector2 start, Vector2 end, Body body) { return AttachEdge(start, end, body, null); } public static Fixture AttachEdge(Vector2 start, Vector2 end, Body body, object userData) { EdgeShape edgeShape = new EdgeShape(start, end); return body.CreateFixture(edgeShape, userData); } public static Fixture AttachLoopShape(Vertices vertices, Body body) { return AttachLoopShape(vertices, body, null); } public static Fixture AttachLoopShape(Vertices vertices, Body body, object userData) { LoopShape shape = new LoopShape(vertices); return body.CreateFixture(shape, userData); } public static Fixture AttachRectangle(float width, float height, float density, Vector2 offset, Body body, object userData) { Vertices rectangleVertices = PolygonTools.CreateRectangle(width / 2, height / 2); rectangleVertices.Translate(ref offset); PolygonShape rectangleShape = new PolygonShape(rectangleVertices, density); return body.CreateFixture(rectangleShape, userData); } public static Fixture AttachRectangle(float width, float height, float density, Vector2 offset, Body body) { return AttachRectangle(width, height, density, offset, body, null); } public static Fixture AttachCircle(float radius, float density, Body body) { return AttachCircle(radius, density, body, null); } public static Fixture AttachCircle(float radius, float density, Body body, object userData) { if (radius <= 0) throw new ArgumentOutOfRangeException("radius", "Radius must be more than 0 meters"); CircleShape circleShape = new CircleShape(radius, density); return body.CreateFixture(circleShape, userData); } public static Fixture AttachCircle(float radius, float density, Body body, Vector2 offset) { return AttachCircle(radius, density, body, offset, null); } public static Fixture AttachCircle(float radius, float density, Body body, Vector2 offset, object userData) { if (radius <= 0) throw new ArgumentOutOfRangeException("radius", "Radius must be more than 0 meters"); CircleShape circleShape = new CircleShape(radius, density); circleShape.Position = offset; return body.CreateFixture(circleShape, userData); } public static Fixture AttachPolygon(Vertices vertices, float density, Body body) { return AttachPolygon(vertices, density, body, null); } public static Fixture AttachPolygon(Vertices vertices, float density, Body body, object userData) { if (vertices.Count <= 1) throw new ArgumentOutOfRangeException("vertices", "Too few points to be a polygon"); PolygonShape polygon = new PolygonShape(vertices, density); return body.CreateFixture(polygon, userData); } public static Fixture AttachEllipse(float xRadius, float yRadius, int edges, float density, Body body) { return AttachEllipse(xRadius, yRadius, edges, density, body, null); } public static Fixture AttachEllipse(float xRadius, float yRadius, int edges, float density, Body body, object userData) { if (xRadius <= 0) throw new ArgumentOutOfRangeException("xRadius", "X-radius must be more than 0"); if (yRadius <= 0) throw new ArgumentOutOfRangeException("yRadius", "Y-radius must be more than 0"); Vertices ellipseVertices = PolygonTools.CreateEllipse(xRadius, yRadius, edges); PolygonShape polygonShape = new PolygonShape(ellipseVertices, density); return body.CreateFixture(polygonShape, userData); } public static List AttachCompoundPolygon(List list, float density, Body body) { return AttachCompoundPolygon(list, density, body, null); } public static List AttachCompoundPolygon(List list, float density, Body body, object userData) { List res = new List(list.Count); //Then we create several fixtures using the body foreach (Vertices vertices in list) { if (vertices.Count == 2) { EdgeShape shape = new EdgeShape(vertices[0], vertices[1]); res.Add(body.CreateFixture(shape, userData)); } else { PolygonShape shape = new PolygonShape(vertices, density); res.Add(body.CreateFixture(shape, userData)); } } return res; } public static List AttachLineArc(float radians, int sides, float radius, Vector2 position, float angle, bool closed, Body body) { Vertices arc = PolygonTools.CreateArc(radians, sides, radius); arc.Rotate((MathHelper.Pi - radians) / 2 + angle); arc.Translate(ref position); List fixtures = new List(arc.Count); if (closed) { fixtures.Add(AttachLoopShape(arc, body)); } for (int i = 1; i < arc.Count; i++) { fixtures.Add(AttachEdge(arc[i], arc[i - 1], body)); } return fixtures; } public static List AttachSolidArc(float density, float radians, int sides, float radius, Vector2 position, float angle, Body body) { Vertices arc = PolygonTools.CreateArc(radians, sides, radius); arc.Rotate((MathHelper.Pi - radians) / 2 + angle); arc.Translate(ref position); //Close the arc arc.Add(arc[0]); List triangles = EarclipDecomposer.ConvexPartition(arc); return AttachCompoundPolygon(triangles, density, body); } } }