Tutorial: Criar um piano no WebXR com Babylon.js

Construir um piano no mundo real requer muito no caminho do tempo, habilidades e materiais. E quanto à construção de um para o mundo vr/AR?

Nesta série de tutoriais, irá aprender a utilizar Babylon.js para criar uma aplicação Web Mixed Reality que contém um piano de stand-up de 88 teclas funcional no mundo virtual. Na aplicação concluída, poderá teletransportar para o piano e tocar as teclas com os seus comandos de realidade mista.

Nesta série de tutoriais, irá aprender a:

  • Criar, posicionar e unir malhas para criar um teclado para piano
  • Importar um modelo de Babylon.js de uma moldura de piano de stand-up
  • Adicionar interações de ponteiro a cada tecla de piano
  • Ativar o suporte de teletransporte e multipointer no WebXR

Pré-requisitos

Introdução

Vamos começar por configurar a página Web HTML que irá conter a cena Babylon.js.

  1. Crie uma pasta com o nome babylonjs-piano-tutorial e abra a pasta no Visual Studio Code.

    Nota

    Embora possa utilizar qualquer editor de código para acompanhar, iremos utilizar o Visual Studio Code ao longo deste tutorial para sua comodidade.

  2. Na pasta, crie um ficheiro com o nome index.html e insira o modelo abaixo no ficheiro:

    <html>
        <head>
            <title>Piano in BabylonJS</title>
            <script src="https://cdn.babylonjs.com/babylon.js"></script>
            <style>
                body,#renderCanvas { width: 100%; height: 100%;}
            </style>
        </head>
        <body>
            <canvas id="renderCanvas"></canvas>
            <script type="text/javascript">
                const canvas = document.getElementById("renderCanvas"); 
                const engine = new BABYLON.Engine(canvas, true); 
    
                createScene(engine).then(sceneToRender => {
                    engine.runRenderLoop(() => sceneToRender.render());
                });
    
                // Watch for browser/canvas resize events
                window.addEventListener("resize", function () {
                    engine.resize();
                });
            </script>
        </body>
    </html>
    

    Se precisar de mais explicações sobre o conteúdo deste modelo, veja o Tutorial Hello World, que é um pré-requisito deste tutorial.

  3. Se tentar abrir este ficheiro num browser, a consola mostra um erro que indica que a createScene() função não foi encontrada. Vamos resolver este erro ao implementar a função createScene() na secção seguinte.

Configurar o cenário

  1. Na mesma pasta queindex.html, crie outro ficheiro com o nome scene.js. Vamos armazenar todo o código javascript relacionado com a configuração da cena e a criação do piano neste ficheiro.

  2. Vamos adicionar a função ao createScene()scene.js:

    const createScene = async function(engine) {
        const scene = new BABYLON.Scene(engine);
        return scene;
    }
    

    Tenha em atenção que estamos a criar createScene() uma função assíncrona. Fique atento para saber porquê.

  3. Em seguida, vamos precisar de uma luz e de uma câmara para tornar a cena visível para nós. Atualizar a createScene() função:

    const createScene = async function(engine) {
        const scene = new BABYLON.Scene(engine);
    
        const alpha =  3*Math.PI/2;
        const beta = Math.PI/50;
        const radius = 220;
        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(0, 1, 0), scene);
        light.intensity = 0.6;
    
        return scene;
    }
    

    Aqui, criámos um ArcRotateCamera, que aponta quase completamente para baixo e visa o ponto de origem do espaço. A luz que criámos é uma HemisféricaLight que aponta para o céu e é útil para simular um espaço ambiente. Também esbatemos um pouco a luz baixando a sua intensidade.

    Se precisar de um atualizador sobre como criar uma câmara e uma luz, reveja a secção Preparar Cena do Hello World Tutorial Series antes de avançar para o passo seguinte.

  4. Por fim, uma vez que estamos a desenvolver para uma plataforma WebXR, teremos de ativar a experiência XR no cenário ao inserir a seguinte linha antes return scene;de :

    const xrHelper = await scene.createDefaultXRExperienceAsync();
    

    No javascript, para utilizar a await palavra-chave numa async função numa função, a função principal também teria de ser async, razão pela qual definimos createScene a função como assíncrona anteriormente. Mais adiante nesta série de tutoriais, vamos utilizá-la xrHelper para ativar e configurar diferentes funcionalidades WebXR suportadas pelo Babylon.js.

  5. O scene.js concluído deverá ter o seguinte aspeto:

    const createScene = async function(engine) {
        const scene = new BABYLON.Scene(engine);
    
        const alpha =  3*Math.PI/2;
        const beta = Math.PI/50;
        const radius = 220;
        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(0, 1, 0), scene);
        light.intensity = 0.6;
    
        const xrHelper = await scene.createDefaultXRExperienceAsync();
    
        return scene;
    }
    
  6. Agora que temos uma função funcional createScene() , vamos ter index.html carregar o ficheiro descene.js como um script para que a createScene() função seja reconhecida no index.html. Adicione esta linha de código na <header> secção do ficheiro html:

    <html>
        <head>
            <title>Piano in BabylonJS</title>
            <script src="https://cdn.babylonjs.com/babylon.js"></script>
            <script src="scene.js"></script>
            <style>
                body,#renderCanvas { width: 100%; height: 100%;}
            </style>
        </head>
        <body>
            <canvas id="renderCanvas"></canvas>
            <script type="text/javascript">
                const canvas = document.getElementById("renderCanvas");
                const engine = new BABYLON.Engine(canvas, true); 
    
                createScene(engine).then(sceneToRender => {
                    engine.runRenderLoop(() => sceneToRender.render());
                });
    
                // Watch for browser/canvas resize events
                window.addEventListener("resize", function () {
                    engine.resize();
                });
            </script>
        </body>
    </html>
    
  7. Abra index.html no browser e verá que a mensagem de erro que vimos anteriormente já não está presente e temos um cenário de Babylon.js vazio na página.

Passos seguintes