From 3c8b72ca10dfb3603b1632ae990cfc2045d5bad1 Mon Sep 17 00:00:00 2001 From: Lawrence <30965946+Halbann@users.noreply.github.com> Date: Sun, 27 Oct 2024 01:09:26 +0100 Subject: [PATCH 1/3] Added an occurrence selection syntax to the material mesh field. --- Source/TexturesUnlimited/Util/TextureSet.cs | 29 ++++++++++++++++ Source/TexturesUnlimited/Util/Utils.cs | 37 +++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/Source/TexturesUnlimited/Util/TextureSet.cs b/Source/TexturesUnlimited/Util/TextureSet.cs index f47ed81..f177e2a 100644 --- a/Source/TexturesUnlimited/Util/TextureSet.cs +++ b/Source/TexturesUnlimited/Util/TextureSet.cs @@ -173,6 +173,8 @@ public static Transform[] findApplicableTransforms(Transform root, string[] mesh int len = rends.Length; for (int i = 0; i < len; i++) { + // For completeness, "name,occurrence" could be supported here as well, but so far there is no use case. + if (!excludeMeshes.Contains(rends[i].name)) { Log.extra("Adding mesh due to blacklist: " + rends[i].transform); @@ -204,6 +206,17 @@ public static Transform[] findApplicableTransforms(Transform root, string[] mesh Renderer r; for (int i = 0; i < len; i++) { + // Check if the mesh name is in the format of "name,occurrence". + if (TryParseNameAndOccurrence(meshes[i], out string name, out int occurrence)) + { + // Find the zero-based occurrence of the child with the given name. + tr = root.FindExactChild(name, occurrence); + if (tr != null && tr.GetComponent() != null) + transforms.AddUnique(tr); + + continue; + } + trs = root.FindChildren(meshes[i]); int len2 = trs.Length; for (int k = 0; k < len2; k++) @@ -226,6 +239,22 @@ public static Transform[] findApplicableTransforms(Transform root, string[] mesh return transforms.ToArray(); } + private static bool TryParseNameAndOccurrence(string fullName, out string name, out int occurrence) + { + // Check for a comma in the second-to-last position. + // If so parse everything before as the name and everything following as the occurrence number. + + name = default; + occurrence = default; + int commaIndex = Mathf.Max(fullName.Length - 2, 0); + + if (fullName[commaIndex] != ',' || !int.TryParse(fullName.Substring(commaIndex + 1), out occurrence)) + return false; + + name = fullName.Substring(0, commaIndex); + return true; + } + /// /// Public utility method to parse texture set instances from config nodes. /// diff --git a/Source/TexturesUnlimited/Util/Utils.cs b/Source/TexturesUnlimited/Util/Utils.cs index 79a3ecd..6e1a1f9 100644 --- a/Source/TexturesUnlimited/Util/Utils.cs +++ b/Source/TexturesUnlimited/Util/Utils.cs @@ -608,6 +608,43 @@ private static void locateTransformsRecursive(Transform tr, String name, List + /// Searches recursively for the child transform that is the given occurrence of a child with the given name. + /// + /// The transform from which to begin the search. + /// The transform name to match with. + /// The zero-based occurrence of the given transform name to match with. + /// The child with the given name and name occurrence or null if not found. + public static Transform FindExactChild(this Transform transform, String name, int occurrence) + { + int count = 0; + return FindExactChildRecursion(name, occurrence, ref transform, ref count) ? transform : null; + } + + private static bool FindExactChildRecursion(String name, int index, ref Transform transform, ref int count) + { + if (transform.name == name) + { + if (count == index) + return true; + + count++; + } + + // Is it necessary to store the parent transform? Or does the foreach loop keep the original reference? + // Would it be faster to return a Transform and null check each child than to return a bool and juggle variables on the stack? + Transform parent = transform; + + foreach (Transform child in parent) + { + transform = child; // Can't use a foreach variable as a ref. + if (FindExactChildRecursion(name, index, ref transform, ref count)) + return true; + } + + return false; + } + /// /// Searches entire model heirarchy from the input transform to end of branches for transforms with the input transform name and returns the first match found, or null if none. /// From 631b59a23f14021453848337aefc736077acfe4c Mon Sep 17 00:00:00 2001 From: Lawrence <30965946+Halbann@users.noreply.github.com> Date: Sun, 27 Oct 2024 01:33:35 +0100 Subject: [PATCH 2/3] Support any number of digits --- Source/TexturesUnlimited/Util/TextureSet.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/TexturesUnlimited/Util/TextureSet.cs b/Source/TexturesUnlimited/Util/TextureSet.cs index f177e2a..c28e763 100644 --- a/Source/TexturesUnlimited/Util/TextureSet.cs +++ b/Source/TexturesUnlimited/Util/TextureSet.cs @@ -241,14 +241,14 @@ public static Transform[] findApplicableTransforms(Transform root, string[] mesh private static bool TryParseNameAndOccurrence(string fullName, out string name, out int occurrence) { - // Check for a comma in the second-to-last position. + // Check if the name contains a comma. // If so parse everything before as the name and everything following as the occurrence number. name = default; occurrence = default; - int commaIndex = Mathf.Max(fullName.Length - 2, 0); + int commaIndex = fullName.LastIndexOf(','); - if (fullName[commaIndex] != ',' || !int.TryParse(fullName.Substring(commaIndex + 1), out occurrence)) + if (commaIndex < 0 || !int.TryParse(fullName.Substring(commaIndex + 1), out occurrence)) return false; name = fullName.Substring(0, commaIndex); From 262ee2b2fcfd4eab3c45bd05715b643fdcd6eafc Mon Sep 17 00:00:00 2001 From: Lawrence <30965946+Halbann@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:57:08 +0000 Subject: [PATCH 3/3] Variable name --- Source/TexturesUnlimited/Util/Utils.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/TexturesUnlimited/Util/Utils.cs b/Source/TexturesUnlimited/Util/Utils.cs index 6e1a1f9..bfd4850 100644 --- a/Source/TexturesUnlimited/Util/Utils.cs +++ b/Source/TexturesUnlimited/Util/Utils.cs @@ -621,11 +621,11 @@ public static Transform FindExactChild(this Transform transform, String name, in return FindExactChildRecursion(name, occurrence, ref transform, ref count) ? transform : null; } - private static bool FindExactChildRecursion(String name, int index, ref Transform transform, ref int count) + private static bool FindExactChildRecursion(String name, int occurrence, ref Transform transform, ref int count) { if (transform.name == name) { - if (count == index) + if (count == occurrence) return true; count++; @@ -638,7 +638,7 @@ private static bool FindExactChildRecursion(String name, int index, ref Transfor foreach (Transform child in parent) { transform = child; // Can't use a foreach variable as a ref. - if (FindExactChildRecursion(name, index, ref transform, ref count)) + if (FindExactChildRecursion(name, occurrence, ref transform, ref count)) return true; }