diff --git a/Assets/UniGLTF/Runtime/UniGLTF/RuntimeGltfInstance.cs b/Assets/UniGLTF/Runtime/UniGLTF/RuntimeGltfInstance.cs index 29e3dee16..79f7d94c1 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/RuntimeGltfInstance.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/RuntimeGltfInstance.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using UniGLTF.Utils; using UnityEngine; @@ -249,5 +250,33 @@ namespace UniGLTF UnityObjectDestroyer.DestroyRuntimeOrEditor(this.gameObject); } } + + static Dictionary> PoseMap = new(); + public static IReadOnlyDictionary SafeGetInitialPose( + Transform root, bool useCache = true) + { + if (useCache && PoseMap.TryGetValue(root, out var pose)) + { + return pose; + } + + if (root.TryGetComponent(out var runtime)) + { + // RuntimeGltfInstance があるとき => RuntimeLoad => 初期姿勢は glTF の node に由来する + // copy + pose = runtime.InitialTransformStates.ToDictionary((kv) => kv.Key, (kv) => kv.Value); + } + else + { + // RuntimeGltfInstance が無いとき => Scene 配置の prefab など。シーンの現状を代用する。 + // T-Pose であることを期待しているが既に T-Pose でないかもしれない。 + pose = root.GetComponentsInChildren().ToDictionary(x => x, x => new TransformState(x)); + } + + // add cache + PoseMap.Add(root, pose); + + return pose; + } } } diff --git a/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs b/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs index 71c5d39f1..58d6192b6 100644 --- a/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs +++ b/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs @@ -53,8 +53,7 @@ namespace VRM.SpringBoneJobs } } - var runtime = root.GetComponent(); - var initMap = runtime != null ? runtime.InitialTransformStates : root.GetComponentsInChildren().ToDictionary(x => x, x => new TransformState(x)); + var initMap = RuntimeGltfInstance.SafeGetInitialPose(root.transform); var joints = new List(); foreach (var springRoot in component.RootBones) diff --git a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs index c8cacae73..f27be9aea 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs @@ -140,15 +140,7 @@ namespace UniVRM10 // importer 内で InitializeAsync が呼び出し済み } - var runtime = GetComponent(); - - // Vrm10Runtimeが使う初期姿勢を固定する。SpringBone や Constraint の初期姿勢になる。 - var initPose = runtime != null - // RuntimeGltfInstance があるとき => RuntimeLoad => 初期姿勢は glTF の node に由来する - ? runtime.InitialTransformStates.ToDictionary((kv) => kv.Key, (kv) => kv.Value) - // RuntimeGltfInstance が無いとき => Scene 配置の prefab など。シーンの現状を代用する。既に T-Pose でないかもしれない。 - : GetComponentsInChildren().ToDictionary(x => x, x => new TransformState(x)) - ; + var initPose = RuntimeGltfInstance.SafeGetInitialPose(transform); return new Vrm10Runtime(this, useControlRig, m_springBoneRuntime, initPose); } diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs index e7a7750af..6dc1761e0 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs @@ -101,11 +101,11 @@ namespace UniVRM10 public void RestoreInitialTransform() { // Spring の joint に対応する transform の回転を初期状態 - var instance = m_instance.GetComponent(); + var pose = RuntimeGltfInstance.SafeGetInitialPose(m_instance.transform); foreach (var logic in m_fastSpringBoneBuffer.Logics) { var transform = m_fastSpringBoneBuffer.Transforms[logic.headTransformIndex]; - transform.localRotation = instance.InitialTransformStates[transform].LocalRotation; + transform.localRotation = pose[transform].LocalRotation; } // jobs のバッファにも反映する必要あり diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs index caf09e2ba..12e151e07 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs @@ -107,11 +107,11 @@ namespace UniVRM10 public void RestoreInitialTransform() { // Spring の joint に対応する transform の回転を初期状態 - var instance = m_instance.GetComponent(); + var pose = RuntimeGltfInstance.SafeGetInitialPose(m_instance.transform); foreach (var logic in m_fastSpringBoneBuffer.Logics) { var transform = m_fastSpringBoneBuffer.Transforms[logic.headTransformIndex]; - transform.localRotation = instance.InitialTransformStates[transform].LocalRotation; + transform.localRotation = pose[transform].LocalRotation; } // jobs のバッファにも反映する必要あり