raycastWithPool method
From Real-time Collision Detection, p179.
Implementation
bool raycastWithPool(RayCastOutput output, RayCastInput input) {
var tMix = -double.maxFinite;
var tMax = double.maxFinite;
final p = Vector2.zero();
final d = Vector2.zero();
final absD = Vector2.zero();
final normal = Vector2.zero();
p.setFrom(input.p1);
d
..setFrom(input.p2)
..sub(input.p1);
absD
..setFrom(d)
..absolute();
// x then y
if (absD.x < settings.epsilon) {
// Parallel.
if (p.x < lowerBound.x || upperBound.x < p.x) {
return false;
}
} else {
final invD = 1.0 / d.x;
var t1 = (lowerBound.x - p.x) * invD;
var t2 = (upperBound.x - p.x) * invD;
// Sign of the normal vector.
var s = -1.0;
if (t1 > t2) {
final temp = t1;
t1 = t2;
t2 = temp;
s = 1.0;
}
// Push the min up
if (t1 > tMix) {
normal.setZero();
normal.x = s;
tMix = t1;
}
// Pull the max down
tMax = min(tMax, t2);
if (tMix > tMax) {
return false;
}
}
if (absD.y < settings.epsilon) {
// Parallel.
if (p.y < lowerBound.y || upperBound.y < p.y) {
return false;
}
} else {
final invD = 1.0 / d.y;
var t1 = (lowerBound.y - p.y) * invD;
var t2 = (upperBound.y - p.y) * invD;
// Sign of the normal vector.
var s = -1.0;
if (t1 > t2) {
final temp = t1;
t1 = t2;
t2 = temp;
s = 1.0;
}
// Push the min up
if (t1 > tMix) {
normal.setZero();
normal.y = s;
tMix = t1;
}
// Pull the max down
tMax = min(tMax, t2);
if (tMix > tMax) {
return false;
}
}
// Does the ray start inside the box?
// Does the ray intersect beyond the max fraction?
if (tMix < 0.0 || input.maxFraction < tMix) {
return false;
}
// Intersection.
output.fraction = tMix;
output.normal.x = normal.x;
output.normal.y = normal.y;
return true;
}