Search in sources :

Example 1 with Sphere

use of com.jme3.scene.shape.Sphere in project jmonkeyengine by jMonkeyEngine.

the class BoundingSphere method collideWithRay.

private int collideWithRay(Ray ray) {
    TempVars vars = TempVars.get();
    Vector3f diff = vars.vect1.set(ray.getOrigin()).subtractLocal(center);
    float a = diff.dot(diff) - (getRadius() * getRadius());
    float a1, discr;
    if (a <= 0.0) {
        // inside sphere
        vars.release();
        return 1;
    }
    a1 = ray.direction.dot(diff);
    vars.release();
    if (a1 >= 0.0) {
        return 0;
    }
    discr = a1 * a1 - a;
    if (discr < 0.0) {
        return 0;
    } else if (discr >= FastMath.ZERO_TOLERANCE) {
        return 2;
    }
    return 1;
}
Also used : TempVars(com.jme3.util.TempVars)

Example 2 with Sphere

use of com.jme3.scene.shape.Sphere in project jmonkeyengine by jMonkeyEngine.

the class BoundingSphere method collideWithRay.

/*
     * (non-Javadoc)
     *
     * @see com.jme.bounding.BoundingVolume#intersectsWhere(com.jme.math.Ray)
     */
private int collideWithRay(Ray ray, CollisionResults results) {
    TempVars vars = TempVars.get();
    Vector3f diff = vars.vect1.set(ray.getOrigin()).subtractLocal(center);
    float a = diff.dot(diff) - (getRadius() * getRadius());
    float a1, discr, root;
    if (a <= 0.0) {
        // inside sphere
        a1 = ray.direction.dot(diff);
        discr = (a1 * a1) - a;
        root = FastMath.sqrt(discr);
        float distance = root - a1;
        Vector3f point = new Vector3f(ray.direction).multLocal(distance).addLocal(ray.origin);
        CollisionResult result = new CollisionResult(point, distance);
        results.addCollision(result);
        vars.release();
        return 1;
    }
    a1 = ray.direction.dot(diff);
    vars.release();
    if (a1 >= 0.0) {
        return 0;
    }
    discr = a1 * a1 - a;
    if (discr < 0.0) {
        return 0;
    } else if (discr >= FastMath.ZERO_TOLERANCE) {
        root = FastMath.sqrt(discr);
        float dist = -a1 - root;
        Vector3f point = new Vector3f(ray.direction).multLocal(dist).addLocal(ray.origin);
        results.addCollision(new CollisionResult(point, dist));
        dist = -a1 + root;
        point = new Vector3f(ray.direction).multLocal(dist).addLocal(ray.origin);
        results.addCollision(new CollisionResult(point, dist));
        return 2;
    } else {
        float dist = -a1;
        Vector3f point = new Vector3f(ray.direction).multLocal(dist).addLocal(ray.origin);
        results.addCollision(new CollisionResult(point, dist));
        return 1;
    }
}
Also used : CollisionResult(com.jme3.collision.CollisionResult) TempVars(com.jme3.util.TempVars)

Example 3 with Sphere

use of com.jme3.scene.shape.Sphere in project jmonkeyengine by jMonkeyEngine.

the class BoundingSphere method collideWithTri.

private int collideWithTri(Triangle tri, CollisionResults results) {
    TempVars tvars = TempVars.get();
    try {
        // Much of this is based on adaptation from this algorithm:
        // http://realtimecollisiondetection.net/blog/?p=103
        // ...mostly the stuff about eliminating sqrts wherever
        // possible.
        // Math is done in center-relative space.
        Vector3f a = tri.get1().subtract(center, tvars.vect1);
        Vector3f b = tri.get2().subtract(center, tvars.vect2);
        Vector3f c = tri.get3().subtract(center, tvars.vect3);
        Vector3f ab = b.subtract(a, tvars.vect4);
        Vector3f ac = c.subtract(a, tvars.vect5);
        // Check the plane... if it doesn't intersect the plane
        // then it doesn't intersect the triangle.
        Vector3f n = ab.cross(ac, tvars.vect6);
        float d = a.dot(n);
        float e = n.dot(n);
        if (d * d > radius * radius * e) {
            // Can't possibly intersect
            return 0;
        }
        // We intersect the verts, or the edges, or the face...
        // First check against the face since it's the most
        // specific.
        // Calculate the barycentric coordinates of the
        // sphere center
        Vector3f v0 = ac;
        Vector3f v1 = ab;
        // a was P relative, so p.subtract(a) is just -a
        // instead of wasting a vector we'll just negate the
        // dot products below... it's all v2 is used for.
        Vector3f v2 = a;
        float dot00 = v0.dot(v0);
        float dot01 = v0.dot(v1);
        float dot02 = -v0.dot(v2);
        float dot11 = v1.dot(v1);
        float dot12 = -v1.dot(v2);
        float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
        float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
        float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
        if (u >= 0 && v >= 0 && (u + v) <= 1) {
            // We intersect... and we even know where
            Vector3f part1 = ac;
            Vector3f part2 = ab;
            Vector3f p = center.add(a.add(part1.mult(u)).addLocal(part2.mult(v)));
            CollisionResult r = new CollisionResult();
            Vector3f normal = n.normalize();
            // a is center relative, so -a points to center
            float dist = -normal.dot(a);
            dist = dist - radius;
            r.setDistance(dist);
            r.setContactNormal(normal);
            r.setContactPoint(p);
            results.addCollision(r);
            return 1;
        }
        // Check the edges looking for the nearest point
        // that is also less than the radius.  We don't care
        // about points that are farther away than that.
        Vector3f nearestPt = null;
        float nearestDist = radius * radius;
        Vector3f base;
        Vector3f edge;
        float t;
        // Edge AB
        base = a;
        edge = ab;
        t = -edge.dot(base) / edge.dot(edge);
        if (t >= 0 && t <= 1) {
            Vector3f Q = base.add(edge.mult(t, tvars.vect7), tvars.vect8);
            // distance squared to origin
            float distSq = Q.dot(Q);
            if (distSq < nearestDist) {
                nearestPt = Q;
                nearestDist = distSq;
            }
        }
        // Edge AC
        base = a;
        edge = ac;
        t = -edge.dot(base) / edge.dot(edge);
        if (t >= 0 && t <= 1) {
            Vector3f Q = base.add(edge.mult(t, tvars.vect7), tvars.vect9);
            // distance squared to origin
            float distSq = Q.dot(Q);
            if (distSq < nearestDist) {
                nearestPt = Q;
                nearestDist = distSq;
            }
        }
        // Edge BC
        base = b;
        Vector3f bc = c.subtract(b);
        edge = bc;
        t = -edge.dot(base) / edge.dot(edge);
        if (t >= 0 && t <= 1) {
            Vector3f Q = base.add(edge.mult(t, tvars.vect7), tvars.vect10);
            // distance squared to origin
            float distSq = Q.dot(Q);
            if (distSq < nearestDist) {
                nearestPt = Q;
                nearestDist = distSq;
            }
        }
        // done.       
        if (nearestPt != null) {
            // We have a hit
            float dist = FastMath.sqrt(nearestDist);
            Vector3f cn = nearestPt.divide(-dist);
            CollisionResult r = new CollisionResult();
            r.setDistance(dist - radius);
            r.setContactNormal(cn);
            r.setContactPoint(nearestPt.add(center));
            results.addCollision(r);
            return 1;
        }
        // Finally check each of the triangle corners
        // Vert A
        base = a;
        // distance squared to origin
        t = base.dot(base);
        if (t < nearestDist) {
            nearestDist = t;
            nearestPt = base;
        }
        // Vert B
        base = b;
        // distance squared to origin
        t = base.dot(base);
        if (t < nearestDist) {
            nearestDist = t;
            nearestPt = base;
        }
        // Vert C
        base = c;
        // distance squared to origin
        t = base.dot(base);
        if (t < nearestDist) {
            nearestDist = t;
            nearestPt = base;
        }
        if (nearestPt != null) {
            // We have a hit
            float dist = FastMath.sqrt(nearestDist);
            Vector3f cn = nearestPt.divide(-dist);
            CollisionResult r = new CollisionResult();
            r.setDistance(dist - radius);
            r.setContactNormal(cn);
            r.setContactPoint(nearestPt.add(center));
            results.addCollision(r);
            return 1;
        }
        // Nothing hit... oh, well 
        return 0;
    } finally {
        tvars.release();
    }
}
Also used : CollisionResult(com.jme3.collision.CollisionResult) TempVars(com.jme3.util.TempVars)

Example 4 with Sphere

use of com.jme3.scene.shape.Sphere in project jmonkeyengine by jMonkeyEngine.

the class BoundingCollisionTest method testBoxSphereCollision.

@Test
public void testBoxSphereCollision() {
    BoundingBox box1 = new BoundingBox(Vector3f.ZERO, 1, 1, 1);
    BoundingSphere sphere2 = new BoundingSphere(1, Vector3f.ZERO);
    checkCollision(box1, sphere2, 1);
    // Put it at the very edge - for sphere vs. box, it will not intersect
    sphere2.setCenter(new Vector3f(2f, 0f, 0f));
    checkCollision(box1, sphere2, 0);
    // Put it a wee bit closer - should intersect.
    sphere2.setCenter(new Vector3f(2f - FastMath.ZERO_TOLERANCE, 0, 0));
    checkCollision(box1, sphere2, 1);
    // Test if the algorithm converts the sphere 
    // to a box before testing the collision (incorrect)
    float sqrt3 = FastMath.sqrt(3);
    sphere2.setCenter(Vector3f.UNIT_XYZ.mult(2));
    sphere2.setRadius(sqrt3);
    checkCollision(box1, sphere2, 0);
    // Make it a wee bit larger.
    sphere2.setRadius(sqrt3 + FastMath.ZERO_TOLERANCE);
    checkCollision(box1, sphere2, 1);
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) BoundingBox(com.jme3.bounding.BoundingBox) Vector3f(com.jme3.math.Vector3f) Test(org.junit.Test)

Example 5 with Sphere

use of com.jme3.scene.shape.Sphere in project jmonkeyengine by jMonkeyEngine.

the class LightFilterTest method testSpotFiltering.

@Test
public void testSpotFiltering() {
    SpotLight sl = new SpotLight(Vector3f.ZERO, Vector3f.UNIT_Z);
    sl.setSpotRange(0);
    geom.addLight(sl);
    // Infinite spot lights are only filtered
    checkFilteredLights(1);
    // if the geometry is outside the infinite cone.
    TempVars vars = TempVars.get();
    try {
        // The spot is not touching the near plane of the camera yet, 
        // should still be culled.
        sl.setSpotRange(1f - FastMath.ZERO_TOLERANCE);
        assert !sl.intersectsFrustum(cam, vars);
        // should be culled from the geometry's PoV
        checkFilteredLights(0);
        // Now it touches the near plane.
        sl.setSpotRange(1f);
        // still culled from the geometry's PoV
        checkFilteredLights(0);
        assert sl.intersectsFrustum(cam, vars);
    } finally {
        vars.release();
    }
    // make it barely reach the geometry
    sl.setSpotRange(9f);
    checkFilteredLights(0);
    // make it reach the geometry (touching its bound)
    sl.setSpotRange(9f + FastMath.ZERO_TOLERANCE);
    checkFilteredLights(1);
    // rotate the cone a bit so it no longer faces the geom
    sl.setDirection(new Vector3f(0.316f, 0, 0.948f).normalizeLocal());
    checkFilteredLights(0);
    // extent the range much farther
    sl.setSpotRange(20);
    checkFilteredLights(0);
    // Create box of size X=10 (double the extent)
    // now, the spot will touch the box.
    geom.setMesh(new Box(5, 1, 1));
    checkFilteredLights(1);
    // ==================================
    // Tests for bounding sphere, with a radius of 1f (in the box geom)
    sl.setPosition(Vector3f.ZERO);
    sl.setDirection(Vector3f.UNIT_Z);
    geom.setLocalTranslation(Vector3f.ZERO);
    geom.setModelBound(new BoundingSphere(1f, Vector3f.ZERO));
    // Infinit spot lights are only filtered
    // if the geometry is outside the infinite cone.
    sl.setSpotRange(0);
    checkFilteredLights(1);
    //the geommetry is outside the infinit cone (cone direction going away from the geom)
    sl.setPosition(Vector3f.UNIT_Z.mult(1 + FastMath.ZERO_TOLERANCE));
    checkFilteredLights(0);
    //place the spote ligth in the corner of the box geom, (in order to test bounding sphere)
    sl.setDirection(new Vector3f(1, 1, 0).normalizeLocal());
    geom.setLocalTranslation(0, 0, 10);
    sl.setPosition(sl.getDirection().mult(-2f).add(geom.getLocalTranslation()));
    // make it barely reach the sphere, incorect with a box
    sl.setSpotRange(1f - FastMath.ZERO_TOLERANCE);
    checkFilteredLights(0);
    // make it reach the sphere
    sl.setSpotRange(1f + FastMath.ZERO_TOLERANCE);
    checkFilteredLights(1);
    // extent the range
    sl.setPosition(Vector3f.ZERO);
    sl.setDirection(Vector3f.UNIT_Z);
    sl.setSpotRange(20);
    checkFilteredLights(1);
    // rotate the cone a bit so it no longer faces the geom
    sl.setDirection(new Vector3f(0, 0.3f, 0.7f).normalizeLocal());
    checkFilteredLights(0);
    // Create sphere of size X=10 (double the radius)
    // now, the spot will touch the sphere.
    geom.setModelBound(new BoundingSphere(5f, Vector3f.ZERO));
    checkFilteredLights(1);
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) Vector3f(com.jme3.math.Vector3f) Box(com.jme3.scene.shape.Box) TempVars(com.jme3.util.TempVars) Test(org.junit.Test)

Aggregations

Sphere (com.jme3.scene.shape.Sphere)63 Geometry (com.jme3.scene.Geometry)58 Vector3f (com.jme3.math.Vector3f)57 Material (com.jme3.material.Material)46 DirectionalLight (com.jme3.light.DirectionalLight)23 Box (com.jme3.scene.shape.Box)22 RigidBodyControl (com.jme3.bullet.control.RigidBodyControl)17 Node (com.jme3.scene.Node)17 PointLight (com.jme3.light.PointLight)15 BulletAppState (com.jme3.bullet.BulletAppState)13 SphereCollisionShape (com.jme3.bullet.collision.shapes.SphereCollisionShape)13 BoundingSphere (com.jme3.bounding.BoundingSphere)12 AmbientLight (com.jme3.light.AmbientLight)12 Quaternion (com.jme3.math.Quaternion)11 ColorRGBA (com.jme3.math.ColorRGBA)10 Spatial (com.jme3.scene.Spatial)9 TempVars (com.jme3.util.TempVars)9 KeyTrigger (com.jme3.input.controls.KeyTrigger)8 Vector2f (com.jme3.math.Vector2f)8 MeshCollisionShape (com.jme3.bullet.collision.shapes.MeshCollisionShape)7