void DistanceRayFrontAndBackface (float &ffd, float& bfd, const vec& rayOrigin, const vec& rayInvDirection) const
{
vec t0 = vec(minmax[0] - rayOrigin).MulPerElem (rayInvDirection);
vec t1 = vec(minmax[1] - rayOrigin).MulPerElem (rayInvDirection);
vec tMin = t0.MinPerElem (t1);
vec tMax = t0.MaxPerElem (t1);
ffd = tMin.MaxElem(); // front face distance (behind origin if inside box)
bfd = tMax.MinElem(); // back face distance
}
bool TestRay (const vec& rayOrigin, const vec& rayInvDirection, const float rayLength) const
{
float ffd, bfd;
DistanceRayFrontAndBackface (ffd, bfd, rayOrigin, rayInvDirection);
return (ffd <= bfd) & (bfd >= 0.0f) & (ffd <= rayLength);
}
bool IntersectRay (float& t, const vec& rayOrigin, const vec& rayInvDirection, const float rayLength) const
{
float ffd, bfd;
DistanceRayFrontAndBackface (ffd, bfd, rayOrigin, rayInvDirection);
t = (ffd > 0) ? ffd : bfd; // always the first intersection with a face
return (ffd <= bfd) & (bfd >= 0.0f) & (ffd <= rayLength);
}
This is what i use for 3D, but math is the same. It is the so called ‘Slab Test’.
MulPerElem for two vectors is: (a,b) x (c,d) = (a x c, b x d)
MinPerElem and MinElem for ((a,b), (c,d)) boils down to simply the minimum af all involved numbers.
(Looks quirky because those are SIMD abstractions)
This is the fastest method to do this AFAIK, but robustness is an issue because of division. I need to look up how to make rayInvDirection to show how to deal with this…