#include "Ray.h" // ========================================================= // Ray .. static item used for generation of unique ID for // each instantiated ray // it has to start from 1, since 0 is default and for the first // ray initial value 0 will not work .. V.H. // The value 0 is reserved for particular purpose - the rays // that are converted to canonical space and thus the mailbox // rayID identification does not work for them! int Ray::genID = 1; // Precompute some Ray parameters. Most of them is used for // ropes traversal. void Ray::Init() { // if (mType == LOCAL_RAY) // intersections.reserve(1); // else // intersections.reserve(10); // apply the standard precomputation Precompute(); } void Ray::Precompute() { // initialize inverted dir invDir.SetValue(0.0); SetID(); } void Ray::SetLoc(const Vector3 &l) { loc = l; } // make such operation to slightly change the ray direction // in case any component of ray direction is zero. void Ray::CorrectZeroComponents() { const float eps = 1e-6; // it does change the ray direction very slightly, // but the size direction vector is not practically changed if (fabs(dir.x) < eps) { if (dir.x < 0.0) dir.x = -eps; else dir.x = eps; } if (fabs(dir.y) < eps) { if (dir.y < 0.0) dir.y = -eps; else dir.y = eps; } if (fabs(dir.z) < eps) { if (dir.z < 0.0) dir.z = -eps; else dir.z = eps; } } void Ray::ComputeInvertedDir() const { if ( (invDir.x != 0.0) || (invDir.y != 0.0) || (invDir.z != 0.0) ) return; // has been already precomputed const float eps = 1e-6; const float invEps = 1e6; // it does change the ray direction very slightly, // but the size direction vector is not practically changed if (fabs(dir.x) < eps) { if (dir.x < 0.0) invDir.x = -invEps; else invDir.x = invEps; } else invDir.x = 1.0 / dir.x; if (fabs(dir.y) < eps) { if (dir.y < 0.0) invDir.y = -invEps; else invDir.y = invEps; } else invDir.y = 1.0 / dir.y; if (fabs(dir.z) < eps) { if (dir.z < 0.0) invDir.z = -invEps; else invDir.z = invEps; } else invDir.z = 1.0 / dir.z; return; }