Making non-visible parts of the ADT transparent to pointer events

In https://playground.babylonjs.com/#XMIQ95#2, I have a UI mesh that overlaps the visible mesh slightly and has an ADT that has the two circular icons at the bottom. I want the UI mesh to be transparent to pointer events except where the icons are. So when I hover the main disc but not the icons I want

  1. the cursor to change to grab (not working)
  2. the pointer over action to fire (working)
  3. the pick down action to fire when I pointer down over the main disc (not working)
  4. the mesh to be draggable (working)

I also want all the icon actions to work. If I make the UI not pickable, then none of the icons respond to pointer events. The docs seem to indicate I could make the root container of the ADT not renderable, and in the repo, it looks like this would bypass picking of the root container, but making the root container not renderable hides all the controls, despite the docs at The Babylon GUI | Babylon.js Documentation suggesting the children would still be visible. In any case, even if I make the rootContainer not renderable, I still do not get the behavior I want. I would add the actions to the UI, but then the pickable are of the disc is larger than the disc, and I don’t want that.

Is there any way to make the transparent parts of a UI transparent to pointer events?

cc @PolygonalSun

@carolhmj Any ideas on this?

You can use detectPointerOnOpaqueOnly: Detect Pointer on Opaque only | Babylon.js Playground (babylonjs.com)

I’m not sure how to do that. I have an ADT that has an ellipse container with an image. I want the enitre ADT except the ellipse to be transparent to pointer events. detectPointerOnOpaqueOnly seems to work only with allowing non-opaque parts of an image to be transparent to pointer events.

Actually I just realized that any pickable mesh with an alpha blended texture still blocks pointer events, even in fully transparent regions. But given that this is a UI, it would be nice if pointer events could be transferred somehow to the underlying mesh when not over a control that has an attached event (or is configured as a pointer blocker). Can you see any way to achieve this?

One thing you could do is to make the icon discs individual meshes instead of images in a plane, so they don’t block the big disc anymore? The ActionManager uses the scene.pick under the hood, so it can’t pick the big disc because the child plane with the images is in front of it (and this has nothing to do with the UI, since pick doesn’t even know about the mesh textures).

We don’t want to make the icons individual meshes due to perf. Thanks for the suggestions, but I suspect this isn’t possible and I’ll have to accept the tradeoff of the slightly larger clickable area.

@carolhmj Is it the case that the ADT blocks the underlying mesh action manager? I tried putting a hover cursor on the UI mesh and it never shows up, but if I don’t create the ADT it works. Also I can’t get a hover cursor to show up on the ADT root container even if I set isPointerBlocker to true and add an observer on pointer enter. https://playground.babylonjs.com/#XMIQ95#7. How can I get the cursor to change to grab when it is over the main disc, or if that is not possible (as it seems it isn’t without losing the icon actions) over the UI.

It looks like hoverCursors don’t work at all on root containers https://playground.babylonjs.com/#ZI9AK7#3502. In the code it looks like maybe it doesn’t check for a hover cursor on a container

            const child = this._children[index];
            if (child._processPicking(x, y, pi, type, pointerId, buttonIndex, deltaX, deltaY)) {
                if (child.hoverCursor) {
                    this._host._changeCursor(child.hoverCursor);
                }
                return true;
            }
        }

Hmmm I remember we had some problems with the hoverCursor not changing when it should, @PolygonalSun did we end up merging any fix? :thinking:

Thanks I appear to have solved it by defining a transparent ellipse and attaching the hover cursor to that. The nice thing about this solution is that I can better control the interactive area, which should actually be less than the root container. https://playground.babylonjs.com/#XMIQ95#9

4 Likes

Oh, glad you found a solution that works! :smiley: