summaryrefslogtreecommitdiffstats
path: root/libdimension/dimension
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2014-06-07 14:15:06 -0400
committerTavian Barnes <tavianator@tavianator.com>2014-06-07 14:30:26 -0400
commita79085ab984979dbf4f78545f7592c8b47e4a794 (patch)
treee2518532db860db8ba59878ecd6d0d4b60f0b5c4 /libdimension/dimension
parent708954192219feead526f84c0c8bdb29088aeae0 (diff)
downloaddimension-a79085ab984979dbf4f78545f7592c8b47e4a794.tar.xz
objects: Refactor how bounding and initialization work.
Diffstat (limited to 'libdimension/dimension')
-rw-r--r--libdimension/dimension/geometry.h45
-rw-r--r--libdimension/dimension/object.h45
2 files changed, 70 insertions, 20 deletions
diff --git a/libdimension/dimension/geometry.h b/libdimension/dimension/geometry.h
index d2479f3..26dd608 100644
--- a/libdimension/dimension/geometry.h
+++ b/libdimension/dimension/geometry.h
@@ -218,6 +218,19 @@ dmnsn_new_line(dmnsn_vector x0, dmnsn_vector n)
return l;
}
+/**
+ * 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_bounding_box
+dmnsn_new_bounding_box(dmnsn_vector min, dmnsn_vector max)
+{
+ dmnsn_bounding_box box = { min, max };
+ return box;
+}
+
/** Return the bounding box which contains nothing. */
DMNSN_INLINE dmnsn_bounding_box
dmnsn_zero_bounding_box(void)
@@ -442,6 +455,22 @@ dmnsn_line_add_epsilon(dmnsn_line l)
);
}
+/**
+ * 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_bounding_box
+dmnsn_symmetric_bounding_box(dmnsn_vector r)
+{
+ dmnsn_vector minus_r = dmnsn_vector_negate(r);
+ dmnsn_bounding_box 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_bounding_box_contains(dmnsn_bounding_box box, dmnsn_vector p)
@@ -457,6 +486,22 @@ dmnsn_bounding_box_is_infinite(dmnsn_bounding_box box)
return box.min.x == -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_bounding_box
+dmnsn_bounding_box_swallow(dmnsn_bounding_box box, dmnsn_vector point)
+{
+ dmnsn_bounding_box ret = {
+ dmnsn_vector_min(box.min, point),
+ dmnsn_vector_max(box.max, point)
+ };
+ return ret;
+}
+
/** Return whether a vector contains any NaN components. */
DMNSN_INLINE bool
dmnsn_vector_isnan(dmnsn_vector v)
diff --git a/libdimension/dimension/object.h b/libdimension/dimension/object.h
index 0f7c940..2e4c68c 100644
--- a/libdimension/dimension/object.h
+++ b/libdimension/dimension/object.h
@@ -41,12 +41,6 @@ typedef struct dmnsn_intersection {
} dmnsn_intersection;
/**
- * Object initialization callback.
- * @param[in,out] object The object to initialize.
- */
-typedef void dmnsn_object_initialize_fn(dmnsn_object *object);
-
-/**
* Ray-object intersection callback.
* @param[in] object The object to test.
* @param[in] line The line to test.
@@ -54,9 +48,7 @@ typedef void dmnsn_object_initialize_fn(dmnsn_object *object);
* closest (if any) intersection.
* @return Whether \p line intersected \p object.
*/
-typedef bool dmnsn_object_intersection_fn(const dmnsn_object *object,
- dmnsn_line line,
- dmnsn_intersection *intersection);
+typedef bool dmnsn_object_intersection_fn(const dmnsn_object *object, dmnsn_line line, dmnsn_intersection *intersection);
/**
* Object inside callback.
@@ -64,14 +56,27 @@ typedef bool dmnsn_object_intersection_fn(const dmnsn_object *object,
* @param[in] point The point to test.
* @return Whether \p point is inside \p object.
*/
-typedef bool dmnsn_object_inside_fn(const dmnsn_object *object,
- dmnsn_vector point);
+typedef bool dmnsn_object_inside_fn(const dmnsn_object *object, dmnsn_vector point);
+
+/**
+ * Object bounding callback.
+ * @param[in,out] object The object to bound.
+ * @param[in,out] trans The effective transformation for the object.
+ */
+typedef dmnsn_bounding_box dmnsn_object_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans);
+
+/**
+ * Object precomputation callback.
+ * @param[in,out] object The object to precompute.
+ */
+typedef void dmnsn_object_precompute_fn(dmnsn_object *object);
/** Object callbacks. */
typedef struct dmnsn_object_vtable {
dmnsn_object_intersection_fn *intersection_fn; /**< Intersection callback. */
dmnsn_object_inside_fn *inside_fn; /**< Inside callback. */
- dmnsn_object_initialize_fn *initialize_fn; /**< Initialization callback. */
+ dmnsn_object_bounding_fn *bounding_fn; /**< Bounding callback. */
+ dmnsn_object_precompute_fn *precompute_fn; /**< Precomputation callback. */
} dmnsn_object_vtable;
/** An object. */
@@ -82,16 +87,16 @@ struct dmnsn_object {
dmnsn_interior *interior; /**< Interior properties. */
dmnsn_matrix trans; /**< Transformation matrix. */
- dmnsn_matrix trans_inv; /**< Inverse of the transformation matrix. */
dmnsn_matrix intrinsic_trans; /**< Transformations intrinsic to the object. */
- dmnsn_matrix pigment_trans; /**< Inverse transformation for the texture. */
-
- dmnsn_bounding_box bounding_box; /**< Object bounding box. */
dmnsn_array *children; /**< Child objects. */
bool split_children; /**< Whether the child objects can be split. */
- bool initialized; /**< @internal Whether the object is initialized yet. */
+ /* Precomputed values */
+ bool precomputed; /**< @internal Whether the object is precomputed yet. */
+ dmnsn_matrix trans_inv; /**< Inverse of the transformation matrix. */
+ dmnsn_matrix pigment_trans; /**< Inverse transformation for the texture. */
+ dmnsn_bounding_box bounding_box; /**< Bounding box in world coordinates. */
};
/**
@@ -108,10 +113,10 @@ dmnsn_object *dmnsn_new_object(dmnsn_pool *pool);
void dmnsn_init_object(dmnsn_object *object);
/**
- * Initialize an object and potentially its children.
- * @param[in,out] object The object to initialize.
+ * Precompute values for an object and its children.
+ * @param[in,out] object The object to precompute.
*/
-void dmnsn_object_initialize(dmnsn_object *object);
+void dmnsn_object_precompute(dmnsn_object *object);
/**
* Appropriately transform a ray, then test for an intersection.