Game Development Community

CastRay bugged, sometimes misses interiors

by Tom Spilman · in Torque Game Engine · 05/05/2006 (4:31 am) · 17 replies

I've got another weird one. It's happening to me in TSE, but i thought i'd get more traffic posting it here.

This is a ray i'm casting from the player shape camera node in the first person in the view direction. As you can see in this shot it's hitting the DIF block i have there.

www.sickheadgames.com/stuff/raybug2.png

Here is the same scene with the free camera moved slightly (the player was not moved):

www.sickheadgames.com/stuff/raybug.png

For some reason movement of the free camera causes the ray cast to miss the interior block. At some camera angles the ray will fluctuate between hitting the block and the terrain with nothing moving in the scene.

This has me baffled. I suspect it's some sort of change in 1.4 that was merged into TSE.

Any tips or ideas for tracking this down is very much appreciated.

About the author

Tom is a programmer and co-owner of Sickhead Games, LLC.


#1
05/05/2006 (4:57 am)
Ok... maybe it's not a change in 1.4 (i checked and nothing major seems to have changed in SceneObject.cc).

But i tracked down why it's happening. I'm creating my ray like so:

Point3F end = start + (vec * 20000);

The 20000 is the problem. At 20000 it fluctuates like in the picture. If i bring it down to 1000 it's solid.

So i figure that there is something wrong with the calculation in castRay() which does the line rasterization of the cast line thru the grid bins. In one failure case 'end' above is calculated as {x=19896.676 y=-897.31061 z=724.63403 }... this seems like a reasonable end position yet castRay fails to hit the block.

So i'm investigating further. I still don't get why the position of the free camera has anything to do with the ray cast.
#2
05/05/2006 (7:34 am)
Interesting post, Tom.
#3
05/05/2006 (8:42 am)
Ok... i think i have the right fix. The problem seems to be in SceneObject.cc line 304 in the function getBinRange. At the end of the function you see this:

// MSVC6 seems to be generating some bad floating point code around
      // here when full optimizations are on.  The min != max test should
      // not be needed, but it clears up the VC issue.
      if (min != max && minCoord > maxCoord)
         maxBin += Container::csmNumBins;

First let me say i have no clue what exactly getBinRange does... a comment would be nice here.

Anyway the problem was that in the cases where the ray would go thru the block getBinRange would return a minBin and maxBin that were equal. Looking further i found in that case minCoord == maxCoord exactly. So my fix was to change the > in the code block above into a >=. This fixes the issue.

Now someone knowledgeable tell me why i fixed it wrong. =)
#4
05/05/2006 (9:09 am)
That's great Tom, this might fix the problem where the character's lighting gets messed up on interiors, occasionally missing the downward cast to see what color the light should be there.
#5
05/05/2006 (9:17 am)
Super work, Tom. I think this fixes a problem for me with my robots laser range finders which would occasionally return a bad result when driving around in a parking garage.
#6
05/05/2006 (9:42 am)
Well don't get too excited... it fixes my problem, but i'm not sure if what i did is right. If someone has an explanation of what getBinRange() is supposed to do it would help me check to be sure i'm not screwing things up somehow.
#7
05/05/2006 (10:24 am)
Tom you probably figured this much out, but it looks like the world is divided into a grid of bins. And objects are sorted into these bins, for quicker raycasting, object finding etc.

think of it like some sort of octree, but not really.

getbinrange would then find what bins need to be looked at given the coordinates
#8
05/05/2006 (10:26 am)
I wonder how old that comment is, might not evenbe an issue anymore and that min/max check could be removed?
#9
05/05/2006 (10:30 am)
This would be a possible explanation why lowering your ray's distance made it work, if the for whatever reason the bin got set to the one containing the endpoint, very far away, and your interior falls into another bin, then your interior would never get checked...when you lower the distance, then maybe it brings the endpoint into the bin that your interior lives in.

This is all psychic interpretation of the code, Ishould really stoptalking until I read more of it which I can't do now :) on a trip in oregon.
#10
05/05/2006 (11:50 am)
@Clint - Don't forget to stop in Eugene! =)

Ask them about this bug while your there.
#11
05/05/2006 (11:42 pm)
Hah I wish I could, I'm a bit too far away though. parents live way way way out in the country up past hood river, its all mountain lions and snakes out here....and wireless internet! which is just really surprising.
#12
05/06/2006 (6:37 am)
I have also had problems with ray's not hitting, but that seemed not to have anything to do with how the camera was positioned. Edit: Randomly, yes.

Anyway, cool thread. :)
#13
06/24/2006 (6:42 pm)
Well I tried Tom's solution and while it has made my weapons be able to hit objects correctly at an angle I am having issues with its ability to identify the material properties of that object now. It in fact looks past the object now and reads the properties of the object behind it. I supose what I would like to know is if there is some way along with Tom's solution to also make sure that it still is performing the reainer of the required functions for the object it contacts with first? I guess Tom's solution has fixed one facet of the overall issue.
#14
07/10/2006 (7:15 am)
Is this something that is going to be fixed in TG 1.4.2?
#15
07/13/2006 (8:41 am)
I'm about to dive back in and try to find the remaining bug/bugs in cast ray. I'll update when i figure it out.
#16
07/14/2006 (2:43 am)
Well my problem with the projectile correctly identifying the object is based upon the speed of the projectile and apparently doesn't give the castray sufficient time to perform its function.
#17
07/15/2006 (11:23 am)
Is there someway to adjust the how often the castray is performed per tick? I have been told it doesn't actually perform the function every tick or 32 ms but either every other tick or even possible more.