diff options
-rw-r--r-- | src/modules/ray/Makefile.am | 2 | ||||
-rw-r--r-- | src/modules/ray/ray_object.h | 95 | ||||
-rw-r--r-- | src/modules/ray/ray_object_light.h | 59 | ||||
-rw-r--r-- | src/modules/ray/ray_object_plane.h | 45 | ||||
-rw-r--r-- | src/modules/ray/ray_object_point.h | 28 | ||||
-rw-r--r-- | src/modules/ray/ray_object_sphere.h | 74 | ||||
-rw-r--r-- | src/modules/ray/ray_render.c | 52 | ||||
-rw-r--r-- | src/modules/ray/ray_render_object.h | 121 | ||||
-rw-r--r-- | src/modules/ray/ray_render_object_plane.h | 61 | ||||
-rw-r--r-- | src/modules/ray/ray_render_object_point.h | 45 | ||||
-rw-r--r-- | src/modules/ray/ray_render_object_sphere.h | 90 |
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 |