diff options
author | Vito Caputo <vcaputo@gnugeneration.com> | 2016-12-13 07:57:56 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@gnugeneration.com> | 2016-12-13 08:01:22 -0800 |
commit | 8340e615d46615894b44b4ffce5dc2dd86cbad40 (patch) | |
tree | ca9f82767d360f03e09425f21e35d0188eb52d1c /modules/ray/ray_object_sphere.h | |
parent | 8add1663d9a02db2bc65224cdceb480733a81379 (diff) |
ray: introduce a rudimentary ray tracer
My first ray tracer, it only has spheres, planes, and point light sources.
No texture mapping, no soft shadows, no global illumination.
This is all very basic right now, the camera movement is simple and boring, but
sufficient for further development and optimization.
I made some effort to support multiple CPUs, it should detect the number of
CPUs in the system and use enough pthreads to keep them busy.
Jacco Bikker's tutorial on flipcode was the original impetus to do this, and
definitely served as a guide early on.
Diffstat (limited to 'modules/ray/ray_object_sphere.h')
-rw-r--r-- | modules/ray/ray_object_sphere.h | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/modules/ray/ray_object_sphere.h b/modules/ray/ray_object_sphere.h new file mode 100644 index 0000000..6786bb7 --- /dev/null +++ b/modules/ray/ray_object_sphere.h @@ -0,0 +1,66 @@ +#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_scene.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 |