Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an occurrence selection syntax to the material mesh field #4

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions Source/TexturesUnlimited/Util/TextureSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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<Renderer>() != null)
transforms.AddUnique(tr);

continue;
}

trs = root.FindChildren(meshes[i]);
int len2 = trs.Length;
for (int k = 0; k < len2; k++)
Expand All @@ -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 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 = fullName.LastIndexOf(',');

if (commaIndex < 0 || !int.TryParse(fullName.Substring(commaIndex + 1), out occurrence))
return false;

name = fullName.Substring(0, commaIndex);
return true;
}

/// <summary>
/// Public utility method to parse texture set instances from config nodes.
/// </summary>
Expand Down
37 changes: 37 additions & 0 deletions Source/TexturesUnlimited/Util/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,43 @@ private static void locateTransformsRecursive(Transform tr, String name, List<Tr
}
}

/// <summary>
/// Searches recursively for the child transform that is the given occurrence of a child with the given name.
/// </summary>
/// <param name="transform">The transform from which to begin the search.</param>
/// <param name="name">The transform name to match with.</param>
/// <param name="occurrence">The zero-based occurrence of the given transform name to match with.</param>
/// <returns>The child with the given name and name occurrence or null if not found.</returns>
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 occurrence, ref Transform transform, ref int count)
{
if (transform.name == name)
{
if (count == occurrence)
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, occurrence, ref transform, ref count))
return true;
}

return false;
}

/// <summary>
/// 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.
/// </summary>
Expand Down
Loading