Game Development Community

Field of view problem

by Toks · in Torque Game Engine · 10/11/2007 (7:11 am) · 5 replies

Hello everyone,

im having a wierd little problem with check wether a player is in a bot's field of view.

im trying some things in AiPlayer.cc now on the end of the getAiMove method. in addition to the simple cast we're doing here, ive added a boolean called inFov. this boolean is set like this:

getEyeTransform(&eyeMat);
VectorF eyeDir;
eyeMat.getColumn(1,&eyeDir);

...

VectorF shapeDir = targetLoc - location;

...

// check if in our cone of view.
bool inFov = false;
shapeDir.normalize();
F32 dot = mDot(shapeDir, eyeDir);
if (dot >= mDegToRad(mSearchFov) / 2)
	inFov = true;

additionally mSearchFov is set to 90 (which i believe any player has by default). oh, almost forgot to say, i stole this code from guiShapeNameHud.cc!

now, this seems to work. when i stand in front of the bot, he'll call onTargetEnterLOS correctly, and when i exit his Fov to one side (but still be in front of him, really) he'd call onTargetExitLOS correctly, too.

now the problem:
Im using mSearchFov since i want to be able to change the cone the bot looks at as he becomes more "alert" (for example when he has heard something). now when I change this something strange happens. the smaller i set his FOV, the further to the side he will still spot me, eventhough i'd expect it to be the other way? why is this?

#1
10/12/2007 (7:00 am)
I just did a bunch of this stuff.

The value returned by the dot product give you a one dimensional representation of how parallel two vectors are.

If they are parallel and pointing in the same direction the value will be 1.
If they are parallel and pointing in the opposite direction the value will be -1.
If they are perpendicular the value will be 0.

So basically you gotta scale your comparision value into that range 1..0..-1.
If you only use mDegToRad you are getting a value between PI and -PI. This is too big of a scale.

Here is what I came up with that seems to work really well.
F32 dot = mDot(shapeDir, eyeDir);
    if (dot >= ((mSearchFov / 2) - 90) / -90)
	  inFov = true;
#2
10/12/2007 (10:11 am)
Yeah, I kinda did the same. but i dont think its right i changed it to:

if (dot >= 1 - mSearchFov / 180)
    inFov = true;

which should work like yours, and work in the three situations you stated. im not sure if it really works perfect in all situations in between.

what i mean is, if the mSearchFov is set to 90 degrees, both our methods say dot should be higher or equal to 0.5 to be inFov. are you sure thats true?
#3
10/12/2007 (10:27 am)
I made some handy math functions which sort of package up this type of stuff.
here's the resource.

you could use it something like this:
if (rangeAngular(botPosition, playerPosition, eyeDir, searchFOVInRadians / 2) > 0)
   // in view
else
   // out of view
#4
10/12/2007 (10:38 am)
Ah great resource, thanks. one more thing though. I copied the code from guiShapeNameHud.cc so there may be a bug there. or maybe they fixed it already this since im using an older version right now.
#5
10/12/2007 (10:50 am)
There was in fact a small bug around this in GuiShapeNameHud,
which i posted a fix for here, and which according to posts on that thread is still present in TGE 1.5.2.