Inside FOV checking functions

Moderator: GZDoom Developers

User avatar
Major Cooke
Posts: 8170
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Inside FOV checking functions

Post by Major Cooke »

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.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49056
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Inside FOV checking functions

Post by Graf Zahl »

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.
User avatar
AFADoomer
Posts: 1322
Joined: Tue Jul 15, 2003 4:18 pm
Contact:

Re: Inside FOV checking functions

Post by AFADoomer »

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*/ }"
User avatar
Apeirogon
Posts: 1605
Joined: Mon Jun 12, 2017 12:57 am

Re: Inside FOV checking functions

Post by Apeirogon »

Double this.
Using thinkeriterator, jumpifinLOS and inventory mark not always lead to success check.
argv
Posts: 184
Joined: Tue Aug 30, 2016 4:47 pm

Re: Inside FOV checking functions

Post by argv »

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.
User avatar
KeksDose
 
 
Posts: 595
Joined: Thu Jul 05, 2007 6:13 pm
Contact:

Re: Inside FOV checking functions

Post by KeksDose »

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 * r
right  = -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.
User avatar
Major Cooke
Posts: 8170
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: Inside FOV checking functions

Post by Major Cooke »

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.
User avatar
KeksDose
 
 
Posts: 595
Joined: Thu Jul 05, 2007 6:13 pm
Contact:

Re: Inside FOV checking functions

Post by KeksDose »

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.
argv
Posts: 184
Joined: Tue Aug 30, 2016 4:47 pm

Re: Inside FOV checking functions

Post by argv »

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.
User avatar
KeksDose
 
 
Posts: 595
Joined: Thu Jul 05, 2007 6:13 pm
Contact:

Re: Inside FOV checking functions

Post by KeksDose »

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.
User avatar
Major Cooke
Posts: 8170
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: Inside FOV checking functions

Post by Major Cooke »

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.
Blue Shadow
Posts: 4949
Joined: Sun Nov 14, 2010 12:59 am

Re: Inside FOV checking functions

Post by Blue Shadow »

The JIT compiler and VM stuff was split here.
User avatar
Apeirogon
Posts: 1605
Joined: Mon Jun 12, 2017 12:57 am

Re: Inside FOV checking functions

Post by Apeirogon »

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.
User avatar
KeksDose
 
 
Posts: 595
Joined: Thu Jul 05, 2007 6:13 pm
Contact:

Re: Inside FOV checking functions

Post by KeksDose »

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.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49056
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Inside FOV checking functions

Post by Graf Zahl »

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.
Post Reply

Return to “Closed Feature Suggestions [GZDoom]”