InternalPickForMesh restructure

Hi,
I am in the middle of upgrading the version of BabylonJS I use from 7.2.2 to 7.28.0.

I can see a change where the Scene.prototype._internalPickForMesh has been removed and instead a new function named InternalPickForMesh is defined within ray.core.ts.

I was overriding the prototype of Scene.prototype._internalPickForMesh to accommodate the renderingGroupId of the meshes to ensure that the higher rendering group Id is always selected with the following code at the top of the function:

if (pickingInfo.pickedMesh.renderingGroupId > mesh.renderingGroupId) {
  return pickingInfo;
}

Now that the logic has been moved into its own function within ray.core.ts, I am unsure how I can override it. Is this possible?

Thanks

We are doing our best to move away from prototype extensions, especially for private or internal functions, as it is not really needed.

At what point exactly are you running this code? the beginning of the function?

As this function is not exported, it is a bit harder to override, which is the right usage for private functions. maybe we can add a hook in the function instead, to allow you your custom implementation.

I was running it at the top, so a hook at the top would help, though I also didn’t want distance incorporated. Could the functions be made public or protected static and put into a class that is exported so we can change them?

  Scene.prototype._internalPickForMesh = function (
    pickingInfo: Nullable<PickingInfo>,
    rayFunction: (world: Matrix, enableDistantPicking: boolean) => Ray,
    mesh: AbstractMesh,
    world: Matrix,
    fastCheck?: boolean,
    onlyBoundingInfo?: boolean,
    trianglePredicate?: TrianglePickingPredicate,
    skipBoundingInfo?: boolean
  ) {
    if (pickingInfo?.pickedMesh) {
      if (pickingInfo.pickedMesh.renderingGroupId > mesh.renderingGroupId) {
        return pickingInfo;
      }
      if (pickingInfo.pickedMesh.renderingGroupId < mesh.renderingGroupId) {
        const ray = rayFunction(world, mesh.enableDistantPicking);
        const result = mesh.intersects(
          ray,
          fastCheck,
          trianglePredicate,
          onlyBoundingInfo,
          world,
          skipBoundingInfo
        );
        if (!result || !result.hit) {
          return pickingInfo;
        }
        return result;
      }
    }

    return originalInternalPickForMesh(
      pickingInfo,
      rayFunction,
      mesh,
      world,
      fastCheck,
      onlyBoundingInfo,
      trianglePredicate,
      skipBoundingInfo
    );
  };

Well the underscore functions are private and should not be accessed (for that very reason:))

can you tell us what you need to achieve?

Hi @Deltakosh ,
In my scene I have meshes on multiple rendering groups.
When picking, I always want meshes with a higher rendering group Id to be picked over meshes with a lower rendering group Id.
This is to accommodate handles, menus and various other things I have in my scene.

I hope this helps describe my use-case. I do however think that removing the ability to change the picking mechanism, and potentially other things will reduce flexibility going forward. There are a number of things I adjust using prototypes just for my use-case that would make no sense to put into a common base engine, removing this option would mean I would have to fork and publish my own flavour of BabylonJS which is more work.

Thanks

We do not plan to change all the public API :wink: this will only happen for _functions that you really should not touch as we do not guarantee backward compat on.

That being said, are you using scene.pick? because there is a predicate to specify what meshes to pick.

If that does not work we can think of a user defined function that could be provided to do the internal picking if defined.

1 Like

Hi @Deltakosh - I’m not using scene.pick, just the built-in mouse and VR pointer picking.
Having a user defined function would be great thanks :smile:

Here we are:

1 Like

Thank you @Deltakosh - really appreciate it :smiley:

1 Like