//-*-c-*- #include #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; }