メインコンテンツまでスキップ

非MMDモデルにMMDアニメーションを適用

MMDアニメーションは、一般的に準標準ボーン構造に従うMMDモデルと互換性があるように設計されています。

しかし、babylon-mmdはヒューマノイドモデルにMMDアニメーションを適用することもサポートしています。

ヒューマノイドモデル

ヒューマノイドモデルは、UnityのHumanoid RigMixamo rigのボーン構造に従うモデルを指します。

ヒューマノイドモデルのボーン構造は以下の通りです:

babylon-mmd/Loader/Util/mmdHumanoidMapper.ts
/**
* refs:
* https://docs.unity3d.com/ScriptReference/HumanBodyBones.html
* https://github.com/V-Sekai/three-vrm-1-sandbox-mixamo/blob/master/mixamoVRMRigMap.js
*
* unity humanoid bone structure:
*
* - Hips
* - Spine
* - Chest
* - UpperChest
* - Neck
* - Head
* - LeftEye
* - RightEye
* - Jaw
*
* - LeftShoulder
* - LeftUpperArm
* - LeftLowerArm
* - LeftHand
* - LeftThumbProximal
* - LeftThumbIntermediate
* - LeftThumbDistal
* - LeftIndexProximal
* - LeftIndexIntermediate
* - LeftIndexDistal
* - LeftMiddleProximal
* - LeftMiddleIntermediate
* - LeftMiddleDistal
* - LeftRingProximal
* - LeftRingIntermediate
* - LeftRingDistal
* - LeftLittleProximal
* - LeftLittleIntermediate
* - LeftLittleDistal
*
* - RightShoulder
* - RightUpperArm
* - RightLowerArm
* - RightHand
* - RightThumbProximal
* - RightThumbIntermediate
* - RightThumbDistal
* - RightIndexProximal
* - RightIndexIntermediate
* - RightIndexDistal
* - RightMiddleProximal
* - RightMiddleIntermediate
* - RightMiddleDistal
* - RightRingProximal
* - RightRingIntermediate
* - RightRingDistal
* - RightLittleProximal
* - RightLittleIntermediate
* - RightLittleDistal
*
* - LeftUpperLeg
* - LeftLowerLeg
* - LeftFoot
* - LeftToes
*
* - RightUpperLeg
* - RightLowerLeg
* - RightFoot
* - RightToes
*/

Humanoid MMD

HumanoidMmdは、ヒューマノイドモデルにMMDアニメーションを適用するためのヘルパークラスです。

このクラスを使用して、プロキシ準標準スケルトンを作成してMmdModelを生成し、リアルタイムリターゲティングを使用してヒューマノイドモデルにMMDアニメーションを適用できます。

const mmdRuntime = new MmdRuntime(scene);

const humanoidMmd = new HumanoidMmd();
const mmdModel = humanoidMmd.createMmdModelFromHumanoid(
mmdRuntime,
modelRoot,
[modelMesh],
{
boneMap: new MmdHumanoidMapper({
hips: "Hips",
spine: "Spine",
chest: "Chest",
neck: "Neck",
head: "Head",
leftShoulder: "LeftShoulder",
leftUpperArm: "LeftUpperArm",
leftLowerArm: "LeftLowerArm",
leftHand: "LeftHand",
rightShoulder: "RightShoulder",
rightUpperArm: "RightUpperArm",
rightLowerArm: "RightLowerArm",
rightHand: "RightHand",
leftUpperLeg: "LeftUpperLeg",
leftLowerLeg: "LeftLowerLeg",
leftFoot: "LeftFoot",
leftToes: "LeftToeBase",
rightUpperLeg: "RightUpperLeg",
rightLowerLeg: "RightLowerLeg",
rightFoot: "RightFoot",
rightToes: "RightToeBase",

leftEye: "LeftEye",
rightEye: "RightEye",

leftThumbProximal: "LeftThumbProximal",
leftThumbIntermediate: "LeftThumbIntermediate",
leftThumbDistal: "LeftThumbDistal",
leftIndexProximal: "LeftIndexProximal",
leftIndexIntermediate: "LeftIndexIntermediate",
leftIndexDistal: "LeftIndexDistal",
leftMiddleProximal: "LeftMiddleProximal",
leftMiddleIntermediate: "LeftMiddleIntermediate",
leftMiddleDistal: "LeftMiddleDistal",
leftRingProximal: "LeftRingProximal",
leftRingIntermediate: "LeftRingIntermediate",
leftRingDistal: "LeftRingDistal",
leftLittleProximal: "LeftLittleProximal",
leftLittleIntermediate: "LeftLittleIntermediate",
leftLittleDistal: "LeftLittleDistal",

rightThumbProximal: "RightThumbProximal",
rightThumbIntermediate: "RightThumbIntermediate",
rightThumbDistal: "RightThumbDistal",
rightIndexProximal: "RightIndexProximal",
rightIndexIntermediate: "RightIndexIntermediate",
rightIndexDistal: "RightIndexDistal",
rightMiddleProximal: "RightMiddleProximal",
rightMiddleIntermediate: "RightMiddleIntermediate",
rightMiddleDistal: "RightMiddleDistal",
rightRingProximal: "RightRingProximal",
rightRingIntermediate: "RightRingIntermediate",
rightRingDistal: "RightRingDistal",
rightLittleProximal: "RightLittleProximal",
rightLittleIntermediate: "RightLittleIntermediate",
rightLittleDistal: "RightLittleDistal"
}).boneMap,
transformOffset: modelArmatureRootWorldTransform
}
);

ヒューマノイドモデルからMmdModelを作成するファンクションのシグネチャは以下の通りです:

HumanoidMmd.createMmdModelFromHumanoid<T extends IMmdModel>(
mmdRuntime: IMmdRuntime<T>,
humanoidMesh: Mesh,
meshes: readonly Mesh[],
options: ICreateMmdModelFromHumanoidOptions = {}
): T
  • mmdRuntime: IMmdRuntime<MmdModel>

    • MmdRuntimeクラスまたはMmdWasmRuntimeクラスのインスタンスが可能です。
  • humanoidMesh: Mesh

    • MMDメタデータを格納するメッシュ。このメッシュはダックタイピングを通じてMMDモデルとして扱われます。
    • MmdModelが作成された後、このメッシュはMmdSkinnedMeshインターフェースを満たします。
  • meshes: readonly Mesh[]

    • ヒューマノイドモデルを構成するメッシュの配列。HumanoidMmdは、MmdModelの初期化時にこのメッシュ配列でスケルトンとモーフターゲットマージャーを検索します。
    • したがって、モーフターゲットアニメーションを使用したい場合は、モーフターゲットを含むメッシュをこの配列に含める必要があります。
  • options: ICreateMmdModelFromHumanoidOptions

    • boneMap: { [key: string]: string }
      • ヒューマノイドモデルのボーン名マップ。
      • UnityのHumanoid Rigはボーン名を特定の文字列に固定しないため、ユーザーはボーン名マップを直接指定する必要があります。
    • morphMap: { [key: string]: string }
      • ヒューマノイドモデルのモーフターゲット名マップ。
      • ヒューマノイドモデルに「あ」、「い」、「う」、「え」、「お」などのMMDモーフに相当するモーフターゲットが含まれている場合、このオプションを使用してそれらをマッピングし、モーフターゲット名マップを指定できます。
      • このオプションが指定されない場合、MMDモーフと同じ名前のモーフターゲットを探します。
    • transformOffset?: Matrix
      • ヒューマノイドモデルのルートボーンに適用するトランスフォームマトリックス。
      • このオプションは、モデルのワールドトランスフォームがレストポーズで特定の方向に回転している場合に必要です。
      • 例えば、GLTFモデルはBabylon.jsにインポートされる際にy軸周りに180度の回転がルートノードに適用されるため、このオプションを使用してスケルトンのルートノードを指定する必要があります。
      • また、一部のモデルはアイデンティティではないスケルトントランスフォームを持っています。この場合も、このオプションを使用してレストポーズのワールドトランスフォームを修正できます。
警告

すべてのオプションは慎重に設定する必要があります。boneMapが間違っていたり、transformOffsetが不適切に設定されている場合、MMDアニメーションがヒューマノイドモデルに正しく適用されない可能性があります。

レストポーズ設定

また、モデルのレストポーズをAポーズに設定する必要があります。

HumanoidMmdは、バインディング時のポーズをレストポーズとして考慮します。

したがって、モデルがTポーズの場合、バインディング前に腕の角度を調整してAポーズを作成する必要があります。

以下のコードは、腕をAポーズに調整する例です:

src/Test/Scene/humanoidMmdTestScene2.ts
const modelMesh = modelLoadResult.meshes[1] as Mesh;
{
const transformNodes = modelLoadResult.transformNodes;
const leftArm = transformNodes.find((transformNode) => transformNode.name === "LeftUpperArm")!;
const rightArm = transformNodes.find((transformNode) => transformNode.name === "RightUpperArm")!;
const degToRad = Math.PI / 180;
leftArm.rotationQuaternion = leftArm.rotationQuaternion!.multiply(Quaternion.FromEulerAngles(0, 0, -35 * degToRad));
rightArm.rotationQuaternion = rightArm.rotationQuaternion!.multiply(Quaternion.FromEulerAngles(0, 0, 35 * degToRad));
}

アプリケーション例

以下は、babylon-mmdのヒューマノイドモデルサポート機能を使用してヒューマノイドモデルにMMDアニメーションを適用する例です:

モデル: あまとうさぎのカリン

このデモのコードはbabylon-mmdのテストコードで確認できます。

制限事項

  • ヒューマノイドMMDにはハードコードされてアドホックに実装された部分が多くあります。そのため、すべてのヒューマノイドモデルで完璧に動作しない可能性があります。
  • ヒューマノイドMMDはリアルタイムでリターゲティングを実行するため、MMDモデルと比較してパフォーマンスが低下する可能性があります。
  • ヒューマノイドMMDは物理シミュレーションを処理しません。非MMDモデルに物理シミュレーションを適用したい場合は、シミュレーションソルバーを自分で実装する必要があります。

したがって、可能な場合は、非MMDモデルをPMXフォーマットに変換してMMDモデルとして使用することが推奨されます。