mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
146 lines
5 KiB
C#
146 lines
5 KiB
C#
namespace Penumbra.Import.Textures;
|
|
|
|
public partial class CombinedTexture
|
|
{
|
|
private enum CombineOp
|
|
{
|
|
LeftMultiply = -4,
|
|
LeftCopy = -3,
|
|
RightCopy = -2,
|
|
Invalid = -1,
|
|
Over = 0,
|
|
Under = 1,
|
|
RightMultiply = 2,
|
|
CopyChannels = 3,
|
|
}
|
|
|
|
private enum ResizeOp
|
|
{
|
|
LeftOnly = -2,
|
|
RightOnly = -1,
|
|
None = 0,
|
|
ToLeft = 1,
|
|
ToRight = 2,
|
|
}
|
|
|
|
[Flags]
|
|
private enum Channels : byte
|
|
{
|
|
Red = 1,
|
|
Green = 2,
|
|
Blue = 4,
|
|
Alpha = 8,
|
|
}
|
|
|
|
private static readonly IReadOnlyList<string> CombineOpLabels = new[]
|
|
{
|
|
"Overlay over Input",
|
|
"Input over Overlay",
|
|
"Replace Input",
|
|
"Copy Channels",
|
|
};
|
|
|
|
private static readonly IReadOnlyList<string> CombineOpTooltips = new[]
|
|
{
|
|
"Standard composition.\nApply the overlay over the input.",
|
|
"Standard composition, reversed.\nApply the input over the overlay ; can be used to fix some wrong imports.",
|
|
"Completely replace the input with the overlay.\nCan be used to select the destination file as input and the source file as overlay.",
|
|
"Replace some input channels with those from the overlay.\nUseful for Multi maps.",
|
|
};
|
|
|
|
private static readonly IReadOnlyList<string> ResizeOpLabels = new string[]
|
|
{
|
|
"No Resizing",
|
|
"Adjust Overlay to Input",
|
|
"Adjust Input to Overlay",
|
|
};
|
|
|
|
private static ResizeOp GetActualResizeOp(ResizeOp resizeOp, CombineOp combineOp)
|
|
=> combineOp switch
|
|
{
|
|
CombineOp.LeftCopy => ResizeOp.LeftOnly,
|
|
CombineOp.LeftMultiply => ResizeOp.LeftOnly,
|
|
CombineOp.RightCopy => ResizeOp.RightOnly,
|
|
CombineOp.RightMultiply => ResizeOp.RightOnly,
|
|
CombineOp.Over => resizeOp,
|
|
CombineOp.Under => resizeOp,
|
|
CombineOp.CopyChannels => resizeOp,
|
|
_ => throw new ArgumentException($"Invalid combine operation {combineOp}"),
|
|
};
|
|
|
|
private CombineOp GetActualCombineOp()
|
|
{
|
|
var combineOp = (_left.IsLoaded, _right.IsLoaded) switch
|
|
{
|
|
(true, true) => _combineOp,
|
|
(true, false) => CombineOp.LeftMultiply,
|
|
(false, true) => CombineOp.RightMultiply,
|
|
(false, false) => CombineOp.Invalid,
|
|
};
|
|
|
|
if (combineOp == CombineOp.CopyChannels)
|
|
{
|
|
if (_copyChannels == 0)
|
|
combineOp = CombineOp.LeftMultiply;
|
|
else if (_copyChannels == (Channels.Red | Channels.Green | Channels.Blue | Channels.Alpha))
|
|
combineOp = CombineOp.RightMultiply;
|
|
}
|
|
|
|
return combineOp switch
|
|
{
|
|
CombineOp.LeftMultiply when _multiplierLeft.IsIdentity && _constantLeft == Vector4.Zero => CombineOp.LeftCopy,
|
|
CombineOp.RightMultiply when _multiplierRight.IsIdentity && _constantRight == Vector4.Zero => CombineOp.RightCopy,
|
|
_ => combineOp,
|
|
};
|
|
}
|
|
|
|
|
|
private static bool InvertChannels(Channels channels, ref Matrix4x4 multiplier, ref Vector4 constant)
|
|
{
|
|
if (channels.HasFlag(Channels.Red))
|
|
InvertRed(ref multiplier, ref constant);
|
|
if (channels.HasFlag(Channels.Green))
|
|
InvertGreen(ref multiplier, ref constant);
|
|
if (channels.HasFlag(Channels.Blue))
|
|
InvertBlue(ref multiplier, ref constant);
|
|
if (channels.HasFlag(Channels.Alpha))
|
|
InvertAlpha(ref multiplier, ref constant);
|
|
return channels != 0;
|
|
}
|
|
|
|
private static void InvertRed(ref Matrix4x4 multiplier, ref Vector4 constant)
|
|
{
|
|
multiplier.M11 = -multiplier.M11;
|
|
multiplier.M21 = -multiplier.M21;
|
|
multiplier.M31 = -multiplier.M31;
|
|
multiplier.M41 = -multiplier.M41;
|
|
constant.X = 1.0f - constant.X;
|
|
}
|
|
|
|
private static void InvertGreen(ref Matrix4x4 multiplier, ref Vector4 constant)
|
|
{
|
|
multiplier.M12 = -multiplier.M12;
|
|
multiplier.M22 = -multiplier.M22;
|
|
multiplier.M32 = -multiplier.M32;
|
|
multiplier.M42 = -multiplier.M42;
|
|
constant.Y = 1.0f - constant.Y;
|
|
}
|
|
|
|
private static void InvertBlue(ref Matrix4x4 multiplier, ref Vector4 constant)
|
|
{
|
|
multiplier.M13 = -multiplier.M13;
|
|
multiplier.M23 = -multiplier.M23;
|
|
multiplier.M33 = -multiplier.M33;
|
|
multiplier.M43 = -multiplier.M43;
|
|
constant.Z = 1.0f - constant.Z;
|
|
}
|
|
|
|
private static void InvertAlpha(ref Matrix4x4 multiplier, ref Vector4 constant)
|
|
{
|
|
multiplier.M14 = -multiplier.M14;
|
|
multiplier.M24 = -multiplier.M24;
|
|
multiplier.M34 = -multiplier.M34;
|
|
multiplier.M44 = -multiplier.M44;
|
|
constant.W = 1.0f - constant.W;
|
|
}
|
|
}
|