Parse GMX files
This commit is contained in:
parent
a448eae546
commit
c73816048b
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -6,10 +6,12 @@ using System.Threading.Tasks;
|
||||
using Switch_Toolbox;
|
||||
using System.Windows.Forms;
|
||||
using Switch_Toolbox.Library;
|
||||
using Switch_Toolbox.Library.IO;
|
||||
using Switch_Toolbox.Library.Rendering;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class GMX : IFileFormat
|
||||
public class GMX : TreeNodeFile, IFileFormat
|
||||
{
|
||||
public FileType FileType { get; set; } = FileType.Model;
|
||||
|
||||
@ -37,9 +39,18 @@ namespace FirstPlugin
|
||||
}
|
||||
}
|
||||
|
||||
public Header GMXHeader;
|
||||
|
||||
public void Load(System.IO.Stream stream)
|
||||
{
|
||||
|
||||
GMXHeader = new Header();
|
||||
GMXHeader.Read(new FileReader(stream));
|
||||
for (int i = 0; i < GMXHeader.Meshes.Count; i++)
|
||||
{
|
||||
var node = new TreeNode($"Mesh ({i})");
|
||||
node.Tag = GMXHeader.Meshes[i];
|
||||
Nodes.Add(node);
|
||||
}
|
||||
}
|
||||
public void Unload()
|
||||
{
|
||||
@ -49,5 +60,235 @@ namespace FirstPlugin
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public class Header
|
||||
{
|
||||
public uint HeaderSize;
|
||||
|
||||
public Header()
|
||||
{
|
||||
HeaderSize = 8;
|
||||
}
|
||||
|
||||
public List<MESH> Meshes = new List<MESH>();
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
reader.ReadSignature(4, "GMX2");
|
||||
reader.SetByteOrder(true);
|
||||
HeaderSize = reader.ReadUInt32();
|
||||
|
||||
while (reader.Position < reader.BaseStream.Length)
|
||||
{
|
||||
long pos = reader.Position;
|
||||
|
||||
string Magic = reader.ReadString(4);
|
||||
uint SectionSize = reader.ReadUInt32();
|
||||
|
||||
Console.WriteLine($"Magic {Magic}");
|
||||
reader.SeekBegin(pos);
|
||||
switch (Magic)
|
||||
{
|
||||
case "PADX":
|
||||
PADX padding = new PADX();
|
||||
padding.Read(reader);
|
||||
break;
|
||||
case "INDX":
|
||||
INDX indexGrp = new INDX();
|
||||
indexGrp.Read(reader);
|
||||
GetLastMesh().IndexGroup = indexGrp;
|
||||
break;
|
||||
case "VMAP":
|
||||
VMAP vmap = new VMAP();
|
||||
vmap.Read(reader);
|
||||
GetLastMesh().VMapGroup = vmap;
|
||||
break;
|
||||
case "MESH":
|
||||
MESH mesh = new MESH();
|
||||
mesh.Read(reader);
|
||||
Meshes.Add(mesh);
|
||||
break;
|
||||
case "VERT":
|
||||
VERT vert = new VERT();
|
||||
vert.Read(reader, GetLastMesh());
|
||||
GetLastMesh().VertexGroup = vert;
|
||||
break;
|
||||
case "ENDX":
|
||||
reader.ReadSignature(4, "ENDX");
|
||||
uint EndSectionSize = reader.ReadUInt32();
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown section! " + Magic);
|
||||
}
|
||||
|
||||
reader.SeekBegin(pos + SectionSize);
|
||||
}
|
||||
}
|
||||
|
||||
public MESH GetLastMesh()
|
||||
{
|
||||
return Meshes[Meshes.Count - 1];
|
||||
}
|
||||
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
writer.WriteSignature("GMX2");
|
||||
writer.Write(HeaderSize);
|
||||
}
|
||||
|
||||
public class VERT
|
||||
{
|
||||
public List<Vertex> Vertices = new List<Vertex>();
|
||||
|
||||
public void Read(FileReader reader, MESH mesh)
|
||||
{
|
||||
reader.ReadSignature(4, "VERT");
|
||||
uint SectionSize = reader.ReadUInt32();
|
||||
|
||||
if (mesh.VertexSize == 32)
|
||||
{
|
||||
for (int v = 0; v < mesh.VertexCount; v++)
|
||||
{
|
||||
Vertex vert = new Vertex();
|
||||
vert.pos = reader.ReadVec3();
|
||||
vert.nrm = reader.ReadVec3();
|
||||
vert.uv0 = reader.ReadVec2();
|
||||
Vertices.Add(vert);
|
||||
}
|
||||
}
|
||||
else if (mesh.VertexSize == 36)
|
||||
{
|
||||
for (int v = 0; v < mesh.VertexCount; v++)
|
||||
{
|
||||
Vertex vert = new Vertex();
|
||||
uint Unknown = reader.ReadUInt32(); //Bone index?
|
||||
vert.pos = reader.ReadVec3();
|
||||
vert.nrm = reader.ReadVec3();
|
||||
vert.uv0 = reader.ReadVec2();
|
||||
Vertices.Add(vert);
|
||||
|
||||
Console.WriteLine($"Unknown {Unknown}");
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}");
|
||||
}
|
||||
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
writer.WriteSignature("VERT");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class MESH
|
||||
{
|
||||
public INDX IndexGroup { get; set; }
|
||||
public VERT VertexGroup { get; set; }
|
||||
public VMAP VMapGroup { get; set; }
|
||||
|
||||
public ushort VertexSize { get; set; }
|
||||
public ushort VertexCount { get; set; }
|
||||
public uint FaceCount { get; set; }
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
reader.ReadSignature(4, "MESH");
|
||||
uint SectionSize = reader.ReadUInt32();
|
||||
uint Padding = reader.ReadUInt32();
|
||||
VertexSize = reader.ReadUInt16();
|
||||
VertexCount = reader.ReadUInt16();
|
||||
uint Padding2 = reader.ReadUInt32();
|
||||
FaceCount = reader.ReadUInt32();
|
||||
uint Padding3 = reader.ReadUInt32();
|
||||
uint Padding4 = reader.ReadUInt32();
|
||||
uint Padding5 = reader.ReadUInt32();
|
||||
uint Padding6 = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
writer.WriteSignature("MESH");
|
||||
writer.Write(0);
|
||||
writer.Write(VertexSize);
|
||||
writer.Write(VertexCount);
|
||||
writer.Write(0);
|
||||
writer.Write(FaceCount);
|
||||
writer.Write(0);
|
||||
writer.Write(0);
|
||||
writer.Write(0);
|
||||
writer.Write(0);
|
||||
}
|
||||
}
|
||||
|
||||
public class INDX
|
||||
{
|
||||
public ushort[] Indices;
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
reader.ReadSignature(4, "INDX");
|
||||
uint SectionSize = reader.ReadUInt32();
|
||||
uint FaceCount = (SectionSize - 8) / sizeof(ushort);
|
||||
|
||||
Indices = new ushort[FaceCount];
|
||||
for (int i = 0; i < FaceCount; i++)
|
||||
{
|
||||
Indices[i] = reader.ReadUInt16();
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
writer.WriteSignature("INDX");
|
||||
writer.Write(Indices.Length * sizeof(ushort) - 8);
|
||||
for (int i = 0; i < Indices.Length; i++)
|
||||
writer.Write(Indices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public class VMAP
|
||||
{
|
||||
public ushort[] Indices;
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
reader.ReadSignature(4, "VMAP");
|
||||
uint SectionSize = reader.ReadUInt32();
|
||||
uint FaceCount = (SectionSize - 8) / sizeof(ushort);
|
||||
|
||||
Indices = new ushort[FaceCount];
|
||||
for (int i = 0; i < FaceCount; i++)
|
||||
{
|
||||
Indices[i] = reader.ReadUInt16();
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
writer.WriteSignature("VMAP");
|
||||
writer.Write(Indices.Length * sizeof(ushort) - 8);
|
||||
for (int i = 0; i < Indices.Length; i++)
|
||||
writer.Write(Indices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public class PADX
|
||||
{
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
reader.ReadSignature(4, "PADX");
|
||||
uint SectionSize = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
public void Write(FileWriter writer, uint Alignment)
|
||||
{
|
||||
writer.WriteSignature("PADX");
|
||||
writer.Write(Alignment - 8);
|
||||
for (int i = 0; i < Alignment; i++)
|
||||
writer.Write(byte.MaxValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,6 +336,8 @@ namespace FirstPlugin
|
||||
Formats.Add(typeof(RARC));
|
||||
Formats.Add(typeof(ME01));
|
||||
Formats.Add(typeof(LM2_DICT));
|
||||
Formats.Add(typeof(GMX));
|
||||
|
||||
//Formats.Add(typeof(GFA));
|
||||
|
||||
//Unfinished wip formats not ready for use
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user