diff --git a/modules/intersect.lua b/modules/intersect.lua index b982943..512d1f5 100644 --- a/modules/intersect.lua +++ b/modules/intersect.lua @@ -542,6 +542,59 @@ function intersect.sphere_sphere(a, b) return intersect.circle_circle(a, b) end +-- http://realtimecollisiondetection.net/blog/?p=103 +-- sphere.position is a vec3 +-- sphere.radius is a number +-- triangle[1] is a vec3 +-- triangle[2] is a vec3 +-- triangle[3] is a vec3 +function intersect.sphere_trianlge(sphere, triangle) + local A = triangle[1] - sphere.position + local B = triangle[2] - sphere.position + local C = triangle[3] - sphere.position + + local rr = sphere.radius * sphere.radius + local V = vec3():cross(B - A, C - A) + + local d = A:dot(V) + local e = V:dot(V) + local aa = A:dot(A) + local ab = A:dot(B) + local ac = A:dot(C) + local bb = B:dot(B) + local bc = B:dot(C) + local cc = C:dot(C) + + local AB = B - A + local BC = C - B + local CA = A - C + + local d1 = ab - aa + local d2 = bc - bb + local d3 = ac - cc + + local e1 = AB:dot(AB) + local e2 = BC:dot(BC) + local e3 = CA:dot(CA) + + local Q1 = A * e1 - d1 * AB + local Q2 = B * e2 - d2 * BC + local Q3 = C * e3 - d3 * CA + local QC = C * e1 - Q1 + local QA = A * e2 - Q2 + local QB = B * e3 - Q3 + + local s1 = d * d > rr * e + local s2 = (aa > rr) and (ab > aa) and (ac > aa) + local s3 = (bb > rr) and (ab > bb) and (bc > bb) + local s4 = (cc > rr) and (ac > cc) and (bc > cc) + local s5 = (Q1:dot(Q1) > rr * e1 * e1) and (Q1:dot(QC) > 0) + local s6 = (Q2:dot(Q2) > rr * e2 * e2) and (Q2:dot(QA) > 0) + local s7 = (Q3:dot(Q3) > rr * e3 * e3) and (Q3:dot(QB) > 0) + + return s1 or s2 or s3 or s4 or s5 or s6 or s7 +end + -- sphere.position is a vec3 -- sphere.radius is a number -- frustum.left is a plane { a, b, c, d }