I was trying to do a calculation to test if a point in 3D space is in the view of a camera placed on specific Vector3 coordinates with specified horizontal and vertical FOV.
This is the bad example:
bool Camera::InView(const Vector3 &objpos)
{
const float angle_x = m_world_view.AngleX(objpos) + m_pitch;
const float angle_y = m_world_view.AngleY(objpos) + m_yaw;
if (!(angle_y >= -m_yaw - m_fov_h
&& angle_y <= -m_yaw + m_fov_h))
{
return false;
}
if (!(angle_x >= -m_pitch - m_fov_v
&& angle_x <= -m_pitch + m_fov_v))
{
return false;
}
return true;
}
(m_world_view and objpos is Vector3. AngleX and AngleY returns angle using std::atan()
)
Example:
inline float AngleX(const Vector3 &input) const
{
return -std::atan(((y - input.y) / ((z - input.z) + FLT_EPSILON)));
}
(I had a problem finding the best way to get the angles and dividing by zero is wrong ofcourse)
The problem is when the object is behind me, it renders too because it thinks that the point is in field of view.
If I set yaw or pitch angles it works fine but if I set the object's coordinates behind the camera, it renders too which is bad. I'm not sure if I have a problem in negative values so it is picking every object in FOV behind me and infront of me. But if the object is above, bellow, or next to me it works fine. Also I don't know how to calculate if the camera is rolled so it is not horizontal. (because screen is not a circle but a rectangle so it will render in corners only when at the limit of FOV)
I was searching for it but I wasn't always sure if the equations are the right ones.
Any ideas?
(This is the project visualization to make it more understandable. I still don't understand OpenGL so this is my primitive rendering method using printf()
to console output to play with 3D stuff.)
U should consider
std::atan2
instead ofstd::atan
. Atan2 takes a sign from arguments to determine a quadrant.So, for example your camera is at position (0,0,1) looking towards center of Coordinate system, where is also point1(0,0,0) and there is a point2(0,0,2) behind the camera. If you use basic atan, result will be 0 degrees for both, but if u use atan2, for point1 it choose first quadrant (result = 0d), and for point2 it will choose third quadrant (because that minus in 0/(-1)) (result = 180d).