Picking sometimes returns infinite distances

I have been experiencing a problem when occasionally geometry picking will return that objects are an an infinite distance away (even though they aren’t) this was the cause of Invalid Matrix4f error I reported previously.

I haven’t been able to produce a simple test case but I have been able to catch it in the debugger and all the input values are reasonably sized (definitely non infinite) values

I can see in BIHNode this code

    float t = r.intersects(v1, v2, v3); // <-- t is finite here
    if (!Float.isInfinite(t)) {
           if (worldMatrix != null) {
                 worldMatrix.mult(v1, v1);
                 worldMatrix.mult(v2, v2);
                 worldMatrix.mult(v3, v3);
                 float t_world = new Ray(o, d).intersects(v1, v2, v3);
                 t = t_world;  // <-- t is infinite here
            }

            Vector3f contactNormal = Triangle.computeTriangleNormal(v1, v2, v3, null);
            Vector3f contactPoint = new Vector3f(d).multLocal(t).addLocal(o);
            float worldSpaceDist = o.distance(contactPoint);

            CollisionResult cr = new CollisionResult(contactPoint, worldSpaceDist); //<--- debugger catches it here as worldSpaceDist infinite
            cr.setContactNormal(contactNormal);
            cr.setTriangleIndex(tree.getTriangleIndex(i));
            results.addCollision(cr);
            cols++;
    }

My understanding of this code is limited. But i think that this first tries to determine if the collision occurs in local coordinates (because that is cheaper). And then if it does then it does the calculation a second time in global coordinates to get the real answer.

What I was wondering is; is my problem that there is a glancing blow across the very very edge of a geometry and (because of numeric precision) in local coordinates it just hits and in world coordinates it just misses (which Ray#intersects reports as positive infinity).

If so would the answer be to put in another !Float.isInfinite(t) before it finally decides to add the collision.

[Basically I’m relatively confident of my answer but I wanted to talk it through before putting in a PR]

1 Like

I imagine most code doesn’t hit this (mine wouldn’t at least) because it distance checks the results based on some sanity distance. The length on the ray is just a suggestion so it’s common to bake that into the result iterator.

Your hypothesis about why it happens may be correct and an additional infinity check is probably warranted here… with a comment. It’s kind of a shame that work has to be done twice, and in a potentially less accurate way, to get the final answer.

Yeah, what I’m doing is putting a pick marker (in 3D) on whatever is pointed at (it’s a tamarin behaviour for picklines) and I don’t care how far away it is I just grab the closest thing and put a marker on it. The new assertions are tripping me up because they don’t like things put at an infinite distance. (Obviously I could do a distance check and probably will) but I’d rather JME didn’t produce weird results).

I’ll put in a PR

PR #2284 Double check the collision really has happened in world space by richardTingle · Pull Request #2285 · jMonkeyEngine/jmonkeyengine · GitHub

2 Likes