summaryrefslogtreecommitdiffstats
path: root/libdimension/prtree.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-05-04 16:47:33 -0600
committerTavian Barnes <tavianator@gmail.com>2010-05-05 22:33:28 -0600
commit97c3e4a7a0c9d7b5a41294f356896ce46451e028 (patch)
tree43a2bfda4cc81f6a365f1e40cc0e4fe8760ceb0e /libdimension/prtree.c
parent0149cd51012afe439c1b179a4d1715f7e0b619bb (diff)
downloaddimension-97c3e4a7a0c9d7b5a41294f356896ce46451e028.tar.xz
Optimize ray-AABB intersection tests a bit.
Diffstat (limited to 'libdimension/prtree.c')
-rw-r--r--libdimension/prtree.c80
1 files changed, 29 insertions, 51 deletions
diff --git a/libdimension/prtree.c b/libdimension/prtree.c
index a4f8b96..baf41b0 100644
--- a/libdimension/prtree.c
+++ b/libdimension/prtree.c
@@ -516,65 +516,43 @@ dmnsn_prtree_search(const dmnsn_prtree *tree, dmnsn_line ray,
static bool
dmnsn_ray_box_intersection(dmnsn_line line, dmnsn_bounding_box box, double t)
{
- if (dmnsn_bounding_box_contains(box, line.x0))
- return true;
-
- double t_temp;
- dmnsn_vector p;
+ double tmin = -INFINITY, tmax = INFINITY;
if (line.n.x != 0.0) {
- /* x == box.min.x */
- t_temp = (box.min.x - line.x0.x)/line.n.x;
- p = dmnsn_line_point(line, t_temp);
- if (p.y >= box.min.y && p.y <= box.max.y
- && p.z >= box.min.z && p.z <= box.max.z
- && t_temp >= 0.0 && (t < 0.0 || t_temp < t))
- return true;
-
- /* x == box.max.x */
- t_temp = (box.max.x - line.x0.x)/line.n.x;
- p = dmnsn_line_point(line, t_temp);
- if (p.y >= box.min.y && p.y <= box.max.y
- && p.z >= box.min.z && p.z <= box.max.z
- && t_temp >= 0.0 && (t < 0.0 || t_temp < t))
- return true;
+ double tx1 = (box.min.x - line.x0.x)/line.n.x;
+ double tx2 = (box.max.x - line.x0.x)/line.n.x;
+
+ tmin = dmnsn_max(tmin, dmnsn_min(tx1, tx2));
+ tmax = dmnsn_min(tmax, dmnsn_max(tx1, tx2));
+
+ if (tmin > tmax)
+ return false;
}
if (line.n.y != 0.0) {
- /* y == box.min.y */
- t_temp = (box.min.y - line.x0.y)/line.n.y;
- p = dmnsn_line_point(line, t_temp);
- if (p.x >= box.min.x && p.x <= box.max.x
- && p.z >= box.min.z && p.z <= box.max.z
- && t_temp >= 0.0 && (t < 0.0 || t_temp < t))
- return true;
-
- /* y == box.max.y */
- t_temp = (box.max.y - line.x0.y)/line.n.y;
- p = dmnsn_line_point(line, t_temp);
- if (p.x >= box.min.x && p.x <= box.max.x
- && p.z >= box.min.z && p.z <= box.max.z
- && t_temp >= 0.0 && (t < 0.0 || t_temp < t))
- return true;
+ double ty1 = (box.min.y - line.x0.y)/line.n.y;
+ double ty2 = (box.max.y - line.x0.y)/line.n.y;
+
+ tmin = dmnsn_max(tmin, dmnsn_min(ty1, ty2));
+ tmax = dmnsn_min(tmax, dmnsn_max(ty1, ty2));
+
+ if (tmin > tmax)
+ return false;
}
if (line.n.z != 0.0) {
- /* z == box.min.z */
- t_temp = (box.min.z - line.x0.z)/line.n.z;
- p = dmnsn_line_point(line, t_temp);
- if (p.x >= box.min.x && p.x <= box.max.x
- && p.y >= box.min.y && p.y <= box.max.y
- && t_temp >= 0.0 && (t < 0.0 || t_temp < t))
- return true;
-
- /* z == box.max.z */
- t_temp = (box.max.z - line.x0.z)/line.n.z;
- p = dmnsn_line_point(line, t_temp);
- if (p.x >= box.min.x && p.x <= box.max.x
- && p.y >= box.min.y && p.y <= box.max.y
- && t_temp >= 0.0 && (t < 0.0 || t_temp < t))
- return true;
+ double tz1 = (box.min.z - line.x0.z)/line.n.z;
+ double tz2 = (box.max.z - line.x0.z)/line.n.z;
+
+ tmin = dmnsn_max(tmin, dmnsn_min(tz1, tz2));
+ tmax = dmnsn_min(tmax, dmnsn_max(tz1, tz2));
+
+ if (tmin > tmax)
+ return false;
}
- return false;
+ if (tmax < 0.0)
+ return false;
+
+ return t < 0.0 || tmin < t;
}