Search in sources :

Example 56 with Vec2

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

the class PolygonShape method computeAABB.

@Override
public void computeAABB(AABB aabb, Transform xf, int childIndex) {
    final Vec2 lower = aabb.lowerBound;
    final Vec2 upper = aabb.upperBound;
    Vec2 v1 = m_vertices[0];
    lower.x = xf.mulX(v1);
    lower.y = xf.mulY(v1);
    upper.x = lower.x;
    upper.y = lower.y;
    for (int i = 1; i < vertexCount; ++i) {
        Vec2 v2 = m_vertices[i];
        float vx = xf.mulX(v2);
        float vy = xf.mulY(v2);
        lower.x = min(lower.x, vx);
        lower.y = min(lower.y, vy);
        upper.x = max(upper.x, vx);
        upper.y = max(upper.y, vy);
    }
    lower.x -= getRadius();
    lower.y -= getRadius();
    upper.x += getRadius();
    upper.y += getRadius();
}
Also used : Vec2(com.almasb.fxgl.core.math.Vec2)

Example 57 with Vec2

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

the class PolygonShape method raycast.

@Override
public boolean raycast(RayCastOutput output, RayCastInput input, Transform xf, int childIndex) {
    final float xfqc = xf.q.c;
    final float xfqs = xf.q.s;
    final Vec2 xfp = xf.p;
    float tempx, tempy;
    // b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p);
    // b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p);
    tempx = input.p1.x - xfp.x;
    tempy = input.p1.y - xfp.y;
    final float p1x = xfqc * tempx + xfqs * tempy;
    final float p1y = -xfqs * tempx + xfqc * tempy;
    tempx = input.p2.x - xfp.x;
    tempy = input.p2.y - xfp.y;
    final float p2x = xfqc * tempx + xfqs * tempy;
    final float p2y = -xfqs * tempx + xfqc * tempy;
    final float dx = p2x - p1x;
    final float dy = p2y - p1y;
    float lower = 0, upper = input.maxFraction;
    int index = -1;
    for (int i = 0; i < vertexCount; ++i) {
        Vec2 normal = m_normals[i];
        Vec2 vertex = m_vertices[i];
        // p = p1 + a * d
        // dot(normal, p - v) = 0
        // dot(normal, p1 - v) + a * dot(normal, d) = 0
        float tempxn = vertex.x - p1x;
        float tempyn = vertex.y - p1y;
        final float numerator = normal.x * tempxn + normal.y * tempyn;
        final float denominator = normal.x * dx + normal.y * dy;
        if (denominator == 0.0f) {
            if (numerator < 0.0f) {
                return false;
            }
        } else {
            // numerator.
            if (denominator < 0.0f && numerator < lower * denominator) {
                // Increase lower.
                // The segment enters this half-space.
                lower = numerator / denominator;
                index = i;
            } else if (denominator > 0.0f && numerator < upper * denominator) {
                // Decrease upper.
                // The segment exits this half-space.
                upper = numerator / denominator;
            }
        }
        if (upper < lower) {
            return false;
        }
    }
    assert 0.0f <= lower && lower <= input.maxFraction;
    if (index >= 0) {
        output.fraction = lower;
        // normal = Mul(xf.R, m_normals[index]);
        Vec2 normal = m_normals[index];
        Vec2 out = output.normal;
        out.x = xfqc * normal.x - xfqs * normal.y;
        out.y = xfqs * normal.x + xfqc * normal.y;
        return true;
    }
    return false;
}
Also used : Vec2(com.almasb.fxgl.core.math.Vec2)

Example 58 with Vec2

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

the class PolygonShape method computeDistanceToOut.

@Override
public float computeDistanceToOut(Transform xf, Vec2 p, int childIndex, Vec2 normalOut) {
    float xfqc = xf.q.c;
    float xfqs = xf.q.s;
    float tx = p.x - xf.p.x;
    float ty = p.y - xf.p.y;
    float pLocalx = xfqc * tx + xfqs * ty;
    float pLocaly = -xfqs * tx + xfqc * ty;
    float maxDistance = -Float.MAX_VALUE;
    float normalForMaxDistanceX = pLocalx;
    float normalForMaxDistanceY = pLocaly;
    for (int i = 0; i < vertexCount; ++i) {
        Vec2 vertex = m_vertices[i];
        Vec2 normal = m_normals[i];
        tx = pLocalx - vertex.x;
        ty = pLocaly - vertex.y;
        float dot = normal.x * tx + normal.y * ty;
        if (dot > maxDistance) {
            maxDistance = dot;
            normalForMaxDistanceX = normal.x;
            normalForMaxDistanceY = normal.y;
        }
    }
    float distance;
    if (maxDistance > 0) {
        float minDistanceX = normalForMaxDistanceX;
        float minDistanceY = normalForMaxDistanceY;
        float minDistance2 = maxDistance * maxDistance;
        for (int i = 0; i < vertexCount; ++i) {
            Vec2 vertex = m_vertices[i];
            float distanceVecX = pLocalx - vertex.x;
            float distanceVecY = pLocaly - vertex.y;
            float distance2 = distanceVecX * distanceVecX + distanceVecY * distanceVecY;
            if (minDistance2 > distance2) {
                minDistanceX = distanceVecX;
                minDistanceY = distanceVecY;
                minDistance2 = distance2;
            }
        }
        distance = FXGLMath.sqrtF(minDistance2);
        normalOut.x = xfqc * minDistanceX - xfqs * minDistanceY;
        normalOut.y = xfqs * minDistanceX + xfqc * minDistanceY;
        normalOut.getLengthAndNormalize();
    } else {
        distance = maxDistance;
        normalOut.x = xfqc * normalForMaxDistanceX - xfqs * normalForMaxDistanceY;
        normalOut.y = xfqs * normalForMaxDistanceX + xfqc * normalForMaxDistanceY;
    }
    return distance;
}
Also used : Vec2(com.almasb.fxgl.core.math.Vec2)

Example 59 with Vec2

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

the class PolygonShape method setImpl.

private void setImpl(final Vec2[] verts, final int num) {
    assert 3 <= num && num <= JBoxSettings.maxPolygonVertices;
    if (num < 3) {
        setAsBox(1.0f, 1.0f);
        return;
    }
    int n = Math.min(num, JBoxSettings.maxPolygonVertices);
    // Perform welding and copy vertices into local buffer.
    Vec2[] ps = new Vec2[JBoxSettings.maxPolygonVertices];
    int tempCount = 0;
    for (int i = 0; i < n; ++i) {
        Vec2 v = verts[i];
        boolean unique = true;
        for (int j = 0; j < tempCount; ++j) {
            if (v.distanceSquared(ps[j]) < 0.5f * JBoxSettings.linearSlop) {
                unique = false;
                break;
            }
        }
        if (unique) {
            ps[tempCount++] = v;
        }
    }
    n = tempCount;
    if (n < 3) {
        // Polygon is degenerate.
        assert false;
        setAsBox(1.0f, 1.0f);
        return;
    }
    // Create the convex hull using the Gift wrapping algorithm
    // http://en.wikipedia.org/wiki/Gift_wrapping_algorithm
    // Find the right most point on the hull
    int i0 = 0;
    float x0 = ps[0].x;
    for (int i = 1; i < n; ++i) {
        float x = ps[i].x;
        if (x > x0 || x == x0 && ps[i].y < ps[i0].y) {
            i0 = i;
            x0 = x;
        }
    }
    int[] hull = new int[JBoxSettings.maxPolygonVertices];
    int m = 0;
    int ih = i0;
    while (true) {
        hull[m] = ih;
        int ie = 0;
        for (int j = 1; j < n; ++j) {
            if (ie == ih) {
                ie = j;
                continue;
            }
            Vec2 r = pool1.set(ps[ie]).subLocal(ps[hull[m]]);
            Vec2 v = pool2.set(ps[j]).subLocal(ps[hull[m]]);
            float c = Vec2.cross(r, v);
            if (c < 0.0f) {
                ie = j;
            }
            // Collinearity check
            if (c == 0.0f && v.lengthSquared() > r.lengthSquared()) {
                ie = j;
            }
        }
        ++m;
        ih = ie;
        if (ie == i0) {
            break;
        }
    }
    this.vertexCount = m;
    // Copy vertices.
    for (int i = 0; i < vertexCount; ++i) {
        if (m_vertices[i] == null) {
            m_vertices[i] = new Vec2();
        }
        m_vertices[i].set(ps[hull[i]]);
    }
    final Vec2 edge = pool1;
    // Compute normals. Ensure the edges have non-zero length.
    for (int i = 0; i < vertexCount; ++i) {
        final int i1 = i;
        final int i2 = i + 1 < vertexCount ? i + 1 : 0;
        edge.set(m_vertices[i2]).subLocal(m_vertices[i1]);
        assert edge.lengthSquared() > JBoxSettings.EPSILON * JBoxSettings.EPSILON;
        Vec2.crossToOutUnsafe(edge, 1f, m_normals[i]);
        m_normals[i].getLengthAndNormalize();
    }
    // Compute the polygon centroid.
    computeCentroid(m_vertices, vertexCount);
}
Also used : Vec2(com.almasb.fxgl.core.math.Vec2)

Example 60 with Vec2

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

the class PolygonShape method computeMass.

@Override
public void computeMass(final MassData massData, float density) {
    assert vertexCount >= 3;
    final Vec2 center = pool1;
    center.setZero();
    float area = 0.0f;
    float I = 0.0f;
    // pRef is the reference point for forming triangles.
    // It's location doesn't change the result (except for rounding error).
    final Vec2 s = pool2;
    s.setZero();
    // This code would put the reference point inside the polygon.
    for (int i = 0; i < vertexCount; ++i) {
        s.addLocal(m_vertices[i]);
    }
    s.mulLocal(1.0f / vertexCount);
    final Vec2 e1 = pool3;
    final Vec2 e2 = pool4;
    for (int i = 0; i < vertexCount; ++i) {
        // Triangle vertices.
        e1.set(m_vertices[i]).subLocal(s);
        e2.set(s).negateLocal().addLocal(i + 1 < vertexCount ? m_vertices[i + 1] : m_vertices[0]);
        final float D = Vec2.cross(e1, e2);
        final float triangleArea = 0.5f * D;
        area += triangleArea;
        // Area weighted centroid
        center.x += triangleArea * INV_3 * (e1.x + e2.x);
        center.y += triangleArea * INV_3 * (e1.y + e2.y);
        final float ex1 = e1.x;
        final float ey1 = e1.y;
        final float ex2 = e2.x;
        final float ey2 = e2.y;
        float intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;
        float inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;
        I += (0.25f * INV_3 * D) * (intx2 + inty2);
    }
    // Total mass
    massData.mass = density * area;
    // Center of mass
    assert area > JBoxSettings.EPSILON;
    center.mulLocal(1.0f / area);
    massData.center.set(center).addLocal(s);
    // Inertia tensor relative to the local origin (point s)
    massData.I = I * density;
    // Shift to center of mass then to original body origin.
    massData.I += massData.mass * (Vec2.dot(massData.center, massData.center));
}
Also used : Vec2(com.almasb.fxgl.core.math.Vec2)

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