Sometimes the function pickWithRay() misses the front surface of a connected object and rather picks the back:
Note that rotating the sphere by 180 degrees around Y seemingly fixes it.
This error leads to serous (somewhat irreproducible) problems. Giving the object double-sided meshes also does not really help.
My suspicion is that it has to do with a “<” sign instead of a “<=” sign somewhere in the default triangle predicate. Or (worse to fix) it is a roundoff-errror, in which case the predicate probably needs some epsilon tolerance?
We already use this algorithm for the ray / triangle intersection code:
In fact, adding epsilon in the code will make things worse, as it will return a non intersection more often.
You could try a workaround by shooting an additional ray with a slightly perturbed direction. If the distance of the intersection for this ray is too different from the distance found with the first ray, shoot a third ray to decide which distance to pick.
Do you mind changing lines 216 and 224 to
bv < -EPS || bv > 1+EPS
And likewise
For a try?
My workaround is to perturb all my rays by just a little EPS to massively decrease the chance of this happening.
But I really think this should be fixed in the source somehow. Having a tiny bit of overlap of neighboring triangles is not such an issue.
I can see this. Bu this that means that the bug (a ray not hitting the front surface) is still present and it may take other a lot of effort to find out whats wrong and to discover this somewhat hidden feature. Can you come up with a use-case where a tiny default epsilon would actually hurt?
I doubt that anyone relies on the beam missing the front surface.
Is there a reason that the Ray is not working properly without RayHelper? I actually find my old comment in my code from many years ago lol:
// Add the ray helper, for some reason the ray doesnt work
// properly without adding the helper and attaching it to a mesh
// @TODO: Ask on forums?
let rayHelper = new RayHelper(ray);
The helper states that it’s useful for debugging, but I never pick anything without it. Should the documentation be changed if it’s always needed?
As mentioned, I would much prefer Epsilon to be by default bigger than zero.
Should we ask someone else? @RaananW ?
Is there a way to test it within a playground? Did you try it with the above example and does it work well?