アニメーションブレンディング
babylon-mmdは、フレーム完璧なアニメーションブレンディングをサポートするMmdCompositeAnimation
アニメーションコンテナを提供します。
babylon-mmdはframe perfectなアニメーションブレンディングを提供するようになりました
ユーザーの入力によってダンスの次の内容を変更することが可能で、正確なタイミングを決めることができるので、リズムゲームを取り入れたQTEアニメーションコンテンツを作ることができると思われます。 pic.twitter.com/ZCRZU9YVMW
— noname0310 (@noname20310)
November 14, 2023
このビデオは、Composite Animationを使用して2人用のダンスアニメーションを1つのMMDモデルで交互に再生する例を示しています。
クレジット:
- モデル:
- YYB Hatsune Miku_10th by YYB
- YYB Miku Default edit by YYB / HB-Squiddy / FreezyChan-3Dreams
- YYB miku Crown Knight by YYB / Pilou la baka
- モーション by srs / ATY
- カメラ by 小紋
- ミュージック:
- 君にとって by Wonder-K
Babylon.jsのAnimationGroup
でMMDアニメーションを再生することにより、Babylon.jsのアニメーションブレンディング機能も使用できます。
ただし、このセクションではAnimationGroup
については説明しません。AnimationGroup
を使用してMMDアニメーションを再生する方法については、Use Babylon.js Animation Runtimeドキュメントを参照してください。
MMD Composite Animation
MmdCompositeAnimation
は、複数のMMD Animationを1つとしてバンドルして管理するアニメーションコンテナです。
各アニメーションは、開始フレームと終了フレームの情報を含むMmdAnimationSpan
オブジェクトとして管理されます。
以下は、2つのMmdAnimation
オブジェクトを1つのMmdCompositeAnimation
にバンドルするサンプルコードです:
const compositeAnimation = new MmdCompositeAnimation("composite");
const duration = Math.max(mmdAnimation1.endFrame, mmdAnimation2.endFrame);
const animationSpan1 = new MmdAnimationSpan(mmdAnimation1, undefined, duration, 0, 1);
const animationSpan2 = new MmdAnimationSpan(mmdAnimation2, undefined, duration, 0, 1);
compositeAnimation.addSpan(animationSpan1);
compositeAnimation.addSpan(animationSpan2);
この場合、両方のアニメーションがフレーム0から開始し、duration
フレームまで再生されます。
MMD Animation Span
MmdAnimationSpan
コンストラクタは以下の通りです:
new MmdAnimationSpan(animation: MmdBindableAnimation, startFrame?: number, endFrame?: number, offset?: number, weight?: number): MmdAnimationSpan
animation
:MmdAnimation
やMmdModelAnimationContainer
など、カメラやモデルにバインド可能なアニメーションコンテナstartFrame
:アニメーションが開始するフレーム(デフォルト:animation.startFrame)endFrame
:アニメーションが終了するフレーム(デフォルト:animation.endFrame)offset
:このSpanがComposite Animationで開始するフレーム(デフォルト:0)weight
:アニメーションブレンディングに使用される重み(デフォルト:1)
MmdCompositeAnimation
は複数のAnimationSpan
オブジェクトを管理し、各AnimationSpan
はアニメーション再生中に動的に追加または削除できます。
MMD Composite Animationメソッド
MmdCompositeAnimation
クラスは以下のメソッドを提供します:
addSpan(span: MmdAnimationSpan): void
:MmdAnimationSpan
を追加します。removeSpan(span: MmdAnimationSpan): void
:MmdAnimationSpan
を削除します。removeSpanFromIndex(index: number): void
:インデックスでMmdAnimationSpan
を削除します。get startFrame(): number
:このComposite Animationの開始フレームを返します。get endFrame(): number
:このComposite Animationの終了フレームを返します。get spans(): readonly MmdAnimationSpan[]
:現在登録されているすべてのMmdAnimationSpan
オブジェクトを返します。
MMD Animation Spanトランジション
MmdAnimationSpan
は、weight
プロパティを通じてアニメーションブレンディングに使用される重みを設定できます。さらに、MmdAnimationSpan
の開始と終了にtransition
フレームを設定して、アニメーション開始時に重みが0から1に、または終了時に1から0に変化することをスムーズに制御する便利機能が提供されています。
この目的のために、MmdAnimationSpan
クラスは以下のプロパティを提供します:
MmdAnimationSpan.easeInFrameTime
:アニメーション開始時に重みが0から1に変化するフレーム数を設定します。MmdAnimationSpan.easeOutFrameTime
:アニメーション終了時に重みが1から0に変化するフレーム数を設定します。MmdAnimationSpan.easingFunction
:重み変化に使用されるイージング関数を設定します。デフォルトはnull
で、この場合線形変化が適用されます。
例えば、MMDアニメーションは30fpsで再生されるため、easeInFrameTime
とeaseOutFrameTime
の両方を30に設定すると、アニメーション開始時と終了時にそれぞれ1秒間重みが変化します。
以下は、easeInFrameTime
とeaseOutFrameTime
の両方を30に設定してトランジションを適用するサンプルコードです:
const animationSpan = new MmdAnimationSpan(mmdAnimation1);
animationSpan.easeInFrameTime = 30;
animationSpan.easeOutFrameTime = 30;
const easingFunction = new BezierCurveEase(0.7, 0.01, 0.3, 0.99);
animationSpan.easingFunction = easingFunction;
compositeAnimation.addSpan(animationSpan);
MMD Composite Runtime Animation
MmdCompositeAnimation
も、他のMMDアニメーションコンテナと同様にMmdCamera
やMmdModel
にバインディングして使用できます。バインディングのために、アニメーション評価とバインディングを担当するランタイムをインポートする必要があります。
import "babylon-mmd/esm/Runtime/Animation/mmdCompositeRuntimeCameraAnimation";
import "babylon-mmd/esm/Runtime/Animation/mmdCompositeRuntimeModelAnimation";
その後、MmdCamera
やMmdModel
のcreateRuntimeAnimation
メソッドを使用してMmdCompositeAnimation
をバインディングできます。
const camera: MmdCamera = ...;
const model: MmdModel = ...;
const compositeAnimationHandle: MmdRuntimeAnimationHandle = camera.createRuntimeAnimation(compositeAnimation);
const compositeAnimationHandle: MmdRuntimeAnimationHandle = model.createRuntimeAnimation(compositeAnimation);
制限事項
MMD Composite Animationは、複数のアニメーションをブレンディングする際に、プロパティパスから評価結果に直接アクセスしてそれらを読み書きします。
そのため、MmdWasmRuntime
が提供するWASM側でのアニメーション評価など、アニメーション評価とプロパティへの実際の適用の間に遅延がある機能とは互換性がありません。
例えば、MmdWasmRuntimeModelAnimation
を使用してMmdWasmAnimation
を評価し、WASM側でアニメーション評価を実行する場合、MmdCompositeAnimation
とのブレンディングはサポートされません。
代わりに、MmdRuntimeModelAnimation
を使用してMmdWasmAnimation
を評価する場合、MmdCompositeAnimation
とのブレンディングは可能です。
サンプルコード
サンプルコードはcompositeAnimationTestScene.tsで確認できます。
このサンプルコードでは、UIを通じて重みを調整でき、静的に設定されたフレーム番号に従って2つのアニメーションが交互に再生される様子を見ることができます。