From 30a226210467c1d00e8bdedc4d93b08e7c07e938 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 9 Dec 2022 21:20:58 +0900 Subject: [PATCH 1/2] Add XR_FB_body_tracking rig. --- .../Rigs/ControlRigGenerationOption.cs | 10 +++ .../ControlRig/Rigs/XR_FB_body_tracking.cs | 85 +++++++++++++++++++ .../Rigs/XR_FB_body_tracking.cs.meta | 11 +++ 3 files changed, 106 insertions(+) create mode 100644 Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs create mode 100644 Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs.meta diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/ControlRigGenerationOption.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/ControlRigGenerationOption.cs index b5a09268a..d99dfc4de 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/ControlRigGenerationOption.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/ControlRigGenerationOption.cs @@ -24,6 +24,13 @@ namespace UniVRM10 /// https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_hand_tracking /// Vrm0XCompatibleWithXR_EXT_hand_tracking = 2, + + /// + /// コントロールリグのボーン Transform を生成し、Root の Animator はコントロールリグのボーンを制御するようになります。 + /// 上半身に関して、XR_FB_body_tracking の初期回転を持ちます。 + /// https://developer.oculus.com/documentation/native/android/move-ref-body-joints/ + /// + Vrm0XCompatibleWithXR_FB_body_tracking = 3, } internal static class ControlRigGenerationOptionExtensions @@ -42,6 +49,9 @@ namespace UniVRM10 case ControlRigGenerationOption.Vrm0XCompatibleWithXR_EXT_hand_tracking: return XR_EXT_hand_tracking.InitialRotations; + case ControlRigGenerationOption.Vrm0XCompatibleWithXR_FB_body_tracking: + return XR_FB_body_tracking.InitialRotations; + default: throw new ArgumentException(); } diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs new file mode 100644 index 000000000..066ef4c27 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace UniVRM10 +{ + /// + /// XR_FB_body_tracking の joint を VRM-1.0 の TPose に当てはめたときの方向を定義します。 + /// + /// * https://developer.oculus.com/documentation/native/android/move-ref-body-joints/ + /// + /// OpenXR は右手系なのに対して Unityは左手系です。 + /// この Rig が期待するボーンの値は、XR_FB_body_tracking の Joint の値を Z軸反転で座標変換したものです。 + /// + public static class XR_FB_body_tracking + { + /// + /// up vector と forward vector の外積により空間を算出して、回転を得ます。 + /// + /// + /// + /// + public static Quaternion GetRotation(Vector3 yAxis, Vector3 zAxis) + { + var xAxis = Vector3.Cross(yAxis, zAxis).normalized; + var m = new Matrix4x4(xAxis, yAxis, zAxis, new Vector4(0, 0, 0, 1)); + return m.rotation; + } + + public static Quaternion Spine = GetRotation(Vector3.forward, Vector3.left); + public static Quaternion Left = GetRotation(Vector3.forward, Vector3.down); + public static Quaternion LeftThumb = GetRotation((Vector3.left + Vector3.forward).normalized, Vector3.up); + public static Quaternion Right = GetRotation(Vector3.back, Vector3.up); + public static Quaternion RightThumb = GetRotation((Vector3.left + Vector3.back).normalized, Vector3.down); + + public static IReadOnlyDictionary InitialRotations => new Dictionary() + { + {HumanBodyBones.Hips, Spine}, + {HumanBodyBones.Spine, Spine}, + {HumanBodyBones.Chest, Spine}, + {HumanBodyBones.UpperChest, Spine}, + {HumanBodyBones.Neck, Spine}, + {HumanBodyBones.Head, Spine}, + {HumanBodyBones.LeftShoulder, Left}, + {HumanBodyBones.LeftUpperArm, Left}, + {HumanBodyBones.LeftLowerArm, Left}, + {HumanBodyBones.LeftHand, Left}, + {HumanBodyBones.RightShoulder, Right}, + {HumanBodyBones.RightUpperArm, Right}, + {HumanBodyBones.RightLowerArm, Right}, + {HumanBodyBones.RightHand, Right}, + // left + {HumanBodyBones.LeftThumbProximal, LeftThumb}, + {HumanBodyBones.LeftThumbIntermediate, LeftThumb}, + {HumanBodyBones.LeftThumbDistal, LeftThumb}, + {HumanBodyBones.LeftIndexProximal, Left}, + {HumanBodyBones.LeftIndexIntermediate, Left}, + {HumanBodyBones.LeftIndexDistal, Left}, + {HumanBodyBones.LeftMiddleProximal, Left}, + {HumanBodyBones.LeftMiddleIntermediate, Left}, + {HumanBodyBones.LeftMiddleDistal, Left}, + {HumanBodyBones.LeftRingProximal, Left}, + {HumanBodyBones.LeftRingIntermediate, Left}, + {HumanBodyBones.LeftRingDistal, Left}, + {HumanBodyBones.LeftLittleProximal, Left}, + {HumanBodyBones.LeftLittleIntermediate, Left}, + {HumanBodyBones.LeftLittleDistal, Left}, + // right + {HumanBodyBones.RightThumbProximal, RightThumb}, + {HumanBodyBones.RightThumbIntermediate, RightThumb}, + {HumanBodyBones.RightThumbDistal, RightThumb}, + {HumanBodyBones.RightIndexProximal, Right}, + {HumanBodyBones.RightIndexIntermediate, Right}, + {HumanBodyBones.RightIndexDistal, Right}, + {HumanBodyBones.RightMiddleProximal, Right}, + {HumanBodyBones.RightMiddleIntermediate, Right}, + {HumanBodyBones.RightMiddleDistal, Right}, + {HumanBodyBones.RightRingProximal, Right}, + {HumanBodyBones.RightRingIntermediate, Right}, + {HumanBodyBones.RightRingDistal, Right}, + {HumanBodyBones.RightLittleProximal, Right}, + {HumanBodyBones.RightLittleIntermediate, Right}, + {HumanBodyBones.RightLittleDistal, Right}, + }; + } +} \ No newline at end of file diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs.meta new file mode 100644 index 000000000..4e602f484 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a4e5ee6aa707a2044a9903133bbf085f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 3e5535cb72d80e10b28075b92b3ebebd3f7c67d1 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 9 Dec 2022 21:37:55 +0900 Subject: [PATCH 2/2] fix hand rotation --- .../ControlRig/Rigs/XR_FB_body_tracking.cs | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs index 066ef4c27..296cee4e8 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_FB_body_tracking.cs @@ -27,10 +27,14 @@ namespace UniVRM10 } public static Quaternion Spine = GetRotation(Vector3.forward, Vector3.left); + public static Quaternion Left = GetRotation(Vector3.forward, Vector3.down); - public static Quaternion LeftThumb = GetRotation((Vector3.left + Vector3.forward).normalized, Vector3.up); + public static Quaternion LeftThumb = GetRotation((Vector3.left + Vector3.back).normalized, Vector3.up); + public static Quaternion LeftHand = GetRotation(Vector3.down, Vector3.back); + public static Quaternion Right = GetRotation(Vector3.back, Vector3.up); - public static Quaternion RightThumb = GetRotation((Vector3.left + Vector3.back).normalized, Vector3.down); + public static Quaternion RightThumb = GetRotation((Vector3.left + Vector3.forward).normalized, Vector3.down); + public static Quaternion RightHand = GetRotation(Vector3.up, Vector3.forward); public static IReadOnlyDictionary InitialRotations => new Dictionary() { @@ -43,43 +47,43 @@ namespace UniVRM10 {HumanBodyBones.LeftShoulder, Left}, {HumanBodyBones.LeftUpperArm, Left}, {HumanBodyBones.LeftLowerArm, Left}, - {HumanBodyBones.LeftHand, Left}, {HumanBodyBones.RightShoulder, Right}, {HumanBodyBones.RightUpperArm, Right}, {HumanBodyBones.RightLowerArm, Right}, - {HumanBodyBones.RightHand, Right}, // left + {HumanBodyBones.LeftHand, LeftHand}, {HumanBodyBones.LeftThumbProximal, LeftThumb}, {HumanBodyBones.LeftThumbIntermediate, LeftThumb}, {HumanBodyBones.LeftThumbDistal, LeftThumb}, - {HumanBodyBones.LeftIndexProximal, Left}, - {HumanBodyBones.LeftIndexIntermediate, Left}, - {HumanBodyBones.LeftIndexDistal, Left}, - {HumanBodyBones.LeftMiddleProximal, Left}, - {HumanBodyBones.LeftMiddleIntermediate, Left}, - {HumanBodyBones.LeftMiddleDistal, Left}, - {HumanBodyBones.LeftRingProximal, Left}, - {HumanBodyBones.LeftRingIntermediate, Left}, - {HumanBodyBones.LeftRingDistal, Left}, - {HumanBodyBones.LeftLittleProximal, Left}, - {HumanBodyBones.LeftLittleIntermediate, Left}, - {HumanBodyBones.LeftLittleDistal, Left}, + {HumanBodyBones.LeftIndexProximal, LeftHand}, + {HumanBodyBones.LeftIndexIntermediate, LeftHand}, + {HumanBodyBones.LeftIndexDistal, LeftHand}, + {HumanBodyBones.LeftMiddleProximal, LeftHand}, + {HumanBodyBones.LeftMiddleIntermediate, LeftHand}, + {HumanBodyBones.LeftMiddleDistal, LeftHand}, + {HumanBodyBones.LeftRingProximal, LeftHand}, + {HumanBodyBones.LeftRingIntermediate, LeftHand}, + {HumanBodyBones.LeftRingDistal, LeftHand}, + {HumanBodyBones.LeftLittleProximal, LeftHand}, + {HumanBodyBones.LeftLittleIntermediate, LeftHand}, + {HumanBodyBones.LeftLittleDistal, LeftHand}, // right + {HumanBodyBones.RightHand, RightHand}, {HumanBodyBones.RightThumbProximal, RightThumb}, {HumanBodyBones.RightThumbIntermediate, RightThumb}, {HumanBodyBones.RightThumbDistal, RightThumb}, - {HumanBodyBones.RightIndexProximal, Right}, - {HumanBodyBones.RightIndexIntermediate, Right}, - {HumanBodyBones.RightIndexDistal, Right}, - {HumanBodyBones.RightMiddleProximal, Right}, - {HumanBodyBones.RightMiddleIntermediate, Right}, - {HumanBodyBones.RightMiddleDistal, Right}, - {HumanBodyBones.RightRingProximal, Right}, - {HumanBodyBones.RightRingIntermediate, Right}, - {HumanBodyBones.RightRingDistal, Right}, - {HumanBodyBones.RightLittleProximal, Right}, - {HumanBodyBones.RightLittleIntermediate, Right}, - {HumanBodyBones.RightLittleDistal, Right}, + {HumanBodyBones.RightIndexProximal, RightHand}, + {HumanBodyBones.RightIndexIntermediate, RightHand}, + {HumanBodyBones.RightIndexDistal, RightHand}, + {HumanBodyBones.RightMiddleProximal, RightHand}, + {HumanBodyBones.RightMiddleIntermediate, RightHand}, + {HumanBodyBones.RightMiddleDistal, RightHand}, + {HumanBodyBones.RightRingProximal, RightHand}, + {HumanBodyBones.RightRingIntermediate, RightHand}, + {HumanBodyBones.RightRingDistal, RightHand}, + {HumanBodyBones.RightLittleProximal, RightHand}, + {HumanBodyBones.RightLittleIntermediate, RightHand}, + {HumanBodyBones.RightLittleDistal, RightHand}, }; } } \ No newline at end of file