Babylon.js に入門する

このスクラップについて
前のスクラップでは Babylon.js Playground で遊んだ。
このスクラップでは下記のドキュメントから読み進めて Babylon.js にもう少し詳しく Babylon.js に入門しようと思う。

豆腐の表示
Playground にアクセスして下記のコードを表示する。
const createScene = () => {
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera(
"camera",
-Math.PI / 2,
Math.PI / 2.5,
3,
new BABYLON.Vector3(0, 0, 0)
);
const light = new BABYLON.HemisphericLight(
"light",
new BABYLON.Vector3(0, 1, 0)
);
const box = BABYLON.MeshBuilder.CreateBox("box", {});
return scene;
}
Math
が Path
になっていて 10 分ほど無駄にしてしまった。

カメラのアタッチを忘れていた
camera.attachControl(canvas, true);

Scene が省略されている
Since at this point there is only one scene you may notice that this parameter can be dropped from the camera, light and box as the default is for them to be placed in the current scene.
Scene が 1 つしか無い場合は指定しなくても良いようだ。

エクスポート
Playground で Inspector > Tools を選ぶ。
エクスポート形式には Babylon / GLB がある。

Web ページで表示
touch ~/Downloads/babylon.html
npx http-server -c-1
<script src="https://cdn.babylonjs.com/viewer/babylon.viewer.js"></script>
<babylon model="/scene.babylon"></babylon>
http://localhost:8080/babylon.html にアクセスする。
scene.babylon を scene.glb に変えても動くことを確認する。

シーンやモデルの読み込み
BABYLON.SceneLoader.ImportMeshAsync(model_name, folder_path, file_name, scene);
scene は 1 つしか無い場合は省略できるようだ。
フォルダーとファイル名が別れているのは何故だろう?
Three.js でもそうだったような気がする。
model_name には文字列の配列も指定できる。
1 つのシーンには複数のモデルが含まれているということなのかもしれない。

実際に読み込んでみる
const createScene = () => {
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera(
"camera",
-Math.PI / 2,
Math.PI / 2.5,
15,
new BABYLON.Vector3(0, 0, 0)
);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight(
"light",
new BABYLON.Vector3(1, 1, 0)
);
BABYLON.SceneLoader.ImportMeshAsync(
"semi_house",
"https://assets.babylonjs.com/meshes/",
"both_houses_scene.babylon"
);
return scene;
}
家が表示された。

複数モデルを読み込んでみる
const createScene = () => {
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera(
"camera",
-Math.PI / 2,
Math.PI / 2.5,
15,
new BABYLON.Vector3(0, 0, 0)
);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight(
"light",
new BABYLON.Vector3(1, 1, 0)
);
BABYLON.SceneLoader.ImportMeshAsync(
["ground", "semi_house"],
"https://assets.babylonjs.com/meshes/",
"both_houses_scene.babylon"
);
return scene;
}

モデル読み込み後の操作
const createScene = () => {
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera(
"camera",
-Math.PI / 2,
Math.PI / 2.5,
15,
new BABYLON.Vector3(0, 0, 0)
);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight(
"light",
new BABYLON.Vector3(1, 1, 0)
);
BABYLON.SceneLoader.ImportMeshAsync(
"",
"https://assets.babylonjs.com/meshes/",
"both_houses_scene.babylon"
).then((result) => {
const house1 = scene.getMeshByName("detached_house");
house1.position.y = 2;
const house2 = result.meshes[2];
house2.position.y = 1;
})
return scene;
}

今日はここまでかな
次回は Web ページで表示できるようにしてみよう。

今日はここから
今日は Web ページで表示させてみたい。

HTML テンプレート
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Babylon Template</title>
<style>
html,
body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#renderCanvas {
width: 100%;
height: 100%;
touch-action: none;
}
</style>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/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 -->
<script>
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 scene = createScene(); //Call the createScene function
// Register a render loop to repeatedly render the scene
engine.runRenderLoop(function () {
scene.render();
});
// Watch for browser/canvas resize events
window.addEventListener("resize", function () {
engine.resize();
});
</script>
</body>
</html>
Add your code here matching the playground format の所に Playground のソースコードを入れれば良いようだ。

コーディング
touch ~/Desktop/first-babylon-app.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Babylon Template</title>
<style>
html,
body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#renderCanvas {
width: 100%;
height: 100%;
touch-action: none;
}
</style>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/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 -->
<script>
const canvas = document.getElementById("renderCanvas"); // Get the canvas element
const engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine
const createScene = () => {
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera(
"camera",
-Math.PI / 2,
Math.PI / 2.5,
15,
new BABYLON.Vector3(0, 0, 0)
);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight(
"light",
new BABYLON.Vector3(1, 1, 0)
);
BABYLON.SceneLoader.ImportMeshAsync(
"",
"https://assets.babylonjs.com/meshes/",
"both_houses_scene.babylon"
).then((result) => {
const house1 = scene.getMeshByName("detached_house");
house1.position.y = 2;
const house2 = result.meshes[2];
house2.position.y = 1;
});
return scene;
};
const scene = createScene(); //Call the createScene function
// Register a render loop to repeatedly render the scene
engine.runRenderLoop(function () {
scene.render();
});
// Watch for browser/canvas resize events
window.addEventListener("resize", function () {
engine.resize();
});
</script>
</body>
</html>

動作確認
HTML ファイルを開けば OK、Web サーバーなどはいらない。

キリが良いのでクローズしよう
次のスクラップはこちら。