Hit Testing в режиме AR

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

Подключение AR и настройка XR-сессии

Для работы с Hit Testing необходимо активировать XR-сессию через WebXR:

const xrHelper = await scene.createDefaultXRExperienceAsync({
    uiOptions: {
        sessionMode: "immersive-ar",
        referenceSpaceType: "local-floor"
    }
});
  • sessionMode: "immersive-ar" — обеспечивает AR-контекст с возможностью размещения объектов в реальном пространстве.
  • referenceSpaceType: "local-floor" — задаёт локальное пространство с уровнем пола, удобное для Hit Testing плоских поверхностей.

После создания XR-сессии активируется baseExperience, к которому привязываются все AR-взаимодействия.

Настройка Hit Test Source

Для отслеживания точек пересечения необходимо создать Hit Test Source. В Babylon.js это делается через XR Helper:

const hitTest = await xrHelper.baseExperience.session.requestHitTestSource({ space: xrHelper.baseExperience.pointerSelection.getRay() });
  • pointerSelection.getRay() возвращает луч, исходящий из центра экрана или от пользовательского указателя.
  • requestHitTestSource создаёт источник данных о пересечениях с реальным миром, который обновляется каждый кадр.

Для постоянного отслеживания Hit Test рекомендуется использовать XRFrame:

scene.onBeforeRenderObservable.add(() => {
    const xrFrame = xrHelper.baseExperience.session.requestAnimationFrame();
    const hitTestResults = xrFrame.getHitTestResults(hitTest);
    
    if (hitTestResults.length > 0) {
        const hit = hitTestResults[0];
        const pose = hit.getPose(xrHelper.baseExperience.referenceSpace);
        reticle.position.copyFrom(pose.transform.position);
        reticle.rotationQuaternion.copyFrom(pose.transform.orientation);
    }
});
  • getHitTestResults(hitTest) возвращает массив всех пересечений луча с реальными поверхностями.
  • pose.transform.position и pose.transform.orientation задают точку и ориентацию для виртуального объекта.

Использование ретикла для визуализации

Ретикл (reticle) — визуальный индикатор точки пересечения луча с поверхностью. Он помогает пользователю видеть, где объект будет размещён. В Babylon.js его можно создать так:

const reticle = BABYLON.MeshBuilder.CreateTorus("reticle", { diameter: 0.1, thickness: 0.01 }, scene);
reticle.isVisible = false;

При наличии результатов Hit Test ретикл становится видимым и позиционируется в пространстве:

reticle.isVisible = hitTestResults.length > 0;

Размещение объектов на Hit Test

После получения координат пересечения можно размещать объекты на поверхности. Пример с мешем:

if (hitTestResults.length > 0 && userTapped) {
    const hit = hitTestResults[0];
    const pose = hit.getPose(xrHelper.baseExperience.referenceSpace);

    const box = BABYLON.MeshBuilder.CreateBox("box", { size: 0.1 }, scene);
    box.position.copyFrom(pose.transform.position);
    box.rotationQuaternion = pose.transform.orientation.clone();
}
  • userTapped — условие, определяющее действие пользователя (например, касание экрана).
  • rotationQuaternion обеспечивает правильное ориентирование объекта по поверхности.

Оптимизация Hit Testing

  1. Ограничение количества источников: создание нескольких источников Hit Test может сильно нагружать устройство.
  2. Фильтрация по плоскости: можно игнорировать вертикальные поверхности, если нужны только горизонтальные.
  3. Использование onBeforeRenderObservable вместо requestAnimationFrame напрямую — снижает накладные расходы на обновление сцены.

Расширенные возможности

  • Hit Testing с различными лучами: луч можно направлять не только из центра экрана, но и от геймпадов или контроллеров.
  • Hit Testing для нескольких объектов: Babylon.js позволяет проверять пересечения с виртуальными объектами сцены наряду с реальными поверхностями.
  • Комбинация с анимацией: объекты можно плавно перемещать к точкам Hit Test с использованием BABYLON.Animation, создавая более естественный эффект AR.

Hit Testing в Babylon.js обеспечивает точное и интерактивное взаимодействие виртуальных объектов с реальным пространством, делая AR-приложения более реалистичными и отзывчивыми.