Babylon.js WebXR Hand tracking
HandTracking
デバイスやブラウザの中には、外部コントローラを必要とせず、手の関節を直接トラッキングすることをサポートしているものがあります。そのようなデバイスは、ネイティブのオキュラスブラウザを使用して、Oculus Quest1,2です。
両手の25点がトラッキングされ、各フレームで配信されています。Babylonのハンドトラッキング機能は、この情報を使って、WebXRHandオブジェクトとその25個の子のトランスフォームを常に更新しています。
このページで「手」に言及する場合、左利き対右利きのシステムではなく、ユーザーの実際の手の大きさに言及していることにご注意ください。WebXRはその性質上、右利きです。
Getting started
開始するには、まず、サポートされているデバイスが必要です。前に書いたように、現在手をサポートしている主なデバイスは2つです - oculus quest 1と2ネイティブブラウザを使用します。(oculus linkを使用しない).
oculus questでハンドジョイントトラッキングサポートを有効にするには、chrome://flagsに行き、
webxr joints-tracking
を有効にすることを確認します。これが有効になると、Babylonは各フレームで手の情報を読み取ることができるようになります。
Babylonシーンでハンドサポートを有効にするには、WebXR機能を有効にしてください。
const featureManager = xrHelper.baseExperience.featuresManager;
featureManager.enableFeature(BABYLON.WebXRFeatureName.HAND_TRACKING, "latest", {
xrInput: xrHelper.input,
});
各手には25個の隠し球が作成され、各手にはデフォルトのハンドメッシュが読み込まれて有効になります。
Configuration Options
このプラグインの現在のオプションは、WebXRハンドトラッキング機能のソースコードで常に確認することができます。それらのほとんどは、後で説明します。
Hand meshes
Babylonのデフォルトのハンドメッシュは、デフォルトで有効になっています。これを完全に無効にしたり、別のメッシュを用意したりすることができます。
無効にするには、機能を作成するときに disableDefaultHandMesh フラグを使用します。
const featureManager = xrHelper.baseExperience.featuresManager;
featureManager.enableFeature(BABYLON.WebXRFeatureName.HAND_TRACKING, "latest", {
xrInput: xrHelper.input,
jointMeshes: {
disableDefaultHandMesh: true,
},
});
もし、異なるハンドメッシュを提供したい場合(例えば、ユーザーに手袋をさせたい場合)、hand meshes assetsディレクトリから現在のRHS(右手系)ハンドメッシュを取り出し、それを修正することをお勧めします。そうでない場合は、独自のスケルトン/ボーンを作成し、スキンに正しいウェイトを付ける必要があります。
作成が完了したら、手ごとに2つの重要なオブジェクトが必要です。ひとつは、実際のメッシュです。もうひとつは、ネイティブのXRトラッキングされたジョイントと、モデルのボーンとの間のマッピングです。これは、各手のボーンの名前を文字列で表した構造化配列で、ジョイントのXRマッピングに従ってソートされています。デフォルトではこのようになっています。
this._rigMapping = [
"wrist_",
"thumb_metacarpal_",
"thumb_proxPhalanx_",
"thumb_distPhalanx_",
"thumb_tip_",
"index_metacarpal_",
"index_proxPhalanx_",
"index_intPhalanx_",
"index_distPhalanx_",
"index_tip_",
"middle_metacarpal_",
"middle_proxPhalanx_",
"middle_intPhalanx_",
"middle_distPhalanx_",
"middle_tip_",
"ring_metacarpal_",
"ring_proxPhalanx_",
"ring_intPhalanx_",
"ring_distPhalanx_",
"ring_tip_",
"little_metacarpal_",
"little_proxPhalanx_",
"little_intPhalanx_",
"little_distPhalanx_",
"little_tip_",
].map((joint) => `${joint}${handedness === "right" ? "R" : "L"}`);
手元に両方のオブジェクトがあれば、機能を有効にする際に提供することができます。
const rightHandMesh = getRightHandMesh(); // get it any way you want
const leftHandMesh = getLeftHandMesh(); // get it any way you want
const featureManager = xrHelper.baseExperience.featuresManager;
featureManager.enableFeature(BABYLON.WebXRFeatureName.HAND_TRACKING, "latest", {
xrInput: xrHelper.input,
jointMeshes: {
disableDefaultHandMesh: true,
handMeshes: {
right: rightHandMesh,
left: leftHandMesh,
},
rigMapping: {
right: [
//... mapping for the right hand mesh
],
left: [
//... mapping for the left hand mesh
],
},
},
});
25 tracked points per hand
前述したように、WebXRでは1ハンドあたり25ポイントをトラッキングすることができます。それらのポイントはここに記載されています。XR Skeleton Joints(スケルトンジョイント)。
おおよそこのような感じです。
この25点のそれぞれには、ハンドトラッキング機能を有効にするとInstancedMeshが作成されます。これらのメッシュは、物理、ジェスチャー認識、衝突検出などに使用することができます。デフォルトのメッシュは球体です。別のメッシュを指定するには、sourceMesh オプションを使用します。
const featureManager = xrHelper.baseExperience.featuresManager;
featureManager.enableFeature(BABYLON.WebXRFeatureName.HAND_TRACKING, "latest", {
xrInput: xrHelper.input,
jointMeshes: {
sourceMesh: BoxBuilder.CreateBox("jointParent", { size: 1 }),
},
});
Babylon は、この sourceMesh を使って、片手あたり 25 個のインスタンスを作成します。このメッシュはその後、不可視に設定されます。ただし、あなたの都合で可視のままにしておくことを要求された場合は別です。
const featureManager = xrHelper.baseExperience.featuresManager;
featureManager.enableFeature(BABYLON.WebXRFeatureName.HAND_TRACKING, "latest", {
xrInput: xrHelper.input,
jointMeshes: {
sourceMesh: BoxBuilder.CreateBox("jointParent", { size: 1 }),
keepOriginalVisible: true, // will keep the original instance visible
},
});