457 lines
20 KiB
C#
457 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);
|
|
}
|
|
}
|
|
}
|