Babylon.js предоставляет гибкую систему для реализации взаимодействия пользователя с 3D-сценой, включая захват объектов с помощью мыши, касаний или VR/AR контроллеров. Центральными элементами являются Raycasting, Pointer Events, Physics Engine и системы Gizmo.
Для определения того, на какой объект указывает пользователь, используется метод picking. Основные функции:
scene.pick(x, y) — выполняет луч от камеры через
экранные координаты (x, y) и возвращает объект типа
PickingInfo, содержащий:
hit — флаг попадания.pickedMesh — объект, с которым произошло
столкновение.pickedPoint — точка столкновения в мировых
координатах.ray — объект луча (Ray), использованный
для расчёта.Пример использования для захвата объекта мышью:
canvas.addEventListener("pointerdown", function(evt) {
let pickResult = scene.pick(evt.clientX, evt.clientY);
if (pickResult.hit) {
console.log("Выбран объект:", pickResult.pickedMesh.name);
}
});
Babylon.js предоставляет GizmoManager, который облегчает перемещение, вращение и масштабирование объектов:
const gizmoManager = new BABYLON.GizmoManager(scene);
gizmoManager.positionGizmoEnabled = true; // Включение перемещения
gizmoManager.rotationGizmoEnabled = true; // Включение вращения
gizmoManager.scaleGizmoEnabled = true; // Включение масштабирования
// Привязка Gizmo к объекту
gizmoManager.attachToMesh(pickResult.pickedMesh);
Особенности:
Для реализации интерактивного захвата объектов используется цепочка событий:
Пример:
let selectedMesh = null;
canvas.addEventListener("pointerdown", function(evt) {
const pickResult = scene.pick(evt.clientX, evt.clientY);
if (pickResult.hit) {
selectedMesh = pickResult.pickedMesh;
}
});
canvas.addEventListener("pointermove", function(evt) {
if (selectedMesh) {
const pickResult = scene.pick(evt.clientX, evt.clientY, mesh => mesh === selectedMesh);
if (pickResult.hit) {
selectedMesh.position.copyFrom(pickResult.pickedPoint);
}
}
});
canvas.addEventListener("pointerup", function(evt) {
selectedMesh = null;
});
Важно: для плавного перемещения часто используется Plane или временная фиктивная сетка, на которой фиксируется позиция объекта относительно камеры.
Для реалистичного взаимодействия с объектами можно использовать физический движок Babylon.js:
PhysicsImpostor) для объектов.Пример:
mesh.physicsImpostor = new BABYLON.PhysicsImpostor(
mesh,
BABYLON.PhysicsImpostor.BoxImpostor,
{ mass: 1, friction: 0.5, restitution: 0.7 },
scene
);
// Перемещение с помощью силы или позиции
mesh.physicsImpostor.setLinearVelocity(new BABYLON.Vector3(0, 1, 0));
Использование физики позволяет захватывать объект и перемещать его через реальные столкновения, гравитацию и силы.
Babylon.js поддерживает WebXR, что позволяет захватывать объекты в VR и AR с контроллерами:
const xrHelper = await scene.createDefaultXRExperienceAsync({});
onSelectStart и onSelectEnd:xrHelper.input.onControllerAddedObservable.add((controller) => {
controller.onMotionControllerInitObservable.add((motionController) => {
motionController.onButtonStateChangedObservable.add(() => {
if (controller.pointerSelectionMesh) {
// Привязка к объекту
gizmoManager.attachToMesh(controller.pointerSelectionMesh);
}
});
});
});
Особенности VR/AR захвата:
Near Interaction — взаимодействие с объектом на коротком расстоянии (обычно контакт или хват рукой). Реализуется через:
Far Interaction — взаимодействие с объектом на расстоянии. Используется:
Комбинация этих подходов позволяет создавать гибкие системы манипуляции объектами, где объекты можно “дотянуться рукой” или “подтянуть на расстоянии” через луч.
mesh.isPickable для объектов, которые
должны быть интерактивными.Этот подход обеспечивает гибкость, совместимость с различными устройствами ввода и реалистичное поведение объектов в Babylon.js.