mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 20:24:17 +01:00
284 lines
8.3 KiB
C#
284 lines
8.3 KiB
C#
using System;
|
|
using SharpGLTF.Geometry.VertexTypes;
|
|
using SharpGLTF.Memory;
|
|
using SharpGLTF.Schema2;
|
|
|
|
namespace Penumbra.Import.Models.Export;
|
|
|
|
/*
|
|
Yeah, look, I tried to make this file less garbage. It's a little difficult.
|
|
Realistically, it will need to stick around until transforms/mutations are built
|
|
and there's reason to overhaul the export pipeline.
|
|
*/
|
|
|
|
public struct VertexColorFfxiv : IVertexCustom
|
|
{
|
|
public IEnumerable<KeyValuePair<string, AttributeFormat>> GetEncodingAttributes()
|
|
{
|
|
// NOTE: We only realistically require UNSIGNED_BYTE for this, however Blender 3.6 errors on that (fixed in 4.0).
|
|
yield return new KeyValuePair<string, AttributeFormat>("_FFXIV_COLOR",
|
|
new AttributeFormat(DimensionType.VEC4, EncodingType.UNSIGNED_SHORT, true));
|
|
}
|
|
|
|
public Vector4 FfxivColor;
|
|
|
|
public int MaxColors
|
|
=> 0;
|
|
|
|
public int MaxTextCoords
|
|
=> 0;
|
|
|
|
private static readonly string[] CustomNames = ["_FFXIV_COLOR"];
|
|
|
|
public IEnumerable<string> CustomAttributes
|
|
=> CustomNames;
|
|
|
|
public VertexColorFfxiv(Vector4 ffxivColor)
|
|
=> FfxivColor = ffxivColor;
|
|
|
|
public void Add(in VertexMaterialDelta delta)
|
|
{ }
|
|
|
|
public VertexMaterialDelta Subtract(IVertexMaterial baseValue)
|
|
=> new(Vector4.Zero, Vector4.Zero, Vector2.Zero, Vector2.Zero);
|
|
|
|
public Vector2 GetTexCoord(int index)
|
|
=> throw new ArgumentOutOfRangeException(nameof(index));
|
|
|
|
public void SetTexCoord(int setIndex, Vector2 coord)
|
|
{ }
|
|
|
|
public bool TryGetCustomAttribute(string attributeName, out object? value)
|
|
{
|
|
switch (attributeName)
|
|
{
|
|
case "_FFXIV_COLOR":
|
|
value = FfxivColor;
|
|
return true;
|
|
|
|
default:
|
|
value = null;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void SetCustomAttribute(string attributeName, object value)
|
|
{
|
|
if (attributeName == "_FFXIV_COLOR" && value is Vector4 valueVector4)
|
|
FfxivColor = valueVector4;
|
|
}
|
|
|
|
public Vector4 GetColor(int index)
|
|
=> throw new ArgumentOutOfRangeException(nameof(index));
|
|
|
|
public void SetColor(int setIndex, Vector4 color)
|
|
{ }
|
|
|
|
public void Validate()
|
|
{
|
|
var components = new[]
|
|
{
|
|
FfxivColor.X,
|
|
FfxivColor.Y,
|
|
FfxivColor.Z,
|
|
FfxivColor.W,
|
|
};
|
|
if (components.Any(component => component < 0 || component > 1))
|
|
throw new ArgumentOutOfRangeException(nameof(FfxivColor));
|
|
}
|
|
}
|
|
|
|
public struct VertexTexture1ColorFfxiv : IVertexCustom
|
|
{
|
|
public IEnumerable<KeyValuePair<string, AttributeFormat>> GetEncodingAttributes()
|
|
{
|
|
yield return new KeyValuePair<string, AttributeFormat>("TEXCOORD_0",
|
|
new AttributeFormat(DimensionType.VEC2, EncodingType.FLOAT, false));
|
|
yield return new KeyValuePair<string, AttributeFormat>("_FFXIV_COLOR",
|
|
new AttributeFormat(DimensionType.VEC4, EncodingType.UNSIGNED_SHORT, true));
|
|
}
|
|
|
|
public Vector2 TexCoord0;
|
|
|
|
public Vector4 FfxivColor;
|
|
|
|
public int MaxColors
|
|
=> 0;
|
|
|
|
public int MaxTextCoords
|
|
=> 1;
|
|
|
|
private static readonly string[] CustomNames = ["_FFXIV_COLOR"];
|
|
|
|
public IEnumerable<string> CustomAttributes
|
|
=> CustomNames;
|
|
|
|
public VertexTexture1ColorFfxiv(Vector2 texCoord0, Vector4 ffxivColor)
|
|
{
|
|
TexCoord0 = texCoord0;
|
|
FfxivColor = ffxivColor;
|
|
}
|
|
|
|
public void Add(in VertexMaterialDelta delta)
|
|
{
|
|
TexCoord0 += delta.TexCoord0Delta;
|
|
}
|
|
|
|
public VertexMaterialDelta Subtract(IVertexMaterial baseValue)
|
|
=> new(Vector4.Zero, Vector4.Zero, TexCoord0 - baseValue.GetTexCoord(0), Vector2.Zero);
|
|
|
|
public Vector2 GetTexCoord(int index)
|
|
=> index switch
|
|
{
|
|
0 => TexCoord0,
|
|
_ => throw new ArgumentOutOfRangeException(nameof(index)),
|
|
};
|
|
|
|
public void SetTexCoord(int setIndex, Vector2 coord)
|
|
{
|
|
if (setIndex == 0)
|
|
TexCoord0 = coord;
|
|
if (setIndex >= 1)
|
|
throw new ArgumentOutOfRangeException(nameof(setIndex));
|
|
}
|
|
|
|
public bool TryGetCustomAttribute(string attributeName, out object? value)
|
|
{
|
|
switch (attributeName)
|
|
{
|
|
case "_FFXIV_COLOR":
|
|
value = FfxivColor;
|
|
return true;
|
|
|
|
default:
|
|
value = null;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void SetCustomAttribute(string attributeName, object value)
|
|
{
|
|
if (attributeName == "_FFXIV_COLOR" && value is Vector4 valueVector4)
|
|
FfxivColor = valueVector4;
|
|
}
|
|
|
|
public Vector4 GetColor(int index)
|
|
=> throw new ArgumentOutOfRangeException(nameof(index));
|
|
|
|
public void SetColor(int setIndex, Vector4 color)
|
|
{ }
|
|
|
|
public void Validate()
|
|
{
|
|
var components = new[]
|
|
{
|
|
FfxivColor.X,
|
|
FfxivColor.Y,
|
|
FfxivColor.Z,
|
|
FfxivColor.W,
|
|
};
|
|
if (components.Any(component => component < 0 || component > 1))
|
|
throw new ArgumentOutOfRangeException(nameof(FfxivColor));
|
|
}
|
|
}
|
|
|
|
public struct VertexTexture2ColorFfxiv : IVertexCustom
|
|
{
|
|
public IEnumerable<KeyValuePair<string, AttributeFormat>> GetEncodingAttributes()
|
|
{
|
|
yield return new KeyValuePair<string, AttributeFormat>("TEXCOORD_0",
|
|
new AttributeFormat(DimensionType.VEC2, EncodingType.FLOAT, false));
|
|
yield return new KeyValuePair<string, AttributeFormat>("TEXCOORD_1",
|
|
new AttributeFormat(DimensionType.VEC2, EncodingType.FLOAT, false));
|
|
yield return new KeyValuePair<string, AttributeFormat>("_FFXIV_COLOR",
|
|
new AttributeFormat(DimensionType.VEC4, EncodingType.UNSIGNED_SHORT, true));
|
|
}
|
|
|
|
public Vector2 TexCoord0;
|
|
public Vector2 TexCoord1;
|
|
public Vector4 FfxivColor;
|
|
|
|
public int MaxColors
|
|
=> 0;
|
|
|
|
public int MaxTextCoords
|
|
=> 2;
|
|
|
|
private static readonly string[] CustomNames = ["_FFXIV_COLOR"];
|
|
|
|
public IEnumerable<string> CustomAttributes
|
|
=> CustomNames;
|
|
|
|
public VertexTexture2ColorFfxiv(Vector2 texCoord0, Vector2 texCoord1, Vector4 ffxivColor)
|
|
{
|
|
TexCoord0 = texCoord0;
|
|
TexCoord1 = texCoord1;
|
|
FfxivColor = ffxivColor;
|
|
}
|
|
|
|
public void Add(in VertexMaterialDelta delta)
|
|
{
|
|
TexCoord0 += delta.TexCoord0Delta;
|
|
TexCoord1 += delta.TexCoord1Delta;
|
|
}
|
|
|
|
public VertexMaterialDelta Subtract(IVertexMaterial baseValue)
|
|
=> new(Vector4.Zero, Vector4.Zero, TexCoord0 - baseValue.GetTexCoord(0), TexCoord1 - baseValue.GetTexCoord(1));
|
|
|
|
public Vector2 GetTexCoord(int index)
|
|
=> index switch
|
|
{
|
|
0 => TexCoord0,
|
|
1 => TexCoord1,
|
|
_ => throw new ArgumentOutOfRangeException(nameof(index)),
|
|
};
|
|
|
|
public void SetTexCoord(int setIndex, Vector2 coord)
|
|
{
|
|
if (setIndex == 0)
|
|
TexCoord0 = coord;
|
|
if (setIndex == 1)
|
|
TexCoord1 = coord;
|
|
if (setIndex >= 2)
|
|
throw new ArgumentOutOfRangeException(nameof(setIndex));
|
|
}
|
|
|
|
public bool TryGetCustomAttribute(string attributeName, out object? value)
|
|
{
|
|
switch (attributeName)
|
|
{
|
|
case "_FFXIV_COLOR":
|
|
value = FfxivColor;
|
|
return true;
|
|
|
|
default:
|
|
value = null;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void SetCustomAttribute(string attributeName, object value)
|
|
{
|
|
if (attributeName == "_FFXIV_COLOR" && value is Vector4 valueVector4)
|
|
FfxivColor = valueVector4;
|
|
}
|
|
|
|
public Vector4 GetColor(int index)
|
|
=> throw new ArgumentOutOfRangeException(nameof(index));
|
|
|
|
public void SetColor(int setIndex, Vector4 color)
|
|
{ }
|
|
|
|
public void Validate()
|
|
{
|
|
var components = new[]
|
|
{
|
|
FfxivColor.X,
|
|
FfxivColor.Y,
|
|
FfxivColor.Z,
|
|
FfxivColor.W,
|
|
};
|
|
if (components.Any(component => component < 0 || component > 1))
|
|
throw new ArgumentOutOfRangeException(nameof(FfxivColor));
|
|
}
|
|
}
|