Search in sources :

Example 96 with Vec2

use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.

the class ParticleSystem method solve.

public void solve(TimeStep step) {
    ++m_timestamp;
    if (m_count == 0) {
        return;
    }
    m_allParticleFlags = 0;
    for (int i = 0; i < m_count; i++) {
        m_allParticleFlags |= m_flagsBuffer.data[i];
    }
    if ((m_allParticleFlags & ParticleTypeInternal.b2_zombieParticle) != 0) {
        solveZombie();
    }
    if (m_count == 0) {
        return;
    }
    m_allGroupFlags = 0;
    for (ParticleGroup group = m_groupList; group != null; group = group.getNext()) {
        m_allGroupFlags |= group.m_groupFlags;
    }
    final float gravityx = step.dt * m_gravityScale * m_world.getGravity().x;
    final float gravityy = step.dt * m_gravityScale * m_world.getGravity().y;
    float criticalVelocytySquared = getCriticalVelocitySquared(step);
    for (int i = 0; i < m_count; i++) {
        Vec2 v = m_velocityBuffer.data[i];
        v.x += gravityx;
        v.y += gravityy;
        float v2 = v.x * v.x + v.y * v.y;
        if (v2 > criticalVelocytySquared) {
            float a = v2 == 0 ? Float.MAX_VALUE : FXGLMath.sqrtF(criticalVelocytySquared / v2);
            v.x *= a;
            v.y *= a;
        }
    }
    solveCollision(step);
    if ((m_allGroupFlags & ParticleGroupType.b2_rigidParticleGroup) != 0) {
        solveRigid(step);
    }
    if ((m_allParticleFlags & ParticleTypeInternal.b2_wallParticle) != 0) {
        solveWall(step);
    }
    for (int i = 0; i < m_count; i++) {
        Vec2 pos = m_positionBuffer.data[i];
        Vec2 vel = m_velocityBuffer.data[i];
        pos.x += step.dt * vel.x;
        pos.y += step.dt * vel.y;
    }
    updateBodyContacts();
    updateContacts(false);
    if ((m_allParticleFlags & ParticleTypeInternal.b2_viscousParticle) != 0) {
        solveViscous(step);
    }
    if ((m_allParticleFlags & ParticleTypeInternal.b2_powderParticle) != 0) {
        solvePowder(step);
    }
    if ((m_allParticleFlags & ParticleTypeInternal.b2_tensileParticle) != 0) {
        solveTensile(step);
    }
    if ((m_allParticleFlags & ParticleTypeInternal.b2_elasticParticle) != 0) {
        solveElastic(step);
    }
    if ((m_allParticleFlags & ParticleTypeInternal.b2_springParticle) != 0) {
        solveSpring(step);
    }
    if ((m_allGroupFlags & ParticleGroupType.b2_solidParticleGroup) != 0) {
        solveSolid(step);
    }
    if ((m_allParticleFlags & ParticleTypeInternal.b2_colorMixingParticle) != 0) {
        solveColorMixing(step);
    }
    solvePressure(step);
    solveDamping(step);
}
Also used : Vec2(com.almasb.fxgl.core.math.Vec2)

Example 97 with Vec2

use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.

the class ParticleSystem method solveRigid.

private void solveRigid(final TimeStep step) {
    for (ParticleGroup group = m_groupList; group != null; group = group.getNext()) {
        if ((group.m_groupFlags & ParticleGroupType.b2_rigidParticleGroup) != 0) {
            group.updateStatistics();
            Vec2 temp = tempVec;
            Vec2 cross = tempVec2;
            Rotation rotation = tempRotation;
            rotation.set(step.dt * group.m_angularVelocity);
            Rotation.mulToOutUnsafe(rotation, group.m_center, cross);
            temp.set(group.m_linearVelocity).mulLocal(step.dt).addLocal(group.m_center).subLocal(cross);
            tempXf.p.set(temp);
            tempXf.q.set(rotation);
            Transform.mulToOut(tempXf, group.m_transform, group.m_transform);
            final Transform velocityTransform = tempXf2;
            velocityTransform.p.x = step.inv_dt * tempXf.p.x;
            velocityTransform.p.y = step.inv_dt * tempXf.p.y;
            velocityTransform.q.s = step.inv_dt * tempXf.q.s;
            velocityTransform.q.c = step.inv_dt * (tempXf.q.c - 1);
            for (int i = group.m_firstIndex; i < group.m_lastIndex; i++) {
                Transform.mulToOutUnsafe(velocityTransform, m_positionBuffer.data[i], m_velocityBuffer.data[i]);
            }
        }
    }
}
Also used : Vec2(com.almasb.fxgl.core.math.Vec2) Transform(com.almasb.fxgl.physics.box2d.common.Transform) Rotation(com.almasb.fxgl.physics.box2d.common.Rotation)

Example 98 with Vec2

use of com.almasb.fxgl.core.math.Vec2 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 99 with Vec2

use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.

the class ParticleSystem method solveTensile.

private void solveTensile(final TimeStep step) {
    m_accumulation2Buffer = requestParticleBuffer(Vec2.class, m_accumulation2Buffer);
    for (int i = 0; i < m_count; i++) {
        m_accumulationBuffer[i] = 0;
        m_accumulation2Buffer[i].setZero();
    }
    for (int k = 0; k < m_contactCount; k++) {
        final ParticleContact contact = m_contactBuffer[k];
        if ((contact.flags & ParticleTypeInternal.b2_tensileParticle) != 0) {
            int a = contact.indexA;
            int b = contact.indexB;
            float w = contact.weight;
            Vec2 n = contact.normal;
            m_accumulationBuffer[a] += w;
            m_accumulationBuffer[b] += w;
            final Vec2 a2A = m_accumulation2Buffer[a];
            final Vec2 a2B = m_accumulation2Buffer[b];
            final float inter = (1 - w) * w;
            a2A.x -= inter * n.x;
            a2A.y -= inter * n.y;
            a2B.x += inter * n.x;
            a2B.y += inter * n.y;
        }
    }
    float strengthA = m_surfaceTensionStrengthA * getCriticalVelocity(step);
    float strengthB = m_surfaceTensionStrengthB * getCriticalVelocity(step);
    for (int k = 0; k < m_contactCount; k++) {
        final ParticleContact contact = m_contactBuffer[k];
        if ((contact.flags & ParticleTypeInternal.b2_tensileParticle) != 0) {
            int a = contact.indexA;
            int b = contact.indexB;
            float w = contact.weight;
            Vec2 n = contact.normal;
            final Vec2 a2A = m_accumulation2Buffer[a];
            final Vec2 a2B = m_accumulation2Buffer[b];
            float h = m_accumulationBuffer[a] + m_accumulationBuffer[b];
            final float sx = a2B.x - a2A.x;
            final float sy = a2B.y - a2A.y;
            float fn = (strengthA * (h - 2) + strengthB * (sx * n.x + sy * n.y)) * w;
            final float fx = fn * n.x;
            final float fy = fn * n.y;
            final Vec2 va = m_velocityBuffer.data[a];
            final Vec2 vb = m_velocityBuffer.data[b];
            va.x -= fx;
            va.y -= fy;
            vb.x += fx;
            vb.y += fy;
        }
    }
}
Also used : Vec2(com.almasb.fxgl.core.math.Vec2)

Example 100 with Vec2

use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.

the class ParticleSystem method solveCollision.

private void solveCollision(TimeStep step) {
    final AABB aabb = temp;
    final Vec2 lowerBound = aabb.lowerBound;
    final Vec2 upperBound = aabb.upperBound;
    lowerBound.x = Float.MAX_VALUE;
    lowerBound.y = Float.MAX_VALUE;
    upperBound.x = -Float.MAX_VALUE;
    upperBound.y = -Float.MAX_VALUE;
    for (int i = 0; i < m_count; i++) {
        final Vec2 v = m_velocityBuffer.data[i];
        final Vec2 p1 = m_positionBuffer.data[i];
        final float p1x = p1.x;
        final float p1y = p1.y;
        final float p2x = p1x + step.dt * v.x;
        final float p2y = p1y + step.dt * v.y;
        final float bx = p1x < p2x ? p1x : p2x;
        final float by = p1y < p2y ? p1y : p2y;
        lowerBound.x = lowerBound.x < bx ? lowerBound.x : bx;
        lowerBound.y = lowerBound.y < by ? lowerBound.y : by;
        final float b1x = p1x > p2x ? p1x : p2x;
        final float b1y = p1y > p2y ? p1y : p2y;
        upperBound.x = upperBound.x > b1x ? upperBound.x : b1x;
        upperBound.y = upperBound.y > b1y ? upperBound.y : b1y;
    }
    sccallback.step = step;
    sccallback.system = this;
    m_world.queryAABB(sccallback, aabb);
}
Also used : Vec2(com.almasb.fxgl.core.math.Vec2) AABB(com.almasb.fxgl.physics.box2d.collision.AABB)

Aggregations

Vec2 (com.almasb.fxgl.core.math.Vec2)138 Rotation (com.almasb.fxgl.physics.box2d.common.Rotation)36 Point2D (javafx.geometry.Point2D)7 Mat22 (com.almasb.fxgl.physics.box2d.common.Mat22)6 Body (com.almasb.fxgl.physics.box2d.dynamics.Body)6 Rectangle (javafx.scene.shape.Rectangle)6 GameApplication (com.almasb.fxgl.app.GameApplication)5 Vec3 (com.almasb.fxgl.core.math.Vec3)5 AABB (com.almasb.fxgl.physics.box2d.collision.AABB)5 ManifoldPoint (com.almasb.fxgl.physics.box2d.collision.ManifoldPoint)5 VelocityConstraintPoint (com.almasb.fxgl.physics.box2d.dynamics.contacts.ContactVelocityConstraint.VelocityConstraintPoint)5 Rectangle2D (javafx.geometry.Rectangle2D)5 Color (javafx.scene.paint.Color)5 Interpolators (com.almasb.fxgl.animation.Interpolators)4 GameSettings (com.almasb.fxgl.app.GameSettings)4 FXGL (com.almasb.fxgl.dsl.FXGL)4 ImagesKt (com.almasb.fxgl.texture.ImagesKt)4 Comparator (java.util.Comparator)4 List (java.util.List)4 Collectors (java.util.stream.Collectors)4