multiPickWithRay doesn't work inside of mesh parented to TransformNode

When the Ray originates somewhere inside of the mesh then scene.multiPickWithRay returns an array which includes that mesh. It makes sense. If the Ray is inside of the mesh, it’s obviously picking that mesh.

However if our mesh is parented to external TransformNode, the mesh will not be picked if the Ray origin is inside of the mesh. If the ray origin is outside of the mesh, it still can be picked.

Playgroud: https://playground.babylonjs.com/#H69092. You can chose the ray origin on the line 22. One variable puts origin outside of the sphere and the second puts it inside.
If you remove parent and put the sphere to the same location manually then picking works with both variables.

When I remove the parent and put the sphere to the same location manually, picking does not work with rayOriginInsideOfTheSphere. See https://playground.babylonjs.com/#H69092#1.

If you’re setting sphere.position.y = 1; to set the sphere position, then you’ll need to call sphere.computeWorldMatrix(true); for sphere.getAbsolutePosition() to return the correct value. See https://playground.babylonjs.com/#H69092#2.

When I remove the parent and put the sphere to the same location manually, picking does not work with rayOriginInsideOfTheSphere. See https://playground.babylonjs.com/#H69092#1.

I swear it worked when I was preparing the playground. I think something was pushed to the master. This happened to me before (when behavior in playground changed some time after I published it, even if there was no official release yet). From my previous experience if you choose LATEST in playground, actually it’s not the latest official release, but the current state (maybe master or some nightly build).

Your solution at https://playground.babylonjs.com/#H69092#2 doesn’t work. I still receive empty array. Right now, at this moment (see the post time), when I use rayOriginInsideOfTheSphere I receive empty array in pickResults for parented and non-parented sphere even with sphere.computeWorldMatrix(true);.

I’m seeing the ray starting and ending inside the sphere in both cases, so I would expect no intersection to be found in both cases. Are you saying you were seeing a case where the ray started and ended inside the sphere and it did intersect the sphere? …and now you’re not seeing the same result anymore?

Exactly. It worked if I didn’t use a transform node as a parent. Now it doesn’t work in both cases.
And sphere.computeWorldMatrix(true); provided by you doesn’t work now in both cases.

Weird. If you’re able to reproduce this again, please let me know.

Okay. I see what happened. Before I didn’t use sphere.computeWorldMatrix(true);. Thus, the ray was being built to the wrong point, which was causing the intersection with the mesh edge. As a result, I saw that mesh being returned by scene.multiPickWithRay.

However, when I do sphere.parent = tn;, then probably sphere.computeWorldMatrix(true) is being called internally. So, the ray is being built correctly and there is no intersection with the mesh edge.

Fortunately, the solution to the initial problem is not that hard: https://playground.babylonjs.com/#H69092#5

The missing ‘pick’ might be restored using intersectsPoint method. Something like that:

const pickResults = scene.multiPickWithRay(ray);

if (pickResults.length === 0) {
    if (sphere.intersectsPoint(rayOrigin)) {
        pickResults.push({
            pickedMesh: sphere,
            pickedPoint: rayOrigin,
            // Some other 'PickingInfo' fields might be manually restored as well, if needed.
        });
    }
}

Of course, in real life you may want to organize the code better, but you got the idea.

1 Like