mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Some formatting and naming changes, splitting files and some minor improvements.
This commit is contained in:
parent
1e471551d4
commit
a2b62a8b6a
13 changed files with 928 additions and 997 deletions
|
|
@ -1,9 +1,7 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using Lumina.Data.Parsing;
|
||||
using Lumina.Extensions;
|
||||
|
|
@ -13,262 +11,10 @@ namespace Penumbra.GameData.Files;
|
|||
|
||||
public partial class MtrlFile : IWritable
|
||||
{
|
||||
public struct UvSet
|
||||
{
|
||||
public string Name;
|
||||
public ushort Index;
|
||||
}
|
||||
|
||||
public unsafe struct ColorSet
|
||||
{
|
||||
public struct Row
|
||||
{
|
||||
public const int Size = 32;
|
||||
|
||||
private fixed ushort _data[16];
|
||||
|
||||
public Vector3 Diffuse
|
||||
{
|
||||
get => new(ToFloat(0), ToFloat(1), ToFloat(2));
|
||||
set
|
||||
{
|
||||
_data[0] = FromFloat(value.X);
|
||||
_data[1] = FromFloat(value.Y);
|
||||
_data[2] = FromFloat(value.Z);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 Specular
|
||||
{
|
||||
get => new(ToFloat(4), ToFloat(5), ToFloat(6));
|
||||
set
|
||||
{
|
||||
_data[4] = FromFloat(value.X);
|
||||
_data[5] = FromFloat(value.Y);
|
||||
_data[6] = FromFloat(value.Z);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 Emissive
|
||||
{
|
||||
get => new(ToFloat(8), ToFloat(9), ToFloat(10));
|
||||
set
|
||||
{
|
||||
_data[8] = FromFloat(value.X);
|
||||
_data[9] = FromFloat(value.Y);
|
||||
_data[10] = FromFloat(value.Z);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 MaterialRepeat
|
||||
{
|
||||
get => new(ToFloat(12), ToFloat(15));
|
||||
set
|
||||
{
|
||||
_data[12] = FromFloat(value.X);
|
||||
_data[15] = FromFloat(value.Y);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 MaterialSkew
|
||||
{
|
||||
get => new(ToFloat(13), ToFloat(14));
|
||||
set
|
||||
{
|
||||
_data[13] = FromFloat(value.X);
|
||||
_data[14] = FromFloat(value.Y);
|
||||
}
|
||||
}
|
||||
|
||||
public float SpecularStrength
|
||||
{
|
||||
get => ToFloat(3);
|
||||
set => _data[3] = FromFloat(value);
|
||||
}
|
||||
|
||||
public float GlossStrength
|
||||
{
|
||||
get => ToFloat(7);
|
||||
set => _data[7] = FromFloat(value);
|
||||
}
|
||||
|
||||
public ushort TileSet
|
||||
{
|
||||
get => (ushort)(ToFloat(11) * 64f);
|
||||
set => _data[11] = FromFloat(value / 64f);
|
||||
}
|
||||
|
||||
private float ToFloat(int idx)
|
||||
=> (float)BitConverter.UInt16BitsToHalf(_data[idx]);
|
||||
|
||||
private static ushort FromFloat(float x)
|
||||
=> BitConverter.HalfToUInt16Bits((Half)x);
|
||||
}
|
||||
|
||||
public struct RowArray : IEnumerable<Row>
|
||||
{
|
||||
public const int NumRows = 16;
|
||||
private fixed byte _rowData[NumRows * Row.Size];
|
||||
|
||||
public ref Row this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
fixed (byte* ptr = _rowData)
|
||||
{
|
||||
return ref ((Row*)ptr)[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<Row> GetEnumerator()
|
||||
{
|
||||
for (var i = 0; i < NumRows; ++i)
|
||||
yield return this[i];
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> GetEnumerator();
|
||||
|
||||
public ReadOnlySpan<byte> AsBytes()
|
||||
{
|
||||
fixed (byte* ptr = _rowData)
|
||||
{
|
||||
return new ReadOnlySpan<byte>(ptr, NumRows * Row.Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RowArray Rows;
|
||||
public string Name;
|
||||
public ushort Index;
|
||||
public bool HasRows;
|
||||
}
|
||||
|
||||
public unsafe struct ColorDyeSet
|
||||
{
|
||||
public struct Row
|
||||
{
|
||||
private ushort _data;
|
||||
|
||||
public ushort Template
|
||||
{
|
||||
get => (ushort)(_data >> 5);
|
||||
set => _data = (ushort)((_data & 0x1F) | (value << 5));
|
||||
}
|
||||
|
||||
public bool Diffuse
|
||||
{
|
||||
get => (_data & 0x01) != 0;
|
||||
set => _data = (ushort)(value ? _data | 0x01 : _data & 0xFFFE);
|
||||
}
|
||||
|
||||
public bool Specular
|
||||
{
|
||||
get => (_data & 0x02) != 0;
|
||||
set => _data = (ushort)(value ? _data | 0x02 : _data & 0xFFFD);
|
||||
}
|
||||
|
||||
public bool Emissive
|
||||
{
|
||||
get => (_data & 0x04) != 0;
|
||||
set => _data = (ushort)(value ? _data | 0x04 : _data & 0xFFFB);
|
||||
}
|
||||
|
||||
public bool Gloss
|
||||
{
|
||||
get => (_data & 0x08) != 0;
|
||||
set => _data = (ushort)(value ? _data | 0x08 : _data & 0xFFF7);
|
||||
}
|
||||
|
||||
public bool SpecularStrength
|
||||
{
|
||||
get => (_data & 0x10) != 0;
|
||||
set => _data = (ushort)(value ? _data | 0x10 : _data & 0xFFEF);
|
||||
}
|
||||
}
|
||||
|
||||
public struct RowArray : IEnumerable<Row>
|
||||
{
|
||||
public const int NumRows = 16;
|
||||
private fixed ushort _rowData[NumRows];
|
||||
|
||||
public ref Row this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
fixed (ushort* ptr = _rowData)
|
||||
{
|
||||
return ref ((Row*)ptr)[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<Row> GetEnumerator()
|
||||
{
|
||||
for (var i = 0; i < NumRows; ++i)
|
||||
yield return this[i];
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> GetEnumerator();
|
||||
|
||||
public ReadOnlySpan<byte> AsBytes()
|
||||
{
|
||||
fixed (ushort* ptr = _rowData)
|
||||
{
|
||||
return new ReadOnlySpan<byte>(ptr, NumRows * sizeof(ushort));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RowArray Rows;
|
||||
public string Name;
|
||||
public ushort Index;
|
||||
}
|
||||
|
||||
public struct Texture
|
||||
{
|
||||
public string Path;
|
||||
public ushort Flags;
|
||||
|
||||
public bool DX11
|
||||
=> (Flags & 0x8000) != 0;
|
||||
}
|
||||
|
||||
public struct Constant
|
||||
{
|
||||
public uint Id;
|
||||
public ushort ByteOffset;
|
||||
public ushort ByteSize;
|
||||
}
|
||||
|
||||
public struct ShaderPackageData
|
||||
{
|
||||
public string Name;
|
||||
public ShaderKey[] ShaderKeys;
|
||||
public Constant[] Constants;
|
||||
public Sampler[] Samplers;
|
||||
public float[] ShaderValues;
|
||||
public uint Flags;
|
||||
}
|
||||
|
||||
|
||||
public readonly uint Version;
|
||||
public bool Valid
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var texture in Textures)
|
||||
{
|
||||
if (!texture.Path.Contains('/'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Valid
|
||||
=> CheckTextures();
|
||||
|
||||
public Texture[] Textures;
|
||||
public UvSet[] UvSets;
|
||||
|
|
@ -277,7 +23,7 @@ public partial class MtrlFile : IWritable
|
|||
public ShaderPackageData ShaderPackage;
|
||||
public byte[] AdditionalData;
|
||||
|
||||
public ShpkFile? AssociatedShpk;
|
||||
public ShpkFile? AssociatedShpk;
|
||||
|
||||
public bool ApplyDyeTemplate(StmFile stm, int colorSetIdx, int rowIdx, StainId stainId)
|
||||
{
|
||||
|
|
@ -324,15 +70,13 @@ public partial class MtrlFile : IWritable
|
|||
|
||||
public Span<float> GetConstantValues(Constant constant)
|
||||
{
|
||||
if ((constant.ByteOffset & 0x3) == 0 && (constant.ByteSize & 0x3) == 0
|
||||
&& ((constant.ByteOffset + constant.ByteSize) >> 2) <= ShaderPackage.ShaderValues.Length)
|
||||
{
|
||||
return ShaderPackage.ShaderValues.AsSpan().Slice(constant.ByteOffset >> 2, constant.ByteSize >> 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((constant.ByteOffset & 0x3) != 0
|
||||
|| (constant.ByteSize & 0x3) != 0
|
||||
|| (constant.ByteOffset + constant.ByteSize) >> 2 > ShaderPackage.ShaderValues.Length)
|
||||
return null;
|
||||
}
|
||||
|
||||
return ShaderPackage.ShaderValues.AsSpan().Slice(constant.ByteOffset >> 2, constant.ByteSize >> 2);
|
||||
|
||||
}
|
||||
|
||||
public List<(Sampler?, ShpkFile.Resource?)> GetSamplersByTexture()
|
||||
|
|
@ -348,13 +92,7 @@ public partial class MtrlFile : IWritable
|
|||
}
|
||||
|
||||
return samplers;
|
||||
}
|
||||
|
||||
// Activator.CreateInstance can't use a ctor with a default value so this has to be made explicit
|
||||
public MtrlFile(byte[] data)
|
||||
: this(data, null)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public MtrlFile(byte[] data, Func<string, ShpkFile?>? loadAssociatedShpk = null)
|
||||
{
|
||||
|
|
@ -469,6 +207,41 @@ public partial class MtrlFile : IWritable
|
|||
{
|
||||
strings = strings[offset..];
|
||||
var end = strings.IndexOf((byte)'\0');
|
||||
return Encoding.UTF8.GetString(strings[..end]);
|
||||
return Encoding.UTF8.GetString(end == -1 ? strings : strings[..end]);
|
||||
}
|
||||
|
||||
private bool CheckTextures()
|
||||
=> Textures.All(texture => texture.Path.Contains('/'));
|
||||
|
||||
public struct UvSet
|
||||
{
|
||||
public string Name;
|
||||
public ushort Index;
|
||||
}
|
||||
|
||||
public struct Texture
|
||||
{
|
||||
public string Path;
|
||||
public ushort Flags;
|
||||
|
||||
public bool DX11
|
||||
=> (Flags & 0x8000) != 0;
|
||||
}
|
||||
|
||||
public struct Constant
|
||||
{
|
||||
public uint Id;
|
||||
public ushort ByteOffset;
|
||||
public ushort ByteSize;
|
||||
}
|
||||
|
||||
public struct ShaderPackageData
|
||||
{
|
||||
public string Name;
|
||||
public ShaderKey[] ShaderKeys;
|
||||
public Constant[] Constants;
|
||||
public Sampler[] Samplers;
|
||||
public float[] ShaderValues;
|
||||
public uint Flags;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue