diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs index a6a2705f9..1bd6e9cf4 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs @@ -40,7 +40,7 @@ namespace UniVRM10 var materialGenerator = GetMaterialDescriptorGenerator(renderPipeline); - using (var loader = new Vrm10Importer(result, extractedObjects, materialGenerator: materialGenerator)) + using (var loader = new Vrm10Importer(result, externalObjectMap: extractedObjects, materialGenerator: materialGenerator)) { // settings TextureImporters foreach (var textureInfo in loader.TextureDescriptorGenerator.Get().GetEnumerable()) diff --git a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs index 6c8afcc26..e3a888704 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs @@ -1,4 +1,5 @@ -using UnityEngine; +using System.Collections.Generic; +using UnityEngine; namespace UniVRM10 @@ -52,7 +53,15 @@ namespace UniVRM10 private UniHumanoid.Humanoid m_humanoid; private Vrm10Runtime m_runtime; - private ControlRigGenerationOption m_controlRigGenerationOption = ControlRigGenerationOption.None; + + /// + /// ControlRig の生成オプション + /// + /// null: ControlRigGenerationOption.None + /// empty: ControlRigGenerationOption.Generate = Vrm0XCompatibleRig + /// other: ControlRigGenerationOption.Vrm0XCompatibleWithXR_EXT_hand_tracking など + /// + private IReadOnlyDictionary m_controlRigInitialRotations; /// /// VRM ファイルに記録された Humanoid ボーンに対応します。 @@ -79,15 +88,15 @@ namespace UniVRM10 { if (m_runtime == null) { - m_runtime = new Vrm10Runtime(this, m_controlRigGenerationOption); + m_runtime = new Vrm10Runtime(this, m_controlRigInitialRotations); } return m_runtime; } } - internal void InitializeAtRuntime(ControlRigGenerationOption controlRigGenerationOption) + internal void InitializeAtRuntime(IReadOnlyDictionary controlRigInitialRotations) { - m_controlRigGenerationOption = controlRigGenerationOption; + m_controlRigInitialRotations = controlRigInitialRotations; } void Start() diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/ControlRigGenerationOption.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/ControlRigGenerationOption.cs deleted file mode 100644 index 6ebb0e6e4..000000000 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/ControlRigGenerationOption.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace UniVRM10 -{ - public enum ControlRigGenerationOption - { - /// - /// コントロールリグを生成しません。 - /// - None, - - /// - /// 推奨されるオプションです。 - /// コントロールリグのボーン Transform を生成し、Root の Animator はコントロールリグのボーンを制御するようになります。 - /// - Generate, - } -} \ No newline at end of file diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/ControlRigGenerationOption.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/ControlRigGenerationOption.cs.meta deleted file mode 100644 index f6e9a90c1..000000000 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/ControlRigGenerationOption.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 9723f89e671a460188d12cbcceccaa4e -timeCreated: 1663314138 \ No newline at end of file diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs.meta new file mode 100644 index 000000000..990bb33f5 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ebc9416609f7b734f87e487dfa0ae076 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/ControlRigGenerationOption.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/ControlRigGenerationOption.cs new file mode 100644 index 000000000..b5a09268a --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/ControlRigGenerationOption.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UniVRM10 +{ + public enum ControlRigGenerationOption + { + /// + /// コントロールリグを生成しません。 + /// + None = 0, + + /// + /// 推奨されるオプションです。 + /// コントロールリグのボーン Transform を生成し、Root の Animator はコントロールリグのボーンを制御するようになります。 + /// + Generate = 1, + Vrm0XCompatibleRig = 1, + + /// + /// コントロールリグのボーン Transform を生成し、Root の Animator はコントロールリグのボーンを制御するようになります。 + /// 手と指に関して、XR_EXT_hand_tracking の初期回転を持ちます。 + /// https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_hand_tracking + /// + Vrm0XCompatibleWithXR_EXT_hand_tracking = 2, + } + + internal static class ControlRigGenerationOptionExtensions + { + internal static IReadOnlyDictionary ToInitialRotations(this ControlRigGenerationOption option) + { + switch (option) + { + case ControlRigGenerationOption.None: + return null; + + case ControlRigGenerationOption.Generate: + // case ControlRigGenerationOption.Vrm0XCompatibleRig: + return Vrm0XCompatibleRig.InitialRotations; + + case ControlRigGenerationOption.Vrm0XCompatibleWithXR_EXT_hand_tracking: + return XR_EXT_hand_tracking.InitialRotations; + + default: + throw new ArgumentException(); + } + } + } +} diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/ControlRigGenerationOption.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/ControlRigGenerationOption.cs.meta new file mode 100644 index 000000000..f32b76551 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/ControlRigGenerationOption.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 254b61afe523dd74b9579ff1e971bee7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/Vrm0XCompatibleRig.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/Vrm0XCompatibleRig.cs new file mode 100644 index 000000000..ddc033dc5 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/Vrm0XCompatibleRig.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace UniVRM10 +{ + public static class Vrm0XCompatibleRig + { + /// + /// 空の Dictionary を返します。 + /// HumanBodyBones に対応する Quaternion が無い場合は Quaternion.Identity を採用する仕様です。 + /// VRM-0.X では T-Pose のときにすべてのボーンが Quaternion.Identity です。 + /// + public static IReadOnlyDictionary InitialRotations => new Dictionary(); + } +} diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/Vrm0XCompatibleRig.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/Vrm0XCompatibleRig.cs.meta new file mode 100644 index 000000000..515a87b3b --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/Vrm0XCompatibleRig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1e0f212571bf3f41809f19c2d8f3211 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_EXT_hand_tracking.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_EXT_hand_tracking.cs new file mode 100644 index 000000000..a563e59bd --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_EXT_hand_tracking.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace UniVRM10 +{ + /// + /// XR_EXT_hand_tracking の joint を VRM-1.0 の TPose に当てはめたときの方向を定義します。 + /// + /// * https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#_conventions_of_hand_joints + /// * https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/tpose.ja.md + /// + /// + public static class XR_EXT_hand_tracking + { + /// + /// up vector と forward vector の外積により空間を算出して、回転を得ます。 + /// + /// OpenXR は右手系なのに対して Unityは左手系です。 + /// 結果として、X軸が反転することに注意してください。 + /// + /// + /// + /// + public static Quaternion GetRotation(Vector3 up, Vector3 forward) + { + var xAxis = Vector3.Cross(up, forward).normalized; + var m = new Matrix4x4(xAxis, up, forward, new Vector4(0, 0, 0, 1)); + return m.rotation; + } + + public static Quaternion LeftHand = GetRotation(Vector3.up, Vector3.right); + public static Quaternion RightHand = GetRotation(Vector3.up, Vector3.left); + + /// + /// 親指は XZ 平面45度です。 + /// + public static Quaternion LeftThumb = GetRotation((Vector3.forward + Vector3.left).normalized, (Vector3.right + Vector3.forward).normalized); + + /// + /// 親指は XZ 平面45度です。 + /// + public static Quaternion RightThumb = GetRotation((Vector3.forward + Vector3.right).normalized, (Vector3.left + Vector3.forward).normalized); + + /// + /// VRM-1.0 の T-Pose の定義から各指はX軸と並行です。親指はXZ平面に45度です。 + /// + public static IReadOnlyDictionary InitialRotations => new Dictionary() + { + // Left + {HumanBodyBones.LeftHand, LeftHand}, + {HumanBodyBones.LeftThumbProximal, LeftThumb}, + {HumanBodyBones.LeftThumbIntermediate, LeftThumb}, + {HumanBodyBones.LeftThumbDistal, LeftThumb}, + {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, 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 diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_EXT_hand_tracking.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_EXT_hand_tracking.cs.meta new file mode 100644 index 000000000..bd891171b --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Rigs/XR_EXT_hand_tracking.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 551eba367636e4b45b222ce636a6adcf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs index 4364c7fd4..f2471e9d4 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs @@ -41,11 +41,12 @@ namespace UniVRM10 /// public Quaternion InitialControlBoneLocalRotation { get; } + private readonly Quaternion _initialControlBoneGlobalRotation; private readonly Quaternion _initialTargetLocalRotation; private readonly Quaternion _initialTargetGlobalRotation; private readonly List _children = new List(); - private Vrm10ControlBone(Transform controlTarget, HumanBodyBones boneType, Vrm10ControlBone parent) + private Vrm10ControlBone(Transform controlTarget, HumanBodyBones boneType, Vrm10ControlBone parent, IReadOnlyDictionary controlRigInitialRotations) { if (boneType == HumanBodyBones.LastBone) { @@ -60,6 +61,13 @@ namespace UniVRM10 ControlTarget = controlTarget; // NOTE: bone name must be unique in the vrm instance. ControlBone = new GameObject($"{nameof(Vrm10ControlBone)}:{boneType.ToString()}").transform; + if (controlRigInitialRotations != null) + { + if (controlRigInitialRotations.TryGetValue(boneType, out var rotation)) + { + ControlBone.rotation = rotation; + } + } ControlBone.position = controlTarget.position; if (parent != null) @@ -70,48 +78,63 @@ namespace UniVRM10 InitialControlBoneLocalPosition = ControlBone.localPosition; InitialControlBoneLocalRotation = ControlBone.localRotation; + _initialControlBoneGlobalRotation = ControlBone.rotation; _initialTargetLocalRotation = controlTarget.localRotation; _initialTargetGlobalRotation = controlTarget.rotation; } + /// + /// 初期姿勢からの相対的な回転。 + /// + /// VRM-0.X 互換リグでは localRotation と同じ値を示す。 + /// + Quaternion NormalizedLocalRotation + { + get + { + var delta = Quaternion.Inverse(_initialControlBoneGlobalRotation) * ControlBone.localRotation * _initialControlBoneGlobalRotation; + return InitialControlBoneLocalRotation * delta; + } + } + /// /// 親から再帰的にNormalized の ローカル回転を初期回転を加味して Target に適用する。 /// internal void ProcessRecursively() { - ControlTarget.localRotation = _initialTargetLocalRotation * Quaternion.Inverse(_initialTargetGlobalRotation) * ControlBone.localRotation * _initialTargetGlobalRotation; + ControlTarget.localRotation = _initialTargetLocalRotation * (Quaternion.Inverse(_initialTargetGlobalRotation) * NormalizedLocalRotation * _initialTargetGlobalRotation); foreach (var child in _children) { child.ProcessRecursively(); } } - public static Vrm10ControlBone Build(UniHumanoid.Humanoid humanoid, out Dictionary boneMap) + public static Vrm10ControlBone Build(UniHumanoid.Humanoid humanoid, IReadOnlyDictionary controlRigInitialRotations, out Dictionary boneMap) { - var hips = new Vrm10ControlBone(humanoid.Hips, HumanBodyBones.Hips, null); + var hips = new Vrm10ControlBone(humanoid.Hips, HumanBodyBones.Hips, null, controlRigInitialRotations); boneMap = new Dictionary(); boneMap.Add(HumanBodyBones.Hips, hips); foreach (Transform child in humanoid.Hips) { - BuildRecursively(humanoid, child, hips, boneMap); + BuildRecursively(humanoid, child, hips, controlRigInitialRotations, boneMap); } return hips; } - private static void BuildRecursively(UniHumanoid.Humanoid humanoid, Transform current, Vrm10ControlBone parent, Dictionary boneMap) + private static void BuildRecursively(UniHumanoid.Humanoid humanoid, Transform current, Vrm10ControlBone parent, IReadOnlyDictionary controlRigInitialRotations, Dictionary boneMap) { if (humanoid.TryGetBoneForTransform(current, out var bone)) { - var newBone = new Vrm10ControlBone(current, bone, parent); + var newBone = new Vrm10ControlBone(current, bone, parent, controlRigInitialRotations); parent = newBone; boneMap.Add(bone, newBone); } foreach (Transform child in current) { - BuildRecursively(humanoid, child, parent, boneMap); + BuildRecursively(humanoid, child, parent, controlRigInitialRotations, boneMap); } } } diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs index 49a0f602b..0265e65b7 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs @@ -49,7 +49,7 @@ namespace UniVRM10 } } - public Vrm10Runtime(Vrm10Instance target, ControlRigGenerationOption controlRigGenerationOption) + public Vrm10Runtime(Vrm10Instance target, IReadOnlyDictionary controlRigInitialRotations) { m_target = target; @@ -58,9 +58,9 @@ namespace UniVRM10 throw new Exception(); } - if (controlRigGenerationOption != ControlRigGenerationOption.None) + if (controlRigInitialRotations != null) { - ControlRig = new Vrm10RuntimeControlRig(target.Humanoid, m_target.transform, controlRigGenerationOption); + ControlRig = new Vrm10RuntimeControlRig(target.Humanoid, m_target.transform, controlRigInitialRotations); } Constraints = target.GetComponentsInChildren(); LookAt = new Vrm10RuntimeLookAt(target.Vrm.LookAt, target.Humanoid, m_head, target.LookAtTargetType, target.Gaze); diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs index cb4f6f05d..681cf681d 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs @@ -25,17 +25,22 @@ namespace UniVRM10 public float InitialHipsHeight { get; } /// - /// コンストラクタ。 - /// humanoid は VRM T-Pose でなければならない。 + /// humanoid に対して ControlRig を生成します /// - public Vrm10RuntimeControlRig(UniHumanoid.Humanoid humanoid, Transform vrmRoot, ControlRigGenerationOption option) + /// T-Pose である必要があります + /// + /// ControlRigの各ボーンの初期回転を表します + public Vrm10RuntimeControlRig(UniHumanoid.Humanoid humanoid, Transform vrmRoot, IReadOnlyDictionary controlRigInitialRotations) { - if (option == ControlRigGenerationOption.None) return; + if (controlRigInitialRotations == null) + { + throw new ArgumentNullException(); + } _controlRigRoot = new GameObject("Runtime Control Rig").transform; _controlRigRoot.SetParent(vrmRoot); - _hipBone = Vrm10ControlBone.Build(humanoid, out _bones); + _hipBone = Vrm10ControlBone.Build(humanoid, controlRigInitialRotations, out _bones); _hipBone.ControlBone.SetParent(_controlRigRoot); InitialHipsHeight = _hipBone.ControlTarget.position.y; diff --git a/Assets/VRM10/Runtime/IO/Vrm10.cs b/Assets/VRM10/Runtime/IO/Vrm10.cs index 721f64b8b..c6b34fbe5 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using UniGLTF; @@ -274,7 +275,7 @@ namespace UniVRM10 throw new ArgumentNullException(nameof(vrm10Data)); } - using (var loader = new Vrm10Importer(vrm10Data, controlRigGenerationOption: controlRigGenerationOption, materialGenerator: materialGenerator)) + using (var loader = new Vrm10Importer(vrm10Data, materialGenerator: materialGenerator, controlRigInitialRotations: controlRigGenerationOption.ToInitialRotations())) { // 1. Load meta information if callback was available. if (vrmMetaInformationCallback != null) diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index fc5da977d..5f86c25b2 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -18,7 +18,7 @@ namespace UniVRM10 private readonly Vrm10Data m_vrm; /// VrmLib.Model の オブジェクトと UnityEngine.Object のマッピングを記録する private readonly ModelMap m_map = new ModelMap(); - private readonly ControlRigGenerationOption m_controlRigGenerationOption; + private readonly IReadOnlyDictionary m_controlRigInitialRotations; private VrmLib.Model m_model; private IReadOnlyDictionary m_externalMap; @@ -31,7 +31,8 @@ namespace UniVRM10 IReadOnlyDictionary externalObjectMap = null, ITextureDeserializer textureDeserializer = null, IMaterialDescriptorGenerator materialGenerator = null, - ControlRigGenerationOption controlRigGenerationOption = ControlRigGenerationOption.None) + IReadOnlyDictionary controlRigInitialRotations = null + ) : base(vrm.Data, externalObjectMap, textureDeserializer) { if (vrm == null) @@ -39,7 +40,7 @@ namespace UniVRM10 throw new ArgumentNullException("vrm"); } m_vrm = vrm; - m_controlRigGenerationOption = controlRigGenerationOption; + m_controlRigInitialRotations = controlRigInitialRotations; TextureDescriptorGenerator = new Vrm10TextureDescriptorGenerator(Data); MaterialDescriptorGenerator = materialGenerator ?? new BuiltInVrm10MaterialDescriptorGenerator(); @@ -246,7 +247,7 @@ namespace UniVRM10 // VrmController var controller = Root.AddComponent(); - controller.InitializeAtRuntime(m_controlRigGenerationOption); + controller.InitializeAtRuntime(m_controlRigInitialRotations); controller.enabled = false; // vrm diff --git a/Assets/VRM10/Tests/ApiSampleTests.cs b/Assets/VRM10/Tests/ApiSampleTests.cs index f306c7990..a53b0dfdb 100644 --- a/Assets/VRM10/Tests/ApiSampleTests.cs +++ b/Assets/VRM10/Tests/ApiSampleTests.cs @@ -21,7 +21,7 @@ namespace UniVRM10.Test GameObject BuildGameObject(Vrm10Data data, bool showMesh) { - using (var loader = new Vrm10Importer(data)) + using (var loader = new Vrm10Importer(data, null)) { var loaded = loader.Load(); if (showMesh) diff --git a/Assets/VRM10/Tests/ExpressionTests.cs b/Assets/VRM10/Tests/ExpressionTests.cs index 8b8be849b..99e832566 100644 --- a/Assets/VRM10/Tests/ExpressionTests.cs +++ b/Assets/VRM10/Tests/ExpressionTests.cs @@ -32,7 +32,7 @@ namespace UniVRM10.Test controller.Vrm.Expression.Aa.MaterialColorBindings = src.ToArray(); // ok if no exception - var r = new Vrm10Runtime(controller, ControlRigGenerationOption.None); + var r = new Vrm10Runtime(controller, null); } [Test] @@ -56,7 +56,7 @@ namespace UniVRM10.Test controller.Vrm.Expression.Aa.MaterialUVBindings = src.ToArray(); // ok if no exception - var r = new Vrm10Runtime(controller, ControlRigGenerationOption.None); + var r = new Vrm10Runtime(controller, null); } } } diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs b/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs index 05824727f..861c2e783 100644 --- a/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs +++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs @@ -126,7 +126,6 @@ namespace UniVRM10.VRM10Viewer /// /// from v0.104 /// - /// public void UpdateControlRigImplicit(Animator src) { var dst = m_controller.GetComponent(); @@ -159,6 +158,40 @@ namespace UniVRM10.VRM10Viewer } } + /// + /// from v0.108 + /// + public void UpdateControlRigImplicit(UniHumanoid.Humanoid src) + { + var dst = m_controller.GetComponent(); + + foreach (HumanBodyBones bone in CachedEnum.GetValues()) + { + if (bone == HumanBodyBones.LastBone) + { + continue; + } + + var boneTransform = dst.GetBoneTransform(bone); + if (boneTransform == null) + { + continue; + } + + var bvhBone = src.GetBoneTransform(bone); + if (bvhBone != null) + { + // set normalized pose + boneTransform.localRotation = bvhBone.localRotation; + if (bone == HumanBodyBones.Hips) + { + // TODO: hips position scaling ? + boneTransform.localPosition = bvhBone.localPosition; + } + } + } + } + public void TPoseControlRig() { var controlRig = m_controller.Runtime.ControlRig;