2023-01-14 11:31:39 -05:00

143 lines
4.4 KiB
C#

using AssetRipper.Assets.Generics;
using AssetRipper.Assets.Metadata;
using AssetRipper.Numerics;
using AssetRipper.SourceGenerated.Classes.ClassID_1;
using AssetRipper.SourceGenerated.Classes.ClassID_4;
using AssetRipper.SourceGenerated.Subclasses.PPtr_Transform;
using System.Numerics;
namespace AssetRipper.SourceGenerated.Extensions
{
public static class TransformExtensions
{
private const char PathSeparator = '/';
public static Transformation ToTransformation(this ITransform transform)
{
return Transformation.Create(transform.LocalPosition_C4.CastToStruct(), transform.LocalRotation_C4.CastToStruct(), transform.LocalScale_C4.CastToStruct());
}
public static Transformation ToInverseTransformation(this ITransform transform)
{
return Transformation.CreateInverse(transform.LocalPosition_C4.CastToStruct(), transform.LocalRotation_C4.CastToStruct(), transform.LocalScale_C4.CastToStruct());
}
public static string GetRootPath(this ITransform transform)
{
string pre = string.Empty;
if (!transform.Father_C4.IsNull())
{
pre = transform.Father_C4.GetAsset(transform.Collection).GetRootPath() + PathSeparator;
}
return pre + transform.GetGameObject().NameString;
}
/// <summary>
/// Initialize an injected Transform with some sensible default values.
/// </summary>
/// <param name="transform"></param>
public static void InitializeDefault(this ITransform transform)
{
transform.LocalPosition_C4.SetZero();
transform.LocalRotation_C4.SetIdentity();
transform.LocalScale_C4.SetOne();
transform.RootOrder_C4 = 0;
transform.LocalEulerAnglesHint_C4?.SetZero();
}
/// <summary>
/// Find the sibling index (aka the root order) of the transform
/// </summary>
/// <param name="transform">The relevant transform</param>
/// <returns>The sibling index of the transform</returns>
/// <exception cref="Exception">if the transform cannot be found among the father's children</exception>
public static int GetSiblingIndex(this ITransform transform)
{
if (transform.Father_C4.IsNull())
{
return 0;
}
ITransform father = transform.Father_C4.GetAsset(transform.Collection);
for (int i = 0; i < father.Children_C4.Count; i++)
{
IPPtr_Transform child = father.Children_C4[i];
if (child.PathID == transform.PathID)
{
return i;
}
}
throw new Exception("Transform hasn't been found among father's children");
}
public static ITransform? FindChild(this ITransform transform, string path)
{
if (path.Length == 0)
{
return transform;
}
return transform.FindChild(path, 0);
}
private static ITransform? FindChild(this ITransform transform, string path, int startIndex)
{
int separatorIndex = path.IndexOf(PathSeparator, startIndex);
string childName = separatorIndex == -1 ?
path.Substring(startIndex, path.Length - startIndex) :
path.Substring(startIndex, separatorIndex - startIndex);
foreach (ITransform child in transform.GetChildren())
{
IGameObject childGO = child.GetGameObject();
if (childGO.NameString == childName)
{
return separatorIndex == -1 ? child : child.FindChild(path, separatorIndex + 1);
}
}
return default;
}
public static IEnumerable<ITransform> GetChildren(this ITransform transform)
{
foreach (IPPtr_Transform childPtr in transform.Children_C4)
{
yield return childPtr.GetAsset(transform.Collection);
}
}
public static void ConvertToEditorFormat(this ITransform transform)
{
if (transform.Has_RootOrder_C4())
{
transform.RootOrder_C4 = transform.CalculateRootOrder();
}
if (transform.Has_LocalEulerAnglesHint_C4())
{
Vector3 eulerHints = new Quaternion(
transform.LocalRotation_C4.X,
transform.LocalRotation_C4.Y,
transform.LocalRotation_C4.Z,
transform.LocalRotation_C4.W).ToEulerAngle(true);
transform.LocalEulerAnglesHint_C4.SetValues(eulerHints.X, eulerHints.Y, eulerHints.Z);
}
}
private static int CalculateRootOrder(this ITransform transform)
{
if (transform.Father_C4.IsNull())
{
return 0;
}
ITransform father = transform.Father_C4.GetAsset(transform.Collection);
AccessListBase<IPPtr_Transform> children = father.Children_C4;
for (int i = 0; i < children.Count; i++)
{
IPPtr_Transform child = children[i];
if (child.PathID == transform.PathID)
{
return i;
}
}
throw new Exception("Transform hasn't been found among father's children");
}
}
}