Triggering pointer out actions when camera change causes pointer to exit mesh

In this PG, I have an icon that I change state on whenever it is hovered. When the icon is no longer hovered, I change the state back to the default. This works as long as you move the pointer over and out of the icon. However, if you hover the icon, and then zoom out so that the pointer is no longer over the icon, then move the pointer, the pointer out action is triggered, but the e.meshUnderPointer is the mesh that the pointer is currently over, rather than the mesh that the action is attached to. Thus the plane’s texture is updated rather than the icon’s texture.

Is it the case that e.meshUnderPointer is the mesh under the pointer when the event is triggered, rather than the mesh the action is attached to? Would it make sense to check pointer on camera view matrix change to account for the possibility that the pointer is out of the mesh due to a camera change? I could work up a PR if that makes sense.

Note that I cannot reference the mesh the action was added to inside of the action because I have multiple instances of the icon (clones really), and I found that when the action fires I cannot rely on the reference to the instance inside the action being the actual instance that the pointer was over for some reason.

Actually I realized I’m getting 2 pointer out events. The first does happen when the pointer goes out due to a camera view change. The second happens after I move the pointer. Why the second event?

@PolygonalSun Have you had a chance to look at this yet? Is there anything else you need from me?

thanks for the reminder @ericwood73 this one slipped through the cracks :slight_smile:

Hey @ericwood73,
Yeah, I did look over thing and if I understand things correctly, meshUnderPointer is the mesh that’s supposed to be under the cursor. The only issue is that, while this is being updated during move events, the mouse wheel event doesn’t update it. As far as adding an update to this in the onViewMatrixChangedObservable, that could work but I’d be worried about adding an additional pick to a render frame’s lifespan. It might be more performant to update the wheel code. @sebavan, just out of curiosity, what are your thoughts on updating the meshUnderPointer (pick and update) in onViewMatrixChangedObservable?

@PolygonalSun @sebavan I don’t know if you saw my update, but the pointer out event does appear to fire when the camera is zoomed in such a way that causes the pointer to exit a mesh (this can be seen because the icon does change state when the camera is zoomed and the pointer exits the icon mesh). The problem is that it fires again when the pointer is moved after that. If we could suppress the second event, that would solve the problem.

Lemme dig a little closer on that one (cc @carolhmj, just in case you might already have an idea)

Hey @ericwood73, just out of curiosity, what browser were you using when you originally reproduced this bug? I’m trying to verify something with a fix I’m finishing up.

Chrome

Awesome, that’s what I was hoping you would say. So there was some old code put in for Safari compatibility that was adding a pointerId of 0 to all WheelEvents. Chrome’s default pointerId for all PointerEvents is 1. By default, WheelEvents tend not to have a pointerId so they were erroneously getting this pointerId of 0. Because of this, the InputManager thought that the WheelEvent and any other PointerEvents came from two different sources. Since we track meshUnderPointer for all pointer sources, the InputManager was firing ActionManager events for both. I’ve updated the old code and you shouldn’t have that second pointerout event. PR has already been merged: WebDeviceInputSystem: Add pointerId to WheelEvents when dispatching to InputManager by PolygonalSun · Pull Request #13661 · BabylonJS/Babylon.js (github.com).

1 Like

Thanks @PolygonalSun for the fix and explanation. We make some changes to input to use the primary button for panning and disable all the others, and I wanted to ask if you think we would have any issues with this due to this change?. I.e.

currentCamera.attachControl(
	null, // ignored
	false, // prevent default
	false, // do not use ctrl key for panning
	0 // use left mouse button for panning
); 

// Only allow left mouse button to control camera.  Disable right,
// which would be used for rotation since we specific left is for panning
currentCamera.inputs.attached.pointers.buttons = [0];