[10190] Fix another numerical corner case...

...hopefully the last one.
Slightly different approach to tree bound intersection.
This commit is contained in:
Lynx3d 2010-07-14 22:31:35 +02:00
parent 904ef55b4e
commit bbe869b75d
2 changed files with 20 additions and 16 deletions

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "10189" #define REVISION_NR "10190"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -118,31 +118,35 @@ class BIH
template<typename RayCallback> template<typename RayCallback>
void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const
{ {
float intervalMin = 0.f; float intervalMin = -1.f;
float intervalMax = maxDist; float intervalMax = -1.f;
Vector3 org = r.origin(); Vector3 org = r.origin();
Vector3 dir = r.direction(); Vector3 dir = r.direction();
Vector3 invDir; Vector3 invDir;
float t1, t2;
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
{ {
invDir[i] = 1.f / dir[i]; invDir[i] = 1.f / dir[i];
t1 = (bounds.low()[i] - org[i]) * invDir[i]; if (dir[i] != 0.f)
t2 = (bounds.high()[i] - org[i]) * invDir[i]; {
if (invDir[i] > 0) { float t1 = (bounds.low()[i] - org[i]) * invDir[i];
float t2 = (bounds.high()[i] - org[i]) * invDir[i];
if (t1 > t2)
std::swap(t1, t2);
if (t1 > intervalMin) if (t1 > intervalMin)
intervalMin = t1; intervalMin = t1;
if (t2 < intervalMax) if (t2 < intervalMax || intervalMax < 0.f)
intervalMax = t2; intervalMax = t2;
} else { // intervalMax can only become smaller for other axis,
if (t2 > intervalMin) // and intervalMin only larger respectively, so stop early
intervalMin = t2; if (intervalMax <= 0 || intervalMin >= maxDist)
if (t1 < intervalMax)
intervalMax = t1;
}
if (intervalMin > intervalMax)
return; return;
} }
}
if (intervalMin > intervalMax)
return;
intervalMin = std::max(intervalMin, 0.f);
intervalMax = std::min(intervalMax, maxDist);
uint32 offsetFront[3]; uint32 offsetFront[3];
uint32 offsetBack[3]; uint32 offsetBack[3];