Switch-Toolbox/Switch_FileFormatsMain/XML/BfresMaterial2XML.cs

456 lines
20 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Syroot.NintenTools.NSW.Bfres;
using System.IO;
using Bfres.Structs;
namespace FirstPlugin
{
public class FMAT2XML
{
public static void Read(FMAT mat, string FileName, bool OnlyMatParams = false)
{
XmlDocument doc = new XmlDocument();
doc.Load(FileName);
foreach (XmlNode node in doc.ChildNodes)
{
foreach (XmlNode n in node.ChildNodes)
{
if (n.Name == "MaterialParameters")
{
ReadShaderParams(doc, n, mat);
}
}
}
}
public static void ReadTextureRefs(XmlDocument doc, XmlNode parentNode, FMAT mat)
{
}
private static void WriteTextureRefs(FMAT mat, XmlDocument doc, XmlNode parentNode)
{
XmlNode matParamsNode = doc.CreateElement("TextureRefs");
parentNode.AppendChild(matParamsNode);
}
#region Read ShaderParams
public static void ReadShaderParams(XmlDocument doc, XmlNode parentNode, FMAT mat)
{
mat.matparam.Clear();
int Index = 0;
foreach (XmlNode node in parentNode.ChildNodes)
{
string Value = node.Attributes[0].Value;
BfresShaderParam param = new BfresShaderParam();
param.Name = node.Name;
param.DependedIndex = (ushort)Index;
param.DependIndex = (ushort)Index;
ushort DependedIndex = 0;
ushort DependIndex = 0;
Index++;
foreach (XmlAttribute att in node.Attributes)
{
Console.WriteLine(att);
if (att.Name == "DependedIndex")
{
string DependedIndexStr = att.Value;
if (ushort.TryParse(DependedIndexStr, out DependedIndex))
{
param.DependedIndex = DependedIndex;
}
}
if (att.Name == "DependIndex")
{
string DependIndexStr = att.Value;
if (ushort.TryParse(DependIndexStr, out DependIndex))
{
param.DependIndex = DependIndex;
}
}
if (att.Name == "Format")
{
string Format = att.Value;
ShaderParamType type;
if (Enum.TryParse(Format, out type))
{
param.Type = type;
switch (type)
{
case ShaderParamType.Bool:
case ShaderParamType.Bool2:
case ShaderParamType.Bool3:
case ShaderParamType.Bool4:
param.ValueBool = Array.ConvertAll(Value.Split(','), bool.Parse);
break;
case ShaderParamType.Float:
case ShaderParamType.Float2:
case ShaderParamType.Float3:
case ShaderParamType.Float4:
case ShaderParamType.Float2x2:
case ShaderParamType.Float2x3:
case ShaderParamType.Float2x4:
case ShaderParamType.Float3x2:
case ShaderParamType.Float3x3:
case ShaderParamType.Float3x4:
case ShaderParamType.Float4x2:
case ShaderParamType.Float4x3:
case ShaderParamType.Float4x4:
param.ValueFloat = Array.ConvertAll(Value.Split(','), float.Parse);
break;
case ShaderParamType.Int:
case ShaderParamType.Int2:
case ShaderParamType.Int3:
case ShaderParamType.Int4:
param.ValueInt = Array.ConvertAll(Value.Split(','), int.Parse);
break;
case ShaderParamType.Reserved2:
case ShaderParamType.Reserved3:
case ShaderParamType.Reserved4:
param.ValueReserved = Array.ConvertAll(Value.Split(','), byte.Parse);
break;
case ShaderParamType.Srt2D:
param.ValueSrt2D = SetSrt2D(node);
break;
case ShaderParamType.Srt3D:
param.ValueSrt3D = SetSrt3D(node);
break;
case ShaderParamType.TexSrt:
param.ValueTexSrt = SetTexSRT(node);
break;
case ShaderParamType.TexSrtEx:
param.ValueTexSrtEx = SetTexSRTEx(node);
break;
case ShaderParamType.UInt:
case ShaderParamType.UInt2:
case ShaderParamType.UInt3:
case ShaderParamType.UInt4:
param.ValueUint = Array.ConvertAll(Value.Split(','), uint.Parse);
break;
}
}
}
}
mat.matparam.Add(param.Name, param);
}
}
static float X, Y, Z;
public static Srt2D SetSrt2D(XmlNode node)
{
Srt2D srt2D = new Srt2D();
foreach (XmlAttribute att in node.Attributes)
{
if (att.Name == "Scaling")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
float.TryParse(values[1], out Y);
srt2D.Scaling = new Syroot.Maths.Vector2F(X, Y);
}
if (att.Name == "Rotation")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
srt2D.Rotation = X;
}
if (att.Name == "Translation")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
float.TryParse(values[1], out Y);
srt2D.Translation = new Syroot.Maths.Vector2F(X, Y);
}
}
return srt2D;
}
public static Srt3D SetSrt3D(XmlNode node)
{
Srt3D srt3D = new Srt3D();
foreach (XmlAttribute att in node.Attributes)
{
if (att.Name == "Scaling")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
float.TryParse(values[1], out Y);
float.TryParse(values[2], out Z);
srt3D.Scaling = new Syroot.Maths.Vector3F(X, Y, Z);
}
if (att.Name == "Rotation")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
float.TryParse(values[1], out Y);
float.TryParse(values[2], out Z);
srt3D.Rotation = new Syroot.Maths.Vector3F(X, Y, Z);
}
if (att.Name == "Translation")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
float.TryParse(values[1], out Y);
float.TryParse(values[2], out Z);
srt3D.Translation = new Syroot.Maths.Vector3F(X, Y, Z);
}
}
return srt3D;
}
public static TexSrt SetTexSRT(XmlNode node)
{
TexSrt texSrt = new TexSrt();
foreach (XmlAttribute att in node.Attributes)
{
if (att.Name == "Mode")
{
TexSrtMode Mode;
Enum.TryParse(att.Value, out Mode);
texSrt.Mode = Mode;
}
if (att.Name == "Scaling")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
float.TryParse(values[1], out Y);
texSrt.Scaling = new Syroot.Maths.Vector2F(X, Y);
}
if (att.Name == "Rotation")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
texSrt.Rotation = X;
}
if (att.Name == "Translation")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
float.TryParse(values[1], out Y);
texSrt.Translation = new Syroot.Maths.Vector2F(X, Y);
}
}
return texSrt;
}
public static string[] GetSrtValues(string str)
{
string[] charsToRemove = new string[] { "X", "Y", "Z", "W", "{", "}", "=" };
foreach (var c in charsToRemove)
{
str = str.Replace(c, string.Empty);
}
return str.Split(',');
}
public static TexSrtEx SetTexSRTEx(XmlNode node)
{
TexSrtEx texSrtEx = new TexSrtEx();
foreach (XmlAttribute att in node.Attributes)
{
if (att.Name == "Mode")
{
TexSrtMode Mode;
Enum.TryParse(att.Value, out Mode);
texSrtEx.Mode = Mode;
}
if (att.Name == "Scaling")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
float.TryParse(values[1], out Y);
texSrtEx.Scaling = new Syroot.Maths.Vector2F(X, Y);
}
if (att.Name == "Rotation")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
texSrtEx.Rotation = X;
}
if (att.Name == "Translation")
{
string[] values = GetSrtValues(att.Value);
float.TryParse(values[0], out X);
float.TryParse(values[1], out Y);
texSrtEx.Translation = new Syroot.Maths.Vector2F(X, Y);
}
if (att.Name == "MatrixPointer")
{
uint ptr;
uint.TryParse(att.Value, out ptr);
texSrtEx.MatrixPointer = ptr;
}
}
return texSrtEx;
}
#endregion
public static void Save(FMAT mat, string FileName, bool OnlyMaterialParams = false)
{
XmlDocument doc = new XmlDocument();
XmlNode mainNode = doc.CreateElement("FMAT");
AddAttribute(doc, "Name", mat.Text, mainNode);
doc.AppendChild(mainNode);
if (OnlyMaterialParams)
{
AppendMaterialParams(mat, doc, mainNode);
}
else
{
AppendMaterialParams(mat, doc, mainNode);
}
doc.Save(FileName);
}
private static void AppendMaterialParams(FMAT mat, XmlDocument doc, XmlNode parentNode)
{
XmlNode matParamsNode = doc.CreateElement("MaterialParameters");
parentNode.AppendChild(matParamsNode);
bool IsSrt = false;
foreach (var param in mat.matparam)
{
string Value = "";
switch (param.Value.Type)
{
case ShaderParamType.Bool:
case ShaderParamType.Bool2:
case ShaderParamType.Bool3:
case ShaderParamType.Bool4:
Value = string.Join(",", param.Value.ValueBool);
break;
case ShaderParamType.Float:
case ShaderParamType.Float2:
case ShaderParamType.Float3:
case ShaderParamType.Float4:
case ShaderParamType.Float2x2:
case ShaderParamType.Float2x3:
case ShaderParamType.Float2x4:
case ShaderParamType.Float3x2:
case ShaderParamType.Float3x3:
case ShaderParamType.Float3x4:
case ShaderParamType.Float4x2:
case ShaderParamType.Float4x3:
case ShaderParamType.Float4x4:
Value = string.Join(",", param.Value.ValueFloat);
break;
case ShaderParamType.Int:
case ShaderParamType.Int2:
case ShaderParamType.Int3:
case ShaderParamType.Int4:
Value = string.Join(",", param.Value.ValueInt);
break;
case ShaderParamType.Reserved2:
case ShaderParamType.Reserved3:
case ShaderParamType.Reserved4:
Value = string.Join(",", param.Value.ValueReserved);
break;
case ShaderParamType.Srt2D:
WriteSrt2DParamNode(doc, param.Value, matParamsNode);
IsSrt = true;
break;
case ShaderParamType.Srt3D:
WriteSrt3DParamNode(doc, param.Value, matParamsNode);
IsSrt = true;
break;
case ShaderParamType.TexSrt:
WriteTexSrtParamNode(doc, param.Value, matParamsNode);
IsSrt = true;
break;
case ShaderParamType.TexSrtEx:
WriteTexSrtExParamNode(doc, param.Value, matParamsNode);
IsSrt = true;
break;
case ShaderParamType.UInt:
case ShaderParamType.UInt2:
case ShaderParamType.UInt3:
case ShaderParamType.UInt4:
Value = string.Join(",", param.Value.ValueUint);
break;
}
if (!IsSrt)
{
XmlNode ParamNode = doc.CreateElement(param.Key);
AddAttribute(doc, "Value", Value, ParamNode);
AddAttribute(doc, "Format", param.Value.Type.ToString(), ParamNode);
AddAttribute(doc, "DependedIndex", param.Value.DependedIndex.ToString(), ParamNode);
AddAttribute(doc, "DependIndex", param.Value.DependIndex.ToString(), ParamNode);
matParamsNode.AppendChild(ParamNode);
}
}
}
private static void WriteSrt2DParamNode(XmlDocument doc,BfresShaderParam param, XmlNode node)
{
XmlNode ParamNode = doc.CreateElement(param.Name);
AddAttribute(doc, "Scaling", param.ValueSrt2D.Scaling.ToString(), ParamNode);
AddAttribute(doc, "Rotation", param.ValueSrt2D.Rotation.ToString(), ParamNode);
AddAttribute(doc, "Translation", param.ValueSrt2D.Translation.ToString(), ParamNode);
AddAttribute(doc, "Format", ShaderParamType.Srt2D.ToString(), ParamNode);
AddAttribute(doc, "DependedIndex", param.DependedIndex.ToString(), ParamNode);
AddAttribute(doc, "DependIndex", param.DependIndex.ToString(), ParamNode);
node.AppendChild(ParamNode);
}
private static void WriteSrt3DParamNode(XmlDocument doc, BfresShaderParam param, XmlNode node)
{
XmlNode ParamNode = doc.CreateElement(param.Name);
AddAttribute(doc, "Scaling", param.ValueSrt3D.Scaling.ToString(), ParamNode);
AddAttribute(doc, "Rotation", param.ValueSrt3D.Rotation.ToString(), ParamNode);
AddAttribute(doc, "Translation", param.ValueSrt3D.Translation.ToString(), ParamNode);
AddAttribute(doc, "Format", ShaderParamType.Srt3D.ToString(), ParamNode);
AddAttribute(doc, "DependedIndex", param.DependedIndex.ToString(), ParamNode);
AddAttribute(doc, "DependIndex", param.DependIndex.ToString(), ParamNode);
node.AppendChild(ParamNode);
}
private static void WriteTexSrtParamNode(XmlDocument doc, BfresShaderParam param, XmlNode node)
{
XmlNode ParamNode = doc.CreateElement(param.Name);
AddAttribute(doc, "Mode", param.ValueTexSrt.Mode.ToString(), ParamNode);
AddAttribute(doc, "Scaling", param.ValueTexSrt.Scaling.ToString(), ParamNode);
AddAttribute(doc, "Rotation", param.ValueTexSrt.Rotation.ToString(), ParamNode);
AddAttribute(doc, "Translation", param.ValueTexSrt.Translation.ToString(), ParamNode);
AddAttribute(doc, "Format", ShaderParamType.TexSrt.ToString(), ParamNode);
AddAttribute(doc, "DependedIndex", param.DependedIndex.ToString(), ParamNode);
AddAttribute(doc, "DependIndex", param.DependIndex.ToString(), ParamNode);
node.AppendChild(ParamNode);
}
private static void WriteTexSrtExParamNode(XmlDocument doc, BfresShaderParam param, XmlNode node)
{
XmlNode ParamNode = doc.CreateElement(param.Name);
AddAttribute(doc, "Mode", param.ValueTexSrtEx.Mode.ToString(), ParamNode);
AddAttribute(doc, "Scaling", param.ValueTexSrtEx.Scaling.ToString(), ParamNode);
AddAttribute(doc, "Rotation", param.ValueTexSrtEx.Rotation.ToString(), ParamNode);
AddAttribute(doc, "Translation", param.ValueTexSrtEx.Translation.ToString(), ParamNode);
AddAttribute(doc, "MatrixPointer", param.ValueTexSrtEx.MatrixPointer.ToString(), ParamNode);
AddAttribute(doc, "Format", ShaderParamType.TexSrtEx.ToString(), ParamNode);
AddAttribute(doc, "DependedIndex", param.DependedIndex.ToString(), ParamNode);
AddAttribute(doc, "DependIndex", param.DependIndex.ToString(), ParamNode);
node.AppendChild(ParamNode);
}
private static void AddAttribute(XmlDocument doc, string name, string value, XmlNode node)
{
XmlAttribute att = doc.CreateAttribute(name);
att.Value = value;
node.Attributes.Append(att);
}
}
}