summaryrefslogtreecommitdiff
path: root/src/modules/ray
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2017-05-12 15:17:52 -0700
committerVito Caputo <vcaputo@pengaru.com>2017-05-12 18:34:40 -0700
commit73ef51a819138e50b3d0b162d61a9f272fe07d01 (patch)
tree21c76ee677da8cd15b229af4715078dbbc1da796 /src/modules/ray
parent6ebf0d428b25a8b4a2dee9af7a91c38b1f8ff124 (diff)
ray: add ray_scene_prepare() object precomputing
Just embed a _prepared struct in the object where precomputed stuff can be cached. Gets called once before rendering, which ends up calling the object-specific ray_object_$type_prepare() methods per object.
Diffstat (limited to 'src/modules/ray')
-rw-r--r--src/modules/ray/ray.c1
-rw-r--r--src/modules/ray/ray_object.c24
-rw-r--r--src/modules/ray/ray_object.h1
-rw-r--r--src/modules/ray/ray_object_light.h5
-rw-r--r--src/modules/ray/ray_object_plane.h5
-rw-r--r--src/modules/ray/ray_object_point.h5
-rw-r--r--src/modules/ray/ray_object_sphere.h11
-rw-r--r--src/modules/ray/ray_scene.c10
-rw-r--r--src/modules/ray/ray_scene.h1
9 files changed, 62 insertions, 1 deletions
diff --git a/src/modules/ray/ray.c b/src/modules/ray/ray.c
index a934c30..185b412 100644
--- a/src/modules/ray/ray.c
+++ b/src/modules/ray/ray.c
@@ -142,6 +142,7 @@ static void ray_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fra
/* tilt camera pitch in time with up and down movements, phase shifted appreciably */
camera.orientation.pitch = sinf((M_PI * 1.5f) + r * 1.3f) * .6f + -.35f;
#endif
+ ray_scene_prepare(&scene);
}
diff --git a/src/modules/ray/ray_object.c b/src/modules/ray/ray_object.c
index 4c5ccaf..ec3dcd8 100644
--- a/src/modules/ray/ray_object.c
+++ b/src/modules/ray/ray_object.c
@@ -9,6 +9,30 @@
#include "ray_surface.h"
+/* 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.
+ */
+void ray_object_prepare(ray_object_t *object)
+{
+ switch (object->type) {
+ case RAY_OBJECT_TYPE_SPHERE:
+ return ray_object_sphere_prepare(&object->sphere);
+
+ case RAY_OBJECT_TYPE_POINT:
+ return ray_object_point_prepare(&object->point);
+
+ case RAY_OBJECT_TYPE_PLANE:
+ return ray_object_plane_prepare(&object->plane);
+
+ case RAY_OBJECT_TYPE_LIGHT:
+ return ray_object_light_prepare(&object->light);
+ 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.
*/
diff --git a/src/modules/ray/ray_object.h b/src/modules/ray/ray_object.h
index abdb254..7edf955 100644
--- a/src/modules/ray/ray_object.h
+++ b/src/modules/ray/ray_object.h
@@ -17,6 +17,7 @@ typedef union ray_object_t {
ray_object_light_t light;
} ray_object_t;
+void ray_object_prepare(ray_object_t *object);
int ray_object_intersects_ray(ray_object_t *object, ray_ray_t *ray, float *res_distance);
ray_3f_t ray_object_normal(ray_object_t *object, ray_3f_t *point);
ray_surface_t ray_object_surface(ray_object_t *object, ray_3f_t *point);
diff --git a/src/modules/ray/ray_object_light.h b/src/modules/ray/ray_object_light.h
index 342c050..44b59d4 100644
--- a/src/modules/ray/ray_object_light.h
+++ b/src/modules/ray/ray_object_light.h
@@ -19,6 +19,11 @@ typedef struct ray_object_light_t {
} ray_object_light_t;
+static void ray_object_light_prepare(ray_object_light_t *light)
+{
+}
+
+
/* TODO: point is really the only one I've implemented... */
static inline int ray_object_light_intersects_ray(ray_object_light_t *light, ray_ray_t *ray, float *res_distance)
{
diff --git a/src/modules/ray/ray_object_plane.h b/src/modules/ray/ray_object_plane.h
index 8fb64c8..cc7ea8d 100644
--- a/src/modules/ray/ray_object_plane.h
+++ b/src/modules/ray/ray_object_plane.h
@@ -15,6 +15,11 @@ typedef struct ray_object_plane_t {
} ray_object_plane_t;
+static void ray_object_plane_prepare(ray_object_plane_t *plane)
+{
+}
+
+
static inline int ray_object_plane_intersects_ray(ray_object_plane_t *plane, ray_ray_t *ray, float *res_distance)
{
float d = ray_3f_dot(&plane->normal, &ray->direction);
diff --git a/src/modules/ray/ray_object_point.h b/src/modules/ray/ray_object_point.h
index c0c9610..0eddf25 100644
--- a/src/modules/ray/ray_object_point.h
+++ b/src/modules/ray/ray_object_point.h
@@ -14,6 +14,11 @@ typedef struct ray_object_point_t {
} ray_object_point_t;
+static void ray_object_point_prepare(ray_object_point_t *point)
+{
+}
+
+
static inline int ray_object_point_intersects_ray(ray_object_point_t *point, ray_ray_t *ray, float *res_distance)
{
/* TODO: determine a ray:point intersection */
diff --git a/src/modules/ray/ray_object_sphere.h b/src/modules/ray/ray_object_sphere.h
index 8a91316..cb8e665 100644
--- a/src/modules/ray/ray_object_sphere.h
+++ b/src/modules/ray/ray_object_sphere.h
@@ -15,14 +15,23 @@ typedef struct ray_object_sphere_t {
ray_surface_t surface;
ray_3f_t center;
float radius;
+ struct {
+ float r2;
+ } _prepared;
} ray_object_sphere_t;
+static void ray_object_sphere_prepare(ray_object_sphere_t *sphere)
+{
+ sphere->_prepared.r2 = sphere->radius * sphere->radius;
+}
+
+
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));
+ float disc = sphere->_prepared.r2 - (ray_3f_dot(&v, &v) - (b * b));
if (disc > 0) {
float i1, i2;
diff --git a/src/modules/ray/ray_scene.c b/src/modules/ray/ray_scene.c
index e2c7f2c..87a77af 100644
--- a/src/modules/ray/ray_scene.c
+++ b/src/modules/ray/ray_scene.c
@@ -167,3 +167,13 @@ void ray_scene_render_fragment(ray_scene_t *scene, ray_camera_t *camera, fb_frag
buf += stride;
} while (ray_camera_frame_y_step(&frame));
}
+
+
+/* prepare the scene for rendering, must be called whenever the scene has been changed. */
+void ray_scene_prepare(ray_scene_t *scene)
+{
+ unsigned i;
+
+ for (i = 0; i < scene->n_objects; i++)
+ ray_object_prepare(&scene->objects[i]);
+}
diff --git a/src/modules/ray/ray_scene.h b/src/modules/ray/ray_scene.h
index 9a31d80..d8a1e7a 100644
--- a/src/modules/ray/ray_scene.h
+++ b/src/modules/ray/ray_scene.h
@@ -20,6 +20,7 @@ typedef struct ray_scene_t {
float ambient_brightness;
} ray_scene_t;
+void ray_scene_prepare(ray_scene_t *scene);
void ray_scene_render_fragment(ray_scene_t *scene, ray_camera_t *camera, fb_fragment_t *fragment);
#endif
© All Rights Reserved