PITMデータ形式

PITMはglTF-2.0と独自のextensions, extrasの組み合わせです。PITMはGLBコンテナ形式でシリアライズされます。extensionsの仕様はProtocol Buffersで記述されています。

PITMの一部仕様を用いてクラフトアイテムやアクセサリーを書き出すためのユーティリティクラスがPythonサンプルコードに含まれています。以下のファイルをご覧ください。

https://github.com/ClusterVR/PITMSample/blob/main/python/pitm.py

glTF構造

PITMはvalidなglTFである必要があります。

PITMは単一のsceneを持ちます。また、bufferのuriなど、外部リソースの参照は利用できません。(全てのテクスチャ、メッシュなどのデータはGLBファイル内で完結して含まれている必要があります)

glTFのトップレベルにClusterItem extensionが、各nodeにClusterItemNode extensionが必要です。

PITMの基本構造はクラフトアイテムとアクセサリーの場合で同じですが、それぞれで利用出来る機能が異なります。

クラフトアイテム

クラフトアイテムの制限に従います。pbrMetallicRoughnessなどglTFの標準マテリアルが利用可能です。

アクセサリー

アクセサリーの制限に従います。

ItemではItem.metaItem.accessory_itemのみ利用でき、これら二つのフィールドは必須です。 ItemNode内のフィールドはアクセサリーでは利用出来ませんが、空のItemNodeが必要です。

マテリアルにはMToonのみ利用出来ます。MToonのパラメーターはglTFのmaterialのClusterVRM0MToon extraに記述されます。

ClusterItem extension と ClusterItemNode extension

トップレベルにはClusterItem extensionが必要です。

"extensions": [
    "ClusterItem": {
      {"item": "URL-safe base64エンコードされたmessage Item"}
    }
]

全てのnodeにはClusterItemNode extensionが必要です。

"extensions": [
    "ClusterItemNode": {
      {"itemNode": "URL-safe base64エンコードされたmessage ItemNode"}
    }
]

ItemとItemNodeの仕様はproto3で記述されています。以下のファイルをご覧ください。

https://github.com/ClusterVR/PITMSample/blob/main/pitm.proto

URL-safe base64エンコーディングには、RFC 4648の Base 64 Encoding with URL and Filename Safe Alphabetの亜種を利用します。

  • 末尾の=はありません
  • +/の代わりに-_を使用します

例: URL-safe base64エンコードされたItemNode “OiQKIgogCg4KDAAAAAAAAAAAmpmZPRIOCgwAAAA_AAAAP5qZGT4”

ClusterHumanoidAnimation extension と ClusterHumanoidAnimationTarget extension

PITM内でHumanoidAnimationはglTFのanimationとして埋め込まれます。

アニメーションがループアニメーションであるかどうかは、animationのextensionsにClusterHumanoidAnimationとして格納されます。 animationにClusterHumanoidAnimationが存在しない場合、ループアニメーションではないとして扱われます。

{
  "extensions": {
    "ClusterHumanoidAnimation": {
      "isLoop": true
    }
  }
}

アニメーションの対象はanimation.channel.targetのextensionsにClusterHumanoidAnimationTargetとして格納される必要があります。 animation.channel.targetのその他のフィールドは無視されます。 アニメーションのキーフレーム情報はglTFのsamplerとして格納されます。

{
  "target": {
    "extensions": {
      "ClusterHumanoidAnimationTarget": {
        "humanoidAnimationTargetType": "LeftShoulderFrontBack"
      }
    },
    "path": "muscle"
  }
}

humanoidAnimationTargetTypeは以下のいずれかの値をとります。

  • "CenterPosition"はglTFのワールド座標系に対する並行移動に対応し、VEC3のsampler出力をXYZとして受け取ります。
  • "CenterRotation"はglTFのワールド座標系に対する回転移動に対応し、VEC4のsampler出力をXYZWのクォータニオンとして受け取ります。
  • それ以外の値はヒューマノイドボーンのMuscle値に対応し、SCALARのsampler出力を受け取ります。
"CenterPosition"
"CenterRotation"
"SpineFrontBack"
"SpineLeftRight"
"SpineTwistLeftRight"
"ChestFrontBack"
"ChestLeftRight"
"ChestTwistLeftRight"
"UpperChestFrontBack"
"UpperChestLeftRight"
"UpperChestTwistLeftRight"
"NeckNodDownUp"
"NeckTiltLeftRight"
"NeckTurnLeftRight"
"HeadNodDownUp"
"HeadTiltLeftRight"
"HeadTurnLeftRight"
"LeftEyeDownUp"
"LeftEyeInOut"
"RightEyeDownUp"
"RightEyeInOut"
"JawClose"
"JawLeftRight"
"LeftUpperLegFrontBack"
"LeftUpperLegInOut"
"LeftUpperLegTwistInOut"
"LeftLowerLegStretch"
"LeftLowerLegTwistInOut"
"LeftFootUpDown"
"LeftFootTwistInOut"
"LeftToesUpDown"
"RightUpperLegFrontBack"
"RightUpperLegInOut"
"RightUpperLegTwistInOut"
"RightLowerLegStretch"
"RightLowerLegTwistInOut"
"RightFootUpDown"
"RightFootTwistInOut"
"RightToesUpDown"
"LeftShoulderDownUp"
"LeftShoulderFrontBack"
"LeftArmDownUp"
"LeftArmFrontBack"
"LeftArmTwistInOut"
"LeftForearmStretch"
"LeftForearmTwistInOut"
"LeftHandDownUp"
"LeftHandInOut"
"RightShoulderDownUp"
"RightShoulderFrontBack"
"RightArmDownUp"
"RightArmFrontBack"
"RightArmTwistInOut"
"RightForearmStretch"
"RightForearmTwistInOut"
"RightHandDownUp"
"RightHandInOut"
"LeftThumb1Stretched"
"LeftThumbSpread"
"LeftThumb2Stretched"
"LeftThumb3Stretched"
"LeftIndex1Stretched"
"LeftIndexSpread"
"LeftIndex2Stretched"
"LeftIndex3Stretched"
"LeftMiddle1Stretched"
"LeftMiddleSpread"
"LeftMiddle2Stretched"
"LeftMiddle3Stretched"
"LeftRing1Stretched"
"LeftRingSpread"
"LeftRing2Stretched"
"LeftRing3Stretched"
"LeftLittle1Stretched"
"LeftLittleSpread"
"LeftLittle2Stretched"
"LeftLittle3Stretched"
"RightThumb1Stretched"
"RightThumbSpread"
"RightThumb2Stretched"
"RightThumb3Stretched"
"RightIndex1Stretched"
"RightIndexSpread"
"RightIndex2Stretched"
"RightIndex3Stretched"
"RightMiddle1Stretched"
"RightMiddleSpread"
"RightMiddle2Stretched"
"RightMiddle3Stretched"
"RightRing1Stretched"
"RightRingSpread"
"RightRing2Stretched"
"RightRing3Stretched"
"RightLittle1Stretched"
"RightLittleSpread"
"RightLittle2Stretched"
"RightLittle3Stretched"

ClusterVRM0MToon extra

PITM内でMToonはglTFのmaterialのextrasにClusterVRM0MToonとして格納されます。

MToonMatのnormalMapAsGltfFormatがtrueの場合、MToonMatのtexturePropertiesで"_BumpMap"をkeyとして指定されるテクスチャをglTFのnormalTextureとして扱います。詳細はSchemaをご覧ください。この値はtrueが推奨されます。 それ以外のテクスチャはガンマ色空間のテクスチャとして扱われます。 MToonMat内のその他のデータはVRM-0.xのmaterialPropertiesの各要素と同様の形式に従います。

{
  ..., // materialのその他の中身
  "extras": {
    "ClusterVRM0MToon": {
      "MToonMat": {
        "normalMapAsGltfFormat": boolean,
        "shader": "VRM/MToon",
        "renderQueue": {...},
        "keywordMap": {...},
        "tagMap": {...},
        "floatProperties": {...},
        "textureProperties": {...},
        "vectorProperties": {...}
      }
    }
  }
}