summaryrefslogtreecommitdiffstats
path: root/libdimension/object.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-11-06 02:08:32 -0400
committerTavian Barnes <tavianator@gmail.com>2010-11-06 02:08:32 -0400
commitb6f1834ac17a11c38091ae0c60e53f8f6320b019 (patch)
treeeb27bf99fbfa38382c3ddd07da03cfab0453deab /libdimension/object.c
parent120c523adc70af185b743e955837e1fe9e9a6785 (diff)
downloaddimension-b6f1834ac17a11c38091ae0c60e53f8f6320b019.tar.xz
Factor out transformation code from object callbacks.
Diffstat (limited to 'libdimension/object.c')
-rw-r--r--libdimension/object.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/libdimension/object.c b/libdimension/object.c
index 768cf68..873f5ee 100644
--- a/libdimension/object.c
+++ b/libdimension/object.c
@@ -71,3 +71,42 @@ dmnsn_object_init(dmnsn_object *object)
dmnsn_texture_init(object->texture);
}
}
+
+/* Helper function to transform a normal vector */
+static 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_vector_div(
+ dmnsn_new_vector(trans.n[0][3], trans.n[1][3], trans.n[2][3]),
+ trans.n[3][3]
+ )
+ )
+ );
+}
+
+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;
+ }
+}
+
+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);
+}