見出し画像

Babylon.js v6.3.1 Practiceめも② MagicaVoxel作成3DモデルをglTF形式で表示

前回からのつづきです。 今回はBabylon.jsにて、自分でMagicaVoxelで作成してglTFファイルに変換した3Dモデルを表示しています。 途中からBase64によるglTFファイル読込・表示なども行っています。

 コーディングは前回までのBabylon.jsコーディングと同じようにHTML、CSS、JavaScriptで行っています(Typescript使っていません)。 目次の各項目では、コードのタイトル文字列をクリックするとコードとその実行結果が見れるCodePenのページを開き、サムネイル画像をクリックすると実行結果をフルスクリーンで表示するCodePenのページを開きます。

 現在CodePenに投稿しているBabylon.js v6.3.1のコードの一覧はCodePenのCollection機能で作成した「Babylon.js v6.3.1 Practice」で見ることができます。


Babylon.js v6.3.1 Practice#17 glTF 3D Model by MagicaVoxel Display

Babylon.js v6.3.1 Practice#17 glTF 3D Model by MagicaVoxel Display

MagicaVoxelで作成し、glTFファイル形式に変換した3DモデルをBabylon.jsで表示させるプログラムになります。 githubに置いたglTFファイルをCDN経由で読み込んでいます。

HTML

<head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
     <title>Babylon Template</title>

    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/babylonjs/6.3.1/babylon.js"></script> -->
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/babylonjs/6.3.1/babylon.min.js"></script> -->


    <!-- <script src="https://cdn.jsdelivr.net/npm/babylonjs@6.3.1/babylon.js"></script> -->
    <script src="https://cdn.jsdelivr.net/npm/babylonjs@6.3.1/babylon.min.js"></script>

    <!-- <script src="https://unpkg.com/babylonjs@6.3.1/babylon.js"></script> -->


    <script src="https://cdn.jsdelivr.net/npm/babylonjs-loaders@6.3.1/babylonjs.loaders.min.js"></script>
    <!-- <script src="https://unpkg.com/babylonjs-loaders@6.3.1/babylonjs.loaders.min.js"></script> -->

    <script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>

</head>

<body>

    <canvas id="renderCanvas" touch-action="none"></canvas> <!--
    touch-action="none" for best results from PEP -->

</body>

HTML内で
glTFファイル形式による3Dモデルを読み込むために

<script src="https://cdn.jsdelivr.net/npm/babylonjs-loaders@6.3.1/babylonjs.loaders.min.js"></script>

を jsDeliver のCDNより読み込んで使用します。

CSS

html, body {
    overflow: hidden;
    width   : 100%;
    height  : 100%;
    margin  : 0;
    padding : 0;
}

#renderCanvas {
    width   : 100%;
    height  : 100%;
    touch-action: none;
}

JavaScript

main = () => {

    const canvas = document.getElementById("renderCanvas"); // Get the canvas element
    const engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

    // Add your code here matching the playground format
    const createScene = () => {

        const scene = new BABYLON.Scene(engine);
        scene.clearColor = new BABYLON.Color3(0, 1, 1);

        const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 3, new BABYLON.Vector3(0, 0, 0));
        camera.attachControl(canvas, true);

        const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0));


        // Load and display 3D model in glTF file format
        BABYLON.SceneLoader.Append("https://rawcdn.githack.com/siouxcitizen/3DModel/a1c2e47550ca20de421f6d779229f66efab07830/", "yuusha.gltf", scene, newMeshes => {
      
            const mesh = scene.meshes[0];

            //mesh.position.y  =  -2.5;
            //mesh.position.z  =  1.5;

            //mesh.rotation  = new BABYLON.Vector3([X-axis rotation], [Y-axis rotation], [Z-axis rotation]); 
            // Used to orient the 3D model

            //mesh.rotation  = new BABYLON.Vector3(0, Math.PI, 0); // 3DModel displayed from the behind
            //mesh.rotation  = new BABYLON.Vector3(0, Math.PI/2, 0); // 3DModel displayed from the side
            mesh.rotation  = new BABYLON.Vector3(0, 0, 0); // 3DModel displayed from the front

            scene.activeCamera = null;
            scene.createDefaultCameraOrLight(true);
            scene.activeCamera.attachControl(canvas, false);
        });

        return scene;
    }

    const scene = createScene(); //Call the createScene function

    // Register a render loop to repeatedly render the scene
    engine.runRenderLoop(() => {
        scene.render();
    });

    // Watch for browser/canvas resize events
    window.addEventListener("resize", () => {
        engine.resize();
    });

}

// Start processing after all DOM elements have been loaded
window.addEventListener("DOMContentLoaded", main);

JavaScript内の

// Load and display 3D model in glTF file format
BABYLON.SceneLoader.Append("https://rawcdn.githack.com/siouxcitizen/3DModel/a1c2e47550ca20de421f6d779229f66efab07830/", "yuusha.gltf", scene, newMeshes => {
      
        const mesh = scene.meshes[0];

        //mesh.position.y  =  -2.5;
        //mesh.position.z  =  1.5;

        //mesh.rotation  = new BABYLON.Vector3([X-axis rotation], [Y-axis rotation], [Z-axis rotation]); 
        // Used to orient the 3D model

        //mesh.rotation  = new BABYLON.Vector3(0, Math.PI, 0); // 3DModel displayed from the behind
        //mesh.rotation  = new BABYLON.Vector3(0, Math.PI/2, 0); // 3DModel displayed from the side
        mesh.rotation  = new BABYLON.Vector3(0, 0, 0); // 3DModel displayed from the front

        scene.activeCamera = null;
        scene.createDefaultCameraOrLight(true);
        scene.activeCamera.attachControl(canvas, false);
});

でgithubに設置したglTFファイルを、githackというCDN経由で読込・表示させています。 コメントアウトしてゴチャゴチャ残しているものは、後々いろいろなglTFファイルを読み込んだ時にサイズや角度を調整するために修正して使いまわそうと残しているものです。


参考にさせていただいたサイト&コード

Loading Any File Type

The Very First Step

Babylon.js v4.2.0 Practice#26 glTF 3D Model by MagicaVoxel Display

Babylon.js v3.3.0 Practice#26 glTF 3D Model by MagicaVoxel Display

Babylon.js .glTF 3D Model Display


Babylon.js v6.3.1 Practice#17_02 glTF(glb) 3D Model by base64

Babylon.js v6.3.1 Practice#17_02 glTF(glb) 3D Model by base64

 ここからglTF形式の3Dモデルファイルを(glbファイルを経由して)Base64に変換して、そのBase64を読み込むことによって対象3Dモデルを表示する実験を行っています。 Practice#17_02~Practice#17_04のコードはそのようなBase64による3Dモデルの表示実験を行っているコードになります。 

 まず最初のこのPractice#17_02ではBase64の文字列をそのままBabylon.jsのコードに貼り付けています。 このnote項目に関連して下に貼り付けているJS(JavaScript)では省略していますが、実際のコードではかなり長ったらしい文字列になっていて、コードが読みづらくなってしまっています。

 ちなみにこのBase64による3Dモデル読み込みは、Practice#17でのCDN経由github設置glTFファイル読み込みの代替案の実験です。 無料版CodePenではファイルを置けないので、CDNにつづくゴマカシファイル使用法の研究ですw。 そのうちCodePenに禁止等されなければ使えるかと。


HTML Practice#17と共通
CSS Practice#17と共通
JavaScript

main = () => {

    const canvas = document.getElementById("renderCanvas"); // Get the canvas element
    const engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

    // Add your code here matching the playground format
    const createScene = () => {

        const scene = new BABYLON.Scene(engine);
        scene.clearColor = new BABYLON.Color3(0, 1, 1);

        const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 3, new BABYLON.Vector3(0, 0, 0));
        camera.attachControl(canvas, true);

        const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0));

        // base64 encoded string of glb file format
        const base64_encoded_str = "Z2xURgIAAA (~省略~) AAOwAAAD8="; 
        const base64_model_content = "data:;base64," + base64_encoded_str;

        // Load and display 3D model in glb file format
        BABYLON.SceneLoader.Append("", base64_model_content, scene, newMeshes => {
      
            const mesh = scene.meshes[0];

            //mesh.position.y  =  -2.5;
            //mesh.position.z  =  1.5;

            //mesh.rotation  = new BABYLON.Vector3([X-axis rotation], [Y-axis rotation], [Z-axis rotation]); 
            // Used to orient the 3D model

            //mesh.rotation  = new BABYLON.Vector3(0, Math.PI, 0); // 3DModel displayed from the behind
            //mesh.rotation  = new BABYLON.Vector3(0, Math.PI/2, 0); // 3DModel displayed from the side
            mesh.rotation  = new BABYLON.Vector3(0, 0, 0); // 3DModel displayed from the front

            scene.activeCamera = null;
            scene.createDefaultCameraOrLight(true);
            scene.activeCamera.attachControl(canvas, false);
        });

        return scene;
    }

    const scene = createScene(); //Call the createScene function

    // Register a render loop to repeatedly render the scene
    engine.runRenderLoop(() => {
        scene.render();
    });

    // Watch for browser/canvas resize events
    window.addEventListener("resize", () => {
        engine.resize();
    });

}

// Start processing after all DOM elements have been loaded
window.addEventListener("DOMContentLoaded", main);

JavaScript内の

// base64 encoded string of glb file format
const base64_encoded_str = "Z2xURgIAAA (~省略~) AAOwAAAD8="; 
const base64_model_content = "data:;base64," + base64_encoded_str;

// Load and display 3D model in glb file format
BABYLON.SceneLoader.Append("", base64_model_content, scene, newMeshes => {
      
    const mesh = scene.meshes[0];

    //mesh.position.y  =  -2.5;
    //mesh.position.z  =  1.5;

    //mesh.rotation  = new BABYLON.Vector3([X-axis rotation], [Y-axis rotation], [Z-axis rotation]); 
    // Used to orient the 3D model

    //mesh.rotation  = new BABYLON.Vector3(0, Math.PI, 0); // 3DModel displayed from the behind
    //mesh.rotation  = new BABYLON.Vector3(0, Math.PI/2, 0); // 3DModel displayed from the side
    mesh.rotation  = new BABYLON.Vector3(0, 0, 0); // 3DModel displayed from the front

    scene.activeCamera = null;
    scene.createDefaultCameraOrLight(true);
    scene.activeCamera.attachControl(canvas, false);
});

でBase64文字列を読み込んで3Dモデルとして表示しています。 BABYLON.SceneLoader.Append()
使えば何事もなくサクッと読み込めるのすごいな~、Babylon.js。

実際の文字列は省略していますが、この

// base64 encoded string of glb file format
const base64_encoded_str = "Z2xURgIAAA (~省略~) AAOwAAAD8="; 
const base64_model_content = "data:;base64," + base64_encoded_str;

でBase64の文字列が作成されています。


参考にさせていただいたサイト&コード

【Babylon.js】Playgroundで遊んでみよう

How to build a GLTF base64 string of bin file

GLB base64 data encoding

Base64 Guru

Loading Any File Type


glTF(glb) yuusha 3D Model by base64

glTF(glb) yuusha 3D Model by base64

サムネイル画像はありません。 このコードは、Practice#17_02で長ったらしくなってしまったBase64の文字列を切り出せないかと作成してみたコードとなります。

コードの内容は、何も考えず cost 宣言したものにBase64文字列を設定しているだけです。 このBase64文字列を後につづくPractice#17_03とPractice#17_04のコードで読み取って3Dモデルを表示させます。


HTML なし
CSS なし
JavaScript

const yuusha01 = "Z2xURgIAAA (~省略~) AAOwAAAD8=";
const yuusha02 = "data:;base64,Z2xURgIAAA (~省略~) AAOwAAAD8=";

https://codepen.io/siouxcitizen/pen/dygQxjJ.js 」をCodePenの機能でとりこめば(※)、あとは取り込んだ先のCodePenコードで「 yuusha01 」「 yuusha02 」を引用すればBase64形式のglTFファイルを読み込んで表示できました。

※CodePenの機能でとりこみ
CodePenのコード編集画面で「Settings」押下より
Pen Settings → JS → Add External Scripts/Pens から対象項目に対象コードのURLを設定してSave


参考にさせていただいたサイト&コード

Base64の切り出しについて以下を参考にしました。

Three.js r149 Buffer Geometry Test36 Textured Heightfield Test26


Babylon.js v6.3.1 Practice#17_03 glTF(glb) 3D Model by base64

Babylon.js v6.3.1 Practice#17_03 glTF(glb) 3D Model by base64

glTF(glb) yuusha 3D Model by base64からの yuusha01 定数に設定されたBase64文字列を使用して3Dモデルを読み込んで表示しています。 このPractice#17_03は、次のPractice#17_04と違い、「data:;base64,」文字列を yuusha01 の文字列と連結してBase64全体の文字列を作成して使用します(元々のサンプルコードがこのようなものだったため)。


HTML Practice#17と共通
CSS Practice#17と共通
JavaScript

main = () => {

    const canvas = document.getElementById("renderCanvas"); // Get the canvas element
    const engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

    // Add your code here matching the playground format
    const createScene = () => {

        const scene = new BABYLON.Scene(engine);
        scene.clearColor = new BABYLON.Color3(0, 1, 1);

        const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 3, new BABYLON.Vector3(0, 0, 0));
        camera.attachControl(canvas, true);

        const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0));

        // base64 encoded string of glb file format
        const base64_encoded_str = yuusha01;
        const base64_model_content = "data:;base64," + base64_encoded_str;

        // Load and display 3D model in glb file format
        BABYLON.SceneLoader.Append("", base64_model_content, scene, newMeshes => {
      
            const mesh = scene.meshes[0];

            //mesh.position.y  =  -2.5;
            //mesh.position.z  =  1.5;

            //mesh.rotation  = new BABYLON.Vector3([X-axis rotation], [Y-axis rotation], [Z-axis rotation]); 
            // Used to orient the 3D model

            //mesh.rotation  = new BABYLON.Vector3(0, Math.PI, 0); // 3DModel displayed from the behind
            //mesh.rotation  = new BABYLON.Vector3(0, Math.PI/2, 0); // 3DModel displayed from the side
            mesh.rotation  = new BABYLON.Vector3(0, 0, 0); // 3DModel displayed from the front

            scene.activeCamera = null;
            scene.createDefaultCameraOrLight(true);
            scene.activeCamera.attachControl(canvas, false);
        });

        return scene;
    }

    const scene = createScene(); //Call the createScene function

    // Register a render loop to repeatedly render the scene
    engine.runRenderLoop(() => {
        scene.render();
    });

    // Watch for browser/canvas resize events
    window.addEventListener("resize", () => {
        engine.resize();
    });

}

// Start processing after all DOM elements have been loaded
window.addEventListener("DOMContentLoaded", main);

JavaScript内の

// base64 encoded string of glb file format
const base64_encoded_str = yuusha01;
const base64_model_content = "data:;base64," + base64_encoded_str;

でBase64文字列を作成しています。


参考にさせていただいたサイト&コード

Base64の切り出しについて参考にした Three.js r149 Buffer Geometry Test36 Textured Heightfield Test26 以外は Practice#17_02 と共通です


Babylon.js v6.3.1 Practice#17_04 glTF(glb) 3D Model by base64

Babylon.js v6.3.1 Practice#17_04 glTF(glb) 3D Model by base64

glTF(glb) yuusha 3D Model by base64からの yuusha02 定数に設定されたBase64文字列を使用して3Dモデルを読み込んで表示しています。 このPractice#17_04は、前のPractice#17_03と違い、「data:;base64,」文字列を含み、yuusha02 の文字列だけでBase64全体の文字列を表すためそのまま使用します(元々のサンプルコードから修正して動かせるかどうかの実験もしています)。


HTML Practice#17と共通
CSS Practice#17と共通
JavaScript

main = () => {

    const canvas = document.getElementById("renderCanvas"); // Get the canvas element
    const engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

    // Add your code here matching the playground format
    const createScene = () => {

        const scene = new BABYLON.Scene(engine);
        scene.clearColor = new BABYLON.Color3(0, 1, 1);

        const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 3, new BABYLON.Vector3(0, 0, 0));
        camera.attachControl(canvas, true);

        const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0));

        // base64 encoded string of glb file format
        const base64_model_content = yuusha02;

        // Load and display 3D model in glb file format
        BABYLON.SceneLoader.Append("", base64_model_content, scene, newMeshes => {
      
            const mesh = scene.meshes[0];

            //mesh.position.y  =  -2.5;
            //mesh.position.z  =  1.5;

            //mesh.rotation  = new BABYLON.Vector3([X-axis rotation], [Y-axis rotation], [Z-axis rotation]); 
            // Used to orient the 3D model

            //mesh.rotation  = new BABYLON.Vector3(0, Math.PI, 0); // 3DModel displayed from the behind
            //mesh.rotation  = new BABYLON.Vector3(0, Math.PI/2, 0); // 3DModel displayed from the side
            mesh.rotation  = new BABYLON.Vector3(0, 0, 0); // 3DModel displayed from the front

            scene.activeCamera = null;
            scene.createDefaultCameraOrLight(true);
            scene.activeCamera.attachControl(canvas, false);
        });

        return scene;
    }

    const scene = createScene(); //Call the createScene function

    // Register a render loop to repeatedly render the scene
    engine.runRenderLoop(() => {
        scene.render();
    });

    // Watch for browser/canvas resize events
    window.addEventListener("resize", () => {
        engine.resize();
    });

}

// Start processing after all DOM elements have been loaded
window.addEventListener("DOMContentLoaded", main);

JavaScript内の

        // base64 encoded string of glb file format
        const base64_model_content = yuusha02;

でBase64文字列を作成しています。 そのまま yuusha02 を使ってもよかったですが、Practice#17_03のコードと比較しやすいように代入処理を残しています。


参考にさせていただいたサイト&コード

Practice#17_03と共通

次回

まとめ


この記事が気に入ったらサポートをしてみませんか?