VRC_Avatar/Assets/RekornTools/Avatar/Components/SkinnedMeshTools/RigNamingConvention.cs
2025-02-15 18:50:31 +09:00

125 lines
4.5 KiB
C#

using System;
using JetBrains.Annotations;
using UnityEngine;
namespace RekornTools.Avatar
{
public enum ModifierPosition
{
Front,
End,
}
public enum ModifierType
{
None,
Both,
Left,
Right,
}
[Serializable]
public struct RigNamingConvention
{
public static RigNamingConvention Default = new RigNamingConvention
{
ModifierPosition = ModifierPosition.End,
Splitter = "_",
ModifierLeft = "L",
ModifierRight = "R",
};
[field: SerializeField] public ModifierPosition ModifierPosition { get; private set; }
[field: SerializeField] [CanBeNull] public string Splitter { get; private set; }
[field: SerializeField] [CanBeNull] public string ModifierLeft { get; private set; }
[field: SerializeField] [CanBeNull] public string ModifierRight { get; private set; }
public RigNamingConvention(ModifierPosition modifierPosition, [CanBeNull] string splitter, [CanBeNull] string modifierLeft, [CanBeNull] string modifierRight)
{
ModifierPosition = modifierPosition;
Splitter = splitter;
ModifierLeft = modifierLeft;
ModifierRight = modifierRight;
}
[NotNull] public string FrontLeft => $"{ModifierLeft}{Splitter}";
[NotNull] public string FrontRight => $"{ModifierRight}{Splitter}";
[NotNull] public string EndLeft => $"{Splitter}{ModifierLeft}";
[NotNull] public string EndRight => $"{Splitter}{ModifierRight}";
public string GetModifier(ModifierType type)
{
var pos = ModifierPosition;
if (pos == ModifierPosition.Front && type == ModifierType.Left) return FrontLeft;
if (pos == ModifierPosition.Front && type == ModifierType.Right) return FrontRight;
if (pos == ModifierPosition.End && type == ModifierType.Left) return EndLeft;
if (pos == ModifierPosition.End && type == ModifierType.Right) return EndRight;
return null;
}
public ModifierType GetModifierType([NotNull] string name)
{
var isLeft = false;
var isRight = false;
if (ModifierPosition == ModifierPosition.Front)
{
isLeft = name.Contains(FrontLeft);
isRight = name.Contains(FrontRight);
}
else
{
isLeft = name.Contains(EndLeft);
isRight = name.Contains(EndRight);
}
if (isLeft && isRight) return ModifierType.Both;
else if (isLeft) return ModifierType.Left;
else if (isRight) return ModifierType.Right;
else return ModifierType.None;
}
[NotNull]
public static string Convert([NotNull] string name, RigNamingConvention src, RigNamingConvention dst)
{
var type = src.GetModifierType(name);
switch (type)
{
case ModifierType.None:
return name;
case ModifierType.Both:
Debug.LogWarning($"Bone name {name} contains both left and right modifiers. Skipping.");
return name;
case ModifierType.Left:
case ModifierType.Right:
var from = src.GetModifier(type) ?? throw new ArgumentException("Unknown modifier type.");
var to = dst.GetModifier(type) ?? throw new ArgumentException("Unknown modifier type.");
return ReplaceModifier(name, from, to, src.ModifierPosition, dst.ModifierPosition);
default:
throw new ArgumentException("Unknown modifier type.");
}
}
[NotNull]
static string ReplaceModifier([NotNull] string name, [NotNull] string from, [NotNull] string to, ModifierPosition srcPosition, ModifierPosition dstPosition)
{
if (srcPosition == dstPosition)
{
return name.Replace(from, to);
}
else
{
if (srcPosition == ModifierPosition.Front)
{
return name.Replace(from, null) + to;
}
else
{
return to + name.Replace(from, null);
}
}
}
}
}