Support path remappings in the FPVProcessor

As part of this, PathMappings was refactored to support processing original paths through
multiple phases of remapping.

Closes #73
This commit is contained in:
bd_ 2022-11-07 20:21:15 -08:00
parent c2f390071a
commit 8bb1969ecf
3 changed files with 20 additions and 17 deletions

View File

@ -112,9 +112,9 @@ namespace net.fushizen.modular_avatar.core.editor
new MergeArmatureHook().OnPreprocessAvatar(avatarGameObject); new MergeArmatureHook().OnPreprocessAvatar(avatarGameObject);
new RetargetMeshes().OnPreprocessAvatar(avatarGameObject); new RetargetMeshes().OnPreprocessAvatar(avatarGameObject);
new BoneProxyProcessor().OnPreprocessAvatar(avatarGameObject); new BoneProxyProcessor().OnPreprocessAvatar(avatarGameObject);
new FirstPersonVisibleProcessor(avatarGameObject.GetComponent<VRCAvatarDescriptor>()).Process();
new MergeAnimatorProcessor().OnPreprocessAvatar(avatarGameObject); new MergeAnimatorProcessor().OnPreprocessAvatar(avatarGameObject);
new BlendshapeSyncAnimationProcessor().OnPreprocessAvatar(avatarGameObject); new BlendshapeSyncAnimationProcessor().OnPreprocessAvatar(avatarGameObject);
new FirstPersonVisibleProcessor(avatarGameObject.GetComponent<VRCAvatarDescriptor>()).Process();
AfterProcessing?.Invoke(avatarGameObject); AfterProcessing?.Invoke(avatarGameObject);

View File

@ -89,7 +89,14 @@ namespace net.fushizen.modular_avatar.core.editor
var oscale = xform.lossyScale; var oscale = xform.lossyScale;
xform.localScale = new Vector3(oscale.x / pscale.x, oscale.y / pscale.y, oscale.z / pscale.z); xform.localScale = new Vector3(oscale.x / pscale.x, oscale.y / pscale.y, oscale.z / pscale.z);
var oldPath = RuntimeUtil.AvatarRootPath(target.gameObject);
target.transform.SetParent(proxy, true); target.transform.SetParent(proxy, true);
var newPath = RuntimeUtil.AvatarRootPath(target.gameObject);
PathMappings.Remap(oldPath, new PathMappings.MappingEntry()
{
path = newPath,
transformPath = newPath
});
didWork = true; didWork = true;
} }

View File

@ -30,8 +30,7 @@ namespace net.fushizen.modular_avatar.core.editor
{ {
public static class PathMappings public static class PathMappings
{ {
private static SortedDictionary<string, MappingEntry> Mappings = new SortedDictionary<string, MappingEntry>(); private static List<(string, MappingEntry)> Mappings = new List<(string, MappingEntry)>();
private static List<string> CachedMappingKeys = null;
public struct MappingEntry public struct MappingEntry
{ {
@ -43,33 +42,30 @@ namespace net.fushizen.modular_avatar.core.editor
return isTransformMapping ? transformPath : path; return isTransformMapping ? transformPath : path;
} }
} }
internal static void Clear() internal static void Clear()
{ {
Mappings.Clear(); Mappings.Clear();
CachedMappingKeys = null;
} }
internal static void Remap(string from, MappingEntry to) internal static void Remap(string from, MappingEntry to)
{ {
Mappings[from] = to; Mappings.Add((from, to));
CachedMappingKeys = null;
} }
internal static string MapPath(string path, bool isTransformMapping = false) internal static string MapPath(string path, bool isTransformMapping = false)
{ {
if (CachedMappingKeys == null) CachedMappingKeys = new List<string>(Mappings.Keys); foreach (var (src, mapping) in Mappings)
var bsResult = CachedMappingKeys.BinarySearch(path);
if (bsResult >= 0) return Mappings[path].Get(isTransformMapping);
int index = ~bsResult;
if (index == 0) return path;
var priorKey = CachedMappingKeys[index - 1];
if (path.StartsWith(priorKey + "/"))
{ {
return Mappings[priorKey].Get(isTransformMapping) + path.Substring(priorKey.Length); if (path == src || path.StartsWith(src + "/"))
{
var suffix = path.Substring(src.Length);
path = mapping.Get(isTransformMapping) + suffix;
// Continue processing subsequent remappings
}
} }
return path; return path;
} }
} }