namespace MaterialLib;
/// Файл материала MAT0.
/// Имя файла из NRes metadata, не из payload материала.
/// Значение attr1 / ElementCount из NRes metadata.
/// Значение attr2 / Magic1 из NRes metadata.
/// Производное от Version: (Version >> 2) & 0xF. 0 = standard, 1 = special, 2 = particle.
/// Производное от Version: (Version & 2) != 0.
/// Производное от Version: Version & 40. 0 = normal, 8 = particle/effect.
/// Глобальный source blend mode; читается, если Magic1 >= 2. Значение по умолчанию: Unknown (0xFF).
/// Глобальный destination blend mode; читается, если Magic1 >= 2. Значение по умолчанию: Unknown (0xFF).
/// Глобальный alpha multiplier; читается, если Magic1 > 2. Значение по умолчанию: 1.0.
/// Глобальная emissive intensity; читается, если Magic1 > 3. Значение по умолчанию: 0.0.
/// Стадии материала в порядке чтения из файла.
/// Анимации материала в порядке чтения из файла.
public record MaterialFile(
string FileName,
uint Version,
int Magic1,
uint MaterialRenderingType,
bool SupportsBumpMapping,
uint IsParticleEffect,
BlendMode SourceBlendMode,
BlendMode DestBlendMode,
float GlobalAlphaMultiplier,
float GlobalEmissiveIntensity,
List Stages,
List Animations);
///
/// Режимы blend для материала. Управляют смешиванием source и destination цветов.
/// Формула: FinalColor = SourceColor * SourceBlend [operation] DestColor * DestBlend.
/// Соответствуют значениям Direct3D D3DBLEND.
///
public enum BlendMode : byte
{
/// Blend factor = (0, 0, 0, 0).
Zero = 1,
/// Blend factor = (1, 1, 1, 1).
One = 2,
/// Blend factor = (Rs, Gs, Bs, As).
SrcColor = 3,
/// Blend factor = (1-Rs, 1-Gs, 1-Bs, 1-As).
InvSrcColor = 4,
/// Blend factor = (As, As, As, As).
SrcAlpha = 5,
/// Blend factor = (1-As, 1-As, 1-As, 1-As).
InvSrcAlpha = 6,
/// Blend factor = (Ad, Ad, Ad, Ad).
DestAlpha = 7,
/// Blend factor = (1-Ad, 1-Ad, 1-Ad, 1-Ad).
InvDestAlpha = 8,
/// Blend factor = (Rd, Gd, Bd, Ad).
DestColor = 9,
/// Blend factor = (1-Rd, 1-Gd, 1-Bd, 1-Ad).
InvDestColor = 10,
/// Blend factor = (f, f, f, 1), где f = min(As, 1-Ad).
SrcAlphaSat = 11,
/// Blend factor = (As, As, As, As) для source и destination; устарело в D3D9+.
BothSrcAlpha = 12,
/// Blend factor = (1-As, 1-As, 1-As, 1-As) для source и destination; устарело в D3D9+.
BothInvSrcAlpha = 13,
/// Неизвестный или неинициализированный режим blend; значение по умолчанию 0xFF.
Unknown = 0xFF
}
/// Стадия материала. Порядок полей соответствует порядку чтения из файла, а не C struct layout.
/// Ambient R, читается первым цветовым блоком.
/// Ambient G, читается первым цветовым блоком.
/// Ambient B, читается первым цветовым блоком.
/// Ambient A, читается первым цветовым блоком и масштабируется на 0.01.
/// Diffuse R, читается вторым цветовым блоком.
/// Diffuse G, читается вторым цветовым блоком.
/// Diffuse B, читается вторым цветовым блоком.
/// Diffuse A, читается вторым цветовым блоком.
/// Specular R, читается третьим цветовым блоком.
/// Specular G, читается третьим цветовым блоком.
/// Specular B, читается третьим цветовым блоком.
/// Specular A, читается третьим цветовым блоком.
/// Emissive R, читается четвертым цветовым блоком.
/// Emissive G, читается четвертым цветовым блоком.
/// Emissive B, читается четвертым цветовым блоком.
/// Emissive A, читается четвертым цветовым блоком.
/// Power, один байт -> float.
/// Индекс texture stage. 255 = не задано/default, 0..47 = ссылка на texture stage.
/// Имя текстуры, строка из 16 байт.
public record MaterialStage(
float AmbientR,
float AmbientG,
float AmbientB,
float AmbientA,
float DiffuseR,
float DiffuseG,
float DiffuseB,
float DiffuseA,
float SpecularR,
float SpecularG,
float SpecularB,
float SpecularA,
float EmissiveR,
float EmissiveG,
float EmissiveB,
float EmissiveA,
float Power,
int TextureStageIndex,
string TextureName);
/// Анимация материала.
/// Целевые компоненты анимации: биты 3..31 combined field.
/// Режим повтора: биты 0..2 combined field.
/// Ключи анимации.
/// Кэшированное описание target для UI.
public record MaterialAnimation(
AnimationTarget Target,
AnimationLoopMode LoopMode,
List Keys,
string TargetDescription);
[Flags]
public enum AnimationTarget : int
{
// Это bitset: несколько флагов могут комбинироваться.
// Установленный флаг означает интерполяцию компонента между стадиями.
// Неустановленный флаг означает копирование компонента из исходной стадии.
// Если все флаги равны 0, вся стадия копируется без интерполяции.
Ambient = 1, // 0x01: интерполирует Ambient RGB.
Diffuse = 2, // 0x02: интерполирует Diffuse RGB.
Specular = 4, // 0x04: интерполирует Specular RGB.
Emissive = 8, // 0x08: интерполирует Emissive RGB.
Power = 16 // 0x10: интерполирует Ambient.A и задает Power.
}
public enum AnimationLoopMode : int
{
Loop = 0,
PingPong = 1,
Clamp = 2,
Random = 3
}
/// Ключ анимации материала (length = 6).
/// [0x00..0x02] Индекс стадии материала.
/// [0x02..0x04] Длительность в миллисекундах.
/// [0x04..0x06] Кривая интерполяции. В исследованных данных всегда 0.
public readonly record struct AnimKey(ushort StageIndex, ushort DurationMs, ushort InterpolationCurve);