mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 06:19:22 +00:00
[BetterShadowClone] Reworked vert finding for exclusions to not nuke game for 20s
This commit is contained in:
parent
0d82606308
commit
df45fb50d9
4 changed files with 64 additions and 44 deletions
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using ABI_RC.Core;
|
using ABI_RC.Core;
|
||||||
using ABI.CCK.Components;
|
using ABI.CCK.Components;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
@ -44,8 +45,13 @@ public static class ShadowCloneHelper
|
||||||
|
|
||||||
private static void ProcessRenderers(IEnumerable<Renderer> renderers, Transform root, Transform headBone)
|
private static void ProcessRenderers(IEnumerable<Renderer> renderers, Transform root, Transform headBone)
|
||||||
{
|
{
|
||||||
|
Stopwatch sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
IReadOnlyDictionary<Transform, FPRExclusion> exclusions = CollectTransformToExclusionMap(root, headBone);
|
IReadOnlyDictionary<Transform, FPRExclusion> exclusions = CollectTransformToExclusionMap(root, headBone);
|
||||||
|
|
||||||
|
// log current time
|
||||||
|
ShadowCloneMod.Logger.Msg($"CollectTransformToExclusionMap in {sw.ElapsedMilliseconds}ms");
|
||||||
|
|
||||||
foreach (Renderer renderer in renderers)
|
foreach (Renderer renderer in renderers)
|
||||||
{
|
{
|
||||||
ConfigureRenderer(renderer);
|
ConfigureRenderer(renderer);
|
||||||
|
@ -59,6 +65,11 @@ public static class ShadowCloneHelper
|
||||||
ITransformHider hider = TransformHiderManager.CreateTransformHider(renderer, exclusions);
|
ITransformHider hider = TransformHiderManager.CreateTransformHider(renderer, exclusions);
|
||||||
if (hider != null) TransformHiderManager.Instance.AddTransformHider(hider);
|
if (hider != null) TransformHiderManager.Instance.AddTransformHider(hider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
|
|
||||||
|
// log current time
|
||||||
|
ShadowCloneMod.Logger.Msg($"ProcessRenderers in {sw.ElapsedMilliseconds}ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -10,6 +10,8 @@ public class FPRExclusion : MonoBehaviour
|
||||||
{
|
{
|
||||||
public Transform target;
|
public Transform target;
|
||||||
|
|
||||||
|
internal readonly List<int> affectedVertexIndices = new();
|
||||||
|
|
||||||
internal readonly List<Transform> affectedChildren = new();
|
internal readonly List<Transform> affectedChildren = new();
|
||||||
internal readonly List<IFPRExclusionTask> relatedTasks = new();
|
internal readonly List<IFPRExclusionTask> relatedTasks = new();
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,6 @@ public class MeshTransformHider : ITransformHider, IFPRExclusionTask
|
||||||
private readonly MeshRenderer _mainMesh;
|
private readonly MeshRenderer _mainMesh;
|
||||||
private bool _enabledState;
|
private bool _enabledState;
|
||||||
|
|
||||||
// exclusion
|
|
||||||
private readonly FPRExclusion _exclusion;
|
|
||||||
|
|
||||||
#region ITransformHider Methods
|
#region ITransformHider Methods
|
||||||
|
|
||||||
public bool IsActive { get; set; } = true; // default hide, but FPRExclusion can override
|
public bool IsActive { get; set; } = true; // default hide, but FPRExclusion can override
|
||||||
|
@ -36,9 +33,8 @@ public class MeshTransformHider : ITransformHider, IFPRExclusionTask
|
||||||
Dispose();
|
Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_exclusion = exclusion;
|
exclusion.relatedTasks.Add(this);
|
||||||
_exclusion.relatedTasks.Add(this);
|
|
||||||
|
|
||||||
_mainMesh = renderer;
|
_mainMesh = renderer;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Rendering;
|
using UnityEngine.Rendering;
|
||||||
|
|
||||||
|
@ -38,6 +39,8 @@ public class SkinnedTransformHider : ITransformHider
|
||||||
|
|
||||||
public SkinnedTransformHider(SkinnedMeshRenderer renderer, IReadOnlyDictionary<Transform, FPRExclusion> exclusions)
|
public SkinnedTransformHider(SkinnedMeshRenderer renderer, IReadOnlyDictionary<Transform, FPRExclusion> exclusions)
|
||||||
{
|
{
|
||||||
|
Stopwatch sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
_mainMesh = renderer;
|
_mainMesh = renderer;
|
||||||
|
|
||||||
if (_mainMesh == null
|
if (_mainMesh == null
|
||||||
|
@ -52,36 +55,35 @@ public class SkinnedTransformHider : ITransformHider
|
||||||
_rootBone = _mainMesh.rootBone;
|
_rootBone = _mainMesh.rootBone;
|
||||||
_rootBone ??= _mainMesh.transform; // fallback to transform if no root bone
|
_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;
|
SubTask.FindExclusionVertList(renderer, exclusions);
|
||||||
List<FPRExclusion> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<int> exclusionVerts;
|
foreach (var exclusion in exclusions)
|
||||||
foreach (FPRExclusion exclusion in fprExclusions)
|
|
||||||
{
|
{
|
||||||
exclusionVerts = SubTask.FindExclusionVertList(renderer, exclusion);
|
FPRExclusion fprExclusion = exclusion.Value;
|
||||||
if (exclusionVerts.Count == 0)
|
if (fprExclusion.affectedVertexIndices.Count == 0)
|
||||||
continue;
|
continue; // no affected verts
|
||||||
|
|
||||||
SubTask subTask = new(this, exclusion, exclusionVerts);
|
SubTask subTask = new(this, fprExclusion, fprExclusion.affectedVertexIndices);
|
||||||
_subTasks.Add(subTask);
|
_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 :?
|
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()
|
public bool Process()
|
||||||
|
@ -176,14 +178,11 @@ public class SkinnedTransformHider : ITransformHider
|
||||||
private readonly int _vertexCount;
|
private readonly int _vertexCount;
|
||||||
private readonly ComputeBuffer _computeBuffer;
|
private readonly ComputeBuffer _computeBuffer;
|
||||||
private readonly int _threadGroups;
|
private readonly int _threadGroups;
|
||||||
|
|
||||||
private readonly FPRExclusion _exclusion;
|
|
||||||
|
|
||||||
public SubTask(SkinnedTransformHider parent, FPRExclusion exclusion, List<int> exclusionVerts)
|
public SubTask(SkinnedTransformHider parent, FPRExclusion exclusion, List<int> exclusionVerts)
|
||||||
{
|
{
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
_exclusion = exclusion;
|
_shrinkBone = exclusion.target;
|
||||||
_shrinkBone = _exclusion.target;
|
|
||||||
|
|
||||||
_vertexCount = exclusionVerts.Count;
|
_vertexCount = exclusionVerts.Count;
|
||||||
_computeBuffer = new ComputeBuffer(_vertexCount, sizeof(int));
|
_computeBuffer = new ComputeBuffer(_vertexCount, sizeof(int));
|
||||||
|
@ -211,28 +210,40 @@ public class SkinnedTransformHider : ITransformHider
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
|
|
||||||
public static List<int> FindExclusionVertList(SkinnedMeshRenderer renderer, FPRExclusion exclusion)
|
public static void FindExclusionVertList(SkinnedMeshRenderer renderer, IReadOnlyDictionary<Transform, FPRExclusion> exclusions)
|
||||||
{
|
{
|
||||||
var boneWeights = renderer.sharedMesh.boneWeights;
|
var boneWeights = renderer.sharedMesh.boneWeights;
|
||||||
var bones = exclusion.affectedChildren;
|
|
||||||
|
|
||||||
HashSet<int> weights = new();
|
HashSet<int> weights = new();
|
||||||
for (int i = 0; i < renderer.bones.Length; i++)
|
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<int> headVertices = new();
|
|
||||||
for (int i = 0; i < boneWeights.Length; i++)
|
for (int i = 0; i < boneWeights.Length; i++)
|
||||||
{
|
{
|
||||||
BoneWeight weight = boneWeights[i];
|
BoneWeight weight = boneWeights[i];
|
||||||
|
|
||||||
|
Transform bone = null;
|
||||||
const float minWeightThreshold = 0.2f;
|
const float minWeightThreshold = 0.2f;
|
||||||
if (weights.Contains(weight.boneIndex0) && weight.weight0 > minWeightThreshold
|
if (weights.Contains(weight.boneIndex0) && weight.weight0 > minWeightThreshold)
|
||||||
|| weights.Contains(weight.boneIndex1) && weight.weight1 > minWeightThreshold
|
bone = renderer.bones[weight.boneIndex0];
|
||||||
|| weights.Contains(weight.boneIndex2) && weight.weight2 > minWeightThreshold
|
else if (weights.Contains(weight.boneIndex1) && weight.weight1 > minWeightThreshold)
|
||||||
|| weights.Contains(weight.boneIndex3) && weight.weight3 > minWeightThreshold)
|
bone = renderer.bones[weight.boneIndex1];
|
||||||
headVertices.Add(i);
|
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
|
#endregion
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue