struct AABB
{
float3 center;
float3 extent;
};
bool intersectAABB(float3 origin, float3 direction, AABB box)
{
float3 boxCenter = box.center;
float3 boxExtent = box.extent;
// Transform the ray to the aligned-box coordinate system.
float3 rayOrigin = origin - boxCenter;
if (any(abs(rayOrigin) > boxExtent && rayOrigin * direction >= 0.0))
{
return false;
}
// Perform AABB-line test
float3 WxD = cross(direction, rayOrigin);
float3 absWdU = abs(direction);
if (any(WxD > float3(dot(boxExtent.yz, absWdU.zy),
dot(boxExtent.xz, absWdU.zx),
dot(boxExtent.xy, absWdU.yx))))
{
return false;
}
return true;
}
struct Triangle
{
float3 v[3];
};
bool intersectTriangle(float3 origin, float3 direction, Triangle triangle)
{
float3 diff = origin - triangle.v[0];
float3 edge1 = triangle.v[1] - triangle.v[0];
float3 edge2 = triangle.v[2] - triangle.v[0];
float3 normal = cross(edge1, edge2);
float DdN = dot(direction, normal);
float sign = 0.0;
if (DdN > 0.0)
{
sign = 1.0;
}
else if (DdN < 0)
{
sign = -1.0;
DdN = -DdN;
}
else
{
// Ray and triangle are parallel.
return false;
}
float DdQxE2 = sign * dot(direction, cross(diff, edge2));
if (DdQxE2 >= 0.0)
{
float DdE1xQ = sign * dot(direction, cross(edge1, diff));
if (DdE1xQ >= 0.0)
{
if (DdQxE2 + DdE1xQ <= DdN)
{
// Line intersects triangle, check whether ray does.
float QdN = -sign * dot(diff, normal);
if (QdN >= 0.0)
{
// Ray intersects triangle.
return true;
}
}
}
}
return false;
}