From dab2e2de3f88b3c5e6995509f33027c2c27f464c Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 2 Jun 2025 20:54:58 +0900 Subject: [PATCH] =?UTF-8?q?nullcheck=20=E3=81=A4=E3=81=8D=E3=81=AE?= =?UTF-8?q?=E5=88=9D=E6=9C=9F=E5=A7=BF=E5=8B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/UniGLTF/RuntimeGltfInstance.cs | 29 +++++++++++++++++++ .../SpringBone/Jobs/FastSpringBoneReplacer.cs | 3 +- .../Components/Vrm10Instance/Vrm10Instance.cs | 10 +------ .../Vrm10FastSpringboneRuntime.cs | 4 +-- .../Vrm10FastSpringboneRuntimeStandalone.cs | 4 +-- 5 files changed, 35 insertions(+), 15 deletions(-) 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 のバッファにも反映する必要あり