summaryrefslogtreecommitdiffstats
path: root/libdimension/triangle.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2014-08-19 17:10:03 -0400
committerTavian Barnes <tavianator@tavianator.com>2015-10-25 11:03:56 -0400
commit7b09710392d35fb55b52031d447a542d99fc6b4b (patch)
tree270eb927ee8c52ceeb99926ebf4843704775a610 /libdimension/triangle.c
parent200c86b91ea7063d35be3bffc11c5da53c054653 (diff)
downloaddimension-7b09710392d35fb55b52031d447a542d99fc6b4b.tar.xz
Modularize the libdimension codebase.
Diffstat (limited to 'libdimension/triangle.c')
-rw-r--r--libdimension/triangle.c162
1 files changed, 0 insertions, 162 deletions
diff --git a/libdimension/triangle.c b/libdimension/triangle.c
deleted file mode 100644
index fdd2b96..0000000
--- a/libdimension/triangle.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*************************************************************************
- * 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
- * Triangles. See
- * http://tavianator.com/2014/05/a-beautiful-raytriangle-intersection-method/
- * for a description of the intersection algorithm.
- */
-
-#include "dimension-internal.h"
-
-/// Optimized ray/triangle intersection test.
-static inline bool
-dmnsn_ray_triangle_intersection(dmnsn_line l, double *t, double *u, double *v)
-{
- // See the change of basis in dmnsn_triangle_basis()
- *t = -l.x0.z/l.n.z;
- *u = l.x0.x + (*t)*l.n.x;
- *v = l.x0.y + (*t)*l.n.y;
- return *t >= 0.0 && *u >= 0.0 && *v >= 0.0 && *u + *v <= 1.0;
-}
-
-/// Triangle intersection callback.
-DMNSN_HOT static bool
-dmnsn_triangle_intersection_fn(const dmnsn_object *object, dmnsn_line l,
- dmnsn_intersection *intersection)
-{
- double t, u, v;
- if (dmnsn_ray_triangle_intersection(l, &t, &u, &v)) {
- intersection->t = t;
- intersection->normal = dmnsn_z;
- return true;
- }
-
- return false;
-}
-
-/// Triangle inside callback.
-static bool
-dmnsn_triangle_inside_fn(const dmnsn_object *object, dmnsn_vector point)
-{
- return false;
-}
-
-/// Triangle bounding callback.
-static dmnsn_bounding_box
-dmnsn_triangle_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
-{
- dmnsn_vector a = dmnsn_transform_point(trans, dmnsn_zero);
- dmnsn_vector b = dmnsn_transform_point(trans, dmnsn_x);
- dmnsn_vector c = dmnsn_transform_point(trans, dmnsn_y);
-
- dmnsn_bounding_box box = dmnsn_new_bounding_box(a, a);
- box = dmnsn_bounding_box_swallow(box, b);
- box = dmnsn_bounding_box_swallow(box, c);
- return box;
-}
-
-/// Triangle vtable.
-static const dmnsn_object_vtable dmnsn_triangle_vtable = {
- .intersection_fn = dmnsn_triangle_intersection_fn,
- .inside_fn = dmnsn_triangle_inside_fn,
- .bounding_fn = dmnsn_triangle_bounding_fn,
-};
-
-/// Smooth triangle type.
-typedef struct {
- dmnsn_object object;
- dmnsn_vector na, nab, nac;
-} dmnsn_smooth_triangle;
-
-/// Smooth triangle intersection callback.
-DMNSN_HOT static bool
-dmnsn_smooth_triangle_intersection_fn(const dmnsn_object *object, dmnsn_line l,
- dmnsn_intersection *intersection)
-{
- const dmnsn_smooth_triangle *triangle = (const dmnsn_smooth_triangle *)object;
-
- double t, u, v;
- if (dmnsn_ray_triangle_intersection(l, &t, &u, &v)) {
- intersection->t = t;
- intersection->normal = dmnsn_vector_add(
- triangle->na,
- dmnsn_vector_add(
- dmnsn_vector_mul(u, triangle->nab),
- dmnsn_vector_mul(v, triangle->nac)
- )
- );
- return true;
- }
-
- return false;
-}
-
-/// Smooth triangle vtable.
-static const dmnsn_object_vtable dmnsn_smooth_triangle_vtable = {
- .intersection_fn = dmnsn_smooth_triangle_intersection_fn,
- .inside_fn = dmnsn_triangle_inside_fn,
- .bounding_fn = dmnsn_triangle_bounding_fn,
-};
-
-/// Make a change-of-basis matrix.
-static inline dmnsn_matrix
-dmnsn_triangle_basis(dmnsn_vector vertices[3])
-{
- // The new vector space has corners at <1, 0, 0>, <0, 1, 0>, and 0,
- // corresponding to the basis (ab, ac, ab X ac).
- dmnsn_vector ab = dmnsn_vector_sub(vertices[1], vertices[0]);
- dmnsn_vector ac = dmnsn_vector_sub(vertices[2], vertices[0]);
- dmnsn_vector normal = dmnsn_vector_cross(ab, ac);
- return dmnsn_new_matrix4(ab, ac, normal, vertices[0]);
-}
-
-dmnsn_object *
-dmnsn_new_triangle(dmnsn_pool *pool, dmnsn_vector vertices[3])
-{
- dmnsn_object *object = dmnsn_new_object(pool);
- object->vtable = &dmnsn_triangle_vtable;
- object->intrinsic_trans = dmnsn_triangle_basis(vertices);
- return object;
-}
-
-dmnsn_object *
-dmnsn_new_smooth_triangle(dmnsn_pool *pool, dmnsn_vector vertices[3], dmnsn_vector normals[3])
-{
- dmnsn_matrix P = dmnsn_triangle_basis(vertices);
-
- // Transform the given normals.
- dmnsn_vector na = dmnsn_vector_normalized(dmnsn_transform_normal(P, normals[0]));
- dmnsn_vector nb = dmnsn_vector_normalized(dmnsn_transform_normal(P, normals[1]));
- dmnsn_vector nc = dmnsn_vector_normalized(dmnsn_transform_normal(P, normals[2]));
-
- dmnsn_smooth_triangle *triangle = DMNSN_PALLOC(pool, dmnsn_smooth_triangle);
- triangle->na = na;
- triangle->nab = dmnsn_vector_sub(nb, na);
- triangle->nac = dmnsn_vector_sub(nc, na);
-
- dmnsn_object *object = &triangle->object;
- dmnsn_init_object(object);
- object->vtable = &dmnsn_smooth_triangle_vtable;
- object->intrinsic_trans = P;
-
- return object;
-}