## [No]Inside FOV checking functions

Moderator: GZDoom Developers

### Inside FOV checking functions

I'm having a lot of difficulty creating a 'check if inside actor FOV' function, particularly with cameras. Specifically, I'm trying to see if the actor is actually capable of being on the screen (regardless of invisibility or not) -- meaning both angle and pitch being accounted for.
Here's what I propose:

bool, double, double ActorInFOV(Actor other, double fov = 90.0, double pitch = ???)
Returns if 'other' is inside the specified FOV or not, along with the angle offset like GetAngle if desired, along with the difference for pitch.

bool, double, double VectorInFOV(Vector3 point, double fov = 90.0, double pitch = ???)
Same as the actor variant but for vectors.

Major Cooke
d = klabs(wall[wall[wall[sector[dasect].wallptr].point2].point2].x-s->x)...

Joined: 28 Jan 2007

### Re: Inside FOV checking functions

Good luck finding someone who can cook up the proper math for it. In all those years I never managed to find out how I need to transform the pitch to get reliable results. That render glitch where there's holes on the screen's corners is a well-known problem.

Graf Zahl

Joined: 19 Jul 2003
Location: Germany

### Re: Inside FOV checking functions

Possibly of use for checks like this:
Code: Select all
`    double PitchTo(Actor mo)    {        double distxy = max(Distance2D(mo), 1);        double distz = pos.z - mo.pos.z;        return clamp(atan(distz / distxy) - pitch, -90, 90);    } `

This roughly returns the "firing" pitch in degrees from one actor to another (specifically the base of the actors)... In other words, the pitch between actors, taking into account the pitch of the originating actor. This doesn't take into account viewpoint or target height, so everything is calculated from the actor's feet, but that could be added...

I'm assuming my math's right... Seems to be, in use, but if someone knows otherwise, please let me know - my trig is very, very rusty.

Examples:
If the target actor is 40 units straight ahead and 23 units above the caller, and the calling actor has a pitch of 0 degrees, then the return value will be ~30 degrees.
If the target actor is straight ahead - 0 pitch - and the calling actor has a pitch of -15 degrees, then the return value will be -15 degrees.

I'm using this for vertical FOV checks... e.g., "if (abs(PitchTo(target)) <= fov) { /*It's in my vertical FOV*/ }"

Joined: 15 Jul 2003

### Re: Inside FOV checking functions

Double this.
Using thinkeriterator, jumpifinLOS and inventory mark not always lead to success check.

Apeirogon
I have a strange sense of humour

Joined: 12 Jun 2017

### Re: Inside FOV checking functions

I've submitted pull request #553 which, if merged, will do what you need. The PR description contains an example for determining how close an actor is to the player's crosshairs (that is, whether it's inside an imaginary cone projected from the player's eyes), and another for determining which nearby actor is closest to the crosshairs.
argv

Joined: 30 Aug 2016

### Re: Inside FOV checking functions

I think MC requested measuring fov in a rectangular measure. The delta angle checks measure more like an apple slice that stops at 90° and -90° pitch and don't take roll into account.

That's because the difference vector is measured in the world, not locally from your eyes.

Here is my solution. Pitch singularity and roll are accounted for. If you assume roll = 0, skip the rotation step and use q and r.

Code: Select all
`// Make forw, right, up an orthonormal basis off player's orientation:forw   = (  cos vang * cos ang,  cos vang * sin ang, sin vang )q      = ( -sin vang * cos ang, -sin vang * sin ang, cos vang )r      = (  sin ang, -cos ang, 0 )// This part is now easier thanks to argv's work.// q and r are non-rolled local up and right vectors. Rolling them is easy since they're orthonormal:up     =  cos roll * q + sin roll * rright  = -sin roll * q + cos roll * r// Checks:diff = target pos - view pos-ver fov < atan2(diff dot up,      diff dot forw) < ver fov ?-hor fov < atan2(diff dot right,   diff dot forw) < hor fov ?`

The dot products are the local coordinates in the standard space rotated to your view. It's practically a player model-view transformation, but without the pixel stretching.

KeksDose
Praise Mima and the Moon

Joined: 06 Jul 2007

### Re: Inside FOV checking functions

I'll wait for native implementation. I have a bunch of projectiles that need to use this and they spawn often.

This is for more than just players too.

Major Cooke
d = klabs(wall[wall[wall[sector[dasect].wallptr].point2].point2].x-s->x)...

Joined: 28 Jan 2007

### Re: Inside FOV checking functions

I wrote player but it works for anything. It's the maths all in all to describe the idea, not implement it. That's up to developers.

I'm very confident this is correct, but Graf's comment does make me wonder, since this kinda seems like a fairly natural idea to try. I could be wrong.

KeksDose
Praise Mima and the Moon

Joined: 06 Jul 2007

### Re: Inside FOV checking functions

KeksDose wrote:I think MC requested measuring fov in a rectangular measure.

If you know the horizontal and vertical fields of view already, then SphericalCoords (the PR I submitted, which has been merged) can do that, too. Just check the polar and azimuthal angles separately, instead of checking the vector length, and you'll be looking in a pyramid-shaped area instead of a conical one. Either way, the computational heavy lifting is all in C++ (deltaangle, VecToAngle, DVector3::Pitch, etc). See the wiki documentation.
argv

Joined: 30 Aug 2016

### Re: Inside FOV checking functions

You are unfortunately mistaken. It's what I mentioned about apple slices and the reason I wrote up the formulation above to begin with.

Do what you said, then fly under the actor so it appears somewhere above your crosshair, but not so far that you'd expect the angle difference to be too large to be picked up. In any case, it won't be picked up, because your view pyramid faces forwards. It also doesn't account for roll.

What should be stressed is that the request is a field of view check. The naive check people tend to think of encountering this issue is more like a location test in the view sphere domain.

KeksDose
Praise Mima and the Moon

Joined: 06 Jul 2007

### Re: Inside FOV checking functions

KeksDose wrote:I wrote player but it works for anything. It's the maths all in all to describe the idea, not implement it. That's up to developers.

I'm very confident this is correct, but Graf's comment does make me wonder, since this kinda seems like a fairly natural idea to try. I could be wrong.

The problem is with the way the VM handles math operations and all that is bound to cause lag when there are lots of these actors at once. It's for reasons like this which I made things like Distance(2/3)DSquared instead of relying on just (x*x + y*y + z*z) in my own mods, because of the amount of extra processing. Vaecrius has tested these out thoroughly and revealed there's a significant advantage to doing it natively for anything math related.

Granted, dpJudas and a bunch of others are working on implementing a JIT compiler to negate this issue but that's still a while off.

Major Cooke
d = klabs(wall[wall[wall[sector[dasect].wallptr].point2].point2].x-s->x)...

Joined: 28 Jan 2007

### Re: Inside FOV checking functions

The JIT compiler and VM stuff was split here.

Joined: 14 Nov 2010
Operating System: Windows 10/8.1/8 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: ATI/AMD (Modern GZDoom)

### Re: Inside FOV checking functions

Graf Zahl wrote:Good luck finding someone who can cook up the proper math for it.

SUDDENLY I remebered that I know some math, soo... is it that hard?
You need to find angles between projection of two lines, one of which represent camera and it angle/pitch another position of "other" actor, onto all three coord. planes, XY XZ and YZ. If all this angle smaller than camera_fov, other actor in fov, if at least one bigger outside of the fov.
Or I miss something.

Apeirogon
I have a strange sense of humour

Joined: 12 Jun 2017

### Re: Inside FOV checking functions

Graf: I need some input on what your idea here is.

What I did is a fov check for the screen. That ignores a horizontal length distortion, which produces the expected output for a screen check (in gl at least). If we assumed a fov check for a monster, though, which we never see the map through, this might be insufficient.

That's because due to the way the unit sphere is parametrised, for non-horizontal pitches, the same horizontal fov covers less length on the unit sphere. The length covered becomes 0 towards 90° pitch. Essentially, actors can escape fov easier when above or below the viewer, because less positions are considered the farther we are from our "view equator".

Do you want to perform this check ensuring the covered lengths are the same?

edit: I'll withhold the idea until I get confirmation on what is supposed to be implemented.

KeksDose
Praise Mima and the Moon

Joined: 06 Jul 2007

### Re: Inside FOV checking functions

I cannot answer because I really do not know what people want. No matter what you do, the one certain thing is that someone will want something differently.

Graf Zahl