Game Development Community

dev|Pro Game Development Curriculum

Small bugfix & Improvement to GuiShapeNameHud viewcone business

by Orion Elenzil · 01/29/2006 (3:32 pm) · 8 comments

This isn't really a very significant bug at all with stock settings,
but does become noticable as your FOV gets large.

If you run stock torque 1.3, press F8 to move outside your player, and back off a little bit,
you'll see that your player name floating above the play disappears when the player gets close to the edge of the screen.

This is due to a bug in the "is in viewcone" math in GuiShapeNameHud.

The original code basically did this:

camFOV = cameraFOV / 2.
...
dot = dot product between line-of-sight and (player) object.
if (dot < camFOV)
  then it's out of sight, don't draw the name.

this is close but wrong.
an quick bit of thinking shows that things aren't right:
consider the case where the FOV is getting very small, say close to zero:
then (dot < camFOV) is going to be false,
and the logic will think the object is in view.
The converse happens as camFOV gets larger, more and more objects get excluded.
So clearly something is wrong.

the math fact to use here is that the dot product of two (normalized) vectors is the cosine of the angle between the vectors. the original code erroneously left out the cosine part.

the pseudo code we want is this:
if (dot < cos(camFOV))
  then it's out of sight, don't draw the name.

there's also a slight optimization that can be done to test early if the object is behind the viewer, which i've included.

here are the changes to make to guiShapeNameHud.cc:

after camFov = mDegToRad(camFov) / 2:
// the next line is optional just to widen the viewcone a little bit for when 40% of a player is visible
   // but their center isn't. Increase the viewcone by 5 degrees:
   // camFov += mDegToRad(5) / 2;
   F32 cosCamFov = mCos(camFov);

before // Test to see if it's in range:
// test early to see if it's behind us.
            // no need to normalize shapeDir for this,
            // we'll normalize it later if needed.
            F32 dot = mDot(shapeDir, camDir);
            if (dot < 0)
               continue;


and finally replace the "Test to see" block with this:
// Test to see if it's within our viewcone, this test doesn't
            // actually match the viewport very well, should consider
            // projection and box test.
            dot /= shapeDist;
            if (dot < cosCamFov)
               continue;

#1
01/31/2006 (9:00 pm)
I'm glad someone was paying attention in math class! Nice fix.

B--
#2
02/13/2006 (3:19 pm)
Well done, and nicely explained.
#3
03/08/2006 (3:23 am)
#4
03/08/2006 (9:07 am)
@Juan -
just checked the 1.4 source, and yes, this fix applies to 1.4 as well as 1.3.
#5
07/14/2006 (2:13 pm)
I was working with this today and checked the forums before trying to fix it and what do you know, Orion already did. Thanks alot man, you've been of great help to everyone with your fixes.
#6
07/14/2006 (5:21 pm)
thanks Stefan !
#7
07/13/2007 (3:55 am)
This still applies in 1.52! This should be in stock TGE!
#8
10/12/2007 (10:50 am)
folks interested in this resource might also be interested in the proximity math utils resource, which includes angular proximity.