Babylon.js предоставляет мощные инструменты для работы с 3D-графикой в браузере, включая интеграцию с WebXR для виртуальной и дополненной реальности. Одной из ключевых возможностей WebXR является hand tracking, позволяющий отслеживать положение и жесты рук пользователя в пространстве. Это открывает новые возможности для взаимодействия с 3D-сценой без использования контроллеров.
Для начала необходимо создать базовую сцену Babylon.js и включить поддержку WebXR. Основные шаги:
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera("Camera", Math.PI/2, Math.PI/2, 2, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), scene);
// Включение WebXR
const xrHelper = await scene.createDefaultXRExperienceAsync({
uiOptions: { sessionMode: 'immersive-vr' },
optionalFeatures: true
});
// Активация отслеживания рук
xrHelper.input.onControllerAddedObservable.add((controller) => {
if (controller.inputSource.hand) {
console.log("Hand tracking доступен");
}
});
Ключевой момент: WebXR hand tracking работает только на устройствах и браузерах с поддержкой WebXR Hand Input API, например, на устройствах серии Oculus Quest.
Каждая рука в Babylon.js представлена объектом
WebXRHand, который содержит коллекцию
костей (joints). Каждая кость имеет
позицию и ориентацию в пространстве сцены.
xrHelper.input.onControllerAddedObservable.add((controller) => {
if (controller.inputSource.hand) {
const hand = controller.inputSource.hand;
hand.joints.forEach((jointName) => {
const joint = hand.get(jointName);
console.log(`Кость ${jointName} координаты:`, joint.getPosition());
});
}
});
Основные кости:
wrist — запястьеthumb-metacarpal…thumb-tip — большой
палецindex-finger-metacarpal…index-finger-tip —
указательный палецКаждая кость возвращает объект WebXRJoint, содержащий
методы:
getPosition() — возвращает позицию в пространстве
сценыgetRotationQuaternion() — возвращает ориентацию кости в
виде кватернионаДля отладки или создания визуальных эффектов можно использовать
MeshBuilder для построения сфер или цилиндров на каждой
кости:
const spheres = {};
hand.joints.forEach((jointName) => {
const sphere = BABYLON.MeshBuilder.CreateSphere(jointName, { diameter: 0.02 }, scene);
spheres[jointName] = sphere;
});
scene.onBeforeRenderObservable.add(() => {
hand.joints.forEach((jointName) => {
const joint = hand.get(jointName);
const pos = joint.getPosition();
spheres[jointName].position.copyFrom(pos);
});
});
Рекомендация: при визуализации всех костей можно использовать разные цвета для каждого пальца для лучшего восприятия.
Базовый подход к распознаванию жестов — использование позиций пальцев относительно запястья. Например, для распознавания сжатого кулака:
function isFist(hand) {
const wrist = hand.get("wrist").getPosition();
let closed = true;
const fingers = ["index-finger-tip", "middle-finger-tip", "ring-finger-tip", "pinky-finger-tip", "thumb-tip"];
fingers.forEach(finger => {
const tip = hand.get(finger).getPosition();
if (BABYLON.Vector3.Distance(tip, wrist) > 0.07) {
closed = false;
}
});
return closed;
}
scene.onBeforeRenderObservable.add(() => {
xrHelper.input.controllers.forEach(controller => {
if (controller.inputSource.hand && isFist(controller.inputSource.hand)) {
console.log("Кулак сжат");
}
});
});
Важно: точные пороги расстояний нужно подбирать под конкретное устройство и масштаб сцены.
Hand tracking позволяет напрямую взаимодействовать с объектами сцены без контроллеров:
const box = BABYLON.MeshBuilder.CreateBox("box", { size: 0.1 }, scene);
scene.onBeforeRenderObservable.add(() => {
xrHelper.input.controllers.forEach(controller => {
if (controller.inputSource.hand) {
const indexTip = controller.inputSource.hand.get("index-finger-tip").getPosition();
if (box.intersectsPoint(indexTip)) {
box.scaling.setAll(1.5);
} else {
box.scaling.setAll(1);
}
}
});
});
Такой подход позволяет создавать жестовые интерфейсы, где объекты реагируют на приближение пальцев, сжатие кулака или раскрытие ладони.
hand-tracking перед выполнением
сложных вычислений, чтобы избежать ошибок на устройствах без
поддержки.Hand tracking в Babylon.js открывает путь к естественным и интуитивным интерфейсам, позволяя строить приложения, где руки пользователя становятся полноценным инструментом управления и взаимодействия с 3D-пространством.