From a79085ab984979dbf4f78545f7592c8b47e4a794 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 7 Jun 2014 14:15:06 -0400 Subject: objects: Refactor how bounding and initialization work. --- libdimension/dimension/geometry.h | 45 +++++++++++++++++++++++++++++++++++++++ libdimension/dimension/object.h | 45 ++++++++++++++++++++++----------------- 2 files changed, 70 insertions(+), 20 deletions(-) (limited to 'libdimension/dimension') 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 @@ -40,12 +40,6 @@ typedef struct dmnsn_intersection { const dmnsn_object *object; } 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. @@ -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. -- cgit v1.2.3