Search in sources :

Example 1 with Shape

use of spacegraph.space2d.phys.collision.shapes.Shape in project narchy by automenta.

the class Fracture method smash.

/**
 * Rozbije objekt. Upravi objekt world tak, ze vymaze triesteny objekt
 * a nahradi ho fragmentami na zaklade nastaveneho materialu a clenskych
 * premennych.
 *
 * @param dt casova dlzka framu
 */
public void smash(Smasher smasher, float dt) {
    Shape s = f1.shape;
    if (s == null)
        return;
    if (contact == null) {
        // riesi sa staticky prvok, ktory ma priliz maly obsah
        b1.setType(BodyType.DYNAMIC);
        return;
    }
    Dynamics2D w = b1.W;
    Polygon p = f1.polygon;
    if (p == null) {
        switch(s.m_type) {
            case POLYGON:
                PolygonShape ps = (PolygonShape) s;
                Tuple2f[] vertices = ps.vertex;
                int n = ps.vertices;
                p = new Polygon(n);
                for (int i = 0; i < n; ++i) {
                    p.add(vertices[n - i - 1]);
                }
                break;
            case CIRCLE:
                CircleShape cs = (CircleShape) s;
                p = new Polygon(CIRCLEVERTICES);
                float radius = cs.radius;
                double u = Math.PI * 2 / CIRCLEVERTICES;
                // upravim radius tak, aby bola zachovana velkost obsahu
                radius = (float) Math.sqrt(u / Math.sin(u)) * radius;
                Tuple2f center = cs.center;
                for (int i = 0; i < CIRCLEVERTICES; ++i) {
                    // uhol
                    double j = u * i;
                    float sin = (float) Math.sin(j);
                    float cos = (float) Math.cos(j);
                    Tuple2f v = new v2(sin, cos).scaled(radius).added(center);
                    p.add(v);
                }
                break;
            default:
                throw new RuntimeException("Dany typ tvaru nepodporuje stiepenie");
        }
    }
    // sila v zavislosti na pevnosti telesa
    float mConst = f1.material.m_rigidity / normalImpulse;
    // true, ak f2 je v objekte contact ako m_fixtureA
    boolean fixA = f1 == contact.aFixture;
    float oldAngularVelocity = fixA ? contact.m_angularVelocity_bodyA : contact.m_angularVelocity_bodyB;
    Tuple2f oldLinearVelocity = fixA ? contact.m_linearVelocity_bodyA : contact.m_linearVelocity_bodyB;
    b1.setAngularVelocity((b1.velAngular - oldAngularVelocity) * mConst + oldAngularVelocity);
    b1.setLinearVelocity(b1.vel.sub(oldLinearVelocity).scaled(mConst).added(oldLinearVelocity));
    if (!w.isFractured(f2) && b2.type == BodyType.DYNAMIC && !b2.m_fractureTransformUpdate) {
        // ak sa druhy objekt nerozbija, tak sa jej nahodia povodne hodnoty (TREBA MODIFIKOVAT POHYB OBJEKTU, KTORY SPOSOBUJE ROZPAD)
        oldAngularVelocity = !fixA ? contact.m_angularVelocity_bodyA : contact.m_angularVelocity_bodyB;
        oldLinearVelocity = !fixA ? contact.m_linearVelocity_bodyA : contact.m_linearVelocity_bodyB;
        b2.setAngularVelocity((b2.velAngular - oldAngularVelocity) * mConst + oldAngularVelocity);
        b2.setLinearVelocity(b2.vel.sub(oldLinearVelocity).scaled(mConst).added(oldLinearVelocity));
        b2.setTransform(b2.transformPrev.pos.add(b2.vel.scale(dt)), b2.transformPrev.angle());
        // osetruje jbox2d od posuvania telesa pri rieseni kolizie
        b2.m_fractureTransformUpdate = true;
    }
    Tuple2f localPoint = Transform.mulTrans(b1, point);
    Tuple2f b1Vec = b1.getLinearVelocityFromWorldPoint(point);
    Tuple2f b2Vec = b2.getLinearVelocityFromWorldPoint(point);
    Tuple2f localVelocity = b2Vec.subbed(b1Vec);
    localVelocity.scaled(dt);
    // rodeli to
    Polygon[] fragment = m.split(smasher, p, localPoint, localVelocity, normalImpulse);
    if (fragment.length <= 1) {
        // nerozbilo to na ziadne fragmenty
        return;
    }
    // definuje tela fragmentov - tie maju vsetky rovnaku definiciu (preberaju parametre z povodneho objektu)
    BodyDef bodyDef = new BodyDef();
    // pozicia
    bodyDef.position.set(b1.pos);
    // otocenie
    bodyDef.angle = b1.angle();
    bodyDef.fixedRotation = b1.isFixedRotation();
    bodyDef.angularDamping = b1.m_angularDamping;
    bodyDef.allowSleep = b1.isSleepingAllowed();
    FixtureDef fd = new FixtureDef();
    // trenie
    fd.friction = f1.friction;
    // odrazivost
    fd.restitution = f1.restitution;
    fd.isSensor = f1.isSensor;
    fd.density = f1.density;
    // odstrani fragmentacne predmety/cele teleso
    List<Fixture> fixtures = new FasterList<>();
    if (f1.polygon != null) {
        for (Fixture f = b1.fixtures; f != null; f = f.next) {
            if (f.polygon == f1.polygon) {
                fixtures.add(f);
            }
        }
    } else {
        fixtures.add(f1);
    }
    for (Fixture f : fixtures) {
        b1.removeFixture(f);
    }
    if (b1.fixtureCount == 0) {
        w.removeBody(b1);
    }
    // prida fragmenty do simulacie
    MyList<Body2D> newbodies = new MyList<>();
    for (Polygon pg : fragment) {
        // vytvori tela, prida fixtury, poriesi konvexnu dekompoziciu
        if (pg.isCorrect()) {
            if (pg instanceof Fragment) {
                Polygon[] convex = pg.convexDecomposition();
                bodyDef.type = BodyType.DYNAMIC;
                for (Polygon pgx : convex) {
                    Body2D f_body = w.addBody(bodyDef);
                    pgx.flip();
                    PolygonShape ps = new PolygonShape();
                    ps.set(pgx.getArray(), pgx.size());
                    fd.shape = ps;
                    fd.polygon = null;
                    fd.material = f1.material;
                    // .m_fragments; //rekurzivne stiepenie
                    f_body.addFixture(fd);
                    f_body.setAngularVelocity(b1.velAngular);
                    f_body.setLinearVelocity(b1.getLinearVelocityFromLocalPoint(f_body.getLocalCenter()));
                    newbodies.add(f_body);
                }
            } else {
                fd.material = // .m_fragments; //rekurzivne stiepenie
                f1.material;
                bodyDef.type = b1.getType();
                Body2D f_body = w.addBody(bodyDef);
                PolygonFixture pf = new PolygonFixture(pg);
                f_body.addFixture(pf, fd);
                f_body.setLinearVelocity(b1.getLinearVelocityFromLocalPoint(f_body.getLocalCenter()));
                f_body.setAngularVelocity(b1.velAngular);
                newbodies.add(f_body);
            }
        }
    }
    // zavola sa funkcia z fraction listeneru (pokial je nadefinovany)
    FractureListener fl = w.getContactManager().m_fractureListener;
    if (fl != null) {
        fl.action(m, normalImpulse, newbodies);
    }
}
Also used : PolygonShape(spacegraph.space2d.phys.collision.shapes.PolygonShape) Shape(spacegraph.space2d.phys.collision.shapes.Shape) CircleShape(spacegraph.space2d.phys.collision.shapes.CircleShape) PolygonShape(spacegraph.space2d.phys.collision.shapes.PolygonShape) Tuple2f(spacegraph.util.math.Tuple2f) CircleShape(spacegraph.space2d.phys.collision.shapes.CircleShape) FasterList(jcog.list.FasterList) MyList(spacegraph.space2d.phys.fracture.util.MyList) spacegraph.util.math.v2(spacegraph.util.math.v2)

Example 2 with Shape

use of spacegraph.space2d.phys.collision.shapes.Shape in project narchy by automenta.

the class Contact method getWorldManifold.

/**
 * Get the world manifold.
 */
public void getWorldManifold(WorldManifold worldManifold) {
    final Body2D bodyA = aFixture.getBody();
    final Body2D bodyB = bFixture.getBody();
    final Shape shapeA = aFixture.shape();
    final Shape shapeB = bFixture.shape();
    worldManifold.initialize(m_manifold, bodyA, shapeA.radius, bodyB, shapeB.radius);
}
Also used : Shape(spacegraph.space2d.phys.collision.shapes.Shape) Body2D(spacegraph.space2d.phys.dynamics.Body2D)

Example 3 with Shape

use of spacegraph.space2d.phys.collision.shapes.Shape in project narchy by automenta.

the class Contact method update.

public void update(ContactListener listener) {
    oldManifold.set(m_manifold);
    // Re-enable this contact.
    m_flags |= ENABLED_FLAG;
    boolean touching = false;
    boolean wasTouching = (m_flags & TOUCHING_FLAG) == TOUCHING_FLAG;
    boolean sensorA = aFixture.isSensor();
    boolean sensorB = bFixture.isSensor();
    boolean sensor = sensorA || sensorB;
    Body2D bodyA = aFixture.getBody();
    Body2D bodyB = bFixture.getBody();
    Transform xfA = bodyA;
    Transform xfB = bodyB;
    if (sensor) {
        Shape shapeA = aFixture.shape();
        Shape shapeB = bFixture.shape();
        touching = pool.getCollision().testOverlap(shapeA, aIndex, shapeB, bIndex, xfA, xfB);
        // Sensors don't generate manifolds.
        m_manifold.pointCount = 0;
    } else {
        evaluate(m_manifold, xfA, xfB);
        touching = m_manifold.pointCount > 0;
        // stored impulses to warm start the solver.
        for (int i = 0; i < m_manifold.pointCount; ++i) {
            ManifoldPoint mp2 = m_manifold.points[i];
            mp2.normalImpulse = 0.0f;
            mp2.tangentImpulse = 0.0f;
            ContactID id2 = mp2.id;
            for (int j = 0; j < oldManifold.pointCount; ++j) {
                ManifoldPoint mp1 = oldManifold.points[j];
                if (mp1.id.isEqual(id2)) {
                    mp2.normalImpulse = mp1.normalImpulse;
                    mp2.tangentImpulse = mp1.tangentImpulse;
                    break;
                }
            }
        }
        if (touching != wasTouching) {
            bodyA.setAwake(true);
            bodyB.setAwake(true);
        }
    }
    if (touching) {
        m_flags |= TOUCHING_FLAG;
    } else {
        m_flags &= ~TOUCHING_FLAG;
    }
    if (!sensor && touching) {
        m_angularVelocity_bodyA = aFixture.body.velAngular;
        m_linearVelocity_bodyA.set(aFixture.body.vel);
        m_angularVelocity_bodyB = bFixture.body.velAngular;
        m_linearVelocity_bodyB.set(bFixture.body.vel);
    }
    if (listener == null) {
        return;
    }
    if (!wasTouching && touching) {
        if (!listener.beginContact(this))
            touching = false;
    }
    if (wasTouching && !touching) {
        listener.endContact(this);
    }
    if (!sensor && touching) {
        listener.preSolve(this, oldManifold);
    }
}
Also used : Shape(spacegraph.space2d.phys.collision.shapes.Shape) ManifoldPoint(spacegraph.space2d.phys.collision.ManifoldPoint) ContactID(spacegraph.space2d.phys.collision.ContactID) Transform(spacegraph.space2d.phys.common.Transform) ManifoldPoint(spacegraph.space2d.phys.collision.ManifoldPoint) Body2D(spacegraph.space2d.phys.dynamics.Body2D)

Example 4 with Shape

use of spacegraph.space2d.phys.collision.shapes.Shape in project narchy by automenta.

the class PhyWall method drawBody.

private void drawBody(Body2D body, GL2 gl) {
    if (body.data() instanceof PhyWindow.WallBody) {
        // its rendered already via its Surface
        return;
    }
    if (body instanceof Consumer) {
        // HACK make better custom enderer interface
        ((Consumer) body).accept(gl);
        return;
    }
    // boolean active = body.isActive();
    boolean awake = body.isAwake();
    gl.glColor4f(0.5f, 0.5f, 0.5f, awake ? 0.75f : 0.65f);
    // List<PolygonFixture> generalPolygons = new FasterList<>();
    for (Fixture f = body.fixtures; f != null; f = f.next) {
        PolygonFixture pg = f.polygon;
        if (pg != null) {
        // generalPolygons.add(pg);
        } else {
            Shape shape = f.shape();
            switch(shape.m_type) {
                case POLYGON:
                    Draw.poly(body, gl, (PolygonShape) shape);
                    break;
                case CIRCLE:
                    CircleShape circle = (CircleShape) shape;
                    float r = circle.radius;
                    v2 v = new v2();
                    body.getWorldPointToOut(circle.center, v);
                    // Point p = getPoint(v);
                    // int wr = (int) (r * zoom);
                    // g.fillOval(p.x - wr, p.y - wr, wr * 2, wr * 2);
                    Draw.circle(gl, v, true, r, 9);
                    break;
                case EDGE:
                    EdgeShape edge = (EdgeShape) shape;
                    Tuple2f p1 = edge.m_vertex1;
                    Tuple2f p2 = edge.m_vertex2;
                    gl.glLineWidth(4f);
                    Draw.line(gl, p1.x, p1.y, p2.x, p2.y);
                    break;
            }
        }
    }
// if (generalPolygons.size() != 0) {
// PolygonFixture[] polygonArray = generalPolygons.toArray(new PolygonFixture[generalPolygons.size()]);
// for (PolygonFixture poly : polygonArray) {
// int n = poly.size();
// int x[] = new int[n];
// int y[] = new int[n];
// for (int i = 0; i < n; ++i) {
// body.getWorldPointToOut(poly.get(i), v);
// Point p = getPoint(v);
// x[i] = p.x;
// y[i] = p.y;
// }
// g.fillPolygon(x, y, n);
// }
}
Also used : EdgeShape(spacegraph.space2d.phys.collision.shapes.EdgeShape) PolygonShape(spacegraph.space2d.phys.collision.shapes.PolygonShape) CircleShape(spacegraph.space2d.phys.collision.shapes.CircleShape) Shape(spacegraph.space2d.phys.collision.shapes.Shape) EdgeShape(spacegraph.space2d.phys.collision.shapes.EdgeShape) Tuple2f(spacegraph.util.math.Tuple2f) Consumer(java.util.function.Consumer) CircleShape(spacegraph.space2d.phys.collision.shapes.CircleShape) PolygonFixture(spacegraph.space2d.phys.fracture.PolygonFixture) PolygonFixture(spacegraph.space2d.phys.fracture.PolygonFixture) spacegraph.util.math.v2(spacegraph.util.math.v2)

Example 5 with Shape

use of spacegraph.space2d.phys.collision.shapes.Shape in project narchy by automenta.

the class Bodies method create.

public Body create(Vec2 position, Shape[] shapes, BodyType bodytype, BodyDefCallback body_instruction, FixtureDefCallback fixture_instruction, CollisionManager colm) {
    Body groundbody = world.createBody(setupBody(position, bodytype, body_instruction));
    FixtureDef temp;
    for (Shape s : shapes) {
        temp = createFix(s, fixture_instruction);
        if (colm != null)
            temp.userData = new FixtureData(colm);
        groundbody.createFixture(temp);
    }
    return groundbody;
}
Also used : EdgeShape(spacegraph.space2d.phys.collision.shapes.EdgeShape) Shape(spacegraph.space2d.phys.collision.shapes.Shape) CircleShape(spacegraph.space2d.phys.collision.shapes.CircleShape) PolygonShape(spacegraph.space2d.phys.collision.shapes.PolygonShape)

Aggregations

Shape (spacegraph.space2d.phys.collision.shapes.Shape)8 CircleShape (spacegraph.space2d.phys.collision.shapes.CircleShape)4 PolygonShape (spacegraph.space2d.phys.collision.shapes.PolygonShape)4 EdgeShape (spacegraph.space2d.phys.collision.shapes.EdgeShape)3 Body2D (spacegraph.space2d.phys.dynamics.Body2D)3 Tuple2f (spacegraph.util.math.Tuple2f)3 spacegraph.util.math.v2 (spacegraph.util.math.v2)3 ManifoldPoint (spacegraph.space2d.phys.collision.ManifoldPoint)2 PolygonFixture (spacegraph.space2d.phys.fracture.PolygonFixture)2 MyList (spacegraph.space2d.phys.fracture.util.MyList)2 Consumer (java.util.function.Consumer)1 FasterList (jcog.list.FasterList)1 AABB (spacegraph.space2d.phys.collision.AABB)1 ContactID (spacegraph.space2d.phys.collision.ContactID)1 Manifold (spacegraph.space2d.phys.collision.Manifold)1 WorldManifold (spacegraph.space2d.phys.collision.WorldManifold)1 Transform (spacegraph.space2d.phys.common.Transform)1 Vec2 (spacegraph.space2d.phys.common.Vec2)1 Fixture (spacegraph.space2d.phys.dynamics.Fixture)1 VelocityConstraintPoint (spacegraph.space2d.phys.dynamics.contacts.ContactVelocityConstraint.VelocityConstraintPoint)1