From 1a9ece2041fe6feb3a39ccff86b93b21d801f498 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 4 Jun 2014 15:06:30 -0400 Subject: triangles: Don't forget to transform normals. This fixes the artifacts seen when rendering meshes. --- libdimension/bench/triangle.c | 2 +- libdimension/triangle.c | 30 ++++++++++++++++-------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/libdimension/bench/triangle.c b/libdimension/bench/triangle.c index 297417c..b149c27 100644 --- a/libdimension/bench/triangle.c +++ b/libdimension/bench/triangle.c @@ -54,7 +54,7 @@ main(void) dmnsn_assert(intersected, "Didn't intersect"); printf("dmnsn_triangle_intersection(true): %ld\n", sandglass.grains); - /* Intersecting case */ + /* Non-intersecting case */ line = dmnsn_new_line(dmnsn_new_vector(3.0, 3.0, -1.0), dmnsn_z); sandglass_bench_fine(&sandglass, { intersected = dmnsn_object_intersection(triangle, line, &intersection); diff --git a/libdimension/triangle.c b/libdimension/triangle.c index 8e584d8..f7081b4 100644 --- a/libdimension/triangle.c +++ b/libdimension/triangle.c @@ -79,9 +79,21 @@ dmnsn_new_triangle(dmnsn_pool *pool, dmnsn_vector vertices[3]) dmnsn_object * dmnsn_new_smooth_triangle(dmnsn_pool *pool, dmnsn_vector vertices[3], dmnsn_vector normals[3]) { - dmnsn_vector na = dmnsn_vector_normalized(normals[0]); - dmnsn_vector nb = dmnsn_vector_normalized(normals[1]); - dmnsn_vector nc = dmnsn_vector_normalized(normals[2]); + /* + * Make a change-of-basis matrix + * + * The new vector space has corners at <0, 1, 0>, <0, 0, 1>, 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); + dmnsn_matrix P = dmnsn_new_matrix4(ab, ac, normal, vertices[0]); + + /* 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_triangle *triangle = DMNSN_PALLOC(pool, dmnsn_triangle); triangle->na = na; @@ -94,17 +106,7 @@ dmnsn_new_smooth_triangle(dmnsn_pool *pool, dmnsn_vector vertices[3], dmnsn_vect object->inside_fn = dmnsn_triangle_inside_fn; object->bounding_box.min = dmnsn_zero; object->bounding_box.max = dmnsn_new_vector(1.0, 1.0, 0.0); - - /* - * Make a change-of-basis matrix - * - * The new vector space has corners at <0, 1, 0>, <0, 0, 1>, 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); - object->intrinsic_trans = dmnsn_new_matrix4(ab, ac, normal, vertices[0]); + object->intrinsic_trans = P; return object; } -- cgit v1.2.3