Pointer события: PointerObservable и PointerInfo

Работа с указателями в Babylon.js является важной частью взаимодействия пользователя с 3D-сценой. Для реализации реакции на события, связанные с движением мыши, касаниями экранов мобильных устройств или других устройств ввода, используется система Pointer событий. Эта система включает в себя классы, такие как PointerObservable и PointerInfo, которые помогают отслеживать и обрабатывать события, происходящие при взаимодействии указателя с объектами на сцене.

PointerObservable

PointerObservable — это класс, который представляет собой механизм наблюдения за событиями указателя (например, мыши или сенсорного экрана). Он предоставляет методы для регистрации и обработки событий, которые происходят на экране, в том числе движения указателя, нажатия и отпускания кнопок мыши или сенсорные касания.

PointerObservable создается и работает с объектами сцены. Он привязывается к объектам, которые могут быть активными в контексте взаимодействия с пользователем, например, Mesh-объекты, камеры, или сама сцена. С помощью этого класса можно обработать целый ряд событий, связанных с указателями, что делает взаимодействие с 3D-сценой максимально удобным.

var pointerObservable = new BABYLON.PointerObservable(scene, pointerEvent => {
    console.log("Pointer Event Type: ", pointerEvent.type);
});

В этом примере создается объект PointerObservable, который отслеживает все события указателя на сцене. Когда происходит событие, вызывается переданная функция, в которой выводится тип события.

PointerObservable поддерживает различные типы событий, включая:

  • PointerDown: Срабатывает при нажатии кнопки мыши или начала сенсорного касания.
  • PointerUp: Срабатывает при отпускании кнопки мыши или окончания сенсорного касания.
  • PointerMove: Срабатывает при движении указателя.

Подписка на события PointerObservable

Для того чтобы начать отслеживать события, необходимо подписаться на нужный тип события, используя метод add(). В Babylon.js можно подписаться на события указателя для конкретных объектов или для всей сцены.

Пример подписки на события для всего экрана:

scene.onPointerObservable.add(function(pointerInfo) {
    if (pointerInfo.type === BABYLON.PointerEventTypes.POINTERDOWN) {
        console.log("Pointer was pressed");
    } else if (pointerInfo.type === BABYLON.PointerEventTypes.POINTERUP) {
        console.log("Pointer was released");
    }
}, BABYLON.PointerEventTypes.POINTERDOWN | BABYLON.PointerEventTypes.POINTERUP);

В этом примере подписка осуществляется на два типа событий: нажатие и отпускание указателя. Это событие срабатывает при взаимодействии с любым объектом сцены.

PointerInfo

Класс PointerInfo является контейнером для информации о текущем событии указателя. Он включает в себя несколько полезных свойств, которые позволяют точнее отслеживать, что именно произошло во время взаимодействия.

Основные свойства класса PointerInfo:

  • type: Тип события указателя, которое произошло (например, POINTERDOWN, POINTERUP, POINTERMOVE).
  • pointerId: Уникальный идентификатор указателя. Это свойство полезно для работы с несколькими указателями (например, при использовании нескольких пальцев на сенсорных экранах).
  • button: Номер кнопки мыши, если событие связано с её нажатием (0 — левая кнопка, 1 — средняя кнопка, 2 — правая кнопка).
  • event: Объект события DOM, связанный с событием указателя (например, MouseEvent для мыши или TouchEvent для сенсорных устройств).
  • pickInfo: Содержит информацию о том, какой объект сцены был “попечен” указателем. Это свойство полезно для реализации кастомных действий при взаимодействии с объектами сцены.

Пример использования класса PointerInfo:

scene.onPointerObservable.add(function(pointerInfo) {
    const type = pointerInfo.type;
    const pointerId = pointerInfo.pointerId;
    const button = pointerInfo.button;
    const pickInfo = pointerInfo.pickInfo;

    if (type === BABYLON.PointerEventTypes.POINTERDOWN) {
        console.log(`Pointer ${pointerId} pressed. Button: ${button}`);
        if (pickInfo.hit) {
            console.log(`Pointer hit object: ${pickInfo.pickedMesh.name}`);
        }
    }
}, BABYLON.PointerEventTypes.POINTERDOWN);

В данном примере для каждого события нажатия указателя выводится информация о кнопке мыши и о том, какой объект сцены был “попечен” этим указателем.

Обработка различных устройств ввода

Babylon.js поддерживает не только события с мышью, но и сенсорные устройства. Это достигается с помощью унифицированного подхода к обработке указателей. Для мобильных устройств (сенсорных экранов) класс PointerObservable будет автоматически отслеживать события касания, а для настольных устройств — события мыши.

Это позволяет создавать кроссплатформенные решения, которые одинаково хорошо работают как на устройствах с сенсорными экранами, так и на устройствах с традиционными указателями, такими как мышь.

Пример обработки касания:

scene.onPointerObservable.add(function(pointerInfo) {
    if (pointerInfo.type === BABYLON.PointerEventTypes.POINTERDOWN) {
        const touchPosition = pointerInfo.event.touches[0];
        console.log(`Touch event at x: ${touchPosition.clientX}, y: ${touchPosition.clientY}`);
    }
}, BABYLON.PointerEventTypes.POINTERDOWN);

В этом примере обработка сенсорного касания позволяет получить координаты касания на экране.

Использование событий с конкретными объектами сцены

Для того чтобы обработать события указателя только для определенных объектов, можно использовать PointerObservable совместно с методом onPickObservable. Этот метод предоставляет возможность подписаться на события указателя, связанные с конкретными Mesh-объектами.

Пример:

var mesh = BABYLON.MeshBuilder.CreateBox("box", {}, scene);
mesh.onPointerObservable.add(function(pointerInfo) {
    if (pointerInfo.type === BABYLON.PointerEventTypes.POINTERDOWN) {
        console.log("Box was clicked");
    }
}, BABYLON.PointerEventTypes.POINTERDOWN);

В этом примере создается куб, и на него подписываются события указателя. Когда пользователь нажимает на куб, выводится сообщение.

Настройка фильтрации событий

Кроме обработки типов событий, в Babylon.js есть возможность фильтровать события указателя по дополнительным условиям. Например, можно отслеживать события только для определенных кнопок мыши или ограничить события только для объектов в определенной области сцены. Это можно сделать с помощью различных фильтров и условий в методах подписки на события.

Пример фильтрации по кнопке мыши:

scene.onPointerObservable.add(function(pointerInfo) {
    if (pointerInfo.button === 0) {
        console.log("Left mouse button pressed");
    }
}, BABYLON.PointerEventTypes.POINTERDOWN);

Этот код обрабатывает только события нажатия левой кнопки мыши.

Заключение

Система событий указателя в Babylon.js позволяет эффективно обрабатывать взаимодействия пользователя с 3D-сценой. Благодаря использованию классов PointerObservable и PointerInfo, можно легко организовать обработку различных типов событий, таких как нажатия, движения указателя и касания. Эта гибкость делает Babylon.js мощным инструментом для создания интерактивных 3D-приложений, поддерживающих широкий спектр устройств и типов ввода.