Event type inconsistency in onPointerObservable

Hello folks!

I have a question regarding the PointerInfo object type that is passed inside the callback of the onPointerObservable.add() method.

Let’s say we have the following piece of code:

        scene.onPointerObservable.add(pointerInfo => {
            // let's say we want to check if the event type is a pointerdown
            // we could do it in two different ways

            // first way (the one that is stated in the docs: `[docs](https://doc.babylonjs.com/features/featuresDeepDive/scene/interactWithScenes#pointer-interactions)`)
            if (pointerInfo.type === BABYLON.PointerEventTypes.POINTERDOWN) {
                // do something
            }

            // second way
            if (pointerInfo.event.type === 'pointerdown') {
                // do something
            }
        })

The first way is obviously preferable since it does the checking against a type and not a string. But that’s not the point of this question. The point is that sometimes those two types are different. So which one should I trust?

I’ve prepared a very simple playground to reproduce it. Just click a few times somewhere under the ground mesh (on the purple zone) and you will see that sometimes the console prints out ‘pointerdown 1’ (which is correct as 1 corresponds to PointerEventTypes.POINTERDOWN so there is a match between the types) but sometimes it will print out ‘pointerdown 4’ (which doesn’t seem to be correct as the 4 corresponds to PointerEventTypes.POINTERMOVE so it doesn’t match with pointerdown).

Is this a bug?

Good catch! Let me tag @PolygonalSun to confirm this :slight_smile:

1 Like

So I should be able to explain what’s going on here. First of all, you can trust the PointerInfo type to always report the accurate pointer action. The reason why you’re seeing ‘pointerdown’ have a type of POINTERMOVE is because that’s how we account for any move changes that may occur in pointer events that aren’t just ‘pointermove’. What we do is that we will issue a POINTERDOWN for the click, which handles our button pressing and a POINTERMOVE for the movement itself. It was originally set up that we would just perform a POINTERDOWN for ‘pointerdown’ events and POINTERMOVE for pointermove events but there were scenarios where data wasn’t being handled so it was decided to just fire a POINTERDOWN/UP if we have a button change and POINTERMOVE if we see any changes to cursor position.

2 Likes

@PolygonalSun has explained the reasoning behind it, I just want to add that there is a better way to filter your callback using masks, which is a way most people probably don’t know we support.

For example, to have the callback react only to pointer down (and not even run the “if type === pointerdown”), add a mask as the second variable of the add function:

scene.onPointerObservable.add(pointerInfo => {
    // will only be triggered if the pointer event type is POINTERDOWN.
}, BABYLON.PointerEventTypes.POINTERDOWN)

You can also add more than one! using |:

scene.onPointerObservable.add(pointerInfo => {
    // will only be triggered if the pointer event type is POINTERDOWN or POINTERUP
}, BABYLON.PointerEventTypes.POINTERDOWN | BABYLON.PointerEventTypes.POINTERUP)

That’s it, flying away.

4 Likes

Thank you all for the answers. Everything is more clear now and the mask solution is just amazing. Keep up the good work!