Browse Source

Math: minor cleanup.

No need to use contractions, inverseRayDirection is okay because nobody
needs to type it anywhere. Also no need for the `ones` vector in the
test, Float/Vector3 works as well.
pull/234/head
Vladimír Vondruš 6 years ago
parent
commit
07ba09c700
  1. 27
      src/Magnum/Math/Intersection.h
  2. 45
      src/Magnum/Math/Test/IntersectionTest.cpp

27
src/Magnum/Math/Intersection.h

@ -172,19 +172,20 @@ template<class T> bool rangeFrustum(const Range3D<T>& range, const Frustum<T>& f
/**
@brief Intersection of a ray with a range.
@param rayOrigin Origin of the ray
@param invRayDir Componentwise inverse of the ray direction
@param range Range
@return @cpp true @ce if the the ray intersect the range, @cpp false @ce otherwise.
@param rayOrigin Origin of the ray
@param inverseRayDirection Component-wise inverse of the ray direction
@param range Range
@return @cpp true @ce if the the ray intersects the range, @cpp false @ce
otherwise
Note that you need to pass the inverse ray direction and not the ray direction.
The purpose for this is to reduce the number of times you have to compute
a ray inverse, when doing multiple ray range intersections (For example
when traversing an aabb-tree).
The algorithm implemented is a version of the classical slabs algorithm, see
listing 1 in [Majercik et al.](http://jcgt.org/published/0007/03/04/).
a ray inverse, when doing multiple ray / range intersections (for example
when traversing an AABB tree). The algorithm implemented is a version of the
classical slabs algorithm, see *Listing 1* in
[Majercik et al.](http://jcgt.org/published/0007/03/04/).
*/
template<class T> bool rayRange(const Vector3<T>& rayOrigin, const Vector3<T>& invRayDir, const Range3D<T>& range);
template<class T> bool rayRange(const Vector3<T>& rayOrigin, const Vector3<T>& inverseRayDirection, const Range3D<T>& range);
/**
@brief Intersection of an axis-aligned box and a frustum
@ -444,10 +445,10 @@ template<class T> bool rangeFrustum(const Range3D<T>& range, const Frustum<T>& f
return true;
}
template<class T> bool rayRange(const Vector3<T>& rayOrigin, const Vector3<T>& invRayDir, const Range3D<T>& range) {
const Vector3<T> t0 = (range.min() - rayOrigin)*invRayDir;
const Vector3<T> t1 = (range.max() - rayOrigin)*invRayDir;
const std::pair<Vector3<T>, Vector3<T>> tminMax = minmax(t0,t1);
template<class T> bool rayRange(const Vector3<T>& rayOrigin, const Vector3<T>& inverseRayDirection, const Range3D<T>& range) {
const Vector3<T> t0 = (range.min() - rayOrigin)*inverseRayDirection;
const Vector3<T> t1 = (range.max() - rayOrigin)*inverseRayDirection;
const std::pair<Vector3<T>, Vector3<T>> tminMax = minmax(t0, t1);
return tminMax.first.max() <= tminMax.second.min();
}

45
src/Magnum/Math/Test/IntersectionTest.cpp

@ -436,52 +436,49 @@ void IntersectionTest::rangeCone() {
center, normal, angle));
}
void IntersectionTest::rayRange() {
const Vector3 origin{2,2,2};
const Range3D range{{-1, -1, -1},
{1, 1, 1}};
const Vector3 center{0,0,1};
const Vector3 edge{0,-1,1};
const Vector3 corner{-1,-1,1};
const Float eps = 1e-6;
const Vector3 origin{2.0f, 2.0f, 2.0f};
const Range3D range{{-1.0f, -1.0f, -1.0f},
{ 1.0f, 1.0f, 1.0f}};
const Vector3 ones{1,1,1};
const Vector3 center{0.0f, 0.0f, 1.0f};
const Vector3 edge{0.0f, -1.0f, 1.0f};
const Vector3 corner{-1.0f, -1.0f, 1.0f};
const Float eps = 1e-6f;
/* intersection at face center */
const Vector3 direction1 = center - origin;
const Vector3 invDir1 = ones/direction1;
const Vector3 invDir1 = 1.0f/direction1;
CORRADE_VERIFY(Intersection::rayRange(origin, invDir1, range));
/* intersection close to edge */
const Vector3 direction2 = edge + Vector3{0,eps,0} - origin;
const Vector3 invDir2 = ones/direction2;
const Vector3 direction2 = edge + Vector3{0.0f, eps, 0.0f} - origin;
const Vector3 invDir2 = 1.0f/direction2;
CORRADE_VERIFY(Intersection::rayRange(origin, invDir2, range));
/* no intersection close to edge */
const Vector3 direction3 = edge - Vector3{0,eps,0} - origin;
const Vector3 invDir3 = ones/direction3;
const Vector3 direction3 = edge - Vector3{0.0f, eps, 0.0f} - origin;
const Vector3 invDir3 = 1.0f/direction3;
CORRADE_VERIFY(!Intersection::rayRange(origin, invDir3, range));
/* intersection close to corner */
const Vector3 direction4 = corner + Vector3{eps,eps,0} - origin;
const Vector3 invDir4 = ones/direction4;
const Vector3 direction4 = corner + Vector3{eps, eps, 0.0f} - origin;
const Vector3 invDir4 = 1.0f/direction4;
CORRADE_VERIFY(Intersection::rayRange(origin, invDir4, range));
/* no intersection close to corner */
const Vector3 direction5 = corner - Vector3{eps,eps,0} - origin;
const Vector3 invDir5 = ones/direction5;
const Vector3 direction5 = corner - Vector3{eps, eps, 0.0f} - origin;
const Vector3 invDir5 = 1.0f/direction5;
CORRADE_VERIFY(!Intersection::rayRange(origin, invDir5, range));
/* divide by zero test with intersection */
const Vector3 direction6{0,0,-1};
const Vector3 invDir6 = ones/direction6;
CORRADE_VERIFY(Intersection::rayRange({0,0,2}, invDir6, range));
const Vector3 direction6{0.0f, 0.0f, -1.0f};
const Vector3 invDir6 = 1.0f/direction6;
CORRADE_VERIFY(Intersection::rayRange({0.0f, 0.0f, 2.0f}, invDir6, range));
/* divide by zero test without intersection */
const Vector3 direction7{0,0,1};
const Vector3 invDir7 = ones/direction7;
const Vector3 direction7{0.0f, 0.0f, 1.0f};
const Vector3 invDir7 = 1.0f/direction7;
CORRADE_VERIFY(!Intersection::rayRange(origin, invDir7, range));
}

Loading…
Cancel
Save