use of org.jbox2d.collision.shapes.PolygonShape in project libgdx by libgdx.
the class Collision method collidePolygons.
/**
* Compute the collision manifold between two polygons.
*
* @param manifold
* @param polygon1
* @param xf1
* @param polygon2
* @param xf2
*/
public final void collidePolygons(Manifold manifold, final PolygonShape polyA, final Transform xfA, final PolygonShape polyB, final Transform xfB) {
// Find edge normal of max separation on A - return if separating axis is found
// Find edge normal of max separation on B - return if separation axis is found
// Choose reference edge as min(minA, minB)
// Find incident edge
// Clip
// The normal points from 1 to 2
manifold.pointCount = 0;
float totalRadius = polyA.m_radius + polyB.m_radius;
findMaxSeparation(results1, polyA, xfA, polyB, xfB);
if (results1.separation > totalRadius) {
return;
}
findMaxSeparation(results2, polyB, xfB, polyA, xfA);
if (results2.separation > totalRadius) {
return;
}
// reference polygon
final PolygonShape poly1;
// incident polygon
final PolygonShape poly2;
Transform xf1, xf2;
// reference edge
int edge1;
boolean flip;
final float k_tol = 0.1f * Settings.linearSlop;
if (results2.separation > results1.separation + k_tol) {
poly1 = polyB;
poly2 = polyA;
xf1 = xfB;
xf2 = xfA;
edge1 = results2.edgeIndex;
manifold.type = ManifoldType.FACE_B;
flip = true;
} else {
poly1 = polyA;
poly2 = polyB;
xf1 = xfA;
xf2 = xfB;
edge1 = results1.edgeIndex;
manifold.type = ManifoldType.FACE_A;
flip = false;
}
final Rot xf1q = xf1.q;
findIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2);
int count1 = poly1.m_count;
final Vec2[] vertices1 = poly1.m_vertices;
final int iv1 = edge1;
final int iv2 = edge1 + 1 < count1 ? edge1 + 1 : 0;
v11.set(vertices1[iv1]);
v12.set(vertices1[iv2]);
localTangent.x = v12.x - v11.x;
localTangent.y = v12.y - v11.y;
localTangent.normalize();
// Vec2 localNormal = Vec2.cross(dv, 1.0f);
localNormal.x = 1f * localTangent.y;
localNormal.y = -1f * localTangent.x;
// Vec2 planePoint = 0.5f * (v11+ v12);
planePoint.x = (v11.x + v12.x) * .5f;
planePoint.y = (v11.y + v12.y) * .5f;
// Rot.mulToOutUnsafe(xf1.q, localTangent, tangent);
tangent.x = xf1q.c * localTangent.x - xf1q.s * localTangent.y;
tangent.y = xf1q.s * localTangent.x + xf1q.c * localTangent.y;
// Vec2.crossToOutUnsafe(tangent, 1f, normal);
final float normalx = 1f * tangent.y;
final float normaly = -1f * tangent.x;
Transform.mulToOut(xf1, v11, v11);
Transform.mulToOut(xf1, v12, v12);
// v11 = Mul(xf1, v11);
// v12 = Mul(xf1, v12);
// Face offset
// float frontOffset = Vec2.dot(normal, v11);
float frontOffset = normalx * v11.x + normaly * v11.y;
// Side offsets, extended by polytope skin thickness.
// float sideOffset1 = -Vec2.dot(tangent, v11) + totalRadius;
// float sideOffset2 = Vec2.dot(tangent, v12) + totalRadius;
float sideOffset1 = -(tangent.x * v11.x + tangent.y * v11.y) + totalRadius;
float sideOffset2 = tangent.x * v12.x + tangent.y * v12.y + totalRadius;
// Clip incident edge against extruded edge1 side edges.
// ClipVertex clipPoints1[2];
// ClipVertex clipPoints2[2];
int np;
// Clip to box side 1
// np = ClipSegmentToLine(clipPoints1, incidentEdge, -sideNormal, sideOffset1);
tangent.negateLocal();
np = clipSegmentToLine(clipPoints1, incidentEdge, tangent, sideOffset1, iv1);
tangent.negateLocal();
if (np < 2) {
return;
}
// Clip to negative box side 1
np = clipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2, iv2);
if (np < 2) {
return;
}
// Now clipPoints2 contains the clipped points.
manifold.localNormal.set(localNormal);
manifold.localPoint.set(planePoint);
int pointCount = 0;
for (int i = 0; i < Settings.maxManifoldPoints; ++i) {
// float separation = Vec2.dot(normal, clipPoints2[i].v) - frontOffset;
float separation = normalx * clipPoints2[i].v.x + normaly * clipPoints2[i].v.y - frontOffset;
if (separation <= totalRadius) {
ManifoldPoint cp = manifold.points[pointCount];
// cp.m_localPoint = MulT(xf2, clipPoints2[i].v);
Vec2 out = cp.localPoint;
final float px = clipPoints2[i].v.x - xf2.p.x;
final float py = clipPoints2[i].v.y - xf2.p.y;
out.x = (xf2.q.c * px + xf2.q.s * py);
out.y = (-xf2.q.s * px + xf2.q.c * py);
cp.id.set(clipPoints2[i].id);
if (flip) {
// Swap features
cp.id.flip();
}
++pointCount;
}
}
manifold.pointCount = pointCount;
}
use of org.jbox2d.collision.shapes.PolygonShape in project SnapStudio by reportmill.
the class PhysicsRunner method createShape.
/**
* Creates a Box2D shape for given snap shape.
*/
public org.jbox2d.collision.shapes.Shape createShape(Polygon aPoly) {
// If invalid, just return null
if (!aPoly.isSimple() || !aPoly.isConvex() || aPoly.getPointCount() > 8)
return null;
// Create Box2D PolygonShape and return
int pc = aPoly.getPointCount();
Vec2[] vecs = new Vec2[pc];
for (int i = 0; i < pc; i++) vecs[i] = viewToBox(aPoly.getX(i), aPoly.getY(i));
PolygonShape pshape = new PolygonShape();
pshape.set(vecs, vecs.length);
return pshape;
}
use of org.jbox2d.collision.shapes.PolygonShape in project SnapStudio by reportmill.
the class PhysicsRunner method createBody.
/**
* Returns a body for a view.
*/
public Body createBody(View aView) {
// Create BodyDef
ViewPhysics<Body> phys = aView.getPhysics();
BodyDef bdef = new BodyDef();
bdef.type = phys.isDynamic() ? BodyType.DYNAMIC : BodyType.KINEMATIC;
bdef.position.set(viewToBox(aView.getMidX(), aView.getMidY()));
bdef.angle = (float) Math.toRadians(-aView.getRotate());
bdef.linearDamping = 10;
bdef.angularDamping = 10;
// Create Body
Body body = _world.createBody(bdef);
// Create PolygonShape
Shape vshape = aView.getBoundsShape();
org.jbox2d.collision.shapes.Shape[] pshapes = createShape(vshape);
// Create FixtureDef
for (org.jbox2d.collision.shapes.Shape pshp : pshapes) {
FixtureDef fdef = new FixtureDef();
fdef.shape = pshp;
fdef.restitution = .25f;
fdef.density = (float) phys.getDensity();
fdef.filter.groupIndex = phys.getGroupIndex();
body.createFixture(fdef);
}
// Return body
phys.setNative(body);
return body;
}
use of org.jbox2d.collision.shapes.PolygonShape in project SnapStudio by reportmill.
the class PhysicsRunner method createShape.
/**
* Creates a Box2D shape for given snap shape.
*/
public org.jbox2d.collision.shapes.Shape[] createShape(Shape aShape) {
// Handle Rect (simple case)
if (aShape instanceof Rect) {
Rect rect = (Rect) aShape;
PolygonShape pshape = new PolygonShape();
float pw = viewToBox(rect.width / 2);
float ph = viewToBox(rect.height / 2);
pshape.setAsBox(pw, ph);
return new org.jbox2d.collision.shapes.Shape[] { pshape };
}
// Handle Ellipse
if (aShape instanceof Ellipse && aShape.getWidth() == aShape.getHeight()) {
Ellipse elp = (Ellipse) aShape;
CircleShape cshape = new CircleShape();
cshape.setRadius(viewToBox(elp.getWidth() / 2));
return new org.jbox2d.collision.shapes.Shape[] { cshape };
}
// Handle Arc
if (aShape instanceof Arc && aShape.getWidth() == aShape.getHeight()) {
Arc arc = (Arc) aShape;
if (arc.getSweepAngle() == 360) {
CircleShape cshape = new CircleShape();
cshape.setRadius(viewToBox(arc.getWidth() / 2));
return new org.jbox2d.collision.shapes.Shape[] { cshape };
}
}
// Handle Polygon if Simple, Convex and less than 8 points
if (aShape instanceof Polygon) {
Polygon poly = (Polygon) aShape;
org.jbox2d.collision.shapes.Shape pshape = createShape(poly);
if (pshape != null)
return new org.jbox2d.collision.shapes.Shape[] { pshape };
}
// Get shape centered around shape midpoint
Rect bnds = aShape.getBounds();
Shape shape = aShape.copyFor(new Transform(-bnds.width / 2, -bnds.height / 2));
// Get convex Polygons for shape
Polygon[] convexPolys = Polygon.getConvexPolys(shape, 8);
List<org.jbox2d.collision.shapes.Shape> pshapes = new ArrayList();
// Iterate over polygons
for (Polygon cpoly : convexPolys) {
// Try simple case
org.jbox2d.collision.shapes.Shape pshp = createShape(cpoly);
if (pshp != null)
pshapes.add(pshp);
else
System.err.println("PhysicsRunner:.createShape: failure");
}
// Return Box2D shapes array
return pshapes.toArray(new org.jbox2d.collision.shapes.Shape[0]);
}
use of org.jbox2d.collision.shapes.PolygonShape in project Bytecoder by mirkosertic.
the class JBox2DSimulation method render.
private static void render() {
renderingContext2D.clear();
renderingContext2D.save();
renderingContext2D.translate(0, 600);
renderingContext2D.scale(1, -1);
renderingContext2D.scale(100, 100);
renderingContext2D.lineWidth(0.01f);
for (Body body = scene.getWorld().getBodyList(); body != null; body = body.getNext()) {
Vec2 center = body.getPosition();
renderingContext2D.save();
renderingContext2D.translate(center.x, center.y);
renderingContext2D.rotate(body.getAngle());
for (Fixture fixture = body.getFixtureList(); fixture != null; fixture = fixture.getNext()) {
Shape shape = fixture.getShape();
if (shape.getType() == ShapeType.CIRCLE) {
CircleShape circle = (CircleShape) shape;
renderingContext2D.beginPath();
renderingContext2D.arc(circle.m_p.x, circle.m_p.y, circle.getRadius(), 0, Math.PI * 2, true);
renderingContext2D.closePath();
renderingContext2D.stroke();
} else if (shape.getType() == ShapeType.POLYGON) {
PolygonShape poly = (PolygonShape) shape;
Vec2[] vertices = poly.getVertices();
renderingContext2D.beginPath();
renderingContext2D.moveTo(vertices[0].x, vertices[0].y);
for (int i = 1; i < poly.getVertexCount(); ++i) {
renderingContext2D.lineTo(vertices[i].x, vertices[i].y);
}
renderingContext2D.closePath();
renderingContext2D.stroke();
}
}
renderingContext2D.restore();
}
renderingContext2D.restore();
}
Aggregations