Skip to content

Commit 148cbb7

Browse files
committed
adjust EPS values and handling, remove clamping.
1 parent 904ea9c commit 148cbb7

File tree

1 file changed

+24
-25
lines changed

1 file changed

+24
-25
lines changed

Graphics/Implicit/ObjectUtil/GetImplicit3.hs

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import qualified Data.Either as Either (either)
1414

1515
import Data.List(filter, genericIndex, length)
1616

17-
import Data.Ord (clamp)
18-
1917
import Linear (V2(V2), V3(V3), _xy, _z, distance, dot)
2018
import qualified Linear (conjugate, inv44, normalizePoint, normalize, point, rotate, Metric)
2119

@@ -230,6 +228,7 @@ getImplicit3 ctx (RotateExtrude totalRotation translate rotate symbObj) =
230228
getImplicit3 ctx (Shared3 obj) = getImplicitShared ctx obj
231229

232230
-- | Check to see if a point is inside or outside of a mesh.
231+
-- FIXME: Replace this with a winding number based approach. See: https://github.com/marmakoide/inside-3d-mesh/blob/master/README.md
233232
insideMesh :: [(V3 , V3 , V3 )] -> V3 -> Bool
234233
insideMesh triangles point = odd . length . filter (==True) $ foundIntersection point unsafeSafeRay <$> triangles
235234
where
@@ -239,16 +238,17 @@ insideMesh triangles point = odd . length . filter (==True) $ foundIntersection
239238
foundIntersection :: V3 -> V3 -> (V3 , V3 , V3 ) -> Bool
240239
foundIntersection source direction (v1, v2, v3)
241240
-- shouldn't happen, triangle is on the same plane as unsafeSafeRay
242-
| abs determinate <= eps = False
241+
| abs determinate < eps = False
243242
-- the intersection is not on the triangle (distance along vec12 out of range)
244-
| u <= eps || u > 1+eps = False
245-
| v <= eps || v > 1+eps = False
246-
| u + v > 1+eps = False
247-
| otherwise = t > 0
243+
| u < eps || u > 1-eps = False
244+
| v < eps || v > 1-eps = False
245+
| u + v > 1-eps-eps = False
246+
| otherwise = t > 0
248247
where
249248
-- fudge factor.
249+
-- adjusted from: 6,7,9,12,15,17,18==(43,171), 16 ==(38,171)
250250
eps ::
251-
eps = 1e-12
251+
eps = 1e-16
252252
-- Our edge vectors. We have picked v1 to address the space by, for convenience.
253253
vec12 = v2 - v1
254254
vec13 = v3 - v1
@@ -262,25 +262,23 @@ insideMesh triangles point = odd . length . filter (==True) $ foundIntersection
262262
u = (vec1s `dot` norm13d) / determinate
263263
-- The normal of the plane fromed by vec12 and vec1s.
264264
norm121s = vec1s `cross` vec12
265-
-- The distance along vec13 to find the intersertion of a ray from source in direction direction, and the plane our triangle is on.
265+
-- The distance along vec13 to find the intersection of a ray from source in direction direction, and the plane our triangle is on.
266266
v = (direction `dot` norm121s) / determinate
267-
-- The distance along the ray to find the intersertion of a ray from source in direction direction, and the plane our triangle is on.
267+
-- The distance along the ray to find the intersection of a ray from source in direction direction, and the plane our triangle is on.
268268
t = (vec13 `dot` norm121s) / determinate
269269

270270
-- With inspiration from: https://github.com/RenderKit/embree/blob/master/tutorials/common/math/closest_point.h
271-
-- FIXME: Sensitive to really skinny triangles; detect these, and select a different 'v1'?.
272271
distancePointToTriangle :: V3 -> (V3 ,V3 ,V3 ) ->
273272
distancePointToTriangle point (virtex1, virtex2, virtex3) = distance point closestPointToTriangleCenteredSorted
274273
where
275-
-- FIXME: Here are two precision error mitigation wrappers. Find out if they're needed.
276-
-- Reorder triangles such that we use one of the corners of the longest side to address the space in barycentric coordinates. Yes, this is wrong, but it's much more numerically stable?
274+
-- Reorder triangles such that we use the corner away from the longest side to address the space in barycentric coordinates.
277275
closestPointToTriangleCenteredSorted :: V3
278276
closestPointToTriangleCenteredSorted = closestPointToTriangleCentered adjustedTriangle
279277
where
280278
adjustedTriangle
281-
| abLength >= bcLength && abLength >= caLength = (virtex2, virtex3, virtex1)
282-
| abLength >= caLength = (virtex3, virtex1, virtex2)
283-
| otherwise = (virtex1, virtex2, virtex3)
279+
| abLength >= bcLength && abLength >= caLength = (virtex3, virtex1, virtex2)
280+
| abLength >= caLength = (virtex1, virtex2, virtex3)
281+
| otherwise = (virtex2, virtex3, virtex1)
284282
where
285283
-- Really, using length-squared. don't have to abs it, don't have to sqrt it.
286284
abLength = (virtex2-virtex1) `dot` (virtex2-virtex1)
@@ -297,18 +295,19 @@ distancePointToTriangle point (virtex1, virtex2, virtex3) = distance point close
297295
closestPointToTriangle (v1, v2, v3) p
298296
-- Closest to the virtices
299297
| d1 <= eps && d2 <= eps = v1
300-
| d3 >= -eps && d4 <= d3 = v2
301-
| d5 >= -eps && d6 <= d5 = v3
298+
| d3 > -eps && d4 <= d3 = v2
299+
| d6 > -eps && d5 <= d6 = v3
302300
-- Closest to the edges
303-
| vc <= eps && d1 >= -eps && d3 <= eps = v1 + (d1 / (d1 - d3)) *^ vec12
304-
| vb <= eps && d2 >= -eps && d6 <= eps = v1 + (d2 / (d2 - d6)) *^ vec13
305-
| va <= eps && dx >= -eps && dy >= -eps = v2 + (dx / (dx + dy)) *^ vec23
301+
| vc <= eps && d1 > -eps && d3 <= eps = v1 + (d1 / (d1 - d3)) *^ vec12
302+
| vb <= eps && d2 > -eps && d6 <= eps = v1 + (d2 / (d2 - d6)) *^ vec13
303+
| va <= eps && dx > -eps && dy > -eps = v2 + (dx / (dx + dy)) *^ vec23
306304
-- On the triangle's surface
307305
| otherwise = v1 + v *^ vec12 + w *^ vec13
308306
where
309-
-- fudge factor.
307+
-- fudge factor. chosen by tuning with our unit pyramid.
308+
-- 3,11 = 52 , 12 == 50, 13,14,15,18 == 45
310309
eps ::
311-
eps = 1e-12
310+
eps = 1e-13
312311
-- The distance along edge12 and edge23, for segment V1 -> P when translated onto the triangle's plane.
313312
-- (P when translaned? Read: a line is drawn down to the plane the triangle is on, from p, to a point that is at a right angle with said line.)
314313
d1 = vec12 `dot` vec1p
@@ -340,5 +339,5 @@ distancePointToTriangle point (virtex1, virtex2, virtex3) = distance point close
340339
-- The denominator.
341340
denom = va + vb + vc
342341
-- barycentric results, where we actually intersect.
343-
v = clamp (0,1) $ vb / denom
344-
w = clamp (0,1) $ vc / denom
342+
v = vb / denom
343+
w = vc / denom

0 commit comments

Comments
 (0)