summaryrefslogtreecommitdiff
path: root/src/intersect.h
diff options
context:
space:
mode:
authorAnthony LaTorre <telatorre@gmail.com>2011-05-18 11:29:26 -0400
committerAnthony LaTorre <telatorre@gmail.com>2011-05-18 11:29:26 -0400
commit9306f888fea903accf827870a122a2f6f76e472e (patch)
tree0fc29e94d8e2e35f04f4d3392326f205403a7fcb /src/intersect.h
parent909309302c83423994e9c1dd36a3309890a67b90 (diff)
downloadchroma-9306f888fea903accf827870a122a2f6f76e472e.tar.gz
chroma-9306f888fea903accf827870a122a2f6f76e472e.tar.bz2
chroma-9306f888fea903accf827870a122a2f6f76e472e.zip
added some more documentation and a more accurate miniature version of lbne
Diffstat (limited to 'src/intersect.h')
-rw-r--r--src/intersect.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/intersect.h b/src/intersect.h
new file mode 100644
index 0000000..b984612
--- /dev/null
+++ b/src/intersect.h
@@ -0,0 +1,141 @@
+//-*-c-*-
+#include <math_constants.h>
+
+#include "linalg.h"
+#include "matrix.h"
+#include "rotate.h"
+
+/* Test the intersection between a ray starting from `origin` traveling in the
+ direction `direction` and a triangle defined by the vertices `v0`, `v1`, and
+ `v2`. If the ray intersects the triangle, set `distance` to the distance
+ between `origin` and the intersection and return true, else return false.
+
+ `direction` must be normalized. */
+__device__ bool intersect_triangle(const float3 &origin, const float3 &direction, const float3 &v0, const float3 &v1, const float3 &v2, float &distance)
+{
+ Matrix m = make_matrix(v1-v0, v2-v0, -direction);
+
+ float determinant = det(m);
+
+ if (determinant == 0.0f)
+ return false;
+
+ float3 b = origin-v0;
+
+ float u1 = ((m.a11*m.a22 - m.a12*m.a21)*b.x +
+ (m.a02*m.a21 - m.a01*m.a22)*b.y +
+ (m.a01*m.a12 - m.a02*m.a11)*b.z)/determinant;
+
+ if (u1 < 0.0f)
+ return false;
+
+ float u2 = ((m.a12*m.a20 - m.a10*m.a22)*b.x +
+ (m.a00*m.a22 - m.a02*m.a20)*b.y +
+ (m.a02*m.a10 - m.a00*m.a12)*b.z)/determinant;
+
+ if (u2 < 0.0f)
+ return false;
+
+ float u3 = ((m.a10*m.a21 - m.a11*m.a20)*b.x +
+ (m.a01*m.a20 - m.a00*m.a21)*b.y +
+ (m.a00*m.a11 - m.a01*m.a10)*b.z)/determinant;
+
+ if (u3 < 0.0f || (1-u1-u2) < 0.0f)
+ return false;
+
+ distance = u3;
+
+ return true;
+}
+
+/* Return the 32 bit color associated with the intersection between a ray
+ starting from `origin` traveling in the direction `direction` and the
+ plane defined by the points `v0`, `v1`, and `v2` using the cosine of the
+ angle between the ray and the plane normal to determine the brightness.
+
+ `direction` must be normalized. */
+__device__ int get_color(const float3 &direction, const float3 &v0, const float3& v1, const float3 &v2)
+{
+ float scale = 255*dot(normalize(cross(v1-v0,v2-v0)),-direction);
+
+ if (scale < 0.0f)
+ scale = 255*dot(-normalize(cross(v1-v0,v2-v0)),-direction);
+
+ int rgb = floorf(scale);
+
+ return rgb << 16 | rgb << 8 | rgb;
+}
+
+/* Test the intersection between a ray starting from `origin` traveling in the
+ direction `direction` and the axis-aligned box defined by the opposite
+ vertices `lower_bound` and `upper_bound`. If the ray intersects the box
+ return True, else return False. */
+__device__ bool intersect_box(const float3 &origin, const float3 &direction, const float3 &lower_bound, const float3 &upper_bound)
+{
+ float kmin, kmax, kymin, kymax, kzmin, kzmax;
+
+ if (direction.x >= 0.0f)
+ {
+ kmin = (lower_bound.x - origin.x)/direction.x;
+ kmax = (upper_bound.x - origin.x)/direction.x;
+ }
+ else
+ {
+ kmin = (upper_bound.x - origin.x)/direction.x;
+ kmax = (lower_bound.x - origin.x)/direction.x;
+ }
+
+ if (kmax < kmin)
+ return false;
+
+ if (direction.y >= 0.0f)
+ {
+ kymin = (lower_bound.y - origin.y)/direction.y;
+ kymax = (upper_bound.y - origin.y)/direction.y;
+ }
+ else
+ {
+ kymin = (upper_bound.y - origin.y)/direction.y;
+ kymax = (lower_bound.y - origin.y)/direction.y;
+ }
+
+ if (kymax < kymin)
+ return false;
+
+ if (kymin > kmin)
+ kmin = kymin;
+
+ if (kymax < kmax)
+ kmax = kymax;
+
+ if (kmin > kmax)
+ return false;
+
+ if (direction.z >= 0.0f)
+ {
+ kzmin = (lower_bound.z - origin.z)/direction.z;
+ kzmax = (upper_bound.z - origin.z)/direction.z;
+ }
+ else
+ {
+ kzmin = (upper_bound.z - origin.z)/direction.z;
+ kzmax = (lower_bound.z - origin.z)/direction.z;
+ }
+
+ if (kzmax < kzmin)
+ return false;
+
+ if (kzmin > kmin)
+ kmin = kzmin;
+
+ if (kzmax < kmax)
+ kmax = kzmax;
+
+ if (kmin > kmax)
+ return false;
+
+ if (kmax < 0.0f)
+ return false;
+
+ return true;
+}