応用編4: 物理演算の組み込み
本章のゴール
babylon-mmd専用の物理エンジンを連携させ、髪や衣装の自然な揺れを再現し、ユーザーがモデルに触れる方法を習得する。
キャラクターの精緻な動きに欠かせないのが、髪の毛やスカートなどが慣性に従って揺れる「物理演算」です。MMDモデル(PMX)にはあらかじめ剛体やジョイントといった物理設定が組み込まれています。
物理エンジンの選択基準
Babylon.js環境において、MMDの物理演算を行うためのエンジンには主に以下の3つの選択肢が用意されています。
- Havok Physics: モダンな物理エンジンでパフォーマンスは最高ですが、MMD特有の複雑な剛体・ジョイント挙動の再現には弱く、意図しない挙動を起こしやすいためMMDモデルには不向きとなっています。
- Ammo.js: JavaScriptネイティブ環境で動かしやすい移植版で、挙動もある程度再現できますが、一部のモデルでジョイントの計算が不安定になる欠点があります。
- Bullet Physics (WASM): MMD本来の物理計算のベースであるBulletエンジンを、WebAssemblyとしてRustで最適化コンパイルしたものです。現在、babylon-mmd公式推奨の物理エンジンです。
組み込みステップ
推奨されている Bullet Physics (WASM) を使用して、大きく分けて以下の3ステップで物理演算を組み込みます。
- ステップ1: 専用物理エンジンの初期化
- ステップ2: アニメーションランタイムへの組み込み
- ステップ3: 物理世界の共有とキャラクターとの接触
1. 専用物理エンジンの初期化
公式から推奨される MmdWasmPhysics クラスのインスタンスを作成します。特別な外部ライブラリの別途ロードは必要なく、標準でbabylon-mmdに最適化状態で同梱されています。
import { MmdWasmPhysics } from "babylon-mmd/esm/Runtime/Optimized/Physics/mmdWasmPhysics";
const mmdPhysics = new MmdWasmPhysics(scene);
2. アニメーションランタイムへの組み込み
前章までで作成していた MmdWasmRuntime の生成時に、準備した mmdPhysics を第2引数として渡します。
import { MmdWasmRuntime } from "babylon-mmd/esm/Runtime/Optimized/mmdWasmRuntime";
currentMmdRuntime = new MmdWasmRuntime(scene, mmdPhysics);
たったこれだけで、モデルを読み込んだ際にPMXデータ内の剛体・ジョイント情報が自動的に解析され、モーションの動きに追従して髪や衣装が自然に揺れるようになります。
3. 物理世界の共有とキャラクターとの接触
通常、追加されたMMDモデルはそれぞれ独立した物理世界を持っていますが、XR空間で自分の手や他のアイテムでキャラクターの髪などの剛体に触れたい場合は、物理空間を共有する必要があります。
モデル作成時に buildPhysics オプションとして kinematicSharedWorldIds: [0] を指定することで、全て同じ「0番世界」の中で物理計算が行われるようになります。
let mmdModel = currentMmdRuntime.createMmdModel(mesh, {
buildPhysics: {
kinematicSharedWorldIds: [0]
}
});
この設定を行った上で、コントローラーなどの位置に「当たり判定のある剛体が仕込まれた見えないダミーPMX」などを配置して同じく kinematicSharedWorldIds: [0] に登録すれば、プレイヤー自身の手で直接キャラクターの物理演算に干渉できる、よりリッチなXR体験を生み出すことができます。
お疲れ様でした。これでキャラクターがより自然で現実感のある動きを手に入れ、インタラクティブに触れ合えるようになりました。
物理演算を使わないという選択肢
インタラクティブにキャラクターに触れる必要がない場合は、Blender等であらかじめ髪やスカートの動きをモーションに焼き込み(ベイク)し、ランタイムでは物理演算をオフにするという方法もあります。glb形式などにエクスポートすれば、ファイルサイズは増えるものの、リアルタイムの剛体計算が不要になるため、VRゴーグルなど処理リソースが限られる環境では特に有効な選択肢です。