Search in sources :

Example 1 with PolygonShape

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;
}
Also used : PolygonShape(org.jbox2d.collision.shapes.PolygonShape) Rot(org.jbox2d.common.Rot) Vec2(org.jbox2d.common.Vec2) Transform(org.jbox2d.common.Transform)

Example 2 with PolygonShape

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;
}
Also used : PolygonShape(org.jbox2d.collision.shapes.PolygonShape) Vec2(org.jbox2d.common.Vec2)

Example 3 with PolygonShape

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;
}
Also used : CircleShape(org.jbox2d.collision.shapes.CircleShape) PolygonShape(org.jbox2d.collision.shapes.PolygonShape)

Example 4 with PolygonShape

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]);
}
Also used : PolygonShape(org.jbox2d.collision.shapes.PolygonShape) CircleShape(org.jbox2d.collision.shapes.CircleShape) PolygonShape(org.jbox2d.collision.shapes.PolygonShape) CircleShape(org.jbox2d.collision.shapes.CircleShape)

Example 5 with PolygonShape

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();
}
Also used : PolygonShape(org.jbox2d.collision.shapes.PolygonShape) CircleShape(org.jbox2d.collision.shapes.CircleShape) PolygonShape(org.jbox2d.collision.shapes.PolygonShape) Shape(org.jbox2d.collision.shapes.Shape) CircleShape(org.jbox2d.collision.shapes.CircleShape) Vec2(org.jbox2d.common.Vec2) Fixture(org.jbox2d.dynamics.Fixture) Body(org.jbox2d.dynamics.Body)

Aggregations

PolygonShape (org.jbox2d.collision.shapes.PolygonShape)7 Vec2 (org.jbox2d.common.Vec2)5 CircleShape (org.jbox2d.collision.shapes.CircleShape)3 Shape (org.jbox2d.collision.shapes.Shape)2 Body (org.jbox2d.dynamics.Body)2 EdgeShape (org.jbox2d.collision.shapes.EdgeShape)1 Rot (org.jbox2d.common.Rot)1 Transform (org.jbox2d.common.Transform)1 BodyDef (org.jbox2d.dynamics.BodyDef)1 Fixture (org.jbox2d.dynamics.Fixture)1 World (org.jbox2d.dynamics.World)1 RevoluteJoint (org.jbox2d.dynamics.joints.RevoluteJoint)1 RevoluteJointDef (org.jbox2d.dynamics.joints.RevoluteJointDef)1 Test (org.junit.jupiter.api.Test)1