using System.IO; using UnityEngine; namespace LibMMD.Unity3D.Animation { // Caches the single most-recently-baked kinematic-FK pose (see MmdAnimationClipBaker) keyed // by (model path+mtime, motion path+mtime). MmdAnimator reads through this instead of // re-baking whenever a model+VMD reload turns out to be the exact same combination as last // time - eg. toggling PhysicsMode and clicking Load again in MmdSettingsController, which // always tears down and rebuilds the whole MmdGameObject since physics components can't be // swapped live. // // Only a single entry is kept: this exists for the reload-and-tweak-settings workflow, not // for juggling many simultaneously-active motions. Storing a new entry replaces the previous // one - BakedPose is plain data (no UnityEngine.Object), so there's no Destroy()/ownership // bookkeeping needed, unlike the AnimationClip this used to cache. internal static class MmdBakedClipCache { private static string _key; private static MmdAnimationClipBaker.BakedPose _pose; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void ResetForPlaySession() { _key = null; _pose = null; } public static string BuildKey(string modelPath, string motionPath) { if (string.IsNullOrEmpty(modelPath) || string.IsNullOrEmpty(motionPath)) { return null; } try { var model = new FileInfo(modelPath); var motion = new FileInfo(motionPath); if (!model.Exists || !motion.Exists) return null; return $"{model.FullName}|{model.Length}|{model.LastWriteTimeUtc.Ticks}|" + $"{motion.FullName}|{motion.Length}|{motion.LastWriteTimeUtc.Ticks}"; } catch (System.Exception) { return null; } } public static MmdAnimationClipBaker.BakedPose TryGet(string key) { return key != null && key == _key ? _pose : null; } public static void Store(string key, MmdAnimationClipBaker.BakedPose pose) { if (key == null) { return; } _key = key; _pose = pose; } } }