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
{
public
static
class
BodyFactory
{
public
static
Body CreateBody(World world)
{
return
CreateBody(world,
null
);
}
public
static
Body CreateBody(World world,
object
userData)
{
Body body =
new
Body(world, userData);
return
body;
}
public
static
Body CreateBody(World world, Vector2 position)
{
return
CreateBody(world, position,
null
);
}
public
static
Body CreateBody(World world, Vector2 position,
object
userData)
{
Body body = CreateBody(world, userData);
body.Position = position;
return
body;
}
public
static
Body CreateEdge(World world, Vector2 start, Vector2 end)
{
return
CreateEdge(world, start, end,
null
);
}
public
static
Body CreateEdge(World world, Vector2 start, Vector2 end,
object
userData)
{
Body body = CreateBody(world);
FixtureFactory.AttachEdge(start, end, body, userData);
return
body;
}
public
static
Body CreateLoopShape(World world, Vertices vertices)
{
return
CreateLoopShape(world, vertices,
null
);
}
public
static
Body CreateLoopShape(World world, Vertices vertices,
object
userData)
{
return
CreateLoopShape(world, vertices, Vector2.Zero, userData);
}
public
static
Body CreateLoopShape(World world, Vertices vertices, Vector2 position)
{
return
CreateLoopShape(world, vertices, position,
null
);
}
public
static
Body CreateLoopShape(World world, Vertices vertices, Vector2 position,
object
userData)
{
Body body = CreateBody(world, position);
FixtureFactory.AttachLoopShape(vertices, body, userData);
return
body;
}
public
static
Body CreateRectangle(World world,
float
width,
float
height,
float
density)
{
return
CreateRectangle(world, width, height, density,
null
);
}
public
static
Body CreateRectangle(World world,
float
width,
float
height,
float
density,
object
userData)
{
return
CreateRectangle(world, width, height, density, Vector2.Zero, userData);
}
public
static
Body CreateRectangle(World world,
float
width,
float
height,
float
density, Vector2 position)
{
return
CreateRectangle(world, width, height, density, position,
null
);
}
public
static
Body CreateRectangle(World world,
float
width,
float
height,
float
density, Vector2 position,
object
userData)
{
if
(width <= 0)
throw
new
ArgumentOutOfRangeException(
"width"
,
"Width must be more than 0 meters"
);
if
(height <= 0)
throw
new
ArgumentOutOfRangeException(
"height"
,
"Height must be more than 0 meters"
);
Body newBody = CreateBody(world, position, userData);
Vertices rectangleVertices = PolygonTools.CreateRectangle(width / 2, height / 2);
PolygonShape rectangleShape =
new
PolygonShape(rectangleVertices, density);
newBody.CreateFixture(rectangleShape, userData);
return
newBody;
}
public
static
Body CreateCircle(World world,
float
radius,
float
density)
{
return
CreateCircle(world, radius, density,
null
);
}
public
static
Body CreateCircle(World world,
float
radius,
float
density,
object
userData)
{
return
CreateCircle(world, radius, density, Vector2.Zero, userData);
}
public
static
Body CreateCircle(World world,
float
radius,
float
density, Vector2 position)
{
return
CreateCircle(world, radius, density, position,
null
);
}
public
static
Body CreateCircle(World world,
float
radius,
float
density, Vector2 position,
object
userData)
{
Body body = CreateBody(world, position);
FixtureFactory.AttachCircle(radius, density, body, userData);
return
body;
}
public
static
Body CreateEllipse(World world,
float
xRadius,
float
yRadius,
int
edges,
float
density)
{
return
CreateEllipse(world, xRadius, yRadius, edges, density,
null
);
}
public
static
Body CreateEllipse(World world,
float
xRadius,
float
yRadius,
int
edges,
float
density,
object
userData)
{
return
CreateEllipse(world, xRadius, yRadius, edges, density, Vector2.Zero, userData);
}
public
static
Body CreateEllipse(World world,
float
xRadius,
float
yRadius,
int
edges,
float
density,
Vector2 position)
{
return
CreateEllipse(world, xRadius, yRadius, edges, density, position,
null
);
}
public
static
Body CreateEllipse(World world,
float
xRadius,
float
yRadius,
int
edges,
float
density,
Vector2 position,
object
userData)
{
Body body = CreateBody(world, position);
FixtureFactory.AttachEllipse(xRadius, yRadius, edges, density, body, userData);
return
body;
}
public
static
Body CreatePolygon(World world, Vertices vertices,
float
density)
{
return
CreatePolygon(world, vertices, density,
null
);
}
public
static
Body CreatePolygon(World world, Vertices vertices,
float
density,
object
userData)
{
return
CreatePolygon(world, vertices, density, Vector2.Zero, userData);
}
public
static
Body CreatePolygon(World world, Vertices vertices,
float
density, Vector2 position)
{
return
CreatePolygon(world, vertices, density, position,
null
);
}
public
static
Body CreatePolygon(World world, Vertices vertices,
float
density, Vector2 position,
object
userData)
{
Body body = CreateBody(world, position);
FixtureFactory.AttachPolygon(vertices, density, body, userData);
return
body;
}
public
static
Body CreateCompoundPolygon(World world, List<Vertices> list,
float
density)
{
return
CreateCompoundPolygon(world, list, density, BodyType.Static);
}
public
static
Body CreateCompoundPolygon(World world, List<Vertices> list,
float
density,
object
userData)
{
return
CreateCompoundPolygon(world, list, density, Vector2.Zero, userData);
}
public
static
Body CreateCompoundPolygon(World world, List<Vertices> list,
float
density,
Vector2 position)
{
return
CreateCompoundPolygon(world, list, density, position,
null
);
}
public
static
Body CreateCompoundPolygon(World world, List<Vertices> list,
float
density,
Vector2 position,
object
userData)
{
Body polygonBody = CreateBody(world, position);
FixtureFactory.AttachCompoundPolygon(list, density, polygonBody, userData);
return
polygonBody;
}
public
static
Body CreateGear(World world,
float
radius,
int
numberOfTeeth,
float
tipPercentage,
float
toothHeight,
float
density)
{
return
CreateGear(world, radius, numberOfTeeth, tipPercentage, toothHeight, density,
null
);
}
public
static
Body CreateGear(World world,
float
radius,
int
numberOfTeeth,
float
tipPercentage,
float
toothHeight,
float
density,
object
userData)
{
Vertices gearPolygon = PolygonTools.CreateGear(radius, numberOfTeeth, tipPercentage, toothHeight);
if
(!gearPolygon.IsConvex())
{
List<Vertices> list = EarclipDecomposer.ConvexPartition(gearPolygon);
return
CreateCompoundPolygon(world, list, density, userData);
}
return
CreatePolygon(world, gearPolygon, density, userData);
}
/// <summary>
/// Creates a capsule.
/// Note: Automatically decomposes the capsule if it contains too many vertices (controlled by Settings.MaxPolygonVertices)
/// </summary>
/// <param name="world">The world.</param>
/// <param name="height">The height.</param>
/// <param name="topRadius">The top radius.</param>
/// <param name="topEdges">The top edges.</param>
/// <param name="bottomRadius">The bottom radius.</param>
/// <param name="bottomEdges">The bottom edges.</param>
/// <param name="density">The density.</param>
/// <param name="position">The position.</param>
/// <returns></returns>
public
static
Body CreateCapsule(World world,
float
height,
float
topRadius,
int
topEdges,
float
bottomRadius,
int
bottomEdges,
float
density, Vector2 position,
object
userData)
{
Vertices verts = PolygonTools.CreateCapsule(height, topRadius, topEdges, bottomRadius, bottomEdges);
Body body;
if
(verts.Count >= Settings.MaxPolygonVertices)
{
List<Vertices> vertList = EarclipDecomposer.ConvexPartition(verts);
body = CreateCompoundPolygon(world, vertList, density, userData);
body.Position = position;
return
body;
}
body = CreatePolygon(world, verts, density, userData);
body.Position = position;
return
body;
}
public
static
Body CreateCapsule(World world,
float
height,
float
topRadius,
int
topEdges,
float
bottomRadius,
int
bottomEdges,
float
density, Vector2 position)
{
return
CreateCapsule(world, height, topRadius, topEdges, bottomRadius, bottomEdges, density, position,
null
);
}
public
static
Body CreateCapsule(World world,
float
height,
float
endRadius,
float
density)
{
return
CreateCapsule(world, height, endRadius, density,
null
);
}
public
static
Body CreateCapsule(World world,
float
height,
float
endRadius,
float
density,
object
userData)
{
Vertices rectangle = PolygonTools.CreateRectangle(endRadius, height / 2);
List<Vertices> list =
new
List<Vertices>();
list.Add(rectangle);
Body body = CreateCompoundPolygon(world, list, density, userData);
CircleShape topCircle =
new
CircleShape(endRadius, density);
topCircle.Position =
new
Vector2(0, height / 2);
body.CreateFixture(topCircle, userData);
CircleShape bottomCircle =
new
CircleShape(endRadius, density);
bottomCircle.Position =
new
Vector2(0, -(height / 2));
body.CreateFixture(bottomCircle, userData);
return
body;
}
/// <summary>
/// Creates a rounded rectangle.
/// Note: Automatically decomposes the capsule if it contains too many vertices (controlled by Settings.MaxPolygonVertices)
/// </summary>
/// <param name="world">The world.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="xRadius">The x radius.</param>
/// <param name="yRadius">The y radius.</param>
/// <param name="segments">The segments.</param>
/// <param name="density">The density.</param>
/// <param name="position">The position.</param>
/// <returns></returns>
public
static
Body CreateRoundedRectangle(World world,
float
width,
float
height,
float
xRadius,
float
yRadius,
int
segments,
float
density, Vector2 position,
object
userData)
{
Vertices verts = PolygonTools.CreateRoundedRectangle(width, height, xRadius, yRadius, segments);
if
(verts.Count >= Settings.MaxPolygonVertices)
{
List<Vertices> vertList = EarclipDecomposer.ConvexPartition(verts);
Body body = CreateCompoundPolygon(world, vertList, density, userData);
body.Position = position;
return
body;
}
return
CreatePolygon(world, verts, density);
}
public
static
Body CreateRoundedRectangle(World world,
float
width,
float
height,
float
xRadius,
float
yRadius,
int
segments,
float
density, Vector2 position)
{
return
CreateRoundedRectangle(world, width, height, xRadius, yRadius, segments, density, position,
null
);
}
public
static
Body CreateRoundedRectangle(World world,
float
width,
float
height,
float
xRadius,
float
yRadius,
int
segments,
float
density)
{
return
CreateRoundedRectangle(world, width, height, xRadius, yRadius, segments, density,
null
);
}
public
static
Body CreateRoundedRectangle(World world,
float
width,
float
height,
float
xRadius,
float
yRadius,
int
segments,
float
density,
object
userData)
{
return
CreateRoundedRectangle(world, width, height, xRadius, yRadius, segments, density, Vector2.Zero,
userData);
}
public
static
BreakableBody CreateBreakableBody(World world, Vertices vertices,
float
density)
{
return
CreateBreakableBody(world, vertices, density,
null
);
}
public
static
BreakableBody CreateBreakableBody(World world, Vertices vertices,
float
density,
object
userData)
{
return
CreateBreakableBody(world, vertices, density, Vector2.Zero, userData);
}
/// <summary>
/// Creates a breakable body. You would want to remove collinear points before using this.
/// </summary>
/// <param name="world">The world.</param>
/// <param name="vertices">The vertices.</param>
/// <param name="density">The density.</param>
/// <param name="position">The position.</param>
/// <returns></returns>
public
static
BreakableBody CreateBreakableBody(World world, Vertices vertices,
float
density, Vector2 position,
object
userData)
{
List<Vertices> triangles = EarclipDecomposer.ConvexPartition(vertices);
BreakableBody breakableBody =
new
BreakableBody(triangles, world, density, userData);
breakableBody.MainBody.Position = position;
world.AddBreakableBody(breakableBody);
return
breakableBody;
}
public
static
BreakableBody CreateBreakableBody(World world, Vertices vertices,
float
density, Vector2 position)
{
return
CreateBreakableBody(world, vertices, density, position,
null
);
}
public
static
Body CreateLineArc(World world,
float
radians,
int
sides,
float
radius, Vector2 position,
float
angle,
bool
closed)
{
Body body = CreateBody(world);
FixtureFactory.AttachLineArc(radians, sides, radius, position, angle, closed, body);
return
body;
}
public
static
Body CreateSolidArc(World world,
float
density,
float
radians,
int
sides,
float
radius,
Vector2 position,
float
angle)
{
Body body = CreateBody(world);
FixtureFactory.AttachSolidArc(density, radians, sides, radius, position, angle, body);
return
body;
}
}
}