Move Box intersection code to DoIntersect
This commit is contained in:
parent
d0d667d6d2
commit
3846a1aa3a
2 changed files with 57 additions and 51 deletions
105
src/objectBox.cc
105
src/objectBox.cc
|
@ -51,56 +51,6 @@ Box::SetFar(const Vector3& far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
Box::DoesIntersect(const Ray& ray,
|
|
||||||
TVector& t,
|
|
||||||
Stats& stats)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
stats.boxIntersectionTests++;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX: For now, I'm assuming that all boxes are parallel to the coordinate
|
|
||||||
* axes. This is the Kay-Kajiya box intersection algorithm.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//Double t0, t1;
|
|
||||||
Double tNear = -std::numeric_limits<Double>::infinity();
|
|
||||||
Double tFar = std::numeric_limits<Double>::infinity();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* From the Ray Tracing book:
|
|
||||||
*
|
|
||||||
* For a more efficient algorithm, unwrap the loop, expand the swap of t0
|
|
||||||
* and t1 into two branches, and change the calculations to multiply by
|
|
||||||
* the inverse of the ray's direction to avoid divisions. Unwrapping the
|
|
||||||
* loop allows elimination of comparing t0 adn t1 to tNear and tFar [for
|
|
||||||
* the X planes], as tNear will always be set to the smaller and tFar the
|
|
||||||
* larger of t0 and t1.
|
|
||||||
*
|
|
||||||
* Initially there was a for loop iterating over each parallel pair of
|
|
||||||
* planes (X, Y, and Z planes).
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!IntersectSlab(mNear.x, mFar.x, ray.origin.x, ray.direction.x, tNear, tFar)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!IntersectSlab(mNear.y, mFar.y, ray.origin.y, ray.direction.y, tNear, tFar)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!IntersectSlab(mNear.z, mFar.z, ray.origin.z, ray.direction.z, tNear, tFar)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have an intersection! */
|
|
||||||
stats.boxIntersections++;
|
|
||||||
t.push_back(tNear);
|
|
||||||
t.push_back(tFar);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Box::point_is_on_surface(const Vector3& p)
|
Box::point_is_on_surface(const Vector3& p)
|
||||||
const
|
const
|
||||||
|
@ -142,6 +92,44 @@ Box::compute_normal(const Vector3& p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* charles::Box::DoIntersect --
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
Box::DoIntersect(const basics::Ray& ray,
|
||||||
|
TVector& t,
|
||||||
|
Stats& stats)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
stats.boxIntersectionTests++;
|
||||||
|
|
||||||
|
/* This is the Kay-Kajiya box intersection algorithm. */
|
||||||
|
|
||||||
|
Double tNear = -std::numeric_limits<Double>::infinity();
|
||||||
|
Double tFar = std::numeric_limits<Double>::infinity();
|
||||||
|
|
||||||
|
if (!IntersectSlab(mNear.x, mFar.x, ray.origin.x, ray.direction.x, tNear, tFar)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!IntersectSlab(mNear.y, mFar.y, ray.origin.y, ray.direction.y, tNear, tFar)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!IntersectSlab(mNear.z, mFar.z, ray.origin.z, ray.direction.z, tNear, tFar)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have an intersection! */
|
||||||
|
stats.boxIntersections++;
|
||||||
|
t.push_back(tNear);
|
||||||
|
t.push_back(tFar);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* charles::Box::IntersectSlab --
|
||||||
|
*/
|
||||||
inline bool
|
inline bool
|
||||||
Box::IntersectSlab(const Double& slabLow,
|
Box::IntersectSlab(const Double& slabLow,
|
||||||
const Double& slabHigh,
|
const Double& slabHigh,
|
||||||
|
@ -153,6 +141,20 @@ Box::IntersectSlab(const Double& slabLow,
|
||||||
{
|
{
|
||||||
Double t0, t1;
|
Double t0, t1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* From the Ray Tracing book:
|
||||||
|
*
|
||||||
|
* For a more efficient algorithm, unwrap the loop, expand the swap of t0
|
||||||
|
* and t1 into two branches, and change the calculations to multiply by
|
||||||
|
* the inverse of the ray's direction to avoid divisions. Unwrapping the
|
||||||
|
* loop allows elimination of comparing t0 adn t1 to tNear and tFar [for
|
||||||
|
* the X planes], as tNear will always be set to the smaller and tFar the
|
||||||
|
* larger of t0 and t1.
|
||||||
|
*
|
||||||
|
* Initially there was a for loop iterating over each parallel pair of
|
||||||
|
* planes (X, Y, and Z planes).
|
||||||
|
*/
|
||||||
|
|
||||||
if (NearZero(rayDirectionComponent)) {
|
if (NearZero(rayDirectionComponent)) {
|
||||||
/* The ray is parallel to the X axis. */
|
/* The ray is parallel to the X axis. */
|
||||||
if (rayOriginComponent < slabLow || rayOriginComponent > slabHigh) {
|
if (rayOriginComponent < slabLow || rayOriginComponent > slabHigh) {
|
||||||
|
@ -170,12 +172,13 @@ Box::IntersectSlab(const Double& slabLow,
|
||||||
tNear = t1;
|
tNear = t1;
|
||||||
tFar = t0;
|
tFar = t0;
|
||||||
}
|
}
|
||||||
#endif
|
#else
|
||||||
if (t0 > t1) {
|
if (t0 > t1) {
|
||||||
Double tmp = t0;
|
Double tmp = t0;
|
||||||
t0 = t1;
|
t0 = t1;
|
||||||
t1 = tmp;
|
t1 = tmp;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (t0 > tNear) {
|
if (t0 > tNear) {
|
||||||
tNear = t0;
|
tNear = t0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@ struct Box
|
||||||
/** @see charles::Object::Write */
|
/** @see charles::Object::Write */
|
||||||
void Write(std::ostream& ost) const;
|
void Write(std::ostream& ost) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool DoIntersect(const basics::Ray& ray, TVector& t, Stats& stats) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Perform the intersection test on a slab, defined by `slabHigh` and
|
* Perform the intersection test on a slab, defined by `slabHigh` and
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue