From b5bc962e834992eeba2abdd10f6e37ee2ba20295 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Mon, 19 Mar 2018 21:39:09 -0700 Subject: ray: libize raytracer core, introduces src/libs This is the first step of breaking out all the core rendering stuffs into reusable libraries and making modules purely compositional, consumers of various included rendering/effects libraries. Expect multiple modules leveraging libray for a variety of scenes and such. Also expect compositions mixing the various libraries for more interesting visuals. --- src/libs/ray/ray_render_object_sphere.h | 90 +++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/libs/ray/ray_render_object_sphere.h (limited to 'src/libs/ray/ray_render_object_sphere.h') diff --git a/src/libs/ray/ray_render_object_sphere.h b/src/libs/ray/ray_render_object_sphere.h new file mode 100644 index 0000000..addf1f5 --- /dev/null +++ b/src/libs/ray/ray_render_object_sphere.h @@ -0,0 +1,90 @@ +#ifndef _RAY_RENDER_OBJECT_SPHERE_H +#define _RAY_RENDER_OBJECT_SPHERE_H + +#include + +#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(const ray_object_sphere_t *sphere, const 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 -- cgit v1.2.1