summaryrefslogtreecommitdiff
path: root/modules/ray
diff options
context:
space:
mode:
Diffstat (limited to 'modules/ray')
-rw-r--r--modules/ray/Makefile.am4
-rw-r--r--modules/ray/ray.c161
-rw-r--r--modules/ray/ray.h8
-rw-r--r--modules/ray/ray_3f.h161
-rw-r--r--modules/ray/ray_camera.c85
-rw-r--r--modules/ray/ray_camera.h77
-rw-r--r--modules/ray/ray_color.h29
-rw-r--r--modules/ray/ray_euler.h45
-rw-r--r--modules/ray/ray_light_emitter.h18
-rw-r--r--modules/ray/ray_object.c74
-rw-r--r--modules/ray/ray_object.h24
-rw-r--r--modules/ray/ray_object_light.h67
-rw-r--r--modules/ray/ray_object_plane.h46
-rw-r--r--modules/ray/ray_object_point.h37
-rw-r--r--modules/ray/ray_object_sphere.h65
-rw-r--r--modules/ray/ray_object_type.h11
-rw-r--r--modules/ray/ray_ray.h11
-rw-r--r--modules/ray/ray_scene.c188
-rw-r--r--modules/ray/ray_scene.h27
-rw-r--r--modules/ray/ray_surface.h14
-rw-r--r--modules/ray/ray_threads.c111
-rw-r--r--modules/ray/ray_threads.h30
22 files changed, 0 insertions, 1293 deletions
diff --git a/modules/ray/Makefile.am b/modules/ray/Makefile.am
deleted file mode 100644
index a0b3fbb..0000000
--- a/modules/ray/Makefile.am
+++ /dev/null
@@ -1,4 +0,0 @@
-noinst_LIBRARIES = libray.a
-libray_a_SOURCES = ray_3f.h ray.c ray_camera.c ray_camera.h ray_color.h ray_euler.h ray.h ray_light_emitter.h ray_object.c ray_object.h ray_object_light.h ray_object_plane.h ray_object_point.h ray_object_sphere.h ray_object_type.h ray_ray.h ray_scene.c ray_scene.h ray_surface.h ray_threads.c ray_threads.h
-libray_a_CFLAGS = @ROTOTILLER_CFLAGS@ -ffast-math
-libray_a_CPPFLAGS = @ROTOTILLER_CFLAGS@ -I../../
diff --git a/modules/ray/ray.c b/modules/ray/ray.c
deleted file mode 100644
index 60d08cf..0000000
--- a/modules/ray/ray.c
+++ /dev/null
@@ -1,161 +0,0 @@
-#include <stdint.h>
-#include <inttypes.h>
-#include <math.h>
-
-#include "fb.h"
-#include "rototiller.h"
-#include "util.h"
-
-#include "ray_camera.h"
-#include "ray_object.h"
-#include "ray_scene.h"
-#include "ray_threads.h"
-
-/* Copyright (C) 2016 Vito Caputo <vcaputo@pengaru.com> */
-
-/* ray trace a simple scene into the fragment */
-static void ray(fb_fragment_t *fragment)
-{
- static ray_object_t objects[] = {
- {
- .plane = {
- .type = RAY_OBJECT_TYPE_PLANE,
- .surface = {
- .color = { .x = 0.4, .y = 0.2, .z = 0.5 },
- .diffuse = 1.0f,
- .specular = 0.2f,
- },
- .normal = { .x = 0.0, .y = 1.0, .z = 0.0 },
- .distance = -3.2f,
- }
- }, {
- .sphere = {
- .type = RAY_OBJECT_TYPE_SPHERE,
- .surface = {
- .color = { .x = 1.0, .y = 0.0, .z = 0.0 },
- .diffuse = 1.0f,
- .specular = 0.05f,
- },
- .center = { .x = 0.5, .y = 1.0, .z = 0.0 },
- .radius = 1.2f,
- }
- }, {
- .sphere = {
- .type = RAY_OBJECT_TYPE_SPHERE,
- .surface = {
- .color = { .x = 0.0, .y = 0.0, .z = 1.0 },
- .diffuse = 1.0f,
- .specular = 1.0f,
- },
- .center = { .x = -2.0, .y = 1.0, .z = 0.0 },
- .radius = 0.9f,
- }
- }, {
- .sphere = {
- .type = RAY_OBJECT_TYPE_SPHERE,
- .surface = {
- .color = { .x = 0.0, .y = 1.0, .z = 1.0 },
- .diffuse = 1.0f,
- .specular = 1.0f,
- },
- .center = { .x = 2.0, .y = -1.0, .z = 0.0 },
- .radius = 1.0f,
- }
- }, {
- .sphere = {
- .type = RAY_OBJECT_TYPE_SPHERE,
- .surface = {
- .color = { .x = 0.0, .y = 1.0, .z = 0.0 },
- .diffuse = 1.0f,
- .specular = 1.0f,
- },
- .center = { .x = 0.2, .y = -1.25, .z = 0.0 },
- .radius = 0.6f,
- }
- }, {
- .light = {
- .type = RAY_OBJECT_TYPE_LIGHT,
- .brightness = 1.0,
- .emitter = {
- .point.type = RAY_LIGHT_EMITTER_TYPE_POINT,
- .point.center = { .x = 3.0f, .y = 3.0f, .z = 3.0f },
- .point.surface = {
- .color = { .x = 1.0f, .y = 1.0f, .z = 1.0f },
- },
- }
- }
- }
- };
-
- ray_camera_t camera = {
- .position = { .x = 0.0, .y = 0.0, .z = 6.0 },
- .orientation = {
- .yaw = RAY_EULER_DEGREES(0.0f),
- .pitch = RAY_EULER_DEGREES(0.0f),
- .roll = RAY_EULER_DEGREES(180.0f),
- },
- .focal_length = 700.0f,
- .width = fragment->width,
- .height = fragment->height,
- };
-
- static ray_scene_t scene = {
- .objects = objects,
- .n_objects = nelems(objects),
- .lights = &objects[5],
- .n_lights = 1,
- .ambient_color = { .x = 1.0f, .y = 1.0f, .z = 1.0f },
- .ambient_brightness = .04f,
- };
- static int initialized;
- static ray_threads_t *threads;
- static fb_fragment_t *fragments;
- static unsigned ncpus;
-#if 1
- /* animated point light source */
- static double r;
-
- r += .02;
-
- scene.lights[0].light.emitter.point.center.x = cosf(r) * 3.5f;
- scene.lights[0].light.emitter.point.center.z = sinf(r) * 3.5f;
- camera.orientation.yaw = sinf(r) / 4;
- camera.orientation.pitch = sinf(r * 10) / 100;
- camera.orientation.roll = RAY_EULER_DEGREES(180.0f) + cosf(r) / 10;
- camera.position.x = cosf(r) / 10;
- camera.position.z = 4.0f + sinf(r) / 10;
-#endif
-
- if (!initialized) {
- initialized = 1;
- ncpus = get_ncpus();
-
- if (ncpus > 1) {
- threads = ray_threads_create(ncpus - 1);
- fragments = malloc(sizeof(fb_fragment_t) * ncpus);
- }
- }
-
- if (ncpus > 1) {
- /* Always recompute the fragments[] geometry.
- * This way the fragment geometry can change at any moment and things will
- * continue functioning, which may prove important later on.
- * (imagine things like a preview window, or perhaps composite modules
- * which call on other modules supplying virtual fragments of varying dimensions..)
- */
- fb_fragment_divide(fragment, ncpus, fragments);
- } else {
- fragments = fragment;
- }
-
- ray_scene_render_fragments(&scene, &camera, threads, fragments);
-}
-
-
-rototiller_renderer_t ray_renderer = {
- .render = ray,
- .name = "ray",
- .description = "Multi-threaded ray tracer",
- .author = "Vito Caputo <vcaputo@pengaru.com>",
- .license = "GPLv2",
-};
diff --git a/modules/ray/ray.h b/modules/ray/ray.h
deleted file mode 100644
index d33f96a..0000000
--- a/modules/ray/ray.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _RAY_RAY_H
-#define _RAY_RAY_H
-
-#include "fb.h"
-
-void ray(fb_fragment_t *fragment);
-
-#endif
diff --git a/modules/ray/ray_3f.h b/modules/ray/ray_3f.h
deleted file mode 100644
index 8408abb..0000000
--- a/modules/ray/ray_3f.h
+++ /dev/null
@@ -1,161 +0,0 @@
-#ifndef _RAY_3F_H
-#define _RAY_3F_H
-
-#include <math.h>
-
-typedef struct ray_3f_t {
- float x, y, z;
-} ray_3f_t;
-
-
-/* return the result of (a + b) */
-static inline ray_3f_t ray_3f_add(ray_3f_t *a, ray_3f_t *b)
-{
- ray_3f_t res = {
- .x = a->x + b->x,
- .y = a->y + b->y,
- .z = a->z + b->z,
- };
-
- return res;
-}
-
-
-/* return the result of (a - b) */
-static inline ray_3f_t ray_3f_sub(ray_3f_t *a, ray_3f_t *b)
-{
- ray_3f_t res = {
- .x = a->x - b->x,
- .y = a->y - b->y,
- .z = a->z - b->z,
- };
-
- return res;
-}
-
-
-/* return the result of (-v) */
-static inline ray_3f_t ray_3f_negate(ray_3f_t *v)
-{
- ray_3f_t res = {
- .x = -v->x,
- .y = -v->y,
- .z = -v->z,
- };
-
- return res;
-}
-
-
-/* return the result of (a * b) */
-static inline ray_3f_t ray_3f_mult(ray_3f_t *a, ray_3f_t *b)
-{
- ray_3f_t res = {
- .x = a->x * b->x,
- .y = a->y * b->y,
- .z = a->z * b->z,
- };
-
- return res;
-}
-
-
-/* return the result of (v * scalar) */
-static inline ray_3f_t ray_3f_mult_scalar(ray_3f_t *v, float scalar)
-{
- ray_3f_t res = {
- .x = v->x * scalar,
- .y = v->y * scalar,
- .z = v->z * scalar,
- };
-
- return res;
-}
-
-
-/* return the result of (uv / scalar) */
-static inline ray_3f_t ray_3f_div_scalar(ray_3f_t *v, float scalar)
-{
- ray_3f_t res = {
- .x = v->x / scalar,
- .y = v->y / scalar,
- .z = v->z / scalar,
- };
-
- return res;
-}
-
-
-/* return the result of (a . b) */
-static inline float ray_3f_dot(ray_3f_t *a, ray_3f_t *b)
-{
- return a->x * b->x + a->y * b->y + a->z * b->z;
-}
-
-
-/* return the length of the supplied vector */
-static inline float ray_3f_length(ray_3f_t *v)
-{
- return sqrtf(ray_3f_dot(v, v));
-}
-
-
-/* return the normalized form of the supplied vector */
-static inline ray_3f_t ray_3f_normalize(ray_3f_t *v)
-{
- ray_3f_t nv;
- float f;
-
- f = 1.0f / ray_3f_length(v);
-
- nv.x = f * v->x;
- nv.y = f * v->y;
- nv.z = f * v->z;
-
- return nv;
-}
-
-
-/* return the distance between two arbitrary points */
-static inline float ray_3f_distance(ray_3f_t *a, ray_3f_t *b)
-{
- return sqrtf(powf(a->x - b->x, 2) + powf(a->y - b->y, 2) + powf(a->z - b->z, 2));
-}
-
-
-/* return the cross product of two unit vectors */
-static inline ray_3f_t ray_3f_cross(ray_3f_t *a, ray_3f_t *b)
-{
- ray_3f_t product;
-
- product.x = a->y * b->z - a->z * b->y;
- product.y = a->z * b->x - a->x * b->z;
- product.z = a->x * b->y - a->y * b->x;
-
- return product;
-}
-
-
-/* return the linearly interpolated vector between the two vectors at point alpha (0-1.0) */
-static inline ray_3f_t ray_3f_lerp(ray_3f_t *a, ray_3f_t *b, float alpha)
-{
- ray_3f_t lerp_a, lerp_b;
-
- lerp_a = ray_3f_mult_scalar(a, 1.0f - alpha);
- lerp_b = ray_3f_mult_scalar(b, alpha);
-
- return ray_3f_add(&lerp_a, &lerp_b);
-}
-
-
-/* return the normalized linearly interpolated vector between the two vectors at point alpha (0-1.0) */
-static inline ray_3f_t ray_3f_nlerp(ray_3f_t *a, ray_3f_t *b, float alpha)
-{
- ray_3f_t lerp;
-
- lerp = ray_3f_lerp(a, b, alpha);
-
- return ray_3f_normalize(&lerp);
-}
-
-#endif
diff --git a/modules/ray/ray_camera.c b/modules/ray/ray_camera.c
deleted file mode 100644
index 0703c2e..0000000
--- a/modules/ray/ray_camera.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "fb.h"
-
-#include "ray_camera.h"
-#include "ray_euler.h"
-
-
-/* Produce a vector from the provided orientation vectors and proportions. */
-static ray_3f_t project_corner(ray_3f_t *forward, ray_3f_t *left, ray_3f_t *up, float focal_length, float horiz, float vert)
-{
- ray_3f_t tmp;
- ray_3f_t corner;
-
- corner = ray_3f_mult_scalar(forward, focal_length);
- tmp = ray_3f_mult_scalar(left, horiz);
- corner = ray_3f_add(&corner, &tmp);
- tmp = ray_3f_mult_scalar(up, vert);
- corner = ray_3f_add(&corner, &tmp);
-
- return ray_3f_normalize(&corner);
-}
-
-
-/* Produce vectors for the corners of the entire camera frame, used for interpolation. */
-static void project_corners(ray_camera_t *camera, ray_camera_frame_t *frame)
-{
- ray_3f_t forward, left, up, right, down;
- float half_horiz = (float)camera->width / 2.0f;
- float half_vert = (float)camera->height / 2.0f;
-
- ray_euler_basis(&camera->orientation, &forward, &up, &left);
- right = ray_3f_negate(&left);
- down = ray_3f_negate(&up);
-
- frame->nw = project_corner(&forward, &left, &up, camera->focal_length, half_horiz, half_vert);
- frame->ne = project_corner(&forward, &right, &up, camera->focal_length, half_horiz, half_vert);
- frame->se = project_corner(&forward, &right, &down, camera->focal_length, half_horiz, half_vert);
- frame->sw = project_corner(&forward, &left, &down, camera->focal_length, half_horiz, half_vert);
-}
-
-
-/* Begin a frame for the fragment of camera projection, initializing frame and ray. */
-void ray_camera_frame_begin(ray_camera_t *camera, fb_fragment_t *fragment, ray_ray_t *ray, ray_camera_frame_t *frame)
-{
- /* References are kept to the camera, fragment, and ray to be traced.
- * The ray is maintained as we step through the frame, that is the
- * purpose of this api.
- *
- * Since the ray direction should be a normalized vector, the obvious
- * implementation is a bit costly. The camera frame api hides this
- * detail so we can explore interpolation techniques to potentially
- * lessen the per-pixel cost.
- */
- frame->camera = camera;
- frame->fragment = fragment;
- frame->ray = ray;
-
- frame->x = frame->y = 0;
-
- /* From camera->orientation and camera->focal_length compute the vectors
- * through the viewport's corners, and place these normalized vectors
- * in frame->(nw,ne,sw,se).
- *
- * These can than be interpolated between to produce the ray vectors
- * throughout the frame's fragment. The efficient option of linear
- * interpolation will not maintain the unit vector length, so to
- * produce normalized interpolated directions will require the costly
- * normalize function.
- *
- * I'm hoping a simple length correction table can be used to fixup the
- * linearly interpolated vectors to make them unit vectors with just
- * scalar multiplication instead of the sqrt of normalize.
- */
- project_corners(camera, frame);
-
- frame->x_delta = 1.0f / (float)camera->width;
- frame->y_delta = 1.0f / (float)camera->height;
- frame->x_alpha = frame->x_delta * (float)fragment->x;
- frame->y_alpha = frame->y_delta * (float)fragment->y;
-
- frame->cur_w = ray_3f_nlerp(&frame->nw, &frame->sw, frame->y_alpha);
- frame->cur_e = ray_3f_nlerp(&frame->ne, &frame->se, frame->y_alpha);
-
- ray->origin = camera->position;
- ray->direction = frame->cur_w;
-}
diff --git a/modules/ray/ray_camera.h b/modules/ray/ray_camera.h
deleted file mode 100644
index 387f8c5..0000000
--- a/modules/ray/ray_camera.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef _RAY_CAMERA_H
-#define _RAY_CAMERA_H
-
-#include <math.h>
-
-#include "fb.h"
-
-#include "ray_3f.h"
-#include "ray_euler.h"
-#include "ray_ray.h"
-
-
-typedef struct ray_camera_t {
- ray_3f_t position; /* position of camera, the origin of all its rays */
- ray_euler_t orientation; /* orientation of the camera */
- float focal_length; /* controls the field of view */
- unsigned width; /* width of camera viewport in pixels */
- unsigned height; /* height of camera viewport in pixels */
-} ray_camera_t;
-
-
-typedef struct ray_camera_frame_t {
- ray_camera_t *camera; /* the camera supplied to frame_begin() */
- fb_fragment_t *fragment; /* the fragment supplied to frame_begin() */
- ray_ray_t *ray; /* the ray supplied to frame_begin(), which gets updated as we step through the frame. */
-
- ray_3f_t nw, ne, sw, se; /* directions pointing through the corners of the frame fragment */
- ray_3f_t cur_w, cur_e; /* current row's west and east ends */
- float x_alpha, y_alpha; /* interpolation position along the x and y axis */
- float x_delta, y_delta; /* interpolation step delta along the x and y axis */
- unsigned x, y; /* integral position within frame fragment */
-} ray_camera_frame_t;
-
-
-void ray_camera_frame_begin(ray_camera_t *camera, fb_fragment_t *fragment, ray_ray_t *ray, ray_camera_frame_t *frame);
-
-
-/* Step the ray through the frame on the x axis, returns 1 when rays remain on this axis, 0 at the end. */
-/* When 1 is returned, frame->ray is left pointing through the new coordinate. */
-static inline int ray_camera_frame_x_step(ray_camera_frame_t *frame)
-{
- frame->x++;
-
- if (frame->x >= frame->fragment->width) {
- frame->x = 0;
- frame->x_alpha = frame->x_delta * (float)frame->fragment->x;
- return 0;
- }
-
- frame->x_alpha += frame->x_delta;
- frame->ray->direction = ray_3f_nlerp(&frame->cur_w, &frame->cur_e, frame->x_alpha);
-
- return 1;
-}
-
-
-/* Step the ray through the frame on the y axis, returns 1 when rays remain on this axis, 0 at the end. */
-/* When 1 is returned, frame->ray is left pointing through the new coordinate. */
-static inline int ray_camera_frame_y_step(ray_camera_frame_t *frame)
-{
- frame->y++;
-
- if (frame->y >= frame->fragment->height) {
- frame->y = 0;
- frame->y_alpha = frame->y_delta * (float)frame->fragment->y;
- return 0;
- }
-
- frame->y_alpha += frame->y_delta;
- frame->cur_w = ray_3f_nlerp(&frame->nw, &frame->sw, frame->y_alpha);
- frame->cur_e = ray_3f_nlerp(&frame->ne, &frame->se, frame->y_alpha);
- frame->ray->direction = frame->cur_w;
-
- return 1;
-}
-
-#endif
diff --git a/modules/ray/ray_color.h b/modules/ray/ray_color.h
deleted file mode 100644
index 9fe62c1..0000000
--- a/modules/ray/ray_color.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _RAY_COLOR_H
-#define _RAY_COLOR_H
-
-#include <stdint.h>
-
-#include "ray_3f.h"
-
-typedef ray_3f_t ray_color_t;
-
-/* convert a vector into a packed, 32-bit rgb pixel value */
-static inline uint32_t ray_color_to_uint32_rgb(ray_color_t color) {
- uint32_t pixel;
-
- /* doing this all per-pixel, ugh. */
-
- if (color.x > 1.0f) color.x = 1.0f;
- if (color.y > 1.0f) color.y = 1.0f;
- if (color.z > 1.0f) color.z = 1.0f;
-
- pixel = (uint32_t)(color.x * 255.0f);
- pixel <<= 8;
- pixel |= (uint32_t)(color.y * 255.0f);
- pixel <<= 8;
- pixel |= (uint32_t)(color.z * 255.0f);
-
- return pixel;
-}
-
-#endif
diff --git a/modules/ray/ray_euler.h b/modules/ray/ray_euler.h
deleted file mode 100644
index 86f5221..0000000
--- a/modules/ray/ray_euler.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef _RAY_EULER_H
-#define _RAY_EULER_H
-
-#include <math.h>
-
-#include "ray_3f.h"
-
-
-/* euler angles are convenient for describing orientation */
-typedef struct ray_euler_t {
- float pitch; /* pitch in radiasn */
- float yaw; /* yaw in radians */
- float roll; /* roll in radians */
-} ray_euler_t;
-
-
-/* convenience macro for converting degrees to radians */
-#define RAY_EULER_DEGREES(_deg) \
- (_deg * (2 * M_PI / 360.0f))
-
-
-/* produce basis vectors from euler angles */
-static inline void ray_euler_basis(ray_euler_t *e, ray_3f_t *forward, ray_3f_t *up, ray_3f_t *left)
-{
- float cos_yaw = cosf(e->yaw);
- float sin_yaw = sinf(e->yaw);
- float cos_roll = cosf(e->roll);
- float sin_roll = sinf(e->roll);
- float cos_pitch = cosf(e->pitch);
- float sin_pitch = sinf(e->pitch);
-
- forward->x = sin_yaw;
- forward->y = -sin_pitch * cos_yaw;
- forward->z = cos_pitch * cos_yaw;
-
- up->x = -cos_yaw * sin_roll;
- up->y = -sin_pitch * sin_yaw * sin_roll + cos_pitch * cos_roll;
- up->z = cos_pitch * sin_yaw * sin_roll + sin_pitch * cos_roll;
-
- left->x = cos_yaw * cos_roll;
- left->y = sin_pitch * sin_yaw * cos_roll + cos_pitch * sin_roll;
- left->z = -cos_pitch * sin_yaw * cos_roll + sin_pitch * sin_roll;
-}
-
-#endif
diff --git a/modules/ray/ray_light_emitter.h b/modules/ray/ray_light_emitter.h
deleted file mode 100644
index 3b5509e..0000000
--- a/modules/ray/ray_light_emitter.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _RAY_LIGHT_EMITTER_H
-#define _RAY_LIGHT_EMITTER_H
-
-#include "ray_object_point.h"
-#include "ray_object_sphere.h"
-
-typedef enum ray_light_emitter_type_t {
- RAY_LIGHT_EMITTER_TYPE_SPHERE,
- RAY_LIGHT_EMITTER_TYPE_POINT,
-} ray_light_emitter_type_t;
-
-typedef union ray_light_emitter_t {
- ray_light_emitter_type_t type;
- ray_object_sphere_t sphere;
- ray_object_point_t point;
-} ray_light_emitter_t;
-
-#endif
diff --git a/modules/ray/ray_object.c b/modules/ray/ray_object.c
deleted file mode 100644
index 4c5ccaf..0000000
--- a/modules/ray/ray_object.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#include <assert.h>
-
-#include "ray_object.h"
-#include "ray_object_light.h"
-#include "ray_object_plane.h"
-#include "ray_object_point.h"
-#include "ray_object_sphere.h"
-#include "ray_ray.h"
-#include "ray_surface.h"
-
-
-/* Determine if a ray intersects object.
- * If the object is intersected, store where along the ray the intersection occurs in res_distance.
- */
-int ray_object_intersects_ray(ray_object_t *object, ray_ray_t *ray, float *res_distance)
-{
- switch (object->type) {
- case RAY_OBJECT_TYPE_SPHERE:
- return ray_object_sphere_intersects_ray(&object->sphere, ray, res_distance);
-
- case RAY_OBJECT_TYPE_POINT:
- return ray_object_point_intersects_ray(&object->point, ray, res_distance);
-
- case RAY_OBJECT_TYPE_PLANE:
- return ray_object_plane_intersects_ray(&object->plane, ray, res_distance);
-
- case RAY_OBJECT_TYPE_LIGHT:
- return ray_object_light_intersects_ray(&object->light, ray, res_distance);
- default:
- assert(0);
- }
-}
-
-
-/* Return the surface normal of object @ point */
-ray_3f_t ray_object_normal(ray_object_t *object, ray_3f_t *point)
-{
- switch (object->type) {
- case RAY_OBJECT_TYPE_SPHERE:
- return ray_object_sphere_normal(&object->sphere, point);
-
- case RAY_OBJECT_TYPE_POINT:
- return ray_object_point_normal(&object->point, point);
-
- case RAY_OBJECT_TYPE_PLANE:
- return ray_object_plane_normal(&object->plane, point);
-
- case RAY_OBJECT_TYPE_LIGHT:
- return ray_object_light_normal(&object->light, point);
- default:
- assert(0);
- }
-}
-
-
-/* Return the surface of object @ point */
-ray_surface_t ray_object_surface(ray_object_t *object, ray_3f_t *point)
-{
- switch (object->type) {
- case RAY_OBJECT_TYPE_SPHERE:
- return ray_object_sphere_surface(&object->sphere, point);
-
- case RAY_OBJECT_TYPE_POINT:
- return ray_object_point_surface(&object->point, point);
-
- case RAY_OBJECT_TYPE_PLANE:
- return ray_object_plane_surface(&object->plane, point);
-
- case RAY_OBJECT_TYPE_LIGHT:
- return ray_object_light_surface(&object->light, point);
- default:
- assert(0);
- }
-}
diff --git a/modules/ray/ray_object.h b/modules/ray/ray_object.h
deleted file mode 100644
index abdb254..0000000
--- a/modules/ray/ray_object.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _RAY_OBJECT_H
-#define _RAY_OBJECT_H
-
-#include "ray_object_light.h"
-#include "ray_object_plane.h"
-#include "ray_object_point.h"
-#include "ray_object_sphere.h"
-#include "ray_object_type.h"
-#include "ray_ray.h"
-#include "ray_surface.h"
-
-typedef union ray_object_t {
- ray_object_type_t type;
- ray_object_sphere_t sphere;
- ray_object_point_t point;
- ray_object_plane_t plane;
- ray_object_light_t light;
-} ray_object_t;
-
-int ray_object_intersects_ray(ray_object_t *object, ray_ray_t *ray, float *res_distance);
-ray_3f_t ray_object_normal(ray_object_t *object, ray_3f_t *point);
-ray_surface_t ray_object_surface(ray_object_t *object, ray_3f_t *point);
-
-#endif
diff --git a/modules/ray/ray_object_light.h b/modules/ray/ray_object_light.h
deleted file mode 100644
index 342c050..0000000
--- a/modules/ray/ray_object_light.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef _RAY_OBJECT_LIGHT_H
-#define _RAY_OBJECT_LIGHT_H
-
-#include <assert.h>
-
-#include "ray_light_emitter.h"
-#include "ray_object_light.h"
-#include "ray_object_point.h"
-#include "ray_object_sphere.h"
-#include "ray_object_type.h"
-#include "ray_ray.h"
-#include "ray_surface.h"
-
-
-typedef struct ray_object_light_t {
- ray_object_type_t type;
- float brightness;
- ray_light_emitter_t emitter;
-} ray_object_light_t;
-
-
-/* TODO: point is really the only one I've implemented... */
-static inline int ray_object_light_intersects_ray(ray_object_light_t *light, ray_ray_t *ray, float *res_distance)
-{
- switch (light->emitter.type) {
- case RAY_LIGHT_EMITTER_TYPE_POINT:
- return ray_object_point_intersects_ray(&light->emitter.point, ray, res_distance);
-
- case RAY_LIGHT_EMITTER_TYPE_SPHERE:
- return ray_object_sphere_intersects_ray(&light->emitter.sphere, ray, res_distance);
- default:
- assert(0);
- }
-}
-
-
-static inline ray_3f_t ray_object_light_normal(ray_object_light_t *light, ray_3f_t *point)
-{
- ray_3f_t normal;
-
- /* TODO */
- switch (light->emitter.type) {
- case RAY_LIGHT_EMITTER_TYPE_SPHERE:
- return normal;
-
- case RAY_LIGHT_EMITTER_TYPE_POINT:
- return normal;
- default:
- assert(0);
- }
-}
-
-
-static inline ray_surface_t ray_object_light_surface(ray_object_light_t *light, ray_3f_t *point)
-{
- switch (light->emitter.type) {
- case RAY_LIGHT_EMITTER_TYPE_SPHERE:
- return ray_object_sphere_surface(&light->emitter.sphere, point);
-
- case RAY_LIGHT_EMITTER_TYPE_POINT:
- return ray_object_point_surface(&light->emitter.point, point);
- default:
- assert(0);
- }
-}
-
-#endif
diff --git a/modules/ray/ray_object_plane.h b/modules/ray/ray_object_plane.h
deleted file mode 100644
index b33f342..0000000
--- a/modules/ray/ray_object_plane.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef _RAY_OBJECT_PLANE_H
-#define _RAY_OBJECT_PLANE_H
-
-#include "ray_object_type.h"
-#include "ray_ray.h"
-#include "ray_surface.h"
-
-
-typedef struct ray_object_plane_t {
- ray_object_type_t type;
- ray_surface_t surface;
- ray_3f_t normal;
- float distance;
-} ray_object_plane_t;
-
-
-static inline int ray_object_plane_intersects_ray(ray_object_plane_t *plane, ray_ray_t *ray, float *res_distance)
-{
- float d = ray_3f_dot(&plane->normal, &ray->direction);
-
- if (d != 0) {
- float distance = -(ray_3f_dot(&plane->normal, &ray->origin) + plane->distance) / d;
-
- if (distance > 0) {
- *res_distance = distance;
-
- return 1;
- }
- }
-
- return 0;
-}
-
-
-static inline ray_3f_t ray_object_plane_normal(ray_object_plane_t *plane, ray_3f_t *point)
-{
- return plane->normal;
-}
-
-
-static inline ray_surface_t ray_object_plane_surface(ray_object_plane_t *plane, ray_3f_t *point)
-{
- return plane->surface;
-}
-
-#endif
diff --git a/modules/ray/ray_object_point.h b/modules/ray/ray_object_point.h
deleted file mode 100644
index c0c9610..0000000
--- a/modules/ray/ray_object_point.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _RAY_OBJECT_POINT_H
-#define _RAY_OBJECT_POINT_H
-
-#include "ray_3f.h"
-#include "ray_object_type.h"
-#include "ray_ray.h"
-#include "ray_surface.h"
-
-
-typedef struct ray_object_point_t {
- ray_object_type_t type;
- ray_surface_t surface;
- ray_3f_t center;
-} ray_object_point_t;
-
-
-static inline int ray_object_point_intersects_ray(ray_object_point_t *point, ray_ray_t *ray, float *res_distance)
-{
- /* TODO: determine a ray:point intersection */
- return 0;
-}
-
-
-static inline ray_3f_t ray_object_point_normal(ray_object_point_t *point, ray_3f_t *_point)
-{
- ray_3f_t normal;
-
- return normal;
-}
-
-
-static inline ray_surface_t ray_object_point_surface(ray_object_point_t *point, ray_3f_t *_point)
-{
- return point->surface;
-}
-
-#endif
diff --git a/modules/ray/ray_object_sphere.h b/modules/ray/ray_object_sphere.h
deleted file mode 100644
index 85b3d93..0000000
--- a/modules/ray/ray_object_sphere.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _RAY_OBJECT_SPHERE_H
-#define _RAY_OBJECT_SPHERE_H
-
-#include <math.h>
-#include <stdio.h>
-
-#include "ray_3f.h"
-#include "ray_color.h"
-#include "ray_object_type.h"
-#include "ray_ray.h"
-#include "ray_surface.h"
-
-
-typedef struct ray_object_sphere_t {
- ray_object_type_t type;
- ray_surface_t surface;
- ray_3f_t center;
- float radius;
-} ray_object_sphere_t;
-
-
-static inline int ray_object_sphere_intersects_ray(ray_object_sphere_t *sphere, ray_ray_t *ray, float *res_distance)
-{
- ray_3f_t v = ray_3f_sub(&ray->origin, &sphere->center);
- float b = ray_3f_dot(&v, &ray->direction);
- float disc = (sphere->radius * sphere->radius) - ray_3f_dot(&v, &v) + (b * b);
-
- if (disc > 0) {
- float i1, i2;
-
- disc = sqrtf(disc);
-
- i1 = b - disc;
- i2 = b + disc;
-
- if (i2 > 0 && i1 > 0) {
- *res_distance = i1;
- return 1;
- }
- }
-
- return 0;
-}
-
-
-/* return the normal of the surface at the specified point */
-static inline ray_3f_t ray_object_sphere_normal(ray_object_sphere_t *sphere, ray_3f_t *point)
-{
- ray_3f_t normal;
-
- normal = ray_3f_sub(point, &sphere->center);
- normal = ray_3f_div_scalar(&normal, sphere->radius); /* normalize without the sqrt() */
-
- return normal;
-}
-
-
-/* return the surface of the sphere @ point */
-static inline ray_surface_t ray_object_sphere_surface(ray_object_sphere_t *sphere, ray_3f_t *point)
-{
- /* uniform solids for now... */
- return sphere->surface;
-}
-
-#endif
diff --git a/modules/ray/ray_object_type.h b/modules/ray/ray_object_type.h
deleted file mode 100644
index 6ce20f5..0000000
--- a/modules/ray/ray_object_type.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _RAY_OBJECT_TYPE_H
-#define _RAY_OBJECT_TYPE_H
-
-typedef enum ray_object_type_t {
- RAY_OBJECT_TYPE_SPHERE,
- RAY_OBJECT_TYPE_POINT,
- RAY_OBJECT_TYPE_PLANE,
- RAY_OBJECT_TYPE_LIGHT,
-} ray_object_type_t;
-
-#endif
diff --git a/modules/ray/ray_ray.h b/modules/ray/ray_ray.h
deleted file mode 100644
index 91469a2..0000000
--- a/modules/ray/ray_ray.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _RAY_RAY_H
-#define _RAY_RAY_H
-
-#include "ray_3f.h"
-
-typedef struct ray_ray_t {
- ray_3f_t origin;
- ray_3f_t direction;
-} ray_ray_t;
-
-#endif
diff --git a/modules/ray/ray_scene.c b/modules/ray/ray_scene.c
deleted file mode 100644
index e44990b..0000000
--- a/modules/ray/ray_scene.c
+++ /dev/null
@@ -1,188 +0,0 @@
-#include <stdlib.h>
-#include <math.h>
-
-#include "fb.h"
-
-#include "ray_camera.h"
-#include "ray_color.h"
-#include "ray_object.h"
-#include "ray_ray.h"
-#include "ray_scene.h"
-#include "ray_threads.h"
-
-#define MAX_RECURSION_DEPTH 5
-
-
-static ray_color_t trace_ray(ray_scene_t *scene, ray_ray_t *ray, unsigned depth);
-
-
-/* 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, ray_ray_t *ray, float distance)
-{
- unsigned i;
-
- for (i = 0; i < scene->n_objects; i++) {
- float ood;
-
- if (scene->objects[i].type == RAY_OBJECT_TYPE_LIGHT)
- continue;
-
- if (ray_object_intersects_ray(&scene->objects[i], ray, &ood) &&
- ood < distance) {
- return 1;
- }
- }
-
- return 0;
-}
-
-
-/* Determine the color @ distance on ray on object viewed from origin */
-static inline ray_color_t shade_ray(ray_scene_t *scene, ray_ray_t *ray, ray_object_t *object, float distance, unsigned depth)
-{
- ray_surface_t surface;
- ray_color_t color;
- ray_3f_t rvec = ray_3f_mult_scalar(&ray->direction, distance);
- ray_3f_t intersection = ray_3f_sub(&ray->origin, &rvec);
- ray_3f_t normal = ray_object_normal(object, &intersection);
- unsigned i;
-
- surface = ray_object_surface(object, &intersection);
- color = ray_3f_mult_scalar(&scene->ambient_color, scene->ambient_brightness);
- color = ray_3f_mult(&surface.color, &color);
-
- /* 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);
- float ldist = ray_3f_length(&lvec);
- float lvec_normal_dot;
- ray_ray_t shadow_ray;
-
- lvec = ray_3f_mult_scalar(&lvec, (1.0f / ldist)); /* normalize lvec */
-#if 1
- /* skip this light if it's obstructed,
- * we must shift the origin slightly towards the light to prevent
- * spurious self-obstruction at the ray:object intersection */
- /* negate the light vector so it's pointed at the light rather than from it */
- shadow_ray.direction = ray_3f_negate(&lvec);
- shadow_ray.origin = ray_3f_mult_scalar(&shadow_ray.direction, 0.00001f);
- shadow_ray.origin = ray_3f_add(&shadow_ray.origin, &intersection);
-
- if (ray_is_obstructed(scene, &shadow_ray, ldist))
- continue;
-#endif
- lvec_normal_dot = ray_3f_dot(&normal, &lvec);
-
- if (lvec_normal_dot > 0) {
-#if 1
- float rvec_lvec_dot = ray_3f_dot(&ray->direction, &lvec);
- ray_color_t diffuse;
- ray_color_t specular;
-
- diffuse = ray_3f_mult_scalar(&surface.color, lvec_normal_dot);
- diffuse = ray_3f_mult_scalar(&diffuse, surface.diffuse);
- color = ray_3f_add(&color, &diffuse);
-
- /* FIXME: assumes light is a point for its color, and 20 is a constant "Phong exponent",
- * which should really be object/surface-specific
- */
- specular = ray_3f_mult_scalar(&scene->lights[i].light.emitter.point.surface.color, powf(rvec_lvec_dot, 20));
- specular = ray_3f_mult_scalar(&specular, surface.specular);
- color = ray_3f_add(&color, &specular);
-#else
- ray_color_t diffuse;
-
- diffuse = ray_3f_mult_scalar(&surface.color, lvec_normal_dot);
- color = ray_3f_add(&color, &diffuse);
-#endif
- }
- }
-
- /* generate a reflection ray */
-#if 1
- float dot = ray_3f_dot(&ray->direction, &normal);
- ray_ray_t reflected_ray = { .direction = ray_3f_mult_scalar(&normal, dot * 2.0f) };
- ray_3f_t reflection;
-
- reflected_ray.origin = intersection;
- reflected_ray.direction = ray_3f_sub(&ray->direction, &reflected_ray.direction);
-
- reflection = trace_ray(scene, &reflected_ray, depth + 1);
- reflection = ray_3f_mult_scalar(&reflection, surface.specular);
- color = ray_3f_add(&color, &reflection);
-#endif
-
- /* TODO: generate a refraction ray */
-
- return color;
-}
-
-
-static ray_color_t trace_ray(ray_scene_t *scene, ray_ray_t *ray, unsigned depth)
-{
- ray_object_t *nearest_object = NULL;
- float nearest_object_distance = INFINITY;
- ray_color_t color = { .x = 0.0, .y = 0.0, .z = 0.0 };
- unsigned i;
-
- depth++;
- if (depth > MAX_RECURSION_DEPTH)
- return color;
-
- for (i = 0; i < scene->n_objects; i++) {
- float distance;
-
- /* Does this ray intersect object? */
- if (ray_object_intersects_ray(&scene->objects[i], ray, &distance)) {
-
- /* Is it the nearest intersection? */
- if (!nearest_object ||
- distance < nearest_object_distance) {
- nearest_object = &scene->objects[i];
- nearest_object_distance = distance;
- }
- }
- }
-
- if (nearest_object)
- color = shade_ray(scene, ray, nearest_object, nearest_object_distance, depth);
-
- depth--;
-
- return color;
-}
-
-
-void ray_scene_render_fragment(ray_scene_t *scene, ray_camera_t *camera, fb_fragment_t *fragment)
-{
- ray_camera_frame_t frame;
- ray_ray_t ray;
- uint32_t *buf = fragment->buf;
- unsigned stride = fragment->stride / 4;
-
- ray_camera_frame_begin(camera, fragment, &ray, &frame);
- do {
- do {
- *buf = ray_color_to_uint32_rgb(trace_ray(scene, &ray, 0));
- buf++;
- } while (ray_camera_frame_x_step(&frame));
-
- buf += stride;
- } while (ray_camera_frame_y_step(&frame));
-}
-
-/* we expect fragments[threads->n_threads + 1], or fragments[1] when threads == NULL */
-void ray_scene_render_fragments(ray_scene_t *scene, ray_camera_t *camera, ray_threads_t *threads, fb_fragment_t *fragments)
-{
- unsigned n_threads = threads ? threads->n_threads + 1 : 1;
- unsigned i;
-
- for (i = 1; i < n_threads; i++)
- ray_thread_fragment_submit(&threads->threads[i - 1], scene, camera, &fragments[i]);
-
- /* always render the zero fragment in-line */
- ray_scene_render_fragment(scene, camera, &fragments[0]);
-
- for (i = 1; i < n_threads; i++)
- ray_thread_wait_idle(&threads->threads[i - 1]);
-}
diff --git a/modules/ray/ray_scene.h b/modules/ray/ray_scene.h
deleted file mode 100644
index e9781c6..0000000
--- a/modules/ray/ray_scene.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef _RAY_SCENE_H
-#define _RAY_SCENE_H
-
-#include "fb.h"
-
-#include "ray_camera.h"
-#include "ray_color.h"
-#include "ray_ray.h"
-#include "ray_threads.h"
-
-typedef union ray_object_t ray_object_t;
-
-typedef struct ray_scene_t {
- ray_object_t *objects;
- unsigned n_objects;
-
- ray_object_t *lights;
- unsigned n_lights;
-
- ray_color_t ambient_color;
- float ambient_brightness;
-} ray_scene_t;
-
-void ray_scene_render_fragments(ray_scene_t *scene, ray_camera_t *camera, ray_threads_t *threads, fb_fragment_t *fragments);
-void ray_scene_render_fragment(ray_scene_t *scene, ray_camera_t *camera, fb_fragment_t *fragment);
-
-#endif
diff --git a/modules/ray/ray_surface.h b/modules/ray/ray_surface.h
deleted file mode 100644
index b3e3c68..0000000
--- a/modules/ray/ray_surface.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _RAY_MATERIAL_H
-#define _RAY_MATERIAL_H
-
-#include "ray_3f.h"
-#include "ray_color.h"
-
-/* Surface properties we expect every object to be able to introspect */
-typedef struct ray_surface_t {
- ray_color_t color;
- float specular;
- float diffuse;
-} ray_surface_t;
-
-#endif
diff --git a/modules/ray/ray_threads.c b/modules/ray/ray_threads.c
deleted file mode 100644
index 2369687..0000000
--- a/modules/ray/ray_threads.c
+++ /dev/null
@@ -1,111 +0,0 @@
-#include <pthread.h>
-#include <stdlib.h>
-
-#include "fb.h"
-
-#include "ray_scene.h"
-#include "ray_threads.h"
-
-#define BUSY_WAIT_NUM 1000000000 /* How much to spin before sleeping in pthread_cond_wait() */
-
-/* for now assuming x86 */
-#define cpu_relax() \
- __asm__ __volatile__ ( "pause\n" : : : "memory")
-
-/* This is a very simple/naive implementation, there's certainly room for improvement.
- *
- * Without the BUSY_WAIT_NUM spinning this approach seems to leave a fairly
- * substantial proportion of CPU idle while waiting for the render thread to
- * complete on my core 2 duo.
- *
- * It's probably just latency in getting the render thread woken when the work
- * is submitted, and since the fragments are split equally the main thread gets
- * a head start and has to wait when it finishes first. The spinning is just
- * an attempt to avoid going to sleep while the render threads finish, there
- * still needs to be improvement in how the work is submitted.
- *
- * I haven't spent much time on optimizing the raytracer yet.
- */
-
-static void * ray_thread_func(void *_thread)
-{
- ray_thread_t *thread = _thread;
-
- for (;;) {
- pthread_mutex_lock(&thread->mutex);
- while (thread->fragment == NULL)
- pthread_cond_wait(&thread->cond, &thread->mutex);
-
- ray_scene_render_fragment(thread->scene, thread->camera, thread->fragment);
- thread->fragment = NULL;
- pthread_mutex_unlock(&thread->mutex);
- pthread_cond_signal(&thread->cond);
- }
-
- return NULL;
-}
-
-
-void ray_thread_fragment_submit(ray_thread_t *thread, ray_scene_t *scene, ray_camera_t *camera, fb_fragment_t *fragment)
-{
- pthread_mutex_lock(&thread->mutex);
- while (thread->fragment != NULL) /* XXX: never true due to ray_thread_wait_idle() */
- pthread_cond_wait(&thread->cond, &thread->mutex);
-
- thread->fragment = fragment;
- thread->scene = scene;
- thread->camera = camera;
-
- pthread_mutex_unlock(&thread->mutex);
- pthread_cond_signal(&thread->cond);
-}
-
-
-void ray_thread_wait_idle(ray_thread_t *thread)
-{
- unsigned n;
-
- /* Spin before going to sleep, the other thread should not take substantially longer. */
- for (n = 0; thread->fragment != NULL && n < BUSY_WAIT_NUM; n++)
- cpu_relax();
-
- pthread_mutex_lock(&thread->mutex);
- while (thread->fragment != NULL)
- pthread_cond_wait(&thread->cond, &thread->mutex);
- pthread_mutex_unlock(&thread->mutex);
-}
-
-
-ray_threads_t * ray_threads_create(unsigned num)
-{
- ray_threads_t *threads;
- unsigned i;
-
- threads = malloc(sizeof(ray_threads_t) + sizeof(ray_thread_t) * num);
- if (!threads)
- return NULL;
-
- for (i = 0; i < num; i++) {
- pthread_mutex_init(&threads->threads[i].mutex, NULL);
- pthread_cond_init(&threads->threads[i].cond, NULL);
- threads->threads[i].fragment = NULL;
- pthread_create(&threads->threads[i].thread, NULL, ray_thread_func, &threads->threads[i]);
- }
- threads->n_threads = num;
-
- return threads;
-}
-
-
-void ray_threads_destroy(ray_threads_t *threads)
-{
- unsigned i;
-
- for (i = 0; i < threads->n_threads; i++)
- pthread_cancel(threads->threads[i].thread);
-
- for (i = 0; i < threads->n_threads; i++)
- pthread_join(threads->threads[i].thread, NULL);
-
- free(threads);
-}
diff --git a/modules/ray/ray_threads.h b/modules/ray/ray_threads.h
deleted file mode 100644
index b4c601d..0000000
--- a/modules/ray/ray_threads.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _RAY_THREADS_H
-#define _RAY_THREADS_H
-
-#include <pthread.h>
-
-typedef struct ray_scene_t ray_scene_t;
-typedef struct ray_camera_t ray_camera_t;
-typedef struct fb_fragment_t fb_fragment_t;
-
-typedef struct ray_thread_t {
- pthread_t thread;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- ray_scene_t *scene;
- ray_camera_t *camera;
- fb_fragment_t *fragment;
-} ray_thread_t;
-
-typedef struct ray_threads_t {
- unsigned n_threads;
- ray_thread_t threads[];
-} ray_threads_t;
-
-
-ray_threads_t * ray_threads_create(unsigned num);
-void ray_threads_destroy(ray_threads_t *threads);
-
-void ray_thread_fragment_submit(ray_thread_t *thread, ray_scene_t *scene, ray_camera_t *camera, fb_fragment_t *fragment);
-void ray_thread_wait_idle(ray_thread_t *thread);
-#endif
© All Rights Reserved