Babylon.jsでglTF Physics拡張を体験してみよう

この記事は[Babylon.js Advent Calendar 2023](https://qiita.com/advent-calendar/2023/babylonjs)の9日目の記事です。

### はじめに

glTF（GL Transmission Format）は、3Dモデルやシーンを表現するためのファイルフォーマットの１つです。glTF にはコア仕様と拡張仕様があり、用途に応じて様々な拡張が提案されています。

その拡張の１つとして glTF Physics 拡張のドラフト仕様が提案されているようなので、どのような仕様なのか少し調べてみました。

### glTF Physics 拡張とは？

簡単に言うと、3Dモデルに物理演算の仕様を組み込んだものです。
現状でも3Dライブラリと物理演算ライブラリを組み合わせてglTFモデルに物理シミュレーション機能を組み込むことは可能ですが、プログラミングが必要になります。
glTF Physics 拡張を使用すると、3D空間にモデルを配置するだけで物理シミュレーションを開始できます。
例えば、ARでその場にドミノを配置すれば、すぐにドミノ倒しを楽しむことができます。

### glTF Physics 拡張の主な機能

glTF Physics 拡張は主に次の2つの拡張が用意されており、これらを組み合わせて使うようになっています。

[KHR_collision_shapes](https://github.com/eoineoineoin/glTF_Physics/tree/master/extensions/2.0/Khronos/KHR_collision_shapes) （衝突シェイプ）で物理形状を指定します。`sphere`、`box`、`capsule`、`cylinder`、`convex`、`trimesh` が指定できます。

[KHR_physics_rigid_bodies](https://github.com/eoineoineoin/glTF_Physics/blob/master/extensions/2.0/Khronos/KHR_physics_rigid_bodies)（剛体）でノードに質量、慣性、速度、ジョイント、制約といった物理特定を指定します。

### 実行結果

以下は glTF Physics 拡張の開発メンバーの一人である Eoin Mcloughlin さんの[リポジトリ](https://github.com/eoineoineoin/glTF_Physics_Babylon)のサンプルの実行結果になります。

Babylon.jsにてglTF Physics拡張に対応したglTF Loaderを用いて様々な物理シミュレーションが体験できます。

■ [Basic shapes](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=0)（基本形状の例）
説明：凸凹のある坂道にモデルを落下させることにより形状ごとに異なった動きをしているのが分かります。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26094/9fa99e76-f2bc-bec3-d8c6-abe5ee949767.png)](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=0)

■ [Filtering](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=1)（衝突フィルターの例）
説明：衝突フィルターを設定することにより、物理シミュレーションを行う対象とそうでないものを設定することが可能です。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26094/54d95643-7555-169f-9576-1d7a529fae97.png)](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=1)

■ [Joints](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=2)（ジョイントの例）
説明：各種ジョイントが設定できます。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26094/c7b4a543-852c-ba86-4ebe-5290b0a9fc20.png)](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=2)

■ [Materials - Friction](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=3)（摩擦の例）
説明：この例では石鹸はツルツルしているのに対し蜂蜜はネバネバしているというのを表しています。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26094/3cf2292a-869e-f8ad-2fb9-35577c9a18dd.png)](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=3)

■ [Materials - Restitution](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=4)（反発係数の例）
説明：バスケットボールとボーリングの玉を落下した場合の例です。バスケットボールは良く跳ねますが、ボーリングは跳ねません。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26094/8b5efc11-009e-65f2-1106-f15cc90b5335.png)](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=4)

■ [Motion properties](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=5)（モーションプロパティの例）
説明：物体の移動に必要な特性（質量、慣性、重心、初速度）の設定例です。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26094/8c29588c-fdf0-be40-8ce9-b0300e24cd51.png)](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=5)

■ [Water Wheel](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=6)（水車の例）
説明：複雑なアセットの例です。複数の物理機能が使われています。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26094/b804496d-5d89-4284-df99-57c51dede2ec.png)](https://eoineoineoin.github.io/glTF_Physics_Babylon/packages/demo/dist/#sceneIndex=6)

■ [Robot](https://eoinrul.es/tmp/babylondev/index.html#sceneUrl=https://eoinrul.es/tmp/Robot_skinned.glb)（ロボットの例）
説明：ゼンマイ式のロボットの例です。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26094/2d5b17cd-6ade-d367-67e8-c5bd8a27cdd1.png)](https://eoinrul.es/tmp/babylondev/index.html#sceneUrl=https://eoinrul.es/tmp/Robot_skinned.glb)

### おわりに

本当は実際にサンプルを作るところまで試したかったのですが時間の都合上間に合いませんでした。
時間ができたらドミノ倒しのサンプルでも作ってみたいと思います。

ちなみに、glTF Physics拡張ですが、WebinarのYouTubeの動画を見た感じだと仕様の完成目標としては[2024年のQ1～2](https://youtu.be/sstdRXYbZrI?t=2071)を予定しているようです。
参考情報のところ参考になりそうなリンクを集めてみましたので興味がある方は確認してみてください。

### 参考情報

■ SIGGRAPH 2023 - Let's Get Moving: Adding Physics to glTF
https://www.khronos.org/assets/uploads/developers/presentations/Physics_BOF.pdf
■ Khronos Webinar - Let's Get Moving: Adding Physics to glTF
https://www.khronos.org/events/lets-get-moving-adding-physics-to-gltf
https://www.youtube.com/watch?v=sstdRXYbZrI
■ glTF に剛体拡張機能を追加するための提案
https://github.com/eoineoineoin/glTF_Physics
■ glTF ファイルをエクスポートするときに剛体情報のエクスポートを有効にする Blender 用プラグイン
https://github.com/eoineoineoin/glTF_Physics_Blender_Exporter
■ 剛体情報を含む glTF ファイルを Babylon.js にロードするためのインポーター
https://github.com/eoineoineoin/glTF_Physics_Babylon
■ Babylon.js フォーラム - glTF + Physics + Babylon
https://forum.babylonjs.com/t/gltf-physics-babylon/43923