summaryrefslogtreecommitdiff
path: root/src/modules/ray
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/ray')
-rw-r--r--src/modules/ray/Makefile.am2
-rw-r--r--src/modules/ray/ray_object.h95
-rw-r--r--src/modules/ray/ray_object_light.h59
-rw-r--r--src/modules/ray/ray_object_plane.h45
-rw-r--r--src/modules/ray/ray_object_point.h28
-rw-r--r--src/modules/ray/ray_object_sphere.h74
-rw-r--r--src/modules/ray/ray_render.c52
-rw-r--r--src/modules/ray/ray_render_object.h121
-rw-r--r--src/modules/ray/ray_render_object_plane.h61
-rw-r--r--src/modules/ray/ray_render_object_point.h45
-rw-r--r--src/modules/ray/ray_render_object_sphere.h90
11 files changed, 347 insertions, 325 deletions
diff --git a/src/modules/ray/Makefile.am b/src/modules/ray/Makefile.am
index a0d7cb9..b62e4ba 100644
--- a/src/modules/ray/Makefile.am
+++ b/src/modules/ray/Makefile.am
@@ -1,4 +1,4 @@
noinst_LIBRARIES = libray.a
-libray_a_SOURCES = ray_3f.h ray.c ray_camera.c ray_camera.h ray_color.h ray_euler.c ray_euler.h ray_light_emitter.h 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_render.c ray_render.h ray_scene.h ray_surface.h
+libray_a_SOURCES = ray_3f.h ray.c ray_camera.c ray_camera.h ray_color.h ray_euler.c ray_euler.h ray_light_emitter.h 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_render.c ray_render.h ray_render_object.h ray_render_object_plane.h ray_render_object_point.h ray_render_object_sphere.h ray_scene.h ray_surface.h
libray_a_CFLAGS = @ROTOTILLER_CFLAGS@ -ffast-math
libray_a_CPPFLAGS = @ROTOTILLER_CFLAGS@ -I@top_srcdir@/src
diff --git a/src/modules/ray/ray_object.h b/src/modules/ray/ray_object.h
index f882e86..fc5ae1b 100644
--- a/src/modules/ray/ray_object.h
+++ b/src/modules/ray/ray_object.h
@@ -1,16 +1,11 @@
#ifndef _RAY_OBJECT_H
#define _RAY_OBJECT_H
-#include <assert.h>
-
-#include "ray_camera.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;
@@ -20,94 +15,4 @@ typedef union ray_object_t {
ray_object_light_t light;
} ray_object_t;
-
-
-/* Prepare an object for rendering.
- * If the object has any pre-calculating to do, this is where it happens.
- * The pre-calculated stuff is object-resident under a _prepared struct member.
- */
-static inline void ray_object_prepare(ray_object_t *object, ray_camera_t *camera)
-{
- switch (object->type) {
- case RAY_OBJECT_TYPE_SPHERE:
- return ray_object_sphere_prepare(&object->sphere, camera);
-
- case RAY_OBJECT_TYPE_POINT:
- return ray_object_point_prepare(&object->point, camera);
-
- case RAY_OBJECT_TYPE_PLANE:
- return ray_object_plane_prepare(&object->plane, camera);
-
- case RAY_OBJECT_TYPE_LIGHT:
- return ray_object_light_prepare(&object->light, camera);
- default:
- assert(0);
- }
-}
-
-
-/* Determine if a ray intersects object.
- * If the object is intersected, store where along the ray the intersection occurs in res_distance.
- */
-static inline int ray_object_intersects_ray(ray_object_t *object, unsigned depth, ray_ray_t *ray, float *res_distance)
-{
- switch (object->type) {
- case RAY_OBJECT_TYPE_SPHERE:
- return ray_object_sphere_intersects_ray(&object->sphere, depth, ray, res_distance);
-
- case RAY_OBJECT_TYPE_POINT:
- return ray_object_point_intersects_ray(&object->point, depth, ray, res_distance);
-
- case RAY_OBJECT_TYPE_PLANE:
- return ray_object_plane_intersects_ray(&object->plane, depth, ray, res_distance);
-
- case RAY_OBJECT_TYPE_LIGHT:
- return ray_object_light_intersects_ray(&object->light, depth, ray, res_distance);
- default:
- assert(0);
- }
-}
-
-
-/* Return the surface normal of object @ point */
-static inline 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 */
-static inline 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);
- }
-}
-
#endif
diff --git a/src/modules/ray/ray_object_light.h b/src/modules/ray/ray_object_light.h
index a6213e8..ca9bac9 100644
--- a/src/modules/ray/ray_object_light.h
+++ b/src/modules/ray/ray_object_light.h
@@ -1,16 +1,8 @@
#ifndef _RAY_OBJECT_LIGHT_H
#define _RAY_OBJECT_LIGHT_H
-#include <assert.h>
-
-#include "ray_camera.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 {
@@ -19,55 +11,4 @@ typedef struct ray_object_light_t {
ray_light_emitter_t emitter;
} ray_object_light_t;
-
-static void ray_object_light_prepare(ray_object_light_t *light, ray_camera_t *camera)
-{
-}
-
-
-/* TODO: point is really the only one I've implemented... */
-static inline int ray_object_light_intersects_ray(ray_object_light_t *light, unsigned depth, 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, depth, ray, res_distance);
-
- case RAY_LIGHT_EMITTER_TYPE_SPHERE:
- return ray_object_sphere_intersects_ray(&light->emitter.sphere, depth, 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/src/modules/ray/ray_object_plane.h b/src/modules/ray/ray_object_plane.h
index 0d3a51b..96ed437 100644
--- a/src/modules/ray/ray_object_plane.h
+++ b/src/modules/ray/ray_object_plane.h
@@ -2,9 +2,7 @@
#define _RAY_OBJECT_PLANE_H
#include "ray_3f.h"
-#include "ray_camera.h"
#include "ray_object_type.h"
-#include "ray_ray.h"
#include "ray_surface.h"
@@ -13,49 +11,6 @@ typedef struct ray_object_plane_t {
ray_surface_t surface;
ray_3f_t normal;
float distance;
- struct {
- float primary_dot_plus;
- } _prepared;
} ray_object_plane_t;
-
-static void ray_object_plane_prepare(ray_object_plane_t *plane, ray_camera_t *camera)
-{
- plane->_prepared.primary_dot_plus = (ray_3f_dot(&plane->normal, &camera->position) + plane->distance);
-}
-
-
-static inline int ray_object_plane_intersects_ray(ray_object_plane_t *plane, unsigned depth, ray_ray_t *ray, float *res_distance)
-{
- float d = ray_3f_dot(&plane->normal, &ray->direction);
-
- if (d < 0.0f) {
- float distance = plane->_prepared.primary_dot_plus;
-
- if (depth)
- distance = (ray_3f_dot(&plane->normal, &ray->origin) + plane->distance);
-
- distance /= -d;
- if (distance > 0.0f) {
- *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/src/modules/ray/ray_object_point.h b/src/modules/ray/ray_object_point.h
index 2b58f5f..5685fdc 100644
--- a/src/modules/ray/ray_object_point.h
+++ b/src/modules/ray/ray_object_point.h
@@ -2,9 +2,7 @@
#define _RAY_OBJECT_POINT_H
#include "ray_3f.h"
-#include "ray_camera.h"
#include "ray_object_type.h"
-#include "ray_ray.h"
#include "ray_surface.h"
@@ -14,30 +12,4 @@ typedef struct ray_object_point_t {
ray_3f_t center;
} ray_object_point_t;
-
-static void ray_object_point_prepare(ray_object_point_t *point, ray_camera_t *camera)
-{
-}
-
-
-static inline int ray_object_point_intersects_ray(ray_object_point_t *point, unsigned depth, 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/src/modules/ray/ray_object_sphere.h b/src/modules/ray/ray_object_sphere.h
index 0077a68..71b6334 100644
--- a/src/modules/ray/ray_object_sphere.h
+++ b/src/modules/ray/ray_object_sphere.h
@@ -1,13 +1,8 @@
#ifndef _RAY_OBJECT_SPHERE_H
#define _RAY_OBJECT_SPHERE_H
-#include <math.h>
-
#include "ray_3f.h"
-#include "ray_camera.h"
-#include "ray_color.h"
#include "ray_object_type.h"
-#include "ray_ray.h"
#include "ray_surface.h"
@@ -16,75 +11,6 @@ typedef struct ray_object_sphere_t {
ray_surface_t surface;
ray_3f_t center;
float radius;
- struct {
- ray_3f_t primary_v;
- float primary_dot_vv;
- float r2;
- float r_inv;
- } _prepared;
} ray_object_sphere_t;
-
-static void ray_object_sphere_prepare(ray_object_sphere_t *sphere, ray_camera_t *camera)
-{
- sphere->_prepared.primary_v = ray_3f_sub(&sphere->center, &camera->position);
- sphere->_prepared.primary_dot_vv = ray_3f_dot(&sphere->_prepared.primary_v, &sphere->_prepared.primary_v);
-
- sphere->_prepared.r2 = sphere->radius * sphere->radius;
-
- /* to divide by radius via multiplication in ray_object_sphere_normal() */
- sphere->_prepared.r_inv = 1.0f / sphere->radius;
-}
-
-
-static inline int ray_object_sphere_intersects_ray(ray_object_sphere_t *sphere, unsigned depth, ray_ray_t *ray, float *res_distance)
-{
- ray_3f_t v = sphere->_prepared.primary_v;
- float dot_vv = sphere->_prepared.primary_dot_vv;
- float b, disc;
-
- if (depth) {
- v = ray_3f_sub(&sphere->center, &ray->origin);
- dot_vv = ray_3f_dot(&v, &v);
- }
-
- b = ray_3f_dot(&v, &ray->direction);
- disc = sphere->_prepared.r2 - (dot_vv - (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_mult_scalar(&normal, sphere->_prepared.r_inv); /* 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/src/modules/ray/ray_render.c b/src/modules/ray/ray_render.c
index bfa5112..c17e1b9 100644
--- a/src/modules/ray/ray_render.c
+++ b/src/modules/ray/ray_render.c
@@ -5,7 +5,7 @@
#include "ray_camera.h"
#include "ray_color.h"
-#include "ray_object.h"
+#include "ray_render_object.h"
#include "ray_ray.h"
#include "ray_scene.h"
@@ -18,17 +18,19 @@ typedef struct ray_render_t {
ray_color_t ambient_light;
ray_camera_frame_t frame;
+
+ ray_render_object_t objects[];
} ray_render_t;
/* Determine if the ray is obstructed by an object within the supplied distance, for shadows */
static inline int ray_is_obstructed(ray_render_t *render, unsigned depth, ray_ray_t *ray, float distance)
{
- ray_object_t *object;
+ ray_render_object_t *object;
- for (object = render->scene->objects; object->type; object++) {
+ for (object = render->objects; object->type; object++) {
float ood;
- if (ray_object_intersects_ray(object, depth, ray, &ood) &&
+ if (ray_render_object_intersects_ray(object, depth, ray, &ood) &&
ood < distance) {
return 1;
}
@@ -64,9 +66,9 @@ static inline float approx_powf(float x, float y)
/* Determine the color @ distance on ray on object viewed from origin */
-static inline ray_color_t shade_intersection(ray_render_t *render, ray_object_t *object, ray_ray_t *ray, ray_3f_t *intersection, ray_3f_t *normal, unsigned depth, float *res_reflectivity)
+static inline ray_color_t shade_intersection(ray_render_t *render, ray_render_object_t *object, ray_ray_t *ray, ray_3f_t *intersection, ray_3f_t *normal, unsigned depth, float *res_reflectivity)
{
- ray_surface_t surface = ray_object_surface(object, intersection);
+ ray_surface_t surface = ray_render_object_surface(object, intersection);
ray_color_t color = ray_3f_mult(&surface.color, &render->ambient_light);
ray_object_t *light;
@@ -116,13 +118,13 @@ static inline ray_color_t shade_intersection(ray_render_t *render, ray_object_t
}
-static inline ray_object_t * find_nearest_intersection(ray_render_t *render, ray_object_t *reflector, ray_ray_t *ray, unsigned depth, float *res_distance)
+static inline ray_render_object_t * find_nearest_intersection(ray_render_t *render, ray_render_object_t *reflector, ray_ray_t *ray, unsigned depth, float *res_distance)
{
- ray_object_t *nearest_object = NULL;
- float nearest_object_distance = INFINITY;
- ray_object_t *object;
+ ray_render_object_t *nearest_object = NULL;
+ float nearest_object_distance = INFINITY;
+ ray_render_object_t *object;
- for (object = render->scene->objects; object->type; object++) {
+ for (object = render->objects; object->type; object++) {
float distance;
/* Don't bother checking if a reflected ray intersects the object reflecting it,
@@ -131,7 +133,7 @@ static inline ray_object_t * find_nearest_intersection(ray_render_t *render, ray
continue;
/* Does this ray intersect object? */
- if (ray_object_intersects_ray(object, depth, ray, &distance)) {
+ if (ray_render_object_intersects_ray(object, depth, ray, &distance)) {
/* Is it the nearest intersection? */
if (distance < nearest_object_distance) {
nearest_object = object;
@@ -149,15 +151,15 @@ static inline ray_object_t * find_nearest_intersection(ray_render_t *render, ray
static inline ray_color_t trace_ray(ray_render_t *render, ray_ray_t *primary_ray)
{
- ray_color_t color = { .x = 0.0f, .y = 0.0f, .z = 0.0f };
- ray_3f_t intersection, normal;
- ray_object_t *reflector = NULL;
- float relevance = 1.0f, reflectivity;
- unsigned depth = 0;
- ray_ray_t reflected_ray, *ray = primary_ray;
+ ray_color_t color = { .x = 0.0f, .y = 0.0f, .z = 0.0f };
+ ray_3f_t intersection, normal;
+ ray_render_object_t *reflector = NULL;
+ float relevance = 1.0f, reflectivity;
+ unsigned depth = 0;
+ ray_ray_t reflected_ray, *ray = primary_ray;
do {
- ray_object_t *nearest_object;
+ ray_render_object_t *nearest_object;
float nearest_distance;
if (reflector) {
@@ -179,7 +181,7 @@ static inline ray_color_t trace_ray(ray_render_t *render, ray_ray_t *primary_ray
rvec = ray_3f_mult_scalar(&ray->direction, nearest_distance);
intersection = ray_3f_add(&ray->origin, &rvec);
- normal = ray_object_normal(nearest_object, &intersection);
+ normal = ray_render_object_normal(nearest_object, &intersection);
more_color = shade_intersection(render, nearest_object, ray, &intersection, &normal, depth, &reflectivity);
more_color = ray_3f_mult_scalar(&more_color, relevance);
@@ -218,8 +220,12 @@ ray_render_t * ray_render_new(ray_scene_t *scene, ray_camera_t *camera)
{
ray_render_t *render;
ray_object_t *object;
+ unsigned i;
+
+ for (i = 0, object = scene->objects; object->type; object++)
+ i++;
- render = malloc(sizeof(ray_render_t));
+ render = malloc(sizeof(ray_render_t) + i * sizeof(ray_render_object_t));
if (!render)
return NULL;
@@ -229,8 +235,8 @@ ray_render_t * ray_render_new(ray_scene_t *scene, ray_camera_t *camera)
render->ambient_light = ray_3f_mult_scalar(&scene->ambient_color, scene->ambient_brightness);
ray_camera_frame_prepare(camera, &render->frame);
- for (object = scene->objects; object->type; object++)
- ray_object_prepare(object, camera);
+ for (i = 0, object = scene->objects; object->type; object++)
+ render->objects[i++] = ray_render_object_prepare(object, camera);
return render;
}
diff --git a/src/modules/ray/ray_render_object.h b/src/modules/ray/ray_render_object.h
new file mode 100644
index 0000000..5b4ce25
--- /dev/null
+++ b/src/modules/ray/ray_render_object.h
@@ -0,0 +1,121 @@
+#ifndef _RAY_RENDER_OBJECT_H
+#define _RAY_RENDER_OBJECT_H
+
+#include <assert.h>
+
+#include "ray_camera.h"
+#include "ray_object.h"
+#include "ray_object_type.h"
+#include "ray_render_object_plane.h"
+#include "ray_render_object_point.h"
+#include "ray_render_object_sphere.h"
+#include "ray_ray.h"
+#include "ray_surface.h"
+
+typedef union ray_render_object_t {
+ ray_object_type_t type;
+ ray_render_object_sphere_t sphere;
+ ray_render_object_point_t point;
+ ray_render_object_plane_t plane;
+} ray_render_object_t;
+
+
+
+/* Prepare an object for rendering.
+ * If the object has any pre-calculating to do, this is where it happens.
+ * The pre-calculated stuff is object-resident under a _prepared struct member.
+ */
+static inline ray_render_object_t ray_render_object_prepare(ray_object_t *object, ray_camera_t *camera)
+{
+ ray_render_object_t prepared = { .type = object->type };
+
+ switch (object->type) {
+ case RAY_OBJECT_TYPE_SPHERE:
+ prepared.sphere = ray_render_object_sphere_prepare(&object->sphere, camera);
+ break;
+
+ case RAY_OBJECT_TYPE_POINT:
+ prepared.point = ray_render_object_point_prepare(&object->point, camera);
+ break;
+
+ case RAY_OBJECT_TYPE_PLANE:
+ prepared.plane = ray_render_object_plane_prepare(&object->plane, camera);
+ break;
+
+ case RAY_OBJECT_TYPE_LIGHT:
+ /* TODO */
+ break;
+
+ default:
+ assert(0);
+ }
+
+ return prepared;
+}
+
+
+/* Determine if a ray intersects object.
+ * If the object is intersected, store where along the ray the intersection occurs in res_distance.
+ */
+static inline int ray_render_object_intersects_ray(ray_render_object_t *object, unsigned depth, ray_ray_t *ray, float *res_distance)
+{
+ switch (object->type) {
+ case RAY_OBJECT_TYPE_SPHERE:
+ return ray_render_object_sphere_intersects_ray(&object->sphere, depth, ray, res_distance);
+
+ case RAY_OBJECT_TYPE_POINT:
+ return ray_render_object_point_intersects_ray(&object->point, depth, ray, res_distance);
+
+ case RAY_OBJECT_TYPE_PLANE:
+ return ray_render_object_plane_intersects_ray(&object->plane, depth, ray, res_distance);
+
+ case RAY_OBJECT_TYPE_LIGHT:
+ /* TODO */
+ default:
+ assert(0);
+ }
+}
+
+
+/* Return the surface normal of object @ point */
+static inline ray_3f_t ray_render_object_normal(ray_render_object_t *object, ray_3f_t *point)
+{
+ switch (object->type) {
+ case RAY_OBJECT_TYPE_SPHERE:
+ return ray_render_object_sphere_normal(&object->sphere, point);
+
+ case RAY_OBJECT_TYPE_POINT:
+ return ray_render_object_point_normal(&object->point, point);
+
+ case RAY_OBJECT_TYPE_PLANE:
+ return ray_render_object_plane_normal(&object->plane, point);
+
+ case RAY_OBJECT_TYPE_LIGHT:
+ /* TODO */
+ default:
+ assert(0);
+ }
+}
+
+
+/* Return the surface of object @ point */
+static inline ray_surface_t ray_render_object_surface(ray_render_object_t *object, ray_3f_t *point)
+{
+ switch (object->type) {
+ case RAY_OBJECT_TYPE_SPHERE:
+ return ray_render_object_sphere_surface(&object->sphere, point);
+
+ case RAY_OBJECT_TYPE_POINT:
+ return ray_render_object_point_surface(&object->point, point);
+
+ case RAY_OBJECT_TYPE_PLANE:
+ return ray_render_object_plane_surface(&object->plane, point);
+
+ case RAY_OBJECT_TYPE_LIGHT:
+ /* TODO */
+ default:
+ assert(0);
+ }
+}
+
+#endif
diff --git a/src/modules/ray/ray_render_object_plane.h b/src/modules/ray/ray_render_object_plane.h
new file mode 100644
index 0000000..e5c6fa7
--- /dev/null
+++ b/src/modules/ray/ray_render_object_plane.h
@@ -0,0 +1,61 @@
+#ifndef _RAY_RENDER_OBJECT_PLANE_H
+#define _RAY_RENDER_OBJECT_PLANE_H
+
+#include "ray_3f.h"
+#include "ray_camera.h"
+#include "ray_object_plane.h"
+#include "ray_object_type.h"
+#include "ray_ray.h"
+#include "ray_surface.h"
+
+
+typedef struct ray_render_object_plane_t {
+ ray_object_plane_t object;
+ float primary_dot_plus;
+} ray_render_object_plane_t;
+
+
+static ray_render_object_plane_t ray_render_object_plane_prepare(ray_object_plane_t *plane, ray_camera_t *camera)
+{
+ ray_render_object_plane_t prepared = { .object = *plane };
+
+ prepared.primary_dot_plus = ray_3f_dot(&plane->normal, &camera->position) + plane->distance;
+
+ return prepared;
+}
+
+
+static inline int ray_render_object_plane_intersects_ray(ray_render_object_plane_t *plane, unsigned depth, ray_ray_t *ray, float *res_distance)
+{
+ float d = ray_3f_dot(&plane->object.normal, &ray->direction);
+
+ if (d < 0.0f) {
+ float distance = plane->primary_dot_plus;
+
+ if (depth)
+ distance = (ray_3f_dot(&plane->object.normal, &ray->origin) + plane->object.distance);
+
+ distance /= -d;
+ if (distance > 0.0f) {
+ *res_distance = distance;
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+static inline ray_3f_t ray_render_object_plane_normal(ray_render_object_plane_t *plane, ray_3f_t *point)
+{
+ return plane->object.normal;
+}
+
+
+static inline ray_surface_t ray_render_object_plane_surface(ray_render_object_plane_t *plane, ray_3f_t *point)
+{
+ return plane->object.surface;
+}
+
+#endif
diff --git a/src/modules/ray/ray_render_object_point.h b/src/modules/ray/ray_render_object_point.h
new file mode 100644
index 0000000..43e48a1
--- /dev/null
+++ b/src/modules/ray/ray_render_object_point.h
@@ -0,0 +1,45 @@
+#ifndef _RAY_RENDER_OBJECT_POINT_H
+#define _RAY_RENDER_OBJECT_POINT_H
+
+#include "ray_3f.h"
+#include "ray_camera.h"
+#include "ray_object_point.h"
+#include "ray_object_type.h"
+#include "ray_ray.h"
+#include "ray_surface.h"
+
+
+typedef struct ray_render_object_point_t {
+ ray_object_point_t object;
+} ray_render_object_point_t;
+
+
+static ray_render_object_point_t ray_render_object_point_prepare(ray_object_point_t *point, ray_camera_t *camera)
+{
+ ray_render_object_point_t prepared = { .object = *point };
+
+ return prepared;
+}
+
+
+static inline int ray_render_object_point_intersects_ray(ray_render_object_point_t *point, unsigned depth, ray_ray_t *ray, float *res_distance)
+{
+ /* TODO: determine a ray:point intersection */
+ return 0;
+}
+
+
+static inline ray_3f_t ray_render_object_point_normal(ray_render_object_point_t *point, ray_3f_t *_point)
+{
+ ray_3f_t normal;
+
+ return normal;
+}
+
+
+static inline ray_surface_t ray_render_object_point_surface(ray_render_object_point_t *point, ray_3f_t *_point)
+{
+ return point->object.surface;
+}
+
+#endif
diff --git a/src/modules/ray/ray_render_object_sphere.h b/src/modules/ray/ray_render_object_sphere.h
new file mode 100644
index 0000000..548eb6b
--- /dev/null
+++ b/src/modules/ray/ray_render_object_sphere.h
@@ -0,0 +1,90 @@
+#ifndef _RAY_RENDER_OBJECT_SPHERE_H
+#define _RAY_RENDER_OBJECT_SPHERE_H
+
+#include <math.h>
+
+#include "ray_3f.h"
+#include "ray_camera.h"
+#include "ray_color.h"
+#include "ray_object_sphere.h"
+#include "ray_object_type.h"
+#include "ray_ray.h"
+#include "ray_surface.h"
+
+
+typedef struct ray_render_object_sphere_t {
+ ray_object_sphere_t object;
+ ray_3f_t primary_v;
+ float primary_dot_vv;
+ float r2;
+ float r_inv;
+} ray_render_object_sphere_t;
+
+
+static ray_render_object_sphere_t ray_render_object_sphere_prepare(ray_object_sphere_t *sphere, ray_camera_t *camera)
+{
+ ray_render_object_sphere_t prepared = { .object = *sphere };
+
+ prepared.primary_v = ray_3f_sub(&sphere->center, &camera->position);
+ prepared.primary_dot_vv = ray_3f_dot(&prepared.primary_v, &prepared.primary_v);
+
+ prepared.r2 = sphere->radius * sphere->radius;
+
+ /* to divide by radius via multiplication in ray_object_sphere_normal() */
+ prepared.r_inv = 1.0f / sphere->radius;
+
+ return prepared;
+}
+
+
+static inline int ray_render_object_sphere_intersects_ray(ray_render_object_sphere_t *sphere, unsigned depth, ray_ray_t *ray, float *res_distance)
+{
+ ray_3f_t v = sphere->primary_v;
+ float dot_vv = sphere->primary_dot_vv;
+ float b, disc;
+
+ if (depth) {
+ v = ray_3f_sub(&sphere->object.center, &ray->origin);
+ dot_vv = ray_3f_dot(&v, &v);
+ }
+
+ b = ray_3f_dot(&v, &ray->direction);
+ disc = sphere->r2 - (dot_vv - (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_render_object_sphere_normal(ray_render_object_sphere_t *sphere, ray_3f_t *point)
+{
+ ray_3f_t normal;
+
+ normal = ray_3f_sub(point, &sphere->object.center);
+ normal = ray_3f_mult_scalar(&normal, sphere->r_inv); /* normalize without the sqrt() */
+
+ return normal;
+}
+
+
+/* return the surface of the sphere @ point */
+static inline ray_surface_t ray_render_object_sphere_surface(ray_render_object_sphere_t *sphere, ray_3f_t *point)
+{
+ /* uniform solids for now... */
+ return sphere->object.surface;
+}
+
+#endif
© All Rights Reserved