/// <summary> /// Creates a chain. /// </summary> /// <param name="world">The world.</param> /// <param name="start">The start.</param> /// <param name="end">The end.</param> /// <param name="linkWidth">The width.</param> /// <param name="linkHeight">The height.</param> /// <param name="fixStart">if set to <c>true</c> [fix start].</param> /// <param name="fixEnd">if set to <c>true</c> [fix end].</param> /// <param name="numberOfLinks">The number of links.</param> /// <param name="linkDensity">The link density.</param> /// <returns></returns> public static Path CreateChain(PhysicsWorld world, Vector2 start, Vector2 end, float linkWidth, float linkHeight, bool fixStart, bool fixEnd, int numberOfLinks, float linkDensity) { //Chain start / end Path path = new Path(); path.Add(start); path.Add(end); //A single chainlink PolygonShape shape = new PolygonShape(PolygonTools.CreateRectangle(linkWidth, linkHeight), linkDensity); //Use PathManager to create all the chainlinks based on the chainlink created before. List<PhysicsBody> chainLinks = PathManager.EvenlyDistributeShapesAlongPath(world, path, shape, BodyType.Dynamic, numberOfLinks); if (fixStart) { //Fix the first chainlink to the world JointFactory.CreateFixedRevoluteJoint(world, chainLinks[0], new Vector2(0, -(linkHeight / 2)), chainLinks[0].Position); } if (fixEnd) { //Fix the last chainlink to the world JointFactory.CreateFixedRevoluteJoint(world, chainLinks[chainLinks.Count - 1], new Vector2(0, (linkHeight / 2)), chainLinks[chainLinks.Count - 1].Position); } //Attach all the chainlinks together with a revolute joint PathManager.AttachBodiesWithRevoluteJoint(world, chainLinks, new Vector2(0, -linkHeight), new Vector2(0, linkHeight), false, false); return (path); }
//TODO: Comment better /// <summary> /// Moves the body on the path. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="time">The time.</param> /// <param name="strength">The strength.</param> /// <param name="timeStep">The time step.</param> public static void MoveBodyOnPath(Path path, PhysicsBody body, float time, float strength, float timeStep) { Vector2 destination = path.GetPosition(time); Vector2 positionDelta = body.Position - destination; Vector2 velocity = (positionDelta / timeStep) * strength; body.LinearVelocity = -velocity; }
public static List<PhysicsBody> EvenlyDistributeShapesAlongPath(PhysicsWorld world, Path path, Shape shape, BodyType type, int copies) { return EvenlyDistributeShapesAlongPath(world, path, shape, type, copies, null); }
/// <summary> /// Duplicates the given Body along the given path for approximatly the given copies. /// </summary> /// <param name="world">The world.</param> /// <param name="path">The path.</param> /// <param name="shape">The shape.</param> /// <param name="type">The type.</param> /// <param name="copies">The copies.</param> /// <param name="userData">The user data.</param> /// <returns></returns> public static List<PhysicsBody> EvenlyDistributeShapesAlongPath(PhysicsWorld world, Path path, Shape shape, BodyType type, int copies, object userData) { List<Shape> shapes = new List<Shape>(1); shapes.Add(shape); return EvenlyDistributeShapesAlongPath(world, path, shapes, type, copies, userData); }
/// <summary> /// Duplicates the given Body along the given path for approximatly the given copies. /// </summary> /// <param name="world">The world.</param> /// <param name="path">The path.</param> /// <param name="shapes">The shapes.</param> /// <param name="type">The type.</param> /// <param name="copies">The copies.</param> /// <param name="userData"></param> /// <returns></returns> public static List<PhysicsBody> EvenlyDistributeShapesAlongPath(PhysicsWorld world, Path path, IEnumerable<Shape> shapes, BodyType type, int copies, object userData) { List<Vector3> centers = path.SubdivideEvenly(copies); List<PhysicsBody> bodyList = new List<PhysicsBody>(); for (int i = 0; i < centers.Count; i++) { PhysicsBody b = new PhysicsBody(world); // copy the type from original body b.BodyType = type; b.Position = new Vector2(centers[i].X, centers[i].Y); b.Rotation = centers[i].Z; foreach (Shape shape in shapes) { b.CreateFixture(shape, userData); } bodyList.Add(b); } return bodyList; }
/// <summary> /// Convert a closed path into a polygon. /// Convex decomposition is automatically performed. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="density">The density.</param> /// <param name="subdivisions">The subdivisions.</param> public static void ConvertPathToPolygon(Path path, PhysicsBody body, float density, int subdivisions) { if (!path.Closed) throw new Exception("The path must be closed to convert to a polygon."); List<Vector2> verts = path.GetVertices(subdivisions); List<Vertices> decomposedVerts = EarclipDecomposer.ConvexPartition(new Vertices(verts)); //List<Vertices> decomposedVerts = BayazitDecomposer.ConvexPartition(new Vertices(verts)); foreach (Vertices item in decomposedVerts) { body.CreateFixture(new PolygonShape(item, density)); } }
//Contributed by Matthew Bettcher /// <summary> /// Convert a path into a set of edges and attaches them to the specified body. /// Note: use only for static edges. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="subdivisions">The subdivisions.</param> public static void ConvertPathToEdges(Path path, PhysicsBody body, int subdivisions) { Vertices verts = path.GetVertices(subdivisions); if (path.Closed) { LoopShape loop = new LoopShape(verts); body.CreateFixture(loop); } else { for (int i = 1; i < verts.Count; i++) { body.CreateFixture(new EdgeShape(verts[i], verts[i - 1])); } } }