# Determine elements currently visible to the camera

I’ve been trying to figure this out in different topics. I’m starting a separate thread hoping for a clear response.

I want to know, any moment in time, the set of entities that are currently visible to the camera.

To achieve this I’ve been doing the following for each spatial under the root node:
[java]
final BoundingVolume worldBound = spatial.getWorldBound();
final Camera.FrustumIntersect intersection = camera.contains(worldBound);

``````    if (intersection != Camera.FrustumIntersect.Outside) {
/* the spatial is visible */
}
``````

[/java]

Unfortunately, this seems to return a lot of false positives… Meaning, it determines objects being visible to the camera even if the are “behind” the camera and totally not visible to the user.

Any solutions to this problem? I’ve seen a few topics on this matter but with no end results really

Casting rays as discussed in the other topic is the only easy solution.

ok. So I presume for a higher accuracy I’d have to cast a larger number of rays from various points of the camera. Is there a way to cast multiple rays simultaneously?

No. You could also use some of the physics collision methods suggested. Then you could maybe at least get mesh to plane collisions.

I managed to work out some sort of an algorithm, but it’s not that accurate. Maybe you have some useful observations:

[java]
private boolean intersects(final Spatial spatial, final float xOffset, final float yOffset) {

``````    final Vector3f point = camera.getLocation().clone();
final Vector3f direction = camera.getDirection().clone();

point.setX(point.getX() + xOffset);
point.setY(point.getY() + yOffset);

res.clear();

final Ray ray = new Ray();
ray.setOrigin(point);
ray.setDirection(direction);

spatial.collideWith(ray, res);

return res.size() &gt; 0;
}

private boolean isOnScreen(final Spatial element) {

for (int x = 0; x &lt; camera.getWidth() / 2; x = x + 1) {

for (int y = 0; y &lt; camera.getHeight() / 2; y = y + 1) {

if (intersects(element, x, 0)) {
return true;
}

if (intersects(element, -x, 0)) {
return true;
}

if (intersects(element, 0, y)) {
return true;
}

if (intersects(element, 0, -y)) {
return true;
}
}
}

return false;
}
``````

[/java]

The isOnScree method should determine whether an item is visible or not.

I’ve managed to finally work this out in another thread casting-a-ray-from-the-cameras-location-to-the-centre-of-a-spatial

[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 &amp;&amp; !closestGeometry.getUserDataKeys().contains(CustomData.TAG)) {
closestGeometry = closestGeometry.getParent();
}

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

return false;
}

return false;
}
``````

[/java]

Cheers!

Is there some kind of university project with this ton of threads lately trying to get pixel accurate visibility information?
Some kind of assignment maybe?
Or are you the same person that asked this question already (multiple times?)?