summaryrefslogtreecommitdiffstats
path: root/libdimension/dimension/math/aabb.h
diff options
context:
space:
mode:
Diffstat (limited to 'libdimension/dimension/math/aabb.h')
-rw-r--r--libdimension/dimension/math/aabb.h129
1 files changed, 129 insertions, 0 deletions
diff --git a/libdimension/dimension/math/aabb.h b/libdimension/dimension/math/aabb.h
new file mode 100644
index 0000000..14cc575
--- /dev/null
+++ b/libdimension/dimension/math/aabb.h
@@ -0,0 +1,129 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Axis-aligned bounding boxes.
+ */
+
+#ifndef DMNSN_MATH_H
+#error "Please include <dimension/math.h> instead of this header directly."
+#endif
+
+/** An axis-aligned bounding box. */
+typedef struct dmnsn_aabb {
+ dmnsn_vector min; /**< The coordinate-wise minimum extent of the box. */
+ dmnsn_vector max; /**< The coordinate-wise maximum extent of the box. */
+} dmnsn_aabb;
+
+/** A standard format string for bounding boxes. */
+#define DMNSN_AABB_FORMAT "(<%g, %g, %g> ==> <%g, %g, %g>)"
+/** The appropriate arguements to printf() a bounding box. */
+#define DMNSN_AABB_PRINTF(box) \
+ DMNSN_VECTOR_PRINTF((box).min), DMNSN_VECTOR_PRINTF((box).max)
+
+/**
+ * Construct a new bounding box.
+ * @param[in] min The minimal extent of the bounding box.
+ * @param[in] max The maximal extent of the bounding box.
+ * @return The new bounding box.
+ */
+DMNSN_INLINE dmnsn_aabb
+dmnsn_new_aabb(dmnsn_vector min, dmnsn_vector max)
+{
+ dmnsn_aabb box = { min, max };
+ return box;
+}
+
+/** Return the bounding box which contains nothing. */
+DMNSN_INLINE dmnsn_aabb
+dmnsn_zero_aabb(void)
+{
+ dmnsn_aabb box = {
+ { DMNSN_INFINITY, DMNSN_INFINITY, DMNSN_INFINITY },
+ { -DMNSN_INFINITY, -DMNSN_INFINITY, -DMNSN_INFINITY }
+ };
+ return box;
+}
+
+/** Return the bounding box which contains everything. */
+DMNSN_INLINE dmnsn_aabb
+dmnsn_infinite_aabb(void)
+{
+ dmnsn_aabb box = {
+ { -DMNSN_INFINITY, -DMNSN_INFINITY, -DMNSN_INFINITY },
+ { DMNSN_INFINITY, DMNSN_INFINITY, DMNSN_INFINITY }
+ };
+ return box;
+}
+
+/**
+ * Construct a new symmetric bounding box.
+ * @param[in] r The extent of the bounding box from the origin.
+ * @return The new bounding box.
+ */
+DMNSN_INLINE dmnsn_aabb
+dmnsn_symmetric_aabb(dmnsn_vector r)
+{
+ dmnsn_vector minus_r = dmnsn_vector_negate(r);
+ dmnsn_aabb box = {
+ dmnsn_vector_min(r, minus_r),
+ dmnsn_vector_max(r, minus_r)
+ };
+ return box;
+}
+
+/** Return whether \p p is within the axis-aligned bounding box. */
+DMNSN_INLINE bool
+dmnsn_aabb_contains(dmnsn_aabb box, dmnsn_vector p)
+{
+ return (p.x >= box.min.x && p.y >= box.min.y && p.z >= box.min.z)
+ && (p.x <= box.max.x && p.y <= box.max.y && p.z <= box.max.z);
+}
+
+/** Return whether a bounding box is infinite. */
+DMNSN_INLINE bool
+dmnsn_aabb_is_infinite(dmnsn_aabb box)
+{
+ return box.min.x == -DMNSN_INFINITY;
+}
+
+/**
+ * Expand a bounding box to contain a point
+ * @param[in] box The bounding box to expand.
+ * @param[in] point The point to swallow.
+ * @return The expanded bounding box.
+ */
+DMNSN_INLINE dmnsn_aabb
+dmnsn_aabb_swallow(dmnsn_aabb box, dmnsn_vector point)
+{
+ dmnsn_aabb ret = {
+ dmnsn_vector_min(box.min, point),
+ dmnsn_vector_max(box.max, point)
+ };
+ return ret;
+}
+
+/** Return whether a bounding box has any NaN components. */
+DMNSN_INLINE bool
+dmnsn_aabb_isnan(dmnsn_aabb box)
+{
+ return dmnsn_vector_isnan(box.min) || dmnsn_vector_isnan(box.max);
+}