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  | 
