Casting a Ray from the camera's location to the centre of a Spatial

Hi. I’ve been using ray casting from the camera’s location using the camera’s direction. But how can’t seem to be able to figure out how to cast a ray from the Camera’s location to the centre of a spatial… Any help?

Vector3f direction = Spatial location - cam location
should do the trick

@netsky08 said: Vector3f direction = Spatial location - cam location should do the trick

And direction.normalizeLocal()

Thanks that seems to do the trick. I’m trying to detect if any object gets in the way and that does not seem to work… I’m trying to detect “on screen objects”. These are objects directly visible to the camera. If they are behind a wall, they should be marked as not visible.

This is what I have so far (all the objects that are o interest carry CustomData as user data:

[java]
private boolean isOnScreen(Spatial spatial) {
if (spatial == null) {
return false;
}

    BoundingVolume bv = spatial.getWorldBound();
    int planeState = cam.getPlaneState();
    cam.setPlaneState(0);
    Camera.FrustumIntersect result = cam.contains(bv);
    cam.setPlaneState(planeState);
    if (result == Camera.FrustumIntersect.Inside || result == Camera.FrustumIntersect.Intersects) {

        final Vector3f direction = spatial.getWorldTranslation().subtract(cam.getLocation()).normalizeLocal();
        final Ray ray = new Ray(cam.getLocation(), direction);

        final CollisionResults collisionResults = new CollisionResults();
        spatial.collideWith(ray, collisionResults);

        final CollisionResult closestResult = collisionResults.getClosestCollision();
        if (closestResult != null) {
            Spatial closestGeometry = closestResult.getGeometry();

            while (closestGeometry != null && !closestGeometry.getUserDataKeys().contains(CustomData.TAG)) {
                closestGeometry = closestGeometry.getParent();
            }

            if (closestGeometry != null) {
                final CustomData data = closestGeometry.getUserData(CustomData.TAG);
                return data != null && closestGeometry.equals(spatial);
            }
        }

        return false;
    }

    return false;
}

[/java]

This is my favorite phrase: “does not seem to work”

…without an actual meaning I love to insert my own. It’s hilarious… not helpful, but hilarious.

You might want to explain which of the million possible meanings it is this time. It detects objects that are visible when they shouldn’t be? Never detects object? Detects all objects always? Detects objects as hidden when they aren’t?

The “isOnScreen” method should detect if an object is visible to the camera and if it is not occluded by other objects in the way. I am trying to do this by casting a ray and if anything is in the way, the object is considered to be occluded. For my purpose, this simplification works.

So, in the method above, occluded objects are still being detected as visible. For instance, if my character is facing a wall, the object behind it is still detected.

Could it be I’m not casting the ray right?

If your ray is not hitting the wall right in front of your face then, yes, you are casting the ray incorrectly. It doesn’t matter what it’s detecting after that… if it misses the wall that is covering the whole screen then you’ve done something wrong.

It was more of a redundant question, but actually stressing on the obvious fact that something might be wrong, got me realise that I was doing collision check against the object I was testing… intersection that will never detect other objects, whatsoever :slight_smile:
So instead of [java]spatial.collideWith(ray, collisionResults);[/java] it should be [java]rootNode.collideWith(ray, collisionResults);[/java]

Thanks a lot for the help! For future reference, here’s the working method:
[java]
/**
* Checks if an object is visible to the camera and not occluded by any other objects!
* The object of interest has to be carrying CustomData to be correctly identified.
*/
private boolean isOnScreen(Spatial spatial) {
if (spatial == null) {
return false;
}

    BoundingVolume bv = spatial.getWorldBound();
    int planeState = cam.getPlaneState();
    cam.setPlaneState(0);
    Camera.FrustumIntersect result = cam.contains(bv);
    cam.setPlaneState(planeState);
    if (result == Camera.FrustumIntersect.Inside || result == Camera.FrustumIntersect.Intersects) {

        /* cast a ray from towards the object's direction */
        final Vector3f direction = spatial.getWorldTranslation().subtract(cam.getLocation());
        final Ray ray = new Ray(cam.getLocation(), direction);

        final CollisionResults collisionResults = new CollisionResults();
        environment.collideWith(ray, collisionResults);

        final CollisionResult closestResult = collisionResults.getClosestCollision();
        if (closestResult != null) {
            Spatial closestGeometry = closestResult.getGeometry();

            while (closestGeometry != null && !closestGeometry.getUserDataKeys().contains(CustomData.TAG)) {
                closestGeometry = closestGeometry.getParent();
            }

            if (closestGeometry != null) {
                final CustomData data = closestGeometry.getUserData(EgocentricContextData.TAG);
                return data != null && closestGeometry.equals(spatial);
            }
        }

        return false;
    }

    return false;
}

[/java]

Cheers!