From 09387c1cb66f26f1a25e7ddee776642d8236cb82 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 8 Jan 2010 15:54:55 -0500 Subject: Make recursion limit a scene parameter. --- libdimension/dimension/scene.h | 3 +++ libdimension/raytrace.c | 36 ++++++++++++++++++------------------ libdimension/scene.c | 1 + 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/libdimension/dimension/scene.h b/libdimension/dimension/scene.h index ccf3992..d873a6d 100644 --- a/libdimension/dimension/scene.h +++ b/libdimension/dimension/scene.h @@ -53,6 +53,9 @@ typedef struct { /* Rendering quality */ dmnsn_quality quality; + + /* Recursion limit */ + unsigned int limit; } dmnsn_scene; /* Create a scene */ diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c index c9dc285..2df267f 100644 --- a/libdimension/raytrace.c +++ b/libdimension/raytrace.c @@ -219,11 +219,12 @@ typedef struct dmnsn_raytrace_state { const dmnsn_scene *scene; const dmnsn_intersection *intersection; dmnsn_kD_splay_tree *kD_splay_tree; + unsigned int level; } dmnsn_raytrace_state; /* Main helper for dmnsn_raytrace_scene_impl - shoot a ray */ static dmnsn_color dmnsn_raytrace_shoot(dmnsn_raytrace_state *state, - dmnsn_line ray, unsigned int level); + dmnsn_line ray); /* Actually raytrace a scene */ static int @@ -254,8 +255,10 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene, ((double)x)/(scene->canvas->x - 1), ((double)y)/(scene->canvas->y - 1) ); + /* Shoot a ray */ - color = dmnsn_raytrace_shoot(&state, ray, 10); + state.level = scene->limit; + color = dmnsn_raytrace_shoot(&state, ray); } dmnsn_set_pixel(scene->canvas, x, y, color); @@ -311,8 +314,7 @@ dmnsn_raytrace_pigment(const dmnsn_raytrace_state *state) /* Get the color of a light ray at an intersection point */ static bool dmnsn_raytrace_light_ray(const dmnsn_raytrace_state *state, - const dmnsn_light *light, dmnsn_color *color, - unsigned int level) + const dmnsn_light *light, dmnsn_color *color) { *color = dmnsn_black; @@ -328,9 +330,8 @@ dmnsn_raytrace_light_ray(const dmnsn_raytrace_state *state, *color = (*light->light_fn)(light, x0); + unsigned int level = state->level; while (level) { - --level; - dmnsn_intersection *shadow_caster = dmnsn_kD_splay_search( state->kD_splay_tree, shadow_ray @@ -343,6 +344,7 @@ dmnsn_raytrace_light_ray(const dmnsn_raytrace_state *state, dmnsn_raytrace_state shadow_state = *state; shadow_state.intersection = shadow_caster; + shadow_state.level = level; dmnsn_color pigment = dmnsn_raytrace_pigment(&shadow_state); if (pigment.filter || pigment.trans) { @@ -357,14 +359,14 @@ dmnsn_raytrace_light_ray(const dmnsn_raytrace_state *state, } dmnsn_delete_intersection(shadow_caster); + --level; } return true; } static dmnsn_color -dmnsn_raytrace_lighting(const dmnsn_raytrace_state *state, dmnsn_color color, - unsigned int level) +dmnsn_raytrace_lighting(const dmnsn_raytrace_state *state, dmnsn_color color) { /* Use the default texture if given a NULL texture */ const dmnsn_texture *texture @@ -394,7 +396,7 @@ dmnsn_raytrace_lighting(const dmnsn_raytrace_state *state, dmnsn_color color, dmnsn_array_get(state->scene->lights, i, &light); dmnsn_color light_color; - if (dmnsn_raytrace_light_ray(state, light, &light_color, level)) { + if (dmnsn_raytrace_light_ray(state, light, &light_color)) { if (state->scene->quality & DMNSN_RENDER_FINISH && finish && finish->finish_fn) { @@ -422,8 +424,7 @@ dmnsn_raytrace_lighting(const dmnsn_raytrace_state *state, dmnsn_color color, static dmnsn_color dmnsn_raytrace_translucency(const dmnsn_raytrace_state *state, - dmnsn_color color, dmnsn_color pigment, - unsigned int level) + dmnsn_color color, dmnsn_color pigment) { dmnsn_color trans = color; if (pigment.filter || pigment.trans) { @@ -436,7 +437,7 @@ dmnsn_raytrace_translucency(const dmnsn_raytrace_state *state, trans_ray = dmnsn_line_add_epsilon(trans_ray); dmnsn_raytrace_state recursive_state = *state; - dmnsn_color rec = dmnsn_raytrace_shoot(&recursive_state, trans_ray, level); + dmnsn_color rec = dmnsn_raytrace_shoot(&recursive_state, trans_ray); dmnsn_color filtered = dmnsn_color_filter(rec, pigment); trans = dmnsn_color_add(trans, filtered); } @@ -445,12 +446,11 @@ dmnsn_raytrace_translucency(const dmnsn_raytrace_state *state, /* Shoot a ray, and calculate the color, using `color' as the background */ static dmnsn_color -dmnsn_raytrace_shoot(dmnsn_raytrace_state *state, dmnsn_line ray, - unsigned int level) +dmnsn_raytrace_shoot(dmnsn_raytrace_state *state, dmnsn_line ray) { - if (level <= 0) + if (state->level <= 0) return dmnsn_black; - --level; + --state->level; dmnsn_intersection *intersection = dmnsn_kD_splay_search(state->kD_splay_tree, ray); @@ -469,7 +469,7 @@ dmnsn_raytrace_shoot(dmnsn_raytrace_state *state, dmnsn_line ray, /* Account for finishes and shadows */ dmnsn_color illum = pigment; if (state->scene->quality & DMNSN_RENDER_LIGHTS) { - illum = dmnsn_raytrace_lighting(state, illum, level); + illum = dmnsn_raytrace_lighting(state, illum); } color = illum; @@ -478,7 +478,7 @@ dmnsn_raytrace_shoot(dmnsn_raytrace_state *state, dmnsn_line ray, trans.filter = 0.0; trans.trans = 0.0; if (state->scene->quality & DMNSN_RENDER_TRANSLUCENCY) { - trans = dmnsn_raytrace_translucency(state, trans, pigment, level); + trans = dmnsn_raytrace_translucency(state, trans, pigment); } color = trans; diff --git a/libdimension/scene.c b/libdimension/scene.c index 7a39679..78e1ffb 100644 --- a/libdimension/scene.c +++ b/libdimension/scene.c @@ -38,6 +38,7 @@ dmnsn_new_scene() scene->objects = dmnsn_new_array(sizeof(dmnsn_object *)); scene->lights = dmnsn_new_array(sizeof(dmnsn_light *)); scene->quality = DMNSN_RENDER_FULL; + scene->limit = 10; } return scene; } -- cgit v1.2.3