Search in sources :

Example 1 with Shape

use of com.almasb.fxgl.physics.box2d.collision.shapes.Shape in project FXGL by AlmasB.

the class Contact method update.

public void update(ContactListener listener) {
    oldManifold.set(m_manifold);
    // Re-enable this contact.
    m_flags |= ENABLED_FLAG;
    boolean wasTouching = (m_flags & TOUCHING_FLAG) == TOUCHING_FLAG;
    boolean sensorA = m_fixtureA.isSensor();
    boolean sensorB = m_fixtureB.isSensor();
    boolean sensor = sensorA || sensorB;
    Body bodyA = m_fixtureA.getBody();
    Body bodyB = m_fixtureB.getBody();
    Transform xfA = bodyA.getTransform();
    Transform xfB = bodyB.getTransform();
    boolean touching;
    if (sensor) {
        Shape shapeA = m_fixtureA.getShape();
        Shape shapeB = m_fixtureB.getShape();
        touching = GenericCollision.testOverlap(pool, shapeA, m_indexA, shapeB, m_indexB, 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 (listener == null) {
        return;
    }
    if (!wasTouching && touching) {
        listener.beginContact(this);
    }
    if (wasTouching && !touching) {
        listener.endContact(this);
    }
    if (!sensor && touching) {
        listener.preSolve(this, oldManifold);
    }
}
Also used : Shape(com.almasb.fxgl.physics.box2d.collision.shapes.Shape) ManifoldPoint(com.almasb.fxgl.physics.box2d.collision.ManifoldPoint) ContactID(com.almasb.fxgl.physics.box2d.collision.ContactID) Transform(com.almasb.fxgl.physics.box2d.common.Transform) Body(com.almasb.fxgl.physics.box2d.dynamics.Body) ManifoldPoint(com.almasb.fxgl.physics.box2d.collision.ManifoldPoint)

Example 2 with Shape

use of com.almasb.fxgl.physics.box2d.collision.shapes.Shape in project FXGL by AlmasB.

the class PhysicsWorld method createFixtures.

private void createFixtures(Entity e) {
    BoundingBoxComponent bbox = e.getBoundingBoxComponent();
    PhysicsComponent physics = e.getComponent(PhysicsComponent.class);
    FixtureDef fd = physics.fixtureDef;
    for (HitBox box : bbox.hitBoxesProperty()) {
        Shape b2Shape = createShape(box, e);
        // we use definitions from user, but override shape
        fd.setShape(b2Shape);
        Fixture fixture = physics.body.createFixture(fd);
        fixture.setHitBox(box);
    }
}
Also used : BoundingBoxComponent(com.almasb.fxgl.entity.components.BoundingBoxComponent) Shape(com.almasb.fxgl.physics.box2d.collision.shapes.Shape)

Example 3 with Shape

use of com.almasb.fxgl.physics.box2d.collision.shapes.Shape in project FXGL by AlmasB.

the class ParticleSystem method createParticleGroup.

@SuppressWarnings("PMD.DontUseFloatTypeForLoopIndices")
public ParticleGroup createParticleGroup(ParticleGroupDef groupDef) {
    float stride = getParticleStride();
    final Transform identity = tempTransform;
    identity.setIdentity();
    Transform transform = tempTransform2;
    transform.setIdentity();
    int firstIndex = m_count;
    if (groupDef.getShape() != null) {
        final ParticleDef particleDef = tempParticleDef;
        particleDef.setTypeFlags(groupDef.getTypeFlags());
        particleDef.color = groupDef.getColor();
        particleDef.setUserData(groupDef.getUserData());
        Shape shape = groupDef.getShape();
        transform.set(groupDef.getPosition(), groupDef.getAngle());
        AABB aabb = temp;
        int childCount = shape.getChildCount();
        for (int childIndex = 0; childIndex < childCount; childIndex++) {
            if (childIndex == 0) {
                shape.computeAABB(aabb, identity, childIndex);
            } else {
                AABB childAABB = temp2;
                shape.computeAABB(childAABB, identity, childIndex);
                aabb.combine(childAABB);
            }
        }
        final float upperBoundY = aabb.upperBound.y;
        final float upperBoundX = aabb.upperBound.x;
        for (float y = FXGLMath.floor(aabb.lowerBound.y / stride) * stride; y < upperBoundY; y += stride) {
            for (float x = FXGLMath.floor(aabb.lowerBound.x / stride) * stride; x < upperBoundX; x += stride) {
                Vec2 p = tempVec;
                p.x = x;
                p.y = y;
                if (shape.containsPoint(identity, p)) {
                    Transform.mulToOut(transform, p, p);
                    particleDef.position.x = p.x;
                    particleDef.position.y = p.y;
                    p.subLocal(groupDef.getPosition());
                    Vec2.crossToOutUnsafe(groupDef.getAngularVelocity(), p, particleDef.velocity);
                    particleDef.velocity.addLocal(groupDef.getLinearVelocity());
                    createParticle(particleDef);
                }
            }
        }
    }
    int lastIndex = m_count;
    ParticleGroup group = new ParticleGroup();
    group.m_system = this;
    group.m_firstIndex = firstIndex;
    group.m_lastIndex = lastIndex;
    group.m_groupFlags = groupDef.getGroupFlags();
    group.m_strength = groupDef.getStrength();
    group.m_userData = groupDef.getUserData();
    group.m_transform.set(transform);
    group.m_destroyAutomatically = groupDef.isDestroyAutomatically();
    group.m_prev = null;
    group.m_next = m_groupList;
    if (m_groupList != null) {
        m_groupList.m_prev = group;
    }
    m_groupList = group;
    ++m_groupCount;
    for (int i = firstIndex; i < lastIndex; i++) {
        m_groupBuffer[i] = group;
    }
    updateContacts(true);
    if ((groupDef.getTypeFlags() & k_pairFlags) != 0) {
        for (int k = 0; k < m_contactCount; k++) {
            ParticleContact contact = m_contactBuffer[k];
            int a = contact.indexA;
            int b = contact.indexB;
            if (a > b) {
                int temp = a;
                a = b;
                b = temp;
            }
            if (firstIndex <= a && b < lastIndex) {
                if (m_pairCount >= m_pairCapacity) {
                    int oldCapacity = m_pairCapacity;
                    int newCapacity = m_pairCount != 0 ? 2 * m_pairCount : JBoxSettings.minParticleBufferCapacity;
                    m_pairBuffer = reallocateBuffer(Pair.class, m_pairBuffer, oldCapacity, newCapacity);
                    m_pairCapacity = newCapacity;
                }
                Pair pair = m_pairBuffer[m_pairCount];
                pair.indexA = a;
                pair.indexB = b;
                pair.flags = contact.flags;
                pair.strength = groupDef.getStrength();
                pair.distance = m_positionBuffer.data[a].distanceF(m_positionBuffer.data[b]);
                m_pairCount++;
            }
        }
    }
    if ((groupDef.getTypeFlags() & k_triadFlags) != 0) {
        VoronoiDiagram diagram = new VoronoiDiagram(lastIndex - firstIndex);
        for (int i = firstIndex; i < lastIndex; i++) {
            diagram.addGenerator(m_positionBuffer.data[i], i);
        }
        diagram.generate(stride / 2);
        createParticleGroupCallback.system = this;
        createParticleGroupCallback.def = groupDef;
        createParticleGroupCallback.firstIndex = firstIndex;
        diagram.getNodes(createParticleGroupCallback);
    }
    if ((groupDef.getGroupFlags() & ParticleGroupType.b2_solidParticleGroup) != 0) {
        computeDepthForGroup(group);
    }
    return group;
}
Also used : Shape(com.almasb.fxgl.physics.box2d.collision.shapes.Shape) Vec2(com.almasb.fxgl.core.math.Vec2) Transform(com.almasb.fxgl.physics.box2d.common.Transform) AABB(com.almasb.fxgl.physics.box2d.collision.AABB)

Example 4 with Shape

use of com.almasb.fxgl.physics.box2d.collision.shapes.Shape in project FXGL by AlmasB.

the class ContactSolver method init.

public void init(ContactSolverDef def) {
    TimeStep step = def.step;
    m_count = def.count;
    if (m_positionConstraints.length < m_count) {
        ContactPositionConstraint[] old = m_positionConstraints;
        m_positionConstraints = new ContactPositionConstraint[Math.max(old.length * 2, m_count)];
        System.arraycopy(old, 0, m_positionConstraints, 0, old.length);
        for (int i = old.length; i < m_positionConstraints.length; i++) {
            m_positionConstraints[i] = new ContactPositionConstraint();
        }
    }
    if (m_velocityConstraints.length < m_count) {
        ContactVelocityConstraint[] old = m_velocityConstraints;
        m_velocityConstraints = new ContactVelocityConstraint[Math.max(old.length * 2, m_count)];
        System.arraycopy(old, 0, m_velocityConstraints, 0, old.length);
        for (int i = old.length; i < m_velocityConstraints.length; i++) {
            m_velocityConstraints[i] = new ContactVelocityConstraint();
        }
    }
    m_positions = def.positions;
    m_velocities = def.velocities;
    m_contacts = def.contacts;
    for (int i = 0; i < m_count; ++i) {
        final Contact contact = m_contacts[i];
        final Fixture fixtureA = contact.m_fixtureA;
        final Fixture fixtureB = contact.m_fixtureB;
        final Shape shapeA = fixtureA.getShape();
        final Shape shapeB = fixtureB.getShape();
        final float radiusA = shapeA.getRadius();
        final float radiusB = shapeB.getRadius();
        final Body bodyA = fixtureA.getBody();
        final Body bodyB = fixtureB.getBody();
        final Manifold manifold = contact.getManifold();
        int pointCount = manifold.pointCount;
        assert pointCount > 0;
        ContactVelocityConstraint vc = m_velocityConstraints[i];
        vc.friction = contact.getFriction();
        vc.restitution = contact.getRestitution();
        vc.tangentSpeed = contact.getTangentSpeed();
        vc.indexA = bodyA.m_islandIndex;
        vc.indexB = bodyB.m_islandIndex;
        vc.invMassA = bodyA.m_invMass;
        vc.invMassB = bodyB.m_invMass;
        vc.invIA = bodyA.m_invI;
        vc.invIB = bodyB.m_invI;
        vc.contactIndex = i;
        vc.pointCount = pointCount;
        vc.K.setZero();
        vc.normalMass.setZero();
        ContactPositionConstraint pc = m_positionConstraints[i];
        pc.indexA = bodyA.m_islandIndex;
        pc.indexB = bodyB.m_islandIndex;
        pc.invMassA = bodyA.m_invMass;
        pc.invMassB = bodyB.m_invMass;
        pc.localCenterA.set(bodyA.m_sweep.localCenter);
        pc.localCenterB.set(bodyB.m_sweep.localCenter);
        pc.invIA = bodyA.m_invI;
        pc.invIB = bodyB.m_invI;
        pc.localNormal.set(manifold.localNormal);
        pc.localPoint.set(manifold.localPoint);
        pc.pointCount = pointCount;
        pc.radiusA = radiusA;
        pc.radiusB = radiusB;
        pc.type = manifold.type;
        for (int j = 0; j < pointCount; j++) {
            ManifoldPoint cp = manifold.points[j];
            VelocityConstraintPoint vcp = vc.points[j];
            if (step.warmStarting) {
                vcp.normalImpulse = step.dtRatio * cp.normalImpulse;
                vcp.tangentImpulse = step.dtRatio * cp.tangentImpulse;
            } else {
                vcp.normalImpulse = 0;
                vcp.tangentImpulse = 0;
            }
            vcp.rA.setZero();
            vcp.rB.setZero();
            vcp.normalMass = 0;
            vcp.tangentMass = 0;
            vcp.velocityBias = 0;
            pc.localPoints[j].x = cp.localPoint.x;
            pc.localPoints[j].y = cp.localPoint.y;
        }
    }
}
Also used : Shape(com.almasb.fxgl.physics.box2d.collision.shapes.Shape) ManifoldPoint(com.almasb.fxgl.physics.box2d.collision.ManifoldPoint) ManifoldPoint(com.almasb.fxgl.physics.box2d.collision.ManifoldPoint) VelocityConstraintPoint(com.almasb.fxgl.physics.box2d.dynamics.contacts.ContactVelocityConstraint.VelocityConstraintPoint) TimeStep(com.almasb.fxgl.physics.box2d.dynamics.TimeStep) WorldManifold(com.almasb.fxgl.physics.box2d.collision.WorldManifold) Manifold(com.almasb.fxgl.physics.box2d.collision.Manifold) VelocityConstraintPoint(com.almasb.fxgl.physics.box2d.dynamics.contacts.ContactVelocityConstraint.VelocityConstraintPoint) Fixture(com.almasb.fxgl.physics.box2d.dynamics.Fixture) Body(com.almasb.fxgl.physics.box2d.dynamics.Body)

Example 5 with Shape

use of com.almasb.fxgl.physics.box2d.collision.shapes.Shape in project FXGL by AlmasB.

the class PhysicsWorld method createSensors.

private void createSensors(Entity e) {
    PhysicsComponent physics = e.getComponent(PhysicsComponent.class);
    if (physics.getSensorHandlers().isEmpty())
        return;
    physics.getSensorHandlers().keySet().forEach(box -> {
        box.bindXY(e.getTransformComponent());
        Shape polygonShape = createShape(box, e);
        FixtureDef fd = new FixtureDef().sensor(true).shape(polygonShape);
        Fixture f = physics.body.createFixture(fd);
        f.setHitBox(box);
    });
}
Also used : Shape(com.almasb.fxgl.physics.box2d.collision.shapes.Shape)

Aggregations

Shape (com.almasb.fxgl.physics.box2d.collision.shapes.Shape)5 ManifoldPoint (com.almasb.fxgl.physics.box2d.collision.ManifoldPoint)2 Transform (com.almasb.fxgl.physics.box2d.common.Transform)2 Body (com.almasb.fxgl.physics.box2d.dynamics.Body)2 Vec2 (com.almasb.fxgl.core.math.Vec2)1 BoundingBoxComponent (com.almasb.fxgl.entity.components.BoundingBoxComponent)1 AABB (com.almasb.fxgl.physics.box2d.collision.AABB)1 ContactID (com.almasb.fxgl.physics.box2d.collision.ContactID)1 Manifold (com.almasb.fxgl.physics.box2d.collision.Manifold)1 WorldManifold (com.almasb.fxgl.physics.box2d.collision.WorldManifold)1 Fixture (com.almasb.fxgl.physics.box2d.dynamics.Fixture)1 TimeStep (com.almasb.fxgl.physics.box2d.dynamics.TimeStep)1 VelocityConstraintPoint (com.almasb.fxgl.physics.box2d.dynamics.contacts.ContactVelocityConstraint.VelocityConstraintPoint)1