Glamourer/Glamourer/GameData/CustomizeParameterData.cs
2024-01-10 16:41:45 +01:00

226 lines
13 KiB
C#

using FFXIVClientStructs.FFXIV.Shader;
namespace Glamourer.GameData;
public struct CustomizeParameterData
{
public Vector4 DecalColor;
public Vector4 LipDiffuse;
public Vector3 SkinDiffuse;
public Vector3 SkinSpecular;
public Vector3 HairDiffuse;
public Vector3 HairSpecular;
public Vector3 HairHighlight;
public Vector3 LeftEye;
public Vector3 RightEye;
public Vector3 FeatureColor;
public float FacePaintUvMultiplier;
public float FacePaintUvOffset;
public float MuscleTone;
public CustomizeParameterValue this[CustomizeParameterFlag flag]
{
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
readonly get
{
return flag switch
{
CustomizeParameterFlag.SkinDiffuse => new CustomizeParameterValue(SkinDiffuse),
CustomizeParameterFlag.MuscleTone => new CustomizeParameterValue(MuscleTone),
CustomizeParameterFlag.SkinSpecular => new CustomizeParameterValue(SkinSpecular),
CustomizeParameterFlag.LipDiffuse => new CustomizeParameterValue(LipDiffuse),
CustomizeParameterFlag.HairDiffuse => new CustomizeParameterValue(HairDiffuse),
CustomizeParameterFlag.HairSpecular => new CustomizeParameterValue(HairSpecular),
CustomizeParameterFlag.HairHighlight => new CustomizeParameterValue(HairHighlight),
CustomizeParameterFlag.LeftEye => new CustomizeParameterValue(LeftEye),
CustomizeParameterFlag.RightEye => new CustomizeParameterValue(RightEye),
CustomizeParameterFlag.FeatureColor => new CustomizeParameterValue(FeatureColor),
CustomizeParameterFlag.DecalColor => new CustomizeParameterValue(DecalColor),
CustomizeParameterFlag.FacePaintUvMultiplier => new CustomizeParameterValue(FacePaintUvMultiplier),
CustomizeParameterFlag.FacePaintUvOffset => new CustomizeParameterValue(FacePaintUvOffset),
_ => CustomizeParameterValue.Zero,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
set => Set(flag, value);
}
public bool Set(CustomizeParameterFlag flag, CustomizeParameterValue value)
{
return flag switch
{
CustomizeParameterFlag.SkinDiffuse => SetIfDifferent(ref SkinDiffuse, value.InternalTriple),
CustomizeParameterFlag.MuscleTone => SetIfDifferent(ref MuscleTone, value.Single),
CustomizeParameterFlag.SkinSpecular => SetIfDifferent(ref SkinSpecular, value.InternalTriple),
CustomizeParameterFlag.LipDiffuse => SetIfDifferent(ref LipDiffuse, value.InternalQuadruple),
CustomizeParameterFlag.HairDiffuse => SetIfDifferent(ref HairDiffuse, value.InternalTriple),
CustomizeParameterFlag.HairSpecular => SetIfDifferent(ref HairSpecular, value.InternalTriple),
CustomizeParameterFlag.HairHighlight => SetIfDifferent(ref HairHighlight, value.InternalTriple),
CustomizeParameterFlag.LeftEye => SetIfDifferent(ref LeftEye, value.InternalTriple),
CustomizeParameterFlag.RightEye => SetIfDifferent(ref RightEye, value.InternalTriple),
CustomizeParameterFlag.FeatureColor => SetIfDifferent(ref FeatureColor, value.InternalTriple),
CustomizeParameterFlag.DecalColor => SetIfDifferent(ref DecalColor, value.InternalQuadruple),
CustomizeParameterFlag.FacePaintUvMultiplier => SetIfDifferent(ref FacePaintUvMultiplier, value.Single),
CustomizeParameterFlag.FacePaintUvOffset => SetIfDifferent(ref FacePaintUvOffset, value.Single),
_ => false,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public readonly void Apply(ref CustomizeParameter parameters, CustomizeParameterFlag flags = CustomizeParameterExtensions.All)
{
parameters.SkinColor = (flags & (CustomizeParameterFlag.SkinDiffuse | CustomizeParameterFlag.MuscleTone)) switch
{
0 => parameters.SkinColor,
CustomizeParameterFlag.SkinDiffuse => new CustomizeParameterValue(SkinDiffuse, parameters.SkinColor.W).XivQuadruple,
CustomizeParameterFlag.MuscleTone => parameters.SkinColor with { W = MuscleTone },
_ => new CustomizeParameterValue(SkinDiffuse, MuscleTone).XivQuadruple,
};
parameters.LeftColor = (flags & (CustomizeParameterFlag.LeftEye | CustomizeParameterFlag.FacePaintUvMultiplier)) switch
{
0 => parameters.LeftColor,
CustomizeParameterFlag.LeftEye => new CustomizeParameterValue(LeftEye, parameters.LeftColor.W).XivQuadruple,
CustomizeParameterFlag.FacePaintUvMultiplier => parameters.LeftColor with { W = FacePaintUvMultiplier },
_ => new CustomizeParameterValue(LeftEye, FacePaintUvMultiplier).XivQuadruple,
};
parameters.RightColor = (flags & (CustomizeParameterFlag.RightEye | CustomizeParameterFlag.FacePaintUvOffset)) switch
{
0 => parameters.RightColor,
CustomizeParameterFlag.RightEye => new CustomizeParameterValue(RightEye, parameters.RightColor.W).XivQuadruple,
CustomizeParameterFlag.FacePaintUvOffset => parameters.RightColor with { W = FacePaintUvOffset },
_ => new CustomizeParameterValue(RightEye, FacePaintUvOffset).XivQuadruple,
};
if (flags.HasFlag(CustomizeParameterFlag.SkinSpecular))
parameters.SkinFresnelValue0 = new CustomizeParameterValue(SkinSpecular).XivQuadruple;
if (flags.HasFlag(CustomizeParameterFlag.HairDiffuse))
parameters.MainColor = new CustomizeParameterValue(HairDiffuse).XivTriple;
if (flags.HasFlag(CustomizeParameterFlag.HairSpecular))
parameters.HairFresnelValue0 = new CustomizeParameterValue(HairSpecular).XivTriple;
if (flags.HasFlag(CustomizeParameterFlag.HairHighlight))
parameters.MeshColor = new CustomizeParameterValue(HairHighlight).XivTriple;
if (flags.HasFlag(CustomizeParameterFlag.LipDiffuse))
parameters.LipColor = new CustomizeParameterValue(LipDiffuse).XivQuadruple;
if (flags.HasFlag(CustomizeParameterFlag.FeatureColor))
parameters.OptionColor = new CustomizeParameterValue(FeatureColor).XivTriple;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public readonly void Apply(ref DecalParameters parameters, CustomizeParameterFlag flags = CustomizeParameterExtensions.All)
{
if (flags.HasFlag(CustomizeParameterFlag.DecalColor))
parameters.Color = new CustomizeParameterValue(DecalColor).XivQuadruple;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public readonly void ApplySingle(ref CustomizeParameter parameters, CustomizeParameterFlag flag)
{
switch (flag)
{
case CustomizeParameterFlag.SkinDiffuse:
parameters.SkinColor = new CustomizeParameterValue(SkinDiffuse, parameters.SkinColor.W).XivQuadruple;
break;
case CustomizeParameterFlag.MuscleTone:
parameters.SkinColor.W = MuscleTone;
break;
case CustomizeParameterFlag.SkinSpecular:
parameters.SkinFresnelValue0 = new CustomizeParameterValue(SkinSpecular).XivQuadruple;
break;
case CustomizeParameterFlag.LipDiffuse:
parameters.LipColor = new CustomizeParameterValue(LipDiffuse).XivQuadruple;
break;
case CustomizeParameterFlag.HairDiffuse:
parameters.MainColor = new CustomizeParameterValue(HairDiffuse).XivTriple;
break;
case CustomizeParameterFlag.HairSpecular:
parameters.HairFresnelValue0 = new CustomizeParameterValue(HairSpecular).XivTriple;
break;
case CustomizeParameterFlag.HairHighlight:
parameters.MeshColor = new CustomizeParameterValue(HairHighlight).XivTriple;
break;
case CustomizeParameterFlag.LeftEye:
parameters.LeftColor = new CustomizeParameterValue(LeftEye, parameters.LeftColor.W).XivQuadruple;
break;
case CustomizeParameterFlag.RightEye:
parameters.RightColor = new CustomizeParameterValue(RightEye, parameters.RightColor.W).XivQuadruple;
break;
case CustomizeParameterFlag.FeatureColor:
parameters.OptionColor = new CustomizeParameterValue(FeatureColor).XivTriple;
break;
case CustomizeParameterFlag.FacePaintUvMultiplier:
parameters.LeftColor.W = FacePaintUvMultiplier;
break;
case CustomizeParameterFlag.FacePaintUvOffset:
parameters.RightColor.W = FacePaintUvOffset;
break;
}
}
public static CustomizeParameterData FromParameters(in CustomizeParameter parameter, in DecalParameters decal)
=> new()
{
FacePaintUvOffset = parameter.RightColor.W,
FacePaintUvMultiplier = parameter.LeftColor.W,
MuscleTone = parameter.SkinColor.W,
SkinDiffuse = new CustomizeParameterValue(parameter.SkinColor).InternalTriple,
SkinSpecular = new CustomizeParameterValue(parameter.SkinFresnelValue0).InternalTriple,
LipDiffuse = new CustomizeParameterValue(parameter.LipColor).InternalQuadruple,
HairDiffuse = new CustomizeParameterValue(parameter.MainColor).InternalTriple,
HairSpecular = new CustomizeParameterValue(parameter.HairFresnelValue0).InternalTriple,
HairHighlight = new CustomizeParameterValue(parameter.MeshColor).InternalTriple,
LeftEye = new CustomizeParameterValue(parameter.LeftColor).InternalTriple,
RightEye = new CustomizeParameterValue(parameter.RightColor).InternalTriple,
FeatureColor = new CustomizeParameterValue(parameter.OptionColor).InternalTriple,
DecalColor = FromParameter(decal),
};
public static CustomizeParameterValue FromParameter(in CustomizeParameter parameter, CustomizeParameterFlag flag)
=> flag switch
{
CustomizeParameterFlag.SkinDiffuse => new CustomizeParameterValue(parameter.SkinColor),
CustomizeParameterFlag.MuscleTone => new CustomizeParameterValue(parameter.SkinColor.W),
CustomizeParameterFlag.SkinSpecular => new CustomizeParameterValue(parameter.SkinFresnelValue0),
CustomizeParameterFlag.LipDiffuse => new CustomizeParameterValue(parameter.LipColor),
CustomizeParameterFlag.HairDiffuse => new CustomizeParameterValue(parameter.MainColor),
CustomizeParameterFlag.HairSpecular => new CustomizeParameterValue(parameter.HairFresnelValue0),
CustomizeParameterFlag.HairHighlight => new CustomizeParameterValue(parameter.MeshColor),
CustomizeParameterFlag.LeftEye => new CustomizeParameterValue(parameter.LeftColor),
CustomizeParameterFlag.RightEye => new CustomizeParameterValue(parameter.RightColor),
CustomizeParameterFlag.FeatureColor => new CustomizeParameterValue(parameter.OptionColor),
CustomizeParameterFlag.FacePaintUvMultiplier => new CustomizeParameterValue(parameter.LeftColor.W),
CustomizeParameterFlag.FacePaintUvOffset => new CustomizeParameterValue(parameter.RightColor.W),
_ => CustomizeParameterValue.Zero,
};
public static Vector4 FromParameter(in DecalParameters parameter)
=> new CustomizeParameterValue(parameter.Color).InternalQuadruple;
private static bool SetIfDifferent(ref Vector3 val, Vector3 @new)
{
if (@new == val)
return false;
val = @new;
return true;
}
private static bool SetIfDifferent(ref float val, float @new)
{
if (@new == val)
return false;
val = @new;
return true;
}
private static bool SetIfDifferent(ref Vector4 val, Vector4 @new)
{
if (@new == val)
return false;
val = @new;
return true;
}
}