summaryrefslogtreecommitdiff
path: root/src/modules/ray
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2017-09-13 18:04:31 -0700
committerVito Caputo <vcaputo@pengaru.com>2017-09-14 14:27:52 -0700
commit445e9481bbe598d1eabcae7a70534c51a52c6de5 (patch)
treecbc7156b0775a8b00ed92714f20aa882a7bfd51a /src/modules/ray
parent121846b0e35607bf8b48d5ce304a65e2657be455 (diff)
ray: simplify object iterators using sentinel type
Trivial optimization eliminates some instructions from the hot path, no need to maintain a separate index from the current object pointer.
Diffstat (limited to 'src/modules/ray')
-rw-r--r--src/modules/ray/ray.c6
-rw-r--r--src/modules/ray/ray_object_type.h1
-rw-r--r--src/modules/ray/ray_scene.c25
3 files changed, 17 insertions, 15 deletions
diff --git a/src/modules/ray/ray.c b/src/modules/ray/ray.c
index 60784db..4af9715 100644
--- a/src/modules/ray/ray.c
+++ b/src/modules/ray/ray.c
@@ -73,6 +73,8 @@ static ray_object_t objects[] = {
.center = { .x = 0.2, .y = -1.25, .z = 0.0 },
.radius = 0.6f,
}
+ }, {
+ .type = RAY_OBJECT_TYPE_SENTINEL,
}
};
@@ -89,6 +91,8 @@ static ray_object_t lights[] = {
},
}
}
+ }, {
+ .type = RAY_OBJECT_TYPE_SENTINEL,
}
};
@@ -105,9 +109,7 @@ static ray_camera_t camera = {
static ray_scene_t scene = {
.objects = objects,
- .n_objects = nelems(objects),
.lights = lights,
- .n_lights = nelems(lights),
.ambient_color = { .x = 1.0f, .y = 1.0f, .z = 1.0f },
.ambient_brightness = .04f,
};
diff --git a/src/modules/ray/ray_object_type.h b/src/modules/ray/ray_object_type.h
index 6ce20f5..ab797d2 100644
--- a/src/modules/ray/ray_object_type.h
+++ b/src/modules/ray/ray_object_type.h
@@ -2,6 +2,7 @@
#define _RAY_OBJECT_TYPE_H
typedef enum ray_object_type_t {
+ RAY_OBJECT_TYPE_SENTINEL,
RAY_OBJECT_TYPE_SPHERE,
RAY_OBJECT_TYPE_POINT,
RAY_OBJECT_TYPE_PLANE,
diff --git a/src/modules/ray/ray_scene.c b/src/modules/ray/ray_scene.c
index cf8fb44..91249f3 100644
--- a/src/modules/ray/ray_scene.c
+++ b/src/modules/ray/ray_scene.c
@@ -16,12 +16,12 @@
/* Determine if the ray is obstructed by an object within the supplied distance, for shadows */
static inline int ray_is_obstructed(ray_scene_t *scene, unsigned depth, ray_ray_t *ray, float distance)
{
- unsigned i;
+ ray_object_t *object;
- for (i = 0; i < scene->n_objects; i++) {
+ for (object = scene->objects; object->type; object++) {
float ood;
- if (ray_object_intersects_ray(&scene->objects[i], depth, ray, &ood) &&
+ if (ray_object_intersects_ray(object, depth, ray, &ood) &&
ood < distance) {
return 1;
}
@@ -61,11 +61,11 @@ static inline ray_color_t shade_intersection(ray_scene_t *scene, ray_object_t *o
{
ray_surface_t surface = ray_object_surface(object, intersection);
ray_color_t color = ray_3f_mult(&surface.color, &scene->_prepared.ambient_light);
- unsigned i;
+ ray_object_t *light;
/* visit lights for shadows and illumination */
- for (i = 0; i < scene->n_lights; i++) {
- ray_3f_t lvec = ray_3f_sub(&scene->lights[i].light.emitter.point.center, intersection);
+ for (light = scene->lights; light->type; light++) {
+ ray_3f_t lvec = ray_3f_sub(&light->light.emitter.point.center, intersection);
float ldist = ray_3f_length(&lvec);
float lvec_normal_dot;
@@ -89,7 +89,7 @@ static inline ray_color_t shade_intersection(ray_scene_t *scene, ray_object_t *o
ray_color_t specular;
/* FIXME: assumes light is a point for its color */
- specular = ray_3f_mult_scalar(&scene->lights[i].light.emitter.point.surface.color, approx_powf(rvec_lvec_dot, surface.highlight_exponent));
+ specular = ray_3f_mult_scalar(&light->light.emitter.point.surface.color, approx_powf(rvec_lvec_dot, surface.highlight_exponent));
specular = ray_3f_mult_scalar(&specular, surface.specular);
color = ray_3f_add(&color, &specular);
}
@@ -113,10 +113,9 @@ static inline ray_object_t * find_nearest_intersection(ray_scene_t *scene, ray_o
{
ray_object_t *nearest_object = NULL;
float nearest_object_distance = INFINITY;
- unsigned i;
+ ray_object_t *object;
- for (i = 0; i < scene->n_objects; i++) {
- ray_object_t *object = &scene->objects[i];
+ for (object = scene->objects; object->type; object++) {
float distance;
/* Don't bother checking if a reflected ray intersects the object reflecting it,
@@ -213,11 +212,11 @@ void ray_scene_render_fragment(ray_scene_t *scene, fb_fragment_t *fb_fragment)
/* the camera is included so primary rays which all have a common origin may be optimized for */
void ray_scene_prepare(ray_scene_t *scene, ray_camera_t *camera)
{
- unsigned i;
+ ray_object_t *object;
scene->_prepared.ambient_light = ray_3f_mult_scalar(&scene->ambient_color, scene->ambient_brightness);
ray_camera_frame_prepare(camera, &scene->_prepared.frame);
- for (i = 0; i < scene->n_objects; i++)
- ray_object_prepare(&scene->objects[i], camera);
+ for (object = scene->objects; object->type; object++)
+ ray_object_prepare(object, camera);
}
© All Rights Reserved