diff --git a/BetterShadowClone/ShadowCloneHelper.cs b/BetterShadowClone/ShadowCloneHelper.cs index c96b76c..29f6a7e 100644 --- a/BetterShadowClone/ShadowCloneHelper.cs +++ b/BetterShadowClone/ShadowCloneHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using ABI_RC.Core; using ABI.CCK.Components; using UnityEngine; @@ -44,8 +45,13 @@ public static class ShadowCloneHelper private static void ProcessRenderers(IEnumerable renderers, Transform root, Transform headBone) { + Stopwatch sw = Stopwatch.StartNew(); + IReadOnlyDictionary exclusions = CollectTransformToExclusionMap(root, headBone); + // log current time + ShadowCloneMod.Logger.Msg($"CollectTransformToExclusionMap in {sw.ElapsedMilliseconds}ms"); + foreach (Renderer renderer in renderers) { ConfigureRenderer(renderer); @@ -59,6 +65,11 @@ public static class ShadowCloneHelper ITransformHider hider = TransformHiderManager.CreateTransformHider(renderer, exclusions); if (hider != null) TransformHiderManager.Instance.AddTransformHider(hider); } + + sw.Stop(); + + // log current time + ShadowCloneMod.Logger.Msg($"ProcessRenderers in {sw.ElapsedMilliseconds}ms"); } #endregion diff --git a/BetterShadowClone/TransformHider/FPRExclusion.cs b/BetterShadowClone/TransformHider/FPRExclusion.cs index c02ceca..b07aeea 100644 --- a/BetterShadowClone/TransformHider/FPRExclusion.cs +++ b/BetterShadowClone/TransformHider/FPRExclusion.cs @@ -10,6 +10,8 @@ public class FPRExclusion : MonoBehaviour { public Transform target; + internal readonly List affectedVertexIndices = new(); + internal readonly List affectedChildren = new(); internal readonly List relatedTasks = new(); diff --git a/BetterShadowClone/TransformHider/ITransformHider/MeshTransformHider.cs b/BetterShadowClone/TransformHider/ITransformHider/MeshTransformHider.cs index d0ac6a9..523aab3 100644 --- a/BetterShadowClone/TransformHider/ITransformHider/MeshTransformHider.cs +++ b/BetterShadowClone/TransformHider/ITransformHider/MeshTransformHider.cs @@ -16,9 +16,6 @@ public class MeshTransformHider : ITransformHider, IFPRExclusionTask private readonly MeshRenderer _mainMesh; private bool _enabledState; - // exclusion - private readonly FPRExclusion _exclusion; - #region ITransformHider Methods public bool IsActive { get; set; } = true; // default hide, but FPRExclusion can override @@ -36,9 +33,8 @@ public class MeshTransformHider : ITransformHider, IFPRExclusionTask Dispose(); return; } - - _exclusion = exclusion; - _exclusion.relatedTasks.Add(this); + + exclusion.relatedTasks.Add(this); _mainMesh = renderer; diff --git a/BetterShadowClone/TransformHider/ITransformHider/SkinnedTransformHider.cs b/BetterShadowClone/TransformHider/ITransformHider/SkinnedTransformHider.cs index 852bafd..10a32b3 100644 --- a/BetterShadowClone/TransformHider/ITransformHider/SkinnedTransformHider.cs +++ b/BetterShadowClone/TransformHider/ITransformHider/SkinnedTransformHider.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using UnityEngine; using UnityEngine.Rendering; @@ -38,6 +39,8 @@ public class SkinnedTransformHider : ITransformHider public SkinnedTransformHider(SkinnedMeshRenderer renderer, IReadOnlyDictionary exclusions) { + Stopwatch sw = Stopwatch.StartNew(); + _mainMesh = renderer; if (_mainMesh == null @@ -52,36 +55,35 @@ public class SkinnedTransformHider : ITransformHider _rootBone = _mainMesh.rootBone; _rootBone ??= _mainMesh.transform; // fallback to transform if no root bone - // subtask creation + // log current time + ShadowCloneMod.Logger.Msg($"SkinnedTransformHider part 1 in {sw.ElapsedMilliseconds}ms"); - var bones = renderer.bones; - List fprExclusions = new(); - - foreach (Transform bone in bones) - { - if (bone == null) - continue; // thanks AdvancedSafety for preventing null ref for so long... - - if (!exclusions.TryGetValue(bone, out FPRExclusion exclusion)) - continue; - - fprExclusions.Add(exclusion); - } + SubTask.FindExclusionVertList(renderer, exclusions); - List exclusionVerts; - foreach (FPRExclusion exclusion in fprExclusions) + foreach (var exclusion in exclusions) { - exclusionVerts = SubTask.FindExclusionVertList(renderer, exclusion); - if (exclusionVerts.Count == 0) - continue; + FPRExclusion fprExclusion = exclusion.Value; + if (fprExclusion.affectedVertexIndices.Count == 0) + continue; // no affected verts - SubTask subTask = new(this, exclusion, exclusionVerts); + SubTask subTask = new(this, fprExclusion, fprExclusion.affectedVertexIndices); _subTasks.Add(subTask); - exclusion.relatedTasks.Add(subTask); + fprExclusion.relatedTasks.Add(subTask); + fprExclusion.affectedVertexIndices.Clear(); // clear list for next SkinnedTransformHider } - if (_subTasks.Count == 0) + // log current time + ShadowCloneMod.Logger.Msg($"SkinnedTransformHider part 3 in {sw.ElapsedMilliseconds}ms"); + + if (_subTasks.Count == 0) + { Dispose(); // had the bones, but not the weights :? + ShadowCloneMod.Logger.Warning("SkinnedTransformHider No valid exclusions found!"); + } + + sw.Stop(); + + ShadowCloneMod.Logger.Msg($"SkinnedTransformHider created in {sw.ElapsedMilliseconds}ms"); } public bool Process() @@ -176,14 +178,11 @@ public class SkinnedTransformHider : ITransformHider private readonly int _vertexCount; private readonly ComputeBuffer _computeBuffer; private readonly int _threadGroups; - - private readonly FPRExclusion _exclusion; - + public SubTask(SkinnedTransformHider parent, FPRExclusion exclusion, List exclusionVerts) { _parent = parent; - _exclusion = exclusion; - _shrinkBone = _exclusion.target; + _shrinkBone = exclusion.target; _vertexCount = exclusionVerts.Count; _computeBuffer = new ComputeBuffer(_vertexCount, sizeof(int)); @@ -211,28 +210,40 @@ public class SkinnedTransformHider : ITransformHider #region Private Methods - public static List FindExclusionVertList(SkinnedMeshRenderer renderer, FPRExclusion exclusion) + public static void FindExclusionVertList(SkinnedMeshRenderer renderer, IReadOnlyDictionary exclusions) { var boneWeights = renderer.sharedMesh.boneWeights; - var bones = exclusion.affectedChildren; HashSet weights = new(); for (int i = 0; i < renderer.bones.Length; i++) - if (bones.Contains(renderer.bones[i])) weights.Add(i); + { + // if bone == any key in exclusions, add to weights + if (!exclusions.TryGetValue(renderer.bones[i], out FPRExclusion _)) + continue; + + weights.Add(i); + } - List headVertices = new(); for (int i = 0; i < boneWeights.Length; i++) { BoneWeight weight = boneWeights[i]; + + Transform bone = null; const float minWeightThreshold = 0.2f; - if (weights.Contains(weight.boneIndex0) && weight.weight0 > minWeightThreshold - || weights.Contains(weight.boneIndex1) && weight.weight1 > minWeightThreshold - || weights.Contains(weight.boneIndex2) && weight.weight2 > minWeightThreshold - || weights.Contains(weight.boneIndex3) && weight.weight3 > minWeightThreshold) - headVertices.Add(i); + if (weights.Contains(weight.boneIndex0) && weight.weight0 > minWeightThreshold) + bone = renderer.bones[weight.boneIndex0]; + else if (weights.Contains(weight.boneIndex1) && weight.weight1 > minWeightThreshold) + bone = renderer.bones[weight.boneIndex1]; + else if (weights.Contains(weight.boneIndex2) && weight.weight2 > minWeightThreshold) + bone = renderer.bones[weight.boneIndex2]; + else if (weights.Contains(weight.boneIndex3) && weight.weight3 > minWeightThreshold) + bone = renderer.bones[weight.boneIndex3]; + + if (bone == null) continue; // no bone found + + // add vertex to exclusion list + exclusions[bone].affectedVertexIndices.Add(i); } - - return headVertices; } #endregion