summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-11-09 15:01:22 -0500
committerTavian Barnes <tavianator@gmail.com>2009-11-09 15:01:22 -0500
commit319491781c1389d82897075b6d890e74d82a08a9 (patch)
tree048b36a0fc9451db499f4f6c1d828814130a67fa
parent1044badd2e625c73eae616f6a0d10479dde54db5 (diff)
downloaddimension-319491781c1389d82897075b6d890e74d82a08a9.tar.xz
Calculate surface normals in intersection callbacks.
-rw-r--r--libdimension/dimension/object.h3
-rw-r--r--libdimension/kD_splay_tree.c12
-rw-r--r--libdimension/objects.c10
-rw-r--r--libdimension/raytrace.c9
-rw-r--r--tests/libdimension/tests.c4
5 files changed, 25 insertions, 13 deletions
diff --git a/libdimension/dimension/object.h b/libdimension/dimension/object.h
index 0f53406..0393d94 100644
--- a/libdimension/dimension/object.h
+++ b/libdimension/dimension/object.h
@@ -31,6 +31,9 @@ typedef struct {
dmnsn_line ray;
double t;
+ /* The surface normal at the intersection point */
+ dmnsn_vector normal;
+
/* The texture at the intersection point */
const dmnsn_texture *texture;
} dmnsn_intersection;
diff --git a/libdimension/kD_splay_tree.c b/libdimension/kD_splay_tree.c
index 5c6289d..77e57dd 100644
--- a/libdimension/kD_splay_tree.c
+++ b/libdimension/kD_splay_tree.c
@@ -304,10 +304,12 @@ dmnsn_kD_splay_search_recursive(dmnsn_kD_splay_node *node, dmnsn_line ray,
dmnsn_intersection *
dmnsn_kD_splay_search(dmnsn_kD_splay_tree *tree, dmnsn_line ray)
{
- dmnsn_kD_splay_search_result result;
- result = dmnsn_kD_splay_search_recursive(tree->root, ray, -1.0);
+ dmnsn_kD_splay_search_result result
+ = dmnsn_kD_splay_search_recursive(tree->root, ray, -1.0);
+
if (result.node)
dmnsn_kD_splay(tree, result.node);
+
return result.intersection;
}
@@ -353,6 +355,12 @@ dmnsn_kD_splay_search_recursive(dmnsn_kD_splay_node *node, dmnsn_line ray,
result.node = node;
result.intersection = result_temp.intersection;
t = result.intersection->t;
+
+ /* Transform the normal vector back to the observer's view */
+ result.intersection->normal = dmnsn_matrix_vector_mul(
+ node->object->trans,
+ result.intersection->normal
+ );
} else {
dmnsn_delete_intersection(result_temp.intersection);
}
diff --git a/libdimension/objects.c b/libdimension/objects.c
index 721d04d..b5e4a32 100644
--- a/libdimension/objects.c
+++ b/libdimension/objects.c
@@ -71,6 +71,7 @@ dmnsn_sphere_intersection_fn(const dmnsn_object *sphere, dmnsn_line line)
intersection = dmnsn_new_intersection();
intersection->ray = line;
intersection->t = t;
+ intersection->normal = dmnsn_line_point(line, t);
intersection->texture = sphere->texture;
}
}
@@ -114,7 +115,7 @@ static dmnsn_intersection *
dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line)
{
double t = -1.0, t_temp;
- dmnsn_vector p;
+ dmnsn_vector p, normal;
dmnsn_intersection *intersection = NULL;
/* Six ray-plane intersection tests (x, y, z) = +/- 1.0 */
@@ -127,6 +128,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line)
&& t_temp >= 0.0 && (t < 0.0 || t_temp < t))
{
t = t_temp;
+ normal = dmnsn_vector_construct(-1.0, 0.0, 0.0);
}
/* x = 1.0 */
@@ -136,6 +138,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line)
&& t_temp >= 0.0 && (t < 0.0 || t_temp < t))
{
t = t_temp;
+ normal = dmnsn_vector_construct(1.0, 0.0, 0.0);
}
}
@@ -147,6 +150,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line)
&& t_temp >= 0.0 && (t < 0.0 || t_temp < t))
{
t = t_temp;
+ normal = dmnsn_vector_construct(0.0, -1.0, 0.0);
}
/* y = 1.0 */
@@ -156,6 +160,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line)
&& t_temp >= 0.0 && (t < 0.0 || t_temp < t))
{
t = t_temp;
+ normal = dmnsn_vector_construct(0.0, 1.0, 0.0);
}
}
@@ -167,6 +172,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line)
&& t_temp >= 0.0 && (t < 0.0 || t_temp < t))
{
t = t_temp;
+ normal = dmnsn_vector_construct(0.0, 0.0, -1.0);
}
/* z = 1.0 */
@@ -176,6 +182,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line)
&& t_temp >= 0.0 && (t < 0.0 || t_temp < t))
{
t = t_temp;
+ normal = dmnsn_vector_construct(0.0, 0.0, 1.0);
}
}
@@ -183,6 +190,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line)
intersection = dmnsn_new_intersection();
intersection->ray = line;
intersection->t = t;
+ intersection->normal = normal;
intersection->texture = cube->texture;
}
diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c
index dc017f5..262929f 100644
--- a/libdimension/raytrace.c
+++ b/libdimension/raytrace.c
@@ -307,7 +307,7 @@ dmnsn_raytrace_shoot(dmnsn_line ray, dmnsn_scene *scene,
= dmnsn_kD_splay_search(kD_splay_tree, shadow_ray);
if (!shadow_caster || shadow_caster->t > 1.0) {
- dmnsn_vector object_normal = x0;
+ dmnsn_vector object_normal = intersection->normal;
dmnsn_vector normal = dmnsn_vector_normalize(
dmnsn_vector_add(
dmnsn_vector_normalize(dmnsn_vector_sub(ray.x0, x0)),
@@ -322,13 +322,6 @@ dmnsn_raytrace_shoot(dmnsn_line ray, dmnsn_scene *scene,
),
illum
);
- illum = dmnsn_color_add(
- dmnsn_color_mul(
- 0.1*dmnsn_vector_dot(normal, object_normal),
- dmnsn_color_illuminate((*light->light_fn)(light, x0), dmnsn_white)
- ),
- illum
- );
}
dmnsn_delete_intersection(shadow_caster);
diff --git a/tests/libdimension/tests.c b/tests/libdimension/tests.c
index 87cbb7b..d79434d 100644
--- a/tests/libdimension/tests.c
+++ b/tests/libdimension/tests.c
@@ -101,7 +101,7 @@ dmnsn_new_default_scene()
return NULL;
}
- cube->texture->pigment = dmnsn_new_solid_pigment(dmnsn_black);
+ cube->texture->pigment = dmnsn_new_solid_pigment(dmnsn_white);
if (!cube->texture->pigment) {
dmnsn_delete_scene(scene);
return NULL;
@@ -113,7 +113,7 @@ dmnsn_new_default_scene()
dmnsn_light *light = dmnsn_new_point_light(
dmnsn_vector_construct(-5.0, 20.0, -5.0),
- dmnsn_white
+ dmnsn_color_mul(0.9, dmnsn_white)
);
if (!light) {
dmnsn_delete_scene(scene);