Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/patch 7.1 #21

Merged
merged 6 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Meddle/Meddle.Plugin/Meddle.Plugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.13"/>
<PackageReference Include="DalamudPackager" Version="11.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0"/>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0"/>
<PackageReference Include="Vortice.Direct3D11" Version="3.5.0"/>
Expand Down
22 changes: 17 additions & 5 deletions Meddle/Meddle.Plugin/Models/Composer/DataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,16 @@ public MaterialBuilder GetMaterialBuilder(MaterialSet material, string path, str
cancellationToken.ThrowIfCancellationRequested();
return new Lazy<MaterialBuilder>(() =>
{
logger.LogInformation("[{shpkName}] Composing material {path}", shpkName, path);
return material.Compose(this);
try
{
logger.LogInformation("[{shpkName}] Composing material {path}", shpkName, path);
return material.Compose(this);
}
catch (Exception e)
{
logger.LogError(e, "[{shpkName}] Failed to compose material {path}", shpkName, path);
return new MaterialBuilder(path);
}
}, LazyThreadSafetyMode.ExecutionAndPublication);
}).Value;
}
Expand Down Expand Up @@ -137,17 +145,21 @@ public ShpkFile GetShpkFile(string fullPath)

return outPath;
}



public ImageBuilder CacheTexture(SKTexture texture, string texName)
public static string FilterTexName(string texName)
{
texName = texName.TrimHandlePath();
if (Path.IsPathRooted(texName))
{
texName = Path.GetFileName(texName);
}

return texName;
}

public ImageBuilder CacheTexture(SKTexture texture, string texName)
{
texName = FilterTexName(texName);
var outPath = Path.Combine(cacheDir, $"{texName}.png");
SaveTextureToDisk(texture, outPath);

Expand Down
102 changes: 62 additions & 40 deletions Meddle/Meddle.Plugin/Models/Composer/MaterialSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ public int Uid()
hash.Add(key);
hash.Add(value);
}
foreach (var key in ShaderKeys)
foreach (var key in ShaderKeyDict)
{
hash.Add(key.Category);
hash.Add(key.Key);
hash.Add(key.Value);
}
return hash.ToHashCode();
Expand Down Expand Up @@ -86,8 +86,28 @@ public string HashStr()
//private readonly ShaderPackage package;
public readonly string MtrlPath;
public readonly string ShpkName;
public readonly ShaderKey[] ShaderKeys;
public readonly Dictionary<MaterialConstant, float[]> Constants;
public Dictionary<MaterialConstant, float[]> Constants => AllConstants();
public readonly Dictionary<MaterialConstant, float[]> ShpkConstants;
public readonly Dictionary<MaterialConstant, float[]> MtrlConstants;
public readonly Dictionary<ShaderCategory, uint> ShaderKeyDict;
private Dictionary<string, object> AdditionalProperties = new();

public void AddProperty(string key, object value)
{
AdditionalProperties[key] = value;
}

private Dictionary<MaterialConstant, float[]> AllConstants()
{
var all = new Dictionary<MaterialConstant, float[]>(ShpkConstants);
foreach (var (key, value) in MtrlConstants)
{
all[key] = value;
}

return all;
}

public readonly Dictionary<TextureUsage, HandleString> TextureUsageDict;
private readonly Func<HandleString, TextureResource?>? textureLoader;

Expand Down Expand Up @@ -312,31 +332,29 @@ public Vector4 GetConstantOrDefault(MaterialConstant id, Vector4 @default)
: @default;
}

public TValue GetShaderKeyOrDefault<TCategory, TValue>(TCategory category, TValue @default) where TCategory : Enum where TValue : Enum
public uint GetShaderKeyOrDefault(uint category)
{
var cat = Convert.ToUInt32(category);
var value = GetShaderKeyOrDefault(cat, Convert.ToUInt32(@default));
return (TValue)Enum.ToObject(typeof(TValue), value);
return GetShaderKeyOrDefault((ShaderCategory)category);
}

public TValue GetShaderKeyOrDefault<TCategory, TValue>(TCategory category, uint @default) where TCategory : Enum where TValue : Enum
public uint GetShaderKeyOrDefault(ShaderCategory category)
{
var cat = Convert.ToUInt32(category);
var value = GetShaderKeyOrDefault(cat, @default);
return (TValue)Enum.ToObject(typeof(TValue), value);
if (ShaderKeyDict.TryGetValue(category, out var value))
{
return value;
}

throw new InvalidOperationException($"Shader key {category} not found");
}

public uint GetShaderKeyOrDefault(uint category, uint @default)
public TValue GetShaderKeyOrDefault<TValue>(ShaderCategory category) where TValue : Enum
{
foreach (var key in ShaderKeys)
if (ShaderKeyDict.TryGetValue(category, out var value))
{
if (key.Category == category)
{
return key.Value;
}
return (TValue)(object)value;
}

return @default;
throw new InvalidOperationException($"Shader key {category} not found");
}

public MaterialSet(MtrlFile file, string mtrlPath, ShpkFile shpk, string shpkName, HandleString[]? texturePathOverride, Func<HandleString, TextureResource?>? textureLoader)
Expand All @@ -347,8 +365,18 @@ public MaterialSet(MtrlFile file, string mtrlPath, ShpkFile shpk, string shpkNam
shaderFlagData = file.ShaderHeader.Flags;
var package = new ShaderPackage(shpk, shpkName);
colorTable = file.GetColorTable();
ShaderKeys = file.ShaderKeys;
Constants = package.MaterialConstants;
ShpkConstants = package.MaterialConstants;
MtrlConstants = new Dictionary<MaterialConstant, float[]>();
ShaderKeyDict = new Dictionary<ShaderCategory, uint>();
foreach (var (key, value) in package.DefaultKeyValues)
{
ShaderKeyDict[(ShaderCategory)key] = value;
}

foreach (var key in file.ShaderKeys)
{
ShaderKeyDict[(ShaderCategory)key.Category] = key.Value;
}

// override with material constants
foreach (var constant in file.Constants)
Expand All @@ -371,7 +399,7 @@ public MaterialSet(MtrlFile file, string mtrlPath, ShpkFile shpk, string shpkNam
}

// even if duplicate, last probably takes precedence
Constants[id] = MemoryMarshal.Cast<uint, float>(buf.ToArray()).ToArray();
MtrlConstants[id] = MemoryMarshal.Cast<uint, float>(buf.ToArray()).ToArray();
if (logOutOfBounds)
{
Plugin.Logger?.LogWarning("Material constant {id} out of bounds for {mtrlPath}, {indexAndCount} greater than {shaderValuesLength}, [{values}]",
Expand Down Expand Up @@ -410,16 +438,9 @@ public MaterialSet(MtrlFile file, string mtrlPath, ShpkFile shpk, string shpkNam

private MeddleMaterialBuilder GetMaterialBuilder(DataProvider dataProvider)
{
var mtrlName = $"{Path.GetFileNameWithoutExtension(MtrlPath)}_{Path.GetFileNameWithoutExtension(ShpkName)}_{Uid()}";
var mtrlName = $"{Path.GetFileNameWithoutExtension(MtrlPath)}_{Path.GetFileNameWithoutExtension(ShpkName)}_{HashStr()}";
switch (ShpkName)
{
case "bg.shpk":
case "bguvscroll.shpk":
return new BgMaterialBuilder(mtrlName, new BgParams(), this, dataProvider);
case "bgcolorchange.shpk":
return new BgMaterialBuilder(mtrlName, new BgColorChangeParams(stainColor), this, dataProvider);
case "lightshaft.shpk":
return new LightshaftMaterialBuilder(mtrlName, this, dataProvider);
case "character.shpk":
case "characterlegacy.shpk":
return new CharacterMaterialBuilder(mtrlName, this, dataProvider, colorTable, textureMode);
Expand Down Expand Up @@ -476,6 +497,11 @@ public Dictionary<string, object> ComposeExtras()
AddCustomizeData();
AddStainColor();
AddColorTable();

foreach (var (key, value) in AdditionalProperties)
{
extrasDict[key] = value;
}

return extrasDict;

Expand Down Expand Up @@ -532,14 +558,13 @@ string IsDefinedOrHex<TEnum>(TEnum value) where TEnum : Enum

void AddShaderKeys()
{
foreach (var key in ShaderKeys)
foreach (var key in ShaderKeyDict)
{
var category = key.Category;
uint category = (uint)key.Key;
var value = key.Value;
if (Enum.IsDefined(typeof(ShaderCategory), category))
{
var keyCat = (ShaderCategory)category;
var valStr = keyCat switch
var valStr = key.Key switch
{
ShaderCategory.CategoryHairType => IsDefinedOrHex((HairType)value),
ShaderCategory.CategorySkinType => IsDefinedOrHex((SkinType)value),
Expand All @@ -551,7 +576,7 @@ void AddShaderKeys()
_ => $"0x{value:X8}"
};

extrasDict[keyCat.ToString()] = valStr;
extrasDict[key.Key.ToString()] = valStr;
}
else
{
Expand All @@ -567,10 +592,7 @@ void AddSamplers()
{
var usageStr = usage.ToString();
extrasDict[usageStr] = path.GamePath;
if (path.FullPath != path.GamePath)
{
extrasDict[$"{usageStr}_FullPath"] = path.FullPath;
}
extrasDict[$"{usageStr}_FullPath"] = path.FullPath;
}
}

Expand Down
Loading
Loading