I am experimenting with LWJGL2 and I want to be able to tell if the camera is able to see a certain point in 3D space. I was trying on my own to see if I could do it, and ended up with something that kinda works and only for rotation on the Y axis.
This code works, but not in both axes. I am not sure if this is the correct way to do it either.
public boolean isInFrame(float x, float y, float z){ //The z isn't used
float camera = rotation.y; //The cameras y rotation
double object = Math.atan2(y, x)*(180/Math.PI);
object += (180 - camera);
if (object <0 ) object += 360;
if (object >360 ) object -= 360;
return 270>object&&90<object; //set to 180˚ for test
}
For the code, I am assuming the camera is centered around 0,0,0.
I just want to know how I could change this so that it works for x and y rotation of the camera. For example, it could tell me if if a point is visible regardless of the cameras rotation.
NOTE: I am not worrying about anything obstructing the view of the point.
Thanks for the help in advance.
If you have the view and projection matrices of the camera (let's call them V
, P
), you can just apply the transformations to your point and check whether the result lies within the clip volume of the camera.
Say your point is at (x, y, z)
. Construct a vector p = (x, y, z, 1)
and apply the camera transform to it:
q = P * V * p
The view transform V
applies the transformation of the world relative to the camera, based on the camera position and orientation. Then, the projection P
deforms the camera's view frustum (i.e., the visible space of the camera) into a unit cube, like this:
(Image source: Song Ho Ahn)
In order to read off the coordinate values of the resulting point, we must first de-homogenize it by dividing by its w
component:
r = q / q.w
Now, the components r.x
, r.y
, r.z
tell you whether the point lies within the visible range of the camera:
r.x < -1
, the point lies beyond the left border of the screen.r.x > 1
, the point lies beyond the right border of the screen.r.y < -1
, the point lies beyond the bottom border of the screen.r.y > 1
, the point lies beyond the top border of the screen.r.z < -1
, the point lies beyond the near plane of the camera, i.e., the point is behind the camera or too close for the camera to see.r.z > 1
, the point lies beyond the far plane of the camera, i.e., the point is too far away for the camera to see.