summaryrefslogtreecommitdiff
path: root/src/modules/ray
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2017-06-02 11:28:45 -0700
committerVito Caputo <vcaputo@pengaru.com>2017-06-02 11:28:45 -0700
commita2ca88eba63a98b50a5a7d037d476a9b041c5413 (patch)
tree8ec724237c8e000f7bc99f2c39fa9c9a4173c251 /src/modules/ray
parent90d3a46622d9af4dd9a1ade5cd3491810c3cc3ab (diff)
ray: precompute primary ray for ray_object_sphere_t
This gets rid of some computation on the primary ray:plane intersection tests The branches on depth suck though... I'm leaning towards specialized primary ray intersection test functions.
Diffstat (limited to 'src/modules/ray')
-rw-r--r--src/modules/ray/ray_object_sphere.h18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/modules/ray/ray_object_sphere.h b/src/modules/ray/ray_object_sphere.h
index 9c74752..1eb37e8 100644
--- a/src/modules/ray/ray_object_sphere.h
+++ b/src/modules/ray/ray_object_sphere.h
@@ -17,6 +17,8 @@ typedef struct ray_object_sphere_t {
ray_3f_t center;
float radius;
struct {
+ ray_3f_t primary_v;
+ float primary_dot_vv;
float r2;
float r_inv;
} _prepared;
@@ -25,6 +27,9 @@ typedef struct 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(&camera->position, &sphere->center);
+ 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() */
@@ -34,10 +39,17 @@ static void ray_object_sphere_prepare(ray_object_sphere_t *sphere, ray_camera_t
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 = ray_3f_sub(&ray->origin, &sphere->center);
- float b = ray_3f_dot(&v, &ray->direction);
- float disc = sphere->_prepared.r2 - (ray_3f_dot(&v, &v) - (b * b));
+ ray_3f_t v = sphere->_prepared.primary_v;
+ float dot_vv = sphere->_prepared.primary_dot_vv;
+ float b, disc;
+
+ if (depth != 1) {
+ v = ray_3f_sub(&ray->origin, &sphere->center);
+ 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;
© All Rights Reserved