Руководство. Взаимодействие с трехмерным объектом

Узнайте, как создавать трехмерные объекты и взаимодействия для работы в смешанной реальности с помощью Babylon.js. В этом разделе вы начнете с простого примера: нарисуете грани куба при выборе объекта.

В этом руководстве рассматриваются следующие темы:

  • добавление взаимодействий;
  • включение режима погружения WebXR;
  • запуск приложения в симуляторе Windows Mixed Reality;
  • запуск и отладка приложения в Chrome на Android.

Подготовка к работе

На предыдущем шаге руководства была создана базовая веб-страница со сценой. Откройте веб-страницу для редактирования.

<html>
<head>
    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <style>
        body,#renderCanvas { width: 100%; height: 100%;}
    </style>
</head>
<body>
    <canvas id="renderCanvas"></canvas>
    <script>
        const canvas = document.getElementById("renderCanvas");
        const engine = new BABYLON.Engine(canvas, true);
        
        const createScene = function() {
            const scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3.Black;
            
            const alpha =  Math.PI/4;
            const beta = Math.PI/3;
            const radius = 8;
            const target = new BABYLON.Vector3(0, 0, 0);
            
            const camera = new BABYLON.ArcRotateCamera("Camera", alpha, beta, radius, target, scene);
            camera.attachControl(canvas, true);
            
            const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0));
            
            const box = BABYLON.MeshBuilder.CreateBox("box", {});
            box.position.x = 0.5;
            box.position.y = 1;
            
            return scene;
        };
        
        const sceneToRender = createScene();
        engine.runRenderLoop(function(){
            sceneToRender.render();
        });
    </script>
</body>
</html>

Добавление взаимодействия

  1. Сначала обновим наш код, создающий куб, чтобы куб был окрашен в случайный цвет. Для этого мы добавим материал для куба. В материале можно указать цвет и текстуры, а также использовать их для покрытия других объектов. Способ отображения материала зависит от света или источников света, используемых в сцене, и от того, как он реагирует. Например, diffuseColor распределяет цвет по сетке, к которой он присоединен. Добавьте следующий код:

    const boxMaterial = new BABYLON.StandardMaterial("material", scene);
    boxMaterial.diffuseColor = BABYLON.Color3.Random();
    box.material = boxMaterial;
    
  2. Теперь, когда куб окрашен в случайный цвет, давайте добавим взаимодействие:

    • для изменения цвета при щелчке по кубу;
    • для перемещения куба после изменения цвета.

    Чтобы добавить взаимодействия, мы будем использовать действия. Действие запускается в ответ на срабатывание триггера события. Например, когда пользователь щелкает куб. Все, что нам нужно сделать, — это создать экземпляр BABYLON.ActionManager и зарегистрировать действие для определенного триггера. BABYLON.ExecuteCodeAction будет выполнять нашу функцию JavaScript, когда кто-то щелкнет куб:

    box.actionManager = new BABYLON.ActionManager(scene);
    box.actionManager.registerAction(new BABYLON.ExecuteCodeAction(
        BABYLON.ActionManager.OnPickTrigger, 
        function (evt) {
            const sourceBox = evt.meshUnderPointer;
    
            //move the box upright
            sourceBox.position.x += 0.1;
            sourceBox.position.y += 0.1;
    
            //update the color
            boxMaterial.diffuseColor = BABYLON.Color3.Random();
        }));
    
  3. Окончательный код веб-страницы будет выглядеть так:

    <html>
    <head>
        <script src="https://cdn.babylonjs.com/babylon.js"></script>
        <style>
            body,#renderCanvas { width: 100%; height: 100%;}
        </style>
    </head>
    <body>
        <canvas id="renderCanvas"></canvas>
        <script>
            const canvas = document.getElementById("renderCanvas");
            const engine = new BABYLON.Engine(canvas, true);
    
            const createScene = function() {
                const scene = new BABYLON.Scene(engine);
                scene.clearColor = new BABYLON.Color3.Black;
    
                const alpha =  Math.PI/4;
                const beta = Math.PI/3;
                const radius = 8;
                const target = new BABYLON.Vector3(0, 0, 0);
    
                const camera = new BABYLON.ArcRotateCamera("Camera", alpha, beta, radius, target, scene);
                camera.attachControl(canvas, true);
    
                const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0));
    
                const box = BABYLON.MeshBuilder.CreateBox("box", {});
                box.position.x = 0.5;
                box.position.y = 1;
    
                const boxMaterial = new BABYLON.StandardMaterial("material", scene);
                boxMaterial.diffuseColor = BABYLON.Color3.Random();
                box.material = boxMaterial;
    
                box.actionManager = new BABYLON.ActionManager(scene);
                box.actionManager.registerAction(
                    new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, 
                    function (evt) {
                        const sourceBox = evt.meshUnderPointer;
                        sourceBox.position.x += 0.1;
                        sourceBox.position.y += 0.1;
    
                        boxMaterial.diffuseColor = BABYLON.Color3.Random();
                    }));
    
                return scene;
            };
    
            const sceneToRender = createScene();
            engine.runRenderLoop(function(){
                sceneToRender.render();
            });
        </script>
    </body>
    </html>
    

Включение иммерсивного интерфейса WebXR

Теперь, когда наш куб изменяет цвета, мы готовы попробовать иммерсивное взаимодействие.

  1. На этом этапе мы введем основание. Куб будет находиться в воздухе, и в нижней части будет отображаться пол. Добавьте основание следующим образом:

    const ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 4, height: 4});
    

    Это создает простой пол размером 4 x 4.

  2. Чтобы добавить поддержку WebXR, необходимо вызвать createDefaultXRExperienceAsync с результатом Promise (обещание). Добавьте этот код в конец функции createScene вместо return scene:

    const xrPromise = scene.createDefaultXRExperienceAsync({
        floorMeshes: [ground]
    });
    return xrPromise.then((xrExperience) => {
        console.log("Done, WebXR is enabled.");
        return scene;
    });
    
  3. Так как функция createScene теперь возвращает обещание вместо сцены, необходимо изменить способ вызова createScene и engine.runRenderLoop. Замените текущие вызовы этих функций, расположенные непосредственно перед тегом /script>, с помощью следующего кода:

    createScene().then(sceneToRender => {
        engine.runRenderLoop(() => sceneToRender.render());
    });
    
  4. Окончательный код веб-страницы будет выглядеть так:

    <html>
    <head>
        <script src="https://cdn.babylonjs.com/babylon.js"></script>
        <style>
            body,#renderCanvas { width: 100%; height: 100%;}
        </style>
    </head>
    <body>
        <canvas id="renderCanvas"></canvas>
        <script>
            const canvas = document.getElementById("renderCanvas");
            const engine = new BABYLON.Engine(canvas, true);
    
            const createScene = function() {
                const scene = new BABYLON.Scene(engine);
                scene.clearColor = new BABYLON.Color3.Black;
    
                const alpha =  Math.PI/4;
                const beta = Math.PI/3;
                const radius = 8;
                const target = new BABYLON.Vector3(0, 0, 0);
    
                const camera = new BABYLON.ArcRotateCamera("Camera", alpha, beta, radius, target, scene);
                camera.attachControl(canvas, true);
    
                const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0));
    
                const box = BABYLON.MeshBuilder.CreateBox("box", {});
                box.position.x = 0.5;
                box.position.y = 1;
    
                const boxMaterial = new BABYLON.StandardMaterial("material", scene);
                boxMaterial.diffuseColor = BABYLON.Color3.Random();
                box.material = boxMaterial;
    
                box.actionManager = new BABYLON.ActionManager(scene);
                box.actionManager.registerAction(
                    new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, 
                    function (evt) {
                        const sourceBox = evt.meshUnderPointer;
                        sourceBox.position.x += 0.1;
                        sourceBox.position.y += 0.1;
    
                        boxMaterial.diffuseColor = BABYLON.Color3.Random();
                    }));
    
                const ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 4, height: 4});
    
                const xrPromise = scene.createDefaultXRExperienceAsync({
                    floorMeshes: [ground]
                });
    
                return xrPromise.then((xrExperience) => {
                    console.log("Done, WebXR is enabled.");
                    return scene;
                });
            };
    
            createScene().then(sceneToRender => {
                engine.runRenderLoop(() => sceneToRender.render());
            });
        </script>
    </body>
    </html>
    
  5. Приведенный выше код создает следующие выходные данные в окне браузера: сцена WebXR.

Запуск в симуляторе Windows Mixed Reality

  1. Включите симулятор Windows Mixed Reality, если вы еще не сделали это в прошлом.

  2. Нажмите кнопку режима иммерсивной виртуальной реальности в правом нижнем углу: кнопка иммерсивной виртуальной реальности.

  3. Это действие запустит окно симулятора Windows Mixed Reality, как показано ниже: Портал смешанной реальности.

  4. Используйте клавиши W, A, S и D на клавиатуре для перемещения вперед, назад, влево и вправо. Используйте смоделированную руку для создания целевого куба и нажмите клавишу ВВОД на клавиатуре, чтобы выполнить действие щелчка. Куб изменит свой цвет и перейдет в новое положение.

Примечание

При нацеливании на куб убедитесь, что конец телекинеза (белый круг) пересекается с кубом, как показано на рисунке выше. Узнайте больше о наведении и фиксации с помощью руки.

Запуск и отладка на устройстве с Android

Чтобы включить отладку на устройстве с Android, выполните следующие действия.

Предварительные требования

  • Веб-сервер, который обслуживает статическую страницу HTML в безопасном контексте (https:// или через перенаправление портов на localhost) на компьютере разработки. Например, вы можете использовать пакет NPM serve в качестве простого упрощенного веб-сервера, который обслуживает статические HTML-файлы. Дополнительные сведения о пакете NPM serve.

  • Устройство с Google Play Маркетом (установленным изначально) и под управлением Android 7.0 или более поздней версии.

  • Последняя версия Google Chrome на рабочей станции разработки и на устройстве.

  • Чтобы убедиться, что устройство правильно настроено для запуска WebXR, перейдите на страницу примера WebXR на устройстве. Должно отобразиться сообщение:

    Your browser supports WebXR and can run Virtual Reality and Augmented Reality experiences if you have the appropriate hardware. (Ваш браузер поддерживает WebXR и может запускать виртуальную реальность и расширенные возможности, если у вас есть соответствующее оборудование.)

  1. Включите режим разработчика и отладку по USB на устройстве с Android. Узнайте, как это сделать для вашей версии Android, на официальной странице документации: Настройка параметров разработчика на устройстве.

  2. Затем подключите устройство с Android к компьютеру разработки или ноутбуку через USB-кабель.

  3. Убедитесь, что веб-сервер на компьютере разработки запущен. Например, перейдите к корневой папке, содержащей основную веб-страницу (index.html), и выполните следующий код (при условии, что используется пакет NPM serve):

    serve
    
  4. Откройте Google Chrome на компьютере разработки и введите в адресной строке следующий текст:

    chrome://inspect#devices Окно отладки USB в Chrome

  5. Убедитесь, что установлен флажок Discover USB devices (Обнаружение USB-устройств).

  6. Нажмите кнопку Port forwarding (Перенаправление портов) и убедитесь, что Port forwarding (Перенаправление портов) включено и содержит запись localhost:5000, как показано ниже: Окно перенаправления портов в Chrome.

  7. На подключенном устройстве с Android откройте окно Google Chrome и перейдите на http://localhost:5000 , где вы должны увидеть куб.

  8. На компьютере разработки в Chrome вы увидите ваше устройство и список веб-страниц, которые в настоящий момент открыты здесь: Окно проверки в Chrome.

  9. Нажмите кнопку Inspect (Проверить) рядом с записью http://localhost:5000: Окно отладки Chrome DevTools.

  10. Использование Chrome DevTools для отладки страницы

Общие выводы

Далее следуют самые важные выводы из этого руководства.

  • Babylon.js упрощает создание впечатляющих интерфейсов с помощью JavaScript.
  • Для создания виртуальных сцен вам не нужно писать низкоуровневый код или изучать новую технологию.
  • Вы можете создавать приложения смешанной реальности с помощью браузера, поддерживающего WebXR, без необходимости покупать гарнитуру.

Дальнейшие действия

Поздравляем! Вы завершили серию руководств по Babylon.js и изучили следующее:

  • Настройка среды разработки
  • Создание веб-страницы для отображения результатов
  • API Babylon.js для создания основных трехмерных элементов и взаимодействия с ними
  • Запуск и тестирование приложения в симуляторе Windows Mixed Reality

Дополнительные сведения о разработке JavaScript в смешанной реальности см. в статье Общие сведения о разработке JavaScript.

Если вам нужен другой учебник по Babylon.js, см. серию учебников по созданию пианино, в которой описывается, как создать пианино в пространстве виртуальной реальности с помощью Babylon.js.