diff options
Diffstat (limited to 'libdimension/dimension')
-rw-r--r-- | libdimension/dimension/object.h | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/libdimension/dimension/object.h b/libdimension/dimension/object.h index 267a515..794d99e 100644 --- a/libdimension/dimension/object.h +++ b/libdimension/dimension/object.h @@ -113,6 +113,25 @@ void dmnsn_delete_object(dmnsn_object *object); */ void dmnsn_initialize_object(dmnsn_object *object); + +/** + * Transform a surface normal vector. + * @param[in] trans The transformation matrix. + * @param[in] normal The normal vector to transform + * @return The transformed normal vector. + */ +DMNSN_INLINE dmnsn_vector +dmnsn_transform_normal(dmnsn_matrix trans, dmnsn_vector normal) +{ + return dmnsn_vector_normalize( + dmnsn_vector_sub( + dmnsn_transform_vector(trans, normal), + /* Optimized form of dmnsn_transform_vector(trans, dmnsn_zero) */ + dmnsn_new_vector(trans.n[0][3], trans.n[1][3], trans.n[2][3]) + ) + ); +} + /** * Appropriately transform a ray, then test for an intersection. * @param[in] object The object to test. @@ -120,8 +139,21 @@ void dmnsn_initialize_object(dmnsn_object *object); * @param[out] intersection Where to store the intersection details. * @return Whether there was an intersection. */ -bool dmnsn_object_intersection(const dmnsn_object *object, dmnsn_line line, - dmnsn_intersection *intersection); +DMNSN_INLINE bool +dmnsn_object_intersection(const dmnsn_object *object, dmnsn_line line, + dmnsn_intersection *intersection) +{ + dmnsn_line line_trans = dmnsn_transform_line(object->trans_inv, line); + if ((*object->intersection_fn)(object, line_trans, intersection)) { + /* Get us back into world coordinates */ + intersection->ray = line; + intersection->normal = dmnsn_transform_normal(object->trans, + intersection->normal); + return true; + } else { + return false; + } +} /** * Appropriately transform a point, then test for containment. @@ -129,6 +161,11 @@ bool dmnsn_object_intersection(const dmnsn_object *object, dmnsn_line line, * @param[in] point The point to test. * @return Whether \p point was inside \p object. */ -bool dmnsn_object_inside(const dmnsn_object *object, dmnsn_vector point); +DMNSN_INLINE bool +dmnsn_object_inside(const dmnsn_object *object, dmnsn_vector point) +{ + point = dmnsn_transform_vector(object->trans_inv, point); + return (*object->inside_fn)(object, point); +} #endif /* DIMENSION_OBJECT_H */ |