[bug] Recent problems introduced in RaySceneQueries

sklug

14-10-2006 23:25:34

There's definitely something squirrely going on with RaySceneQueries. This seems to have been introduced recently, as I don't think I was having any issues before re-syncing with CVS this week. I'm having two seperate problems. One problem happens when the start point of the ray is above the world height. All the returned intersections have a 0 y coord. I'm not grokking the code fully, but there's something odd in IntersectSegmentTerrain(). Here's a snippet:


const Real maxHeight = mData2DManager->getMaxHeight ();
if (raystart.y > maxHeight)
{
// find ray to highest terrain plane intersection
// so that ray begins at a pertinent place.
Plane plane(Vector3::UNIT_Y, maxHeight); // getOption()->offset ?
const Real denom = Vector3::UNIT_Y.dotProduct(raydir);
if (Math::Abs(denom) < std::numeric_limits<Real>::epsilon())
{
// Parallel ?
*rayresult = Vector3(-1.0f, -1.0f, -1.0f);
return false;
}
const Real nom = Vector3::UNIT_Y.dotProduct(raystart);
const Real t = -(nom/denom);
raystart += raydir*t;
if (raystart.y <= mData2DManager->getInterpolatedWorldHeight(raystart.x, raystart.z))
{
*rayresult = raystart;
return true;
}
}

I'm not positive of the intent here, but something is odd when you create a plane at the max height, normal to the y axis, then never use it.

The second problem is when the start point of the ray is below the max height. There seems to be issues when crossing page boundaries. That is, when the start is in one page, and the intersection is in another. As long as both are in the same page, everything works. But going from a page with positive x to negative x in world coords seems to have sticking points, where the intersection returned stays on your side of the page boundary until the intersection is WELL into the next page. It's a little hard to describe.

In any case, I started looking at these bugs, but realized I was getting very distracted from working on the decals (which are pretty close to working with LOD!), so figured I'd toss it up on the boards.

sklug

tuan kuranes

16-10-2006 13:40:27

Thanks for spotting that and reporting, I'll defenitly look on that asap.

Sorry for plane, was me looking for a particular optimisation on interesctsegment using least square planes, that should really speed up the thing.

which are pretty close to working with LOD!

Great !

CABAListic

25-02-2007 03:01:16

Sorry for bringing up an old thread, but I just stumbled across the same problem with scene queries returning interjections at y=0. Since this only happens when the camera's y coordinate trespasses a certain border, I took a quick glance into the code and also spotted the above quoted code segment. The Plane statement is commented out, but the rest remains (my CVS checkout should be up to date, at least an update didn't modify any of the source files).

I don't really understand what this code segment is supposed to do, I guess it's supposed to be a speed optimisation. But it doesn't really seem to make sense to me. For one, why does it calculate two dot products which really only extract the y coordinate of the two vectors? In addition, shouldn't the line


const Ogre::Real nom = Ogre::Vector3::UNIT_Y.dotProduct(raystart);


really be something like

const Ogre::Real nom = raystart.y - maxHeight;

? Otherwise the starting position for the query could would always be the intersection with the plane y = 0, which would explain the bug.

Anyway, removing the whole code block solved the bug as far as I can tell.

kungfoomasta

25-02-2007 05:55:15

CABAListic, thanks for throwing this on the forum, commenting out the code shown in the first post seems to make ray casting work properly for me also. :D

KungFooMasta

CABAListic

25-02-2007 11:08:47

Update:
Just tested my suggested line replacement, and this also seems to fix the bug, potentially keeping the intended speed improvement (though, since I do not know how the actual query works, I have no idea how much this gains). The corrected code piece could look like this:


if (raystart.y > maxHeight)
{
if (Math::Abs(raydir.y) < std::numeric_limits<Real>::epsilon())
{
// Parallel ?
*rayresult = Ogre::Vector3(-1.0f, -1.0f, -1.0f);
return false;
}
const Ogre::Real t = -(raystart.y-maxHeight)/raydir.y;
raystart += raydir*t;
if (raystart.y <= mData2DManager->getInterpolatedWorldHeight(raystart.x, raystart.z))
{
*rayresult = raystart;
return true;
}
}

tuan kuranes

28-02-2007 15:14:42

Thanks, fix in CVS.
Good spot, btw.