A few additions

Update primative type for meshes. This will allow custom primative types for rendering.
Add strikers and punch out wii model/texture support (older formats of LM2/LM3).
Add LM2 Arcade model support (updated format of MKAGPDX)
Add support for LM2/LM3 pck audio archives.
Add support for LM2 message/localization data.
This commit is contained in:
KillzXGaming 2019-11-10 08:41:17 -05:00
parent 622011d025
commit c78251aab3
34 changed files with 4263 additions and 45 deletions

View file

@ -149,7 +149,7 @@ namespace FirstPlugin
{
foreach (var buffer in faceDescriptors.Buffers)
{
msh.PrimitiveType = STPolygonType.Triangle;
msh.PrimativeType = STPrimativeType.Triangles;
msh.FirstVertex = 0;
uint[] indicesArray = buffer.GetIndices().ToArray();

View file

@ -132,7 +132,7 @@ namespace FirstPlugin
Mesh msh = new Mesh();
msh.MemoryPool = new MemoryPool();
msh.SubMeshes = new List<SubMesh>();
msh.PrimitiveType = (PrimitiveType)mesh.PrimitiveType;
msh.PrimitiveType = (PrimitiveType)mesh.PrimativeType;
msh.FirstVertex = mesh.FirstVertex;
foreach (FSHP.LOD_Mesh.SubMesh sub in mesh.subMeshes)
@ -210,7 +210,7 @@ namespace FirstPlugin
lod.subMeshes.Add(sub);
}
lod.IndexFormat = (STIndexFormat)msh.IndexFormat;
lod.PrimitiveType = (STPolygonType)msh.PrimitiveType;
lod.PrimativeType = (STPrimativeType)msh.PrimitiveType;
lod.FirstVertex = msh.FirstVertex;
for (int face = 0; face < FaceCount; face++)

View file

@ -161,7 +161,7 @@ namespace FirstPlugin
lod.subMeshes.Add(sub);
}
lod.IndexFormat = (STIndexFormat)msh.IndexFormat;
lod.PrimitiveType = (STPolygonType)msh.PrimitiveType;
lod.PrimativeType = (STPrimativeType)msh.PrimitiveType;
lod.FirstVertex = msh.FirstVertex;
for (int face = 0; face < FaceCount; face++)
@ -390,18 +390,18 @@ namespace FirstPlugin
int indx = 0;
foreach (var mesh in shp.Meshes)
{
switch (s.lodMeshes[indx].PrimitiveType)
switch (s.lodMeshes[indx].PrimativeType)
{
case STPolygonType.Triangle:
case STPrimativeType.Triangles:
mesh.PrimitiveType = GX2PrimitiveType.Triangles;
break;
case STPolygonType.Line:
case STPrimativeType.Lines:
mesh.PrimitiveType = GX2PrimitiveType.Lines;
break;
case STPolygonType.LineStrip:
case STPrimativeType.LineStrips:
mesh.PrimitiveType = GX2PrimitiveType.LineStrip;
break;
case STPolygonType.Point:
case STPrimativeType.Points:
mesh.PrimitiveType = GX2PrimitiveType.Points;
break;
}
@ -872,7 +872,7 @@ namespace FirstPlugin
{
Mesh msh = new Mesh();
msh.SubMeshes = new List<SubMesh>();
msh.PrimitiveType = (GX2PrimitiveType)mesh.PrimitiveType;
msh.PrimitiveType = (GX2PrimitiveType)mesh.PrimativeType;
msh.FirstVertex = mesh.FirstVertex;
foreach (FSHP.LOD_Mesh.SubMesh sub in mesh.subMeshes)

View file

@ -104,7 +104,7 @@ namespace FirstPlugin
STobj.ObjectName = model.Name;
lod = new STGenericObject.LOD_Mesh();
lod.IndexFormat = STIndexFormat.UInt16;
lod.PrimitiveType = STPolygonType.Triangle;
lod.PrimativeType = STPrimativeType.Triangles;
STobj.lodMeshes.Add(lod);
STobj.VertexBufferIndex = Index;
objects.Add(STobj);

View file

@ -142,7 +142,7 @@ namespace FirstPlugin
{
renderedMesh.lodMeshes = new List<STGenericObject.LOD_Mesh>();
var msh = new STGenericObject.LOD_Mesh();
msh.PrimitiveType = STPolygonType.Triangle;
msh.PrimativeType = STPrimativeType.Triangles;
msh.FirstVertex = 0;
/* int VertexID = 0;

View file

@ -709,7 +709,7 @@ namespace FirstPlugin
case CmbDataType.UShort:
values.Add(reader.ReadUInt16());
break;
default: throw new Exception("Unknwon format! " + VertexAttribute.Type);
default: throw new Exception("Unknown format! " + VertexAttribute.Type);
}
}
@ -1157,13 +1157,15 @@ namespace FirstPlugin
public long StartPosition;
public uint MaxIndex;
public void Read(FileReader reader, Header header)
{
StartPosition = reader.Position;
reader.ReadSignature(4, Magic);
uint sectionSize = reader.ReadUInt32();
uint maxIndex = reader.ReadUInt32();
MaxIndex = reader.ReadUInt32();
PositionSlice = ReadSlice(reader);
NormalSlice = ReadSlice(reader);
@ -1180,8 +1182,32 @@ namespace FirstPlugin
public void Write(FileWriter writer, Header header)
{
long pos = writer.Position;
writer.WriteSignature(Magic);
writer.Write(uint.MaxValue);//SectionSize
writer.Write(MaxIndex);
WriteSlice(writer, PositionSlice);
WriteSlice(writer, NormalSlice);
if (header.Version >= CMBVersion.MM3DS)
WriteSlice(writer, TangentSlice);
WriteSlice(writer, ColorSlice);
WriteSlice(writer, Texcoord0Slice);
WriteSlice(writer, Texcoord1Slice);
WriteSlice(writer, Texcoord2Slice);
WriteSlice(writer, BoneIndicesSlice);
WriteSlice(writer, BoneWeightsSlice);
long endPos = writer.Position;
using (writer.TemporarySeek(pos + 4, System.IO.SeekOrigin.Begin)) {
writer.Write((uint)(endPos - pos));
}
}
private void WriteSlice(FileWriter writer, BufferSlice slice) {
writer.Write(slice.Size);
writer.Write(slice.Offset);
}
private BufferSlice ReadSlice(FileReader reader)
@ -1313,8 +1339,18 @@ namespace FirstPlugin
public void Write(FileWriter writer, Header header)
{
long pos = writer.Position;
writer.WriteSignature(Magic);
writer.Write(uint.MaxValue);//SectionSize
for (int i = 0; i < Materials.Count; i++)
Materials[i].Write(writer, header);
long endPos = writer.Position;
using (writer.TemporarySeek(pos + 4, System.IO.SeekOrigin.Begin)) {
writer.Write((uint)(endPos - pos));
}
}
}
@ -1525,6 +1561,39 @@ namespace FirstPlugin
Console.WriteLine(ToString());
}
public void Write(FileWriter writer, Header header)
{
long pos = writer.Position;
writer.Write(CullMode, true);
writer.Write(IsPolygonOffsetEnabled);
writer.Write(PolygonOffset);
writer.SeekBegin(pos + 0x10);
for (int j = 0; j < 3; j++)
{
writer.Write(TextureMaps[j].TextureIndex);
writer.Write((ushort)0);
writer.Write((ushort)TextureMaps[j].MinFiler);
writer.Write((ushort)TextureMaps[j].MagFiler);
writer.Write((ushort)TextureMaps[j].WrapS);
writer.Write((ushort)TextureMaps[j].WrapT);
writer.Write((ushort)TextureMaps[j].LodBias);
writer.Write(TextureMaps[j].borderColorR);
writer.Write(TextureMaps[j].borderColorG);
writer.Write(TextureMaps[j].borderColorB);
writer.Write(TextureMaps[j].borderColorA);
}
for (int j = 0; j < 3; j++)
{
writer.Write(TextureMaticies[j].Flags);
writer.Write(TextureMaticies[j].Scale);
writer.Write(TextureMaticies[j].Translate);
writer.Write(TextureMaticies[j].Rotate);
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();

View file

@ -0,0 +1,806 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Threading.Tasks;
using Toolbox;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Forms;
using Toolbox.Library.Rendering;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using GL_EditorFramework.Interfaces;
using GL_EditorFramework.GL_Core;
namespace FirstPlugin
{
public class LM2_ARCADE_Model : TreeNodeFile, IFileFormat
{
public FileType FileType { get; set; } = FileType.Model;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Luigi's Masion 2 Arcase Model" };
public string[] Extension { get; set; } = new string[] { "*.bin", "*.mot" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
using (var reader = new Toolbox.Library.IO.FileReader(stream, true))
{
return reader.CheckSignature(4, "VM61");
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
// types.Add(typeof(MenuExt));
return types.ToArray();
}
}
class MenuExt : IFileMenuExtension
{
public STToolStripItem[] NewFileMenuExtensions => null;
public STToolStripItem[] NewFromFileMenuExtensions => null;
public STToolStripItem[] ToolsMenuExtensions => toolExt;
public STToolStripItem[] TitleBarExtensions => null;
public STToolStripItem[] CompressionMenuExtensions => null;
public STToolStripItem[] ExperimentalMenuExtensions => null;
public STToolStripItem[] EditMenuExtensions => null;
public ToolStripButton[] IconButtonMenuExtensions => null;
STToolStripItem[] toolExt = new STToolStripItem[1];
public MenuExt()
{
toolExt[0] = new STToolStripItem("Models");
toolExt[0].DropDownItems.Add(new STToolStripItem("Batch Export (LM2A .bin)", BatchExport));
toolExt[0].DropDownItems.Add(new STToolStripItem("Batch Export as Combined (LM2A .bin)", BatchExportCombined));
}
public void BatchExportCombined(object sender, EventArgs args)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = true;
ofd.Filter = "Supported Formats|*.bin";
if (ofd.ShowDialog() != DialogResult.OK) return;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Supported Formats|*.dae";
if (sfd.ShowDialog() == DialogResult.OK)
{
List<STGenericObject> Objects = new List<STGenericObject>();
STSkeleton Skeleton = new STSkeleton();
List<STGenericMaterial> Materials = new List<STGenericMaterial>();
int MatIndex = 0;
foreach (var file in ofd.FileNames)
{
LM2_ARCADE_Model model = new LM2_ARCADE_Model();
var stream = File.Open(file, FileMode.Open);
model.Load(stream);
stream.Dispose();
foreach (STGenericMaterial mat in model.Nodes[0].Nodes)
{
mat.Text = $"Material {MatIndex++}";
Materials.Add(mat);
}
Skeleton.bones.AddRange(((STSkeleton)model.DrawableContainer.Drawables[0]).bones);
Objects.AddRange(((GenericModelRenderer)model.DrawableContainer.Drawables[1]).Meshes);
model.Unload();
}
AssimpSaver assimp = new AssimpSaver();
ExportModelSettings settings = new ExportModelSettings();
assimp.SaveFromModel(Objects, Materials, sfd.FileName, new List<STGenericTexture>(), Skeleton);
}
}
public void BatchExport(object sender, EventArgs args)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = true;
ofd.Filter = "Supported Formats|*.bin";
if (ofd.ShowDialog() != DialogResult.OK) return;
FolderSelectDialog folderDlg = new FolderSelectDialog();
if (folderDlg.ShowDialog() == DialogResult.OK)
{
foreach (var file in ofd.FileNames)
{
LM2_ARCADE_Model model = new LM2_ARCADE_Model();
var stream = File.Open(file, FileMode.Open);
model.Load(stream);
stream.Dispose();
string Path = System.IO.Path.Combine(folderDlg.SelectedPath,
System.IO.Path.GetFileNameWithoutExtension(file) + ".dae");
model.ExportModel(Path);
model.Unload();
}
}
}
}
Header header;
public DrawableContainer DrawableContainer = new DrawableContainer();
public void Load(System.IO.Stream stream)
{
DrawableContainer.Name = FileName;
Text = FileName;
header = new Header();
header.Read(new FileReader(stream), this);
ContextMenuStrip = new STContextMenuStrip();
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export Model", null, ExportModelAction, Keys.Control | Keys.E));
}
private void ExportModelAction(object sender, EventArgs args) {
ExportModel();
}
private void ExportModel()
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Supported Formats|*.dae;";
if (sfd.ShowDialog() == DialogResult.OK)
{
ExportModel(sfd.FileName);
}
}
private void ExportModel(string FileName)
{
AssimpSaver assimp = new AssimpSaver();
ExportModelSettings settings = new ExportModelSettings();
List<STGenericMaterial> Materials = new List<STGenericMaterial>();
foreach (STGenericMaterial mat in Nodes[0].Nodes)
Materials.Add(mat);
var model = new STGenericModel();
model.Materials = Materials;
model.Objects = ((GenericModelRenderer)DrawableContainer.Drawables[1]).Meshes;
assimp.SaveFromModel(model, FileName, new List<STGenericTexture>(), ((STSkeleton)DrawableContainer.Drawables[0]));
}
public void Unload()
{
foreach (var mesh in ((GenericModelRenderer)DrawableContainer.Drawables[1]).Meshes)
{
mesh.vertices.Clear();
mesh.faces.Clear();
mesh.display = new int[0];
}
((GenericModelRenderer)DrawableContainer.Drawables[1]).Meshes.Clear();
DrawableContainer.Drawables.Clear();
DrawableContainer = null;
header.Materials.Clear();
header.TextureMaps.Clear();
header.TotalNodes.Clear();
header.BoneList.Clear();
header.LinkNodes.Clear();
Nodes.Clear();
header = null;
}
public void Save(System.IO.Stream stream)
{
}
Viewport viewport
{
get
{
var editor = LibraryGUI.GetObjectEditor();
return editor.GetViewport();
}
set
{
var editor = LibraryGUI.GetObjectEditor();
editor.LoadViewport(value);
}
}
bool DrawablesLoaded = false;
public override void OnClick(TreeView treeView)
{
if (Runtime.UseOpenGL)
{
if (viewport == null)
{
viewport = new Viewport(ObjectEditor.GetDrawableContainers());
viewport.Dock = DockStyle.Fill;
}
if (!DrawablesLoaded)
{
ObjectEditor.AddContainer(DrawableContainer);
DrawablesLoaded = true;
}
viewport.ReloadDrawables(DrawableContainer);
LibraryGUI.LoadEditor(viewport);
viewport.Text = Text;
}
}
public class Header
{
public uint Version { get; set; }
public uint Alignment { get; set; }
public ulong HeaderSize { get; set; }
public List<Material> Materials = new List<Material>();
public List<string> TextureMaps = new List<string>();
public List<Node> BoneList = new List<Node>();
public List<Tuple<Node, Node>> LinkNodes = new List<Tuple<Node, Node>>(); //Links two nodes. Possbily a mesh to bones for example
public List<Node> TotalNodes = new List<Node>();
public STSkeleton Skeleton { get; set; }
GenericModelRenderer DrawableRenderer { get; set; }
public void Read(FileReader reader, LM2_ARCADE_Model root)
{
Skeleton = new STSkeleton();
DrawableRenderer = new GenericModelRenderer();
root.DrawableContainer.Drawables.Add(Skeleton);
root.DrawableContainer.Drawables.Add(DrawableRenderer);
reader.ReadSignature(4, "VM61");
ushort Type = reader.ReadUInt16();
ushort Unknown = reader.ReadUInt16();
if (Type == 0)
{
}
else if ((Type == 1))
{
throw new Exception("Animation files not supported yet!");
}
else
{
throw new Exception("Unknown type found! " + Type);
}
Alignment = reader.ReadUInt32();
uint Padding = reader.ReadUInt32();
ulong MaterialCount = reader.ReadUInt64();
HeaderSize = reader.ReadUInt64();
ulong TextureMapsCount = reader.ReadUInt64();
ulong TextureMapsOffset = reader.ReadUInt64();
ulong BoneCount = reader.ReadUInt64();
ulong BoneOffset = reader.ReadUInt64();
ulong FirstNodeOffset = reader.ReadUInt64(); //Either an offset or the total size of section up to the node
ulong LinkNodeCount = reader.ReadUInt64();
ulong LinkNodeOffset = reader.ReadUInt64();
ulong TotalNodeCount = reader.ReadUInt64();
ulong TotalNodeOffset = reader.ReadUInt64();
ulong Padding2 = reader.ReadUInt64();
root.Nodes.Add("Materials");
root.Nodes.Add("Root");
root.Nodes.Add("All Nodes");
long pos = reader.Position;
if (TextureMapsOffset != 0)
{
reader.SeekBegin(TextureMapsOffset);
for (int i = 0; i < (int)TextureMapsCount; i++)
{
TextureMaps.Add(reader.ReadNameOffset(false, typeof(ulong)));
}
}
reader.SeekBegin(pos);
for (int i = 0; i < (int)MaterialCount; i++)
{
Material mat = new Material();
mat.Read(reader);
Materials.Add(mat);
var genericMat = new STGenericMaterial();
genericMat.Text = mat.Name;
for (int t = 0; t < mat.TextureIndices.Length; t++)
{
if(mat.TextureIndices[t] != -1)
{
Console.WriteLine("TextureIndices " + mat.TextureIndices[t]);
string Texture = TextureMaps[mat.TextureIndices[t]];
var textureMap = new STGenericMatTexture();
textureMap.Name = Texture;
genericMat.TextureMaps.Add(textureMap);
if (Texture.EndsWith("col.dds"))
textureMap.Type = STGenericMatTexture.TextureType.Diffuse;
if (Texture.EndsWith("col.mot"))
textureMap.Type = STGenericMatTexture.TextureType.Diffuse;
}
}
root.Nodes[0].Nodes.Add(genericMat);
}
if (TotalNodeCount != 0)
{
for (int i = 0; i < (int)TotalNodeCount; i++)
{
reader.SeekBegin((int)TotalNodeOffset + (i * 16));
string NodeName = reader.ReadNameOffset(false, typeof(ulong));
var Offset = reader.ReadUInt64();
Console.WriteLine($"{NodeName}");
if (Offset != 0)
{
reader.SeekBegin(Offset);
Node node = new Node();
node.Name = NodeName;
node.Read(reader);
TotalNodes.Add(node);
}
}
}
if (BoneCount != 0)
{
for (int i = 0; i < (int)BoneCount; i++)
{
reader.SeekBegin((int)BoneOffset + (i * 16));
string NodeName = reader.ReadNameOffset(false, typeof(ulong));
ulong Offset = reader.ReadUInt64();
if (Offset != 0)
{
reader.SeekBegin(Offset);
Node node = new Node();
node.Name = NodeName;
node.Read(reader);
BoneList.Add(node); //This list is for mapping to meshes
}
}
}
foreach (var node in TotalNodes)
{
// TreeNode lowerWrapper = new TreeNode($"{node.Name}");
// root.Nodes[3].Nodes.Add(lowerWrapper);
LoadChildern(TotalNodes, node, root.Nodes[2]);
}
if (FirstNodeOffset != 0)
{
reader.SeekBegin(FirstNodeOffset);
ulong NodeOffset = reader.ReadUInt64();
reader.SeekBegin(NodeOffset);
Node node = new Node();
node.Name = GetNodeName(TotalNodes, node);
node.Read(reader);
LoadBones(TotalNodes, node, root.Nodes[1]);
}
if (LinkNodeCount != 0)
{
root.Nodes.Add("Links");
for (int i = 0; i < (int)LinkNodeCount; i++)
{
TreeNode linkWrapper = new TreeNode($"Link {i}");
root.Nodes[3].Nodes.Add(linkWrapper);
reader.SeekBegin((int)LinkNodeOffset + (i * 16));
ulong NodeOffset1 = reader.ReadUInt64();
ulong NodeOffset2 = reader.ReadUInt64();
reader.SeekBegin(NodeOffset1);
Node node1 = new Node();
node1.Name = GetNodeName(TotalNodes, node1);
node1.Read(reader);
reader.SeekBegin(NodeOffset2);
Node node2 = new Node();
node2.Name = GetNodeName(TotalNodes, node1);
node2.Read(reader);
// LoadChildern(TotalNodes, node1, linkWrapper);
// LoadChildern(TotalNodes, node2, linkWrapper);
LinkNodes.Add(Tuple.Create(node1, node2));
}
}
Skeleton.update();
Skeleton.reset();
}
private void LoadChildern(List<Node> NodeLookup, Node Node, TreeNode root)
{
var NewNode = SetWrapperNode(Node, root);
for (int i = 0; i < Node.Children.Count; i++)
{
Node.Children[i].Name = GetNodeName(NodeLookup, Node.Children[i]);
var newChild = SetWrapperNode(Node.Children[i], NewNode);
LoadChildern(NodeLookup, Node.Children[i], newChild);
}
}
private List<SubMesh> AddedMeshes = new List<SubMesh>();
private void LoadBones(List<Node> NodeLookup, Node Node, TreeNode root)
{
var NewNode = SetBoneNode(Node, root);
for (int i = 0; i < Node.Children.Count; i++)
{
Node.Children[i].Name = GetNodeName(NodeLookup, Node.Children[i]);
var newChild = SetBoneNode(Node.Children[i], NewNode);
LoadBones(NodeLookup, Node.Children[i], newChild);
}
}
private TreeNode SetBoneNode(Node Node, TreeNode parentNode)
{
if (Node.IsBone)
{
STBone boneNode = new STBone(Skeleton);
boneNode.RotationType = STBone.BoneRotationType.Euler;
boneNode.Checked = true;
boneNode.Text = Node.Name;
boneNode.position = new float[3];
boneNode.scale = new float[3];
boneNode.rotation = new float[4];
boneNode.position[0] = Node.Translation.X;
boneNode.position[1] = Node.Translation.Y;
boneNode.position[2] = Node.Translation.Z;
boneNode.rotation[0] = Node.Rotation.X;
boneNode.rotation[1] = Node.Rotation.Y;
boneNode.rotation[2] = Node.Rotation.Z;
boneNode.scale[0] = Node.Scale.X;
boneNode.scale[1] = Node.Scale.Y;
boneNode.scale[2] = Node.Scale.Z;
if (Node.IsBone)
Skeleton.bones.Add(boneNode);
parentNode.Nodes.Add(boneNode);
return boneNode;
}
return new TreeNode(Node.Name);
}
private TreeNode SetWrapperNode(Node Node, TreeNode parentNode)
{
if (Node.IsMesh)
{
List<TreeNode> MeshNodes = new List<TreeNode>();
int i = 0;
foreach (SubMesh subMesh in Node.SubMeshes)
{
GenericRenderedObject subMeshNode = new GenericRenderedObject();
subMeshNode.ImageKey = "mesh";
subMeshNode.SelectedImageKey = "mesh";
subMeshNode.Checked = true;
subMeshNode.Text = $"{Node.Name} {i}";
subMeshNode.lodMeshes = new List<GenericRenderedObject.LOD_Mesh>();
var submsh = new GenericRenderedObject.LOD_Mesh();
submsh.PrimativeType = STPrimativeType.Triangles;
submsh.FirstVertex = 0;
submsh.faces = subMesh.Faces;
subMeshNode.lodMeshes.Add(submsh);
subMeshNode.vertices = subMesh.Vertices;
//Check duplicate models being rendered
if (!AddedMeshes.Contains(subMesh))
DrawableRenderer.Meshes.Add(subMeshNode);
AddedMeshes.Add(subMesh);
if (i == 0)
parentNode.Nodes.Add(subMeshNode);
else
parentNode.Nodes[0].Nodes.Add(subMeshNode);
MeshNodes.Add(subMeshNode);
i++;
}
var FirstNode = MeshNodes[0];
MeshNodes.Clear();
return FirstNode;
}
else
{
var NewNode = new TreeNode(Node.Name);
parentNode.Nodes.Add(NewNode);
return NewNode;
}
}
private static string GetNodeName(List<Node> NodeLookup, Node node)
{
for (int i = 0; i < NodeLookup.Count; i++)
{
if (NodeLookup[i].Position == node.Position)
return NodeLookup[i].Name;
}
return "";
}
}
public class Material
{
public string Name;
public Vector4 Ambient;
public Vector4 Diffuse;
public Vector4 Specular;
public Vector4 Ambience;
public float Shiny;
public Vector4 Transparency;
public float TransGlossy;
public float TransparencySamples;
public Vector4 Reflectivity;
public float ReflectGlossy;
public float ReflectSample;
public float IndexRefreaction;
public float Translucency;
public float Unknown;
public short[] TextureIndices;
public uint[] Unknowns;
public Material()
{
Ambient = new Vector4(0.3f, 0.3f, 0.3f,1.0f);
Diffuse = new Vector4(0.7f, 0.7f, 0.7f, 1.0f);
Specular = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Ambience = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Shiny = 50;
Transparency = new Vector4(0.0f, 0.0f, 0.0f, 1.0f);
TextureIndices = new short[10];
}
public void Read(FileReader reader)
{
Name = reader.LoadString(false, typeof(ulong));
Ambient = reader.ReadVec4();
Diffuse = reader.ReadVec4();
Specular = reader.ReadVec4();
Ambience = reader.ReadVec4();
Shiny = reader.ReadSingle();
Transparency = reader.ReadVec4();
TransGlossy = reader.ReadSingle();
TransparencySamples = reader.ReadSingle();
Reflectivity = reader.ReadVec4();
ReflectGlossy = reader.ReadSingle();
ReflectSample = reader.ReadSingle();
IndexRefreaction = reader.ReadSingle();
Translucency = reader.ReadSingle();
Unknown = reader.ReadSingle();
reader.ReadSingle();
reader.ReadSingle();
reader.ReadSingle();
TextureIndices = reader.ReadInt16s(6);
Unknowns = reader.ReadUInt32s(10);
}
}
public class SubMesh
{
public Node ParentNode { get; set; }
public Material Material { get; set; }
public List<Vertex> Vertices = new List<Vertex>();
public List<int> Faces = new List<int>();
public SubMesh(Node parentNode)
{
ParentNode = parentNode;
}
public void Read(FileReader reader)
{
var pos = reader.Position;
uint Padding = reader.ReadUInt32();
uint FaceCount = reader.ReadUInt32();
uint[] Unknowns = reader.ReadUInt32s(5);
uint VertexCount = reader.ReadUInt32();
ulong VertexPositionOffset = reader.ReadUInt64();
ulong VertexNormalOffset = reader.ReadUInt64();
ulong UnknownOffset = reader.ReadUInt64();
ulong TexCoord0Offset = reader.ReadUInt64();
ulong TexCoord1Offset = reader.ReadUInt64();
ulong TexCoord2Offset = reader.ReadUInt64();
ulong TexCoord3Offset = reader.ReadUInt64();
reader.SeekBegin(pos + 112);
ulong FaceOffset = reader.ReadUInt64();
uint SkinCount = reader.ReadUInt32(); //Unsure
uint Unknown = reader.ReadUInt32(); //Something related to count
uint WeightOffset = reader.ReadUInt32();
uint Unknown2 = reader.ReadUInt32();
for (int i = 0; i < VertexCount; i++)
{
Vertex vertex = new Vertex();
Vertices.Add(vertex);
if (VertexPositionOffset != 0)
{
reader.SeekBegin((int)VertexPositionOffset + (i * 12));
vertex.pos = reader.ReadVec3();
vertex.pos = Vector3.TransformPosition(vertex.pos, ParentNode.Transform);
}
if (VertexNormalOffset != 0)
{
reader.SeekBegin((int)VertexNormalOffset + (i * 12));
vertex.nrm = reader.ReadVec3();
vertex.nrm = Vector3.TransformNormal(vertex.nrm, ParentNode.Transform);
}
if (TexCoord0Offset != 0)
{
reader.SeekBegin((int)TexCoord0Offset + (i * 8));
vertex.uv0 = reader.ReadVec2();
}
if (TexCoord1Offset != 0)
{
reader.SeekBegin((int)TexCoord1Offset + (i * 8));
vertex.uv1 = reader.ReadVec2();
}
if (TexCoord2Offset != 0)
{
reader.SeekBegin((int)TexCoord2Offset + (i * 8));
vertex.uv2 = reader.ReadVec2();
}
if (TexCoord3Offset != 0)
{
reader.SeekBegin((int)TexCoord3Offset + (i * 8));
}
}
reader.SeekBegin((int)FaceOffset);
for (int i = 0; i < FaceCount * 3; i++)
{
Faces.Add(reader.ReadUInt16());
}
}
}
public class Node
{
public string Name { get; set; }
public bool Visible { get; set; }
public Vector3 Scale { get; set; }
public Vector3 Rotation { get; set; }
public Vector3 Translation { get; set; }
public byte[] Unknowns;
public List<Node> Children = new List<Node>();
public List<SubMesh> SubMeshes = new List<SubMesh>();
internal long Position;
public bool IsBone
{
get { return SubMeshes.Count == 0; }
}
public bool IsMesh
{
get { return SubMeshes.Count > 0; }
}
public Matrix4 Transform { get; set; }
public void Read(FileReader reader)
{
Position = reader.Position;
Visible = reader.ReadUInt32() == 1;
if (!Visible) return;
reader.ReadBytes(28);
Scale = reader.ReadVec3();
Rotation = reader.ReadVec3();
Translation = reader.ReadVec3();
Unknowns = reader.ReadBytes(20);
ulong SubMeshArrayOffsetPtr = reader.ReadUInt64();
ulong unkoff = reader.ReadUInt64();
ulong ChildNodeOffsetPtr = reader.ReadUInt64();
reader.ReadUInt32();
Matrix4 TranslateMat = Matrix4.CreateTranslation(Translation);
Matrix4 RotXMat = Matrix4.CreateRotationX(Rotation.X);
Matrix4 RotYMat = Matrix4.CreateRotationY(Rotation.Y);
Matrix4 RotZMat = Matrix4.CreateRotationZ(Rotation.Z);
Matrix4 ScaleMat = Matrix4.CreateTranslation(Scale);
Transform = ScaleMat * (RotXMat * RotYMat * RotZMat) * TranslateMat;
if (SubMeshArrayOffsetPtr != 0)
{
int i = 0;
while (true)
{
reader.SeekBegin((int)SubMeshArrayOffsetPtr + i * 8);
ulong SubMeshArrayOffset1 = reader.ReadUInt64();
if (SubMeshArrayOffset1 == 0) break;
if (SubMeshArrayOffset1 != 0)
{
reader.SeekBegin(SubMeshArrayOffset1);
SubMesh subMesh = new SubMesh(this);
subMesh.Read(reader);
SubMeshes.Add(subMesh);
}
i++;
}
}
if (ChildNodeOffsetPtr != 0)
{
//2 possible children
for (int i = 0; i < 2; i++)
{
reader.SeekBegin((int)ChildNodeOffsetPtr + i * 8);
ulong ChildNodeOffset1 = reader.ReadUInt64();
if (ChildNodeOffset1 != 0)
{
reader.SeekBegin(ChildNodeOffset1);
Node ChildNode = new Node();
ChildNode.Read(reader);
Children.Add(ChildNode);
}
}
}
//After repeats a fairly similar structure, with SRT values
//Unsure what it's used for?
}
}
}
}

View file

@ -0,0 +1,767 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Rendering;
using OpenTK;
using Toolbox.Library.Forms;
using System.Windows.Forms;
namespace FirstPlugin.NLG
{
public class StrikersRLG : TreeNodeFile, IFileFormat, IContextMenuNode
{
public FileType FileType { get; set; } = FileType.Model;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Strikers Model" };
public string[] Extension { get; set; } = new string[] { "*.glg", "*.rlg" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
return Utils.GetExtension(FileName) == ".rlg" || Utils.GetExtension(FileName) == ".glg";
using (var reader = new FileReader(stream, true))
{
return reader.CheckSignature(4, 0x8001B000);
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
Viewport viewport
{
get
{
var editor = LibraryGUI.GetObjectEditor();
return editor.GetViewport();
}
set
{
var editor = LibraryGUI.GetObjectEditor();
editor.LoadViewport(value);
}
}
private bool DrawablesLoaded;
public override void OnClick(TreeView treeView)
{
Renderer.UpdateVertexData();
if (Runtime.UseOpenGL)
{
if (viewport == null)
{
viewport = new Viewport(ObjectEditor.GetDrawableContainers());
viewport.Dock = DockStyle.Fill;
}
if (!DrawablesLoaded)
{
ObjectEditor.AddContainer(DrawableContainer);
DrawablesLoaded = true;
}
Viewport editor = (Viewport)LibraryGUI.GetActiveContent(typeof(Viewport));
if (editor == null)
{
editor = viewport;
LibraryGUI.LoadEditor(viewport);
}
viewport.ReloadDrawables(DrawableContainer);
viewport.Text = Text;
}
}
public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new ToolStripMenuItem("Export", null, ExportModelAction, Keys.Control | Keys.E));
return Items.ToArray();
}
private void ExportModelAction(object sender, EventArgs args)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Supported Formats|*.dae;";
if (sfd.ShowDialog() == DialogResult.OK)
{
ExportModel(sfd.FileName);
}
}
private void ExportModel(string FileName)
{
AssimpSaver assimp = new AssimpSaver();
ExportModelSettings settings = new ExportModelSettings();
List<STGenericMaterial> Materials = new List<STGenericMaterial>();
// foreach (var msh in DataDictionary.Renderer.Meshes)
// Materials.Add(msh.GetMaterial());
var model = new STGenericModel();
model.Materials = Materials;
model.Objects = Renderer.Meshes;
assimp.SaveFromModel(model, FileName, new List<STGenericTexture>(), new STSkeleton());
}
public enum SectionMagic : uint
{
MaterialData = 0x0001B016,
IndexData = 0x0001B007,
VertexData = 0x0001B006,
VertexAttributePointerData = 0x0001B005,
MeshData = 0x0001B004,
ModelData = 0x0001B003,
MatrixData = 0x0001B002,
SkeletonData = 0x8001B008,
BoneHashes = 0x0001B00B,
BoneData = 0x0001B00A,
UnknownHashList = 0x0001B00C,
}
public enum MaterailPresets : uint
{
EnvDiffuseDamage = 0x1ACE1D01,
}
private Strikers_Renderer Renderer;
public DrawableContainer DrawableContainer = new DrawableContainer();
public List<Model> Models = new List<Model>();
public bool IsGamecube = false;
public void Load(System.IO.Stream stream)
{
Renderer = new Strikers_Renderer();
DrawableContainer.Name = FileName;
DrawableContainer.Drawables.Add(Renderer);
IsGamecube = Utils.GetExtension(FileName) == ".glg";
Text = FileName;
using (var reader = new FileReader(stream))
{
reader.SetByteOrder(true);
reader.ReadUInt32(); //magic
reader.ReadUInt32(); //fileSize
//Create a list of all the major sections
//The sections are not in order, so we must order them while parsing
Dictionary<SectionMagic, SectionHeader> SectionLookup = new Dictionary<SectionMagic, SectionHeader>();
while (!reader.EndOfStream) {
uint magic = reader.ReadUInt32();
uint sectionSize = reader.ReadUInt32();
long pos = reader.Position;
Console.WriteLine($"Magic {(SectionMagic)magic} sectionSize {sectionSize}");
if (!SectionLookup.ContainsKey((SectionMagic)magic))
SectionLookup.Add((SectionMagic)magic, new SectionHeader(sectionSize, pos));
//This section will skip sub sections so don't do that
if (magic != 0x8001B000)
reader.SeekBegin(pos + sectionSize);
if (!IsGamecube)
reader.Align(4);
}
var HashList = NLG_Common.HashNames;
//Now read our model properly
//First get our model info
Matrix4 TransformMatrix = Matrix4.Identity;
uint totalNumMeshes = 0;
uint modelSize = 12;
if (IsGamecube)
modelSize = 16;
if (SectionLookup.ContainsKey(SectionMagic.ModelData))
{
var modelHeader = SectionLookup[SectionMagic.ModelData];
for (int m = 0; m < modelHeader.Size / modelSize; m++)
{
reader.SeekBegin(modelHeader.Position + (m * modelSize));
if (IsGamecube)
{
totalNumMeshes += reader.ReadUInt32();
reader.ReadUInt32();
}
else
{
reader.ReadUInt32();
totalNumMeshes += reader.ReadUInt32();
}
}
}
uint meshIndex = 0;
if (SectionLookup.ContainsKey(SectionMagic.ModelData))
{
var modelHeader = SectionLookup[SectionMagic.ModelData];
reader.SeekBegin(modelHeader.Position);
uint numModels = modelHeader.Size / modelSize;
uint hashId = 0;
for (int m = 0; m < numModels; m++)
{
Model model = new Model();
Nodes.Add(model);
Models.Add(model);
uint numMeshes = 0;
reader.SeekBegin(modelHeader.Position + (m * modelSize));
if (IsGamecube)
{
numMeshes = reader.ReadUInt32();
hashId = reader.ReadUInt32();
}
else
{
hashId = reader.ReadUInt32();
numMeshes = reader.ReadUInt32();
}
model.Text = hashId.ToString("X");
if (HashList.ContainsKey(hashId))
model.Text = HashList[hashId];
if (SectionLookup.ContainsKey(SectionMagic.MeshData))
{
var meshHeader = SectionLookup[SectionMagic.MeshData];
reader.SeekBegin(meshHeader.Position);
for (int i = 0; i < numMeshes; i++)
{
if (IsGamecube)
{
uint meshSize = meshHeader.Size / totalNumMeshes;
reader.SeekBegin(meshHeader.Position + ((meshIndex + i) * meshSize));
}
else
reader.SeekBegin(meshHeader.Position + ((meshIndex + i) * 48));
var mesh = new MeshData(reader, IsGamecube);
model.Meshes.Add(mesh);
}
meshIndex += numMeshes;
}
}
if (SectionLookup.ContainsKey(SectionMagic.MatrixData))
{
var matSection = SectionLookup[SectionMagic.MatrixData];
reader.SeekBegin(matSection.Position);
TransformMatrix = reader.ReadMatrix4(true);
}
List<VertexAttribute> Pointers = new List<VertexAttribute>();
if (SectionLookup.ContainsKey(SectionMagic.VertexAttributePointerData))
{
var pointerSection = SectionLookup[SectionMagic.VertexAttributePointerData];
reader.SeekBegin(pointerSection.Position);
int attributeSize = 8;
if (IsGamecube)
attributeSize = 6;
for (int i = 0; i < pointerSection.Size / attributeSize; i++)
{
VertexAttribute pointer = new VertexAttribute();
if (IsGamecube)
{
pointer.Offset = reader.ReadUInt32();
pointer.Type = reader.ReadByte();
pointer.Stride = reader.ReadByte();
}
else
{
pointer.Offset = reader.ReadUInt32();
pointer.Type = reader.ReadByte();
pointer.Stride = reader.ReadByte();
reader.ReadUInt16();
}
Pointers.Add(pointer);
}
}
int pointerIndex = 0;
foreach (var model in Models)
{
for (int i = 0; i < model.Meshes.Count; i++)
{
RenderableMeshWrapper mesh = new RenderableMeshWrapper();
model.Nodes.Add(mesh);
Renderer.Meshes.Add(mesh);
mesh.Text = model.Meshes[i].HashID.ToString("X");
if (HashList.ContainsKey(model.Meshes[i].HashID))
mesh.Text = HashList[model.Meshes[i].HashID];
string material = model.Meshes[i].MaterialHashID.ToString("X");
if (HashList.ContainsKey(model.Meshes[i].MaterialHashID))
material = HashList[model.Meshes[i].MaterialHashID];
mesh.Nodes.Add(material);
var faceSecton = SectionLookup[SectionMagic.IndexData];
var vertexSecton = SectionLookup[SectionMagic.VertexData];
STGenericPolygonGroup polyGroup = new STGenericPolygonGroup();
mesh.PolygonGroups.Add(polyGroup);
reader.SeekBegin(faceSecton.Position + model.Meshes[i].IndexStartOffset);
List<int> faces = new List<int>();
for (int f = 0; f < model.Meshes[i].IndexCount; f++)
{
if (model.Meshes[i].IndexFormat == 0)
polyGroup.faces.Add(reader.ReadUInt16());
else
polyGroup.faces.Add(reader.ReadByte());
}
if (model.Meshes[i].FaceType == MeshData.PolygonType.TriangleStrips)
polyGroup.PrimativeType = STPrimativeType.TrangleStrips;
else
polyGroup.PrimativeType = STPrimativeType.Triangles;
if (IsGamecube)
{
uint size = Pointers[pointerIndex + 1].Offset - Pointers[pointerIndex].Offset;
model.Meshes[i].VertexCount = (ushort)(size / Pointers[pointerIndex].Stride);
}
Console.WriteLine($"mesh {mesh.Text} {model.Meshes[i].VertexCount}");
for (int v = 0; v < model.Meshes[i].VertexCount; v++)
{
Vertex vert = new Vertex();
mesh.vertices.Add(vert);
for (int a = 0; a < model.Meshes[i].NumAttributePointers; a++)
{
var pointer = Pointers[pointerIndex + a];
reader.SeekBegin(vertexSecton.Position + pointer.Offset + (pointer.Stride * v));
if (pointer.Type == 0)
{
if (pointer.Stride == 6)
vert.pos = new Vector3(reader.ReadInt16() / 1024f, reader.ReadInt16() / 1024f, reader.ReadInt16() / 1024f);
else if (pointer.Stride == 12)
vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
vert.pos = Vector3.TransformPosition(vert.pos, TransformMatrix);
}
if (pointer.Type == 1)
{
if (pointer.Stride == 3)
vert.nrm = Read_8_8_8_Snorm(reader).Normalized();
else if (pointer.Stride == 12)
vert.nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
if (pointer.Type == 3)
{
vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f);
}
if (pointer.Type == 0x67)
{
vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
if (pointer.Type == 0xFE)
{
vert.nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
if (pointer.Type == 0x26)
{
vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f);
}
if (pointer.Type == 0xCC)
{
vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f);
}
if (pointer.Type == 0x17)
{
vert.uv1 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f);
}
if (pointer.Type == 0xD4)
{
vert.boneIds = new List<int>() { reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte() };
}
if (pointer.Type == 0xB0)
{
vert.boneWeights = new List<float>() { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() };
}
}
}
mesh.TransformPosition(new Vector3(0), new Vector3(-90, 0, 0), new Vector3(1));
pointerIndex += model.Meshes[i].NumAttributePointers;
}
for (int i = 0; i < model.Meshes.Count; i++)
{
if (IsGamecube)
{
var renderedMesh = (RenderableMeshWrapper)Renderer.Meshes[i];
renderedMesh.Material = new STGenericMaterial();
string diffuseName = model.Meshes[i].TexturHashID.ToString("X");
if (HashList.ContainsKey(model.Meshes[i].TexturHashID))
diffuseName = HashList[model.Meshes[i].TexturHashID];
var texUnit = 1;
renderedMesh.Material.TextureMaps.Add(new STGenericMatTexture()
{
textureUnit = texUnit++,
Type = STGenericMatTexture.TextureType.Diffuse,
Name = diffuseName,
});
}
if (SectionLookup.ContainsKey(SectionMagic.MaterialData))
{
var materialSecton = SectionLookup[SectionMagic.MaterialData];
reader.SeekBegin(materialSecton.Position + model.Meshes[i].MaterialOffset);
var renderedMesh = (RenderableMeshWrapper)Renderer.Meshes[i];
renderedMesh.Material = new STGenericMaterial();
switch (model.Meshes[i].MaterailPreset)
{
case MaterailPresets.EnvDiffuseDamage:
{
uint diffuseMapHashID = reader.ReadUInt32();
uint diffuseMapParam = reader.ReadUInt32();
string diffuseName = diffuseMapHashID.ToString("X");
if (HashList.ContainsKey(diffuseMapHashID))
diffuseName = HashList[diffuseMapHashID];
var texUnit = 1;
renderedMesh.Material.TextureMaps.Add(new STGenericMatTexture()
{
textureUnit = texUnit++,
Type = STGenericMatTexture.TextureType.Diffuse,
Name = diffuseName,
});
}
break;
default:
{
uint diffuseMapHashID = reader.ReadUInt32();
string diffuseName = diffuseMapHashID.ToString("X");
if (HashList.ContainsKey(diffuseMapHashID))
diffuseName = HashList[diffuseMapHashID];
var texUnit = 1;
renderedMesh.Material.TextureMaps.Add(new STGenericMatTexture()
{
textureUnit = texUnit++,
Type = STGenericMatTexture.TextureType.Diffuse,
Name = diffuseName,
});
}
break;
}
}
}
}
List<BoneListEntry> BoneLists = new List<BoneListEntry>();
List<uint> boneHashOrder = new List<uint>();
TreeNode parentBoneList = new TreeNode("Bone List");
Nodes.Add(parentBoneList);
if (SectionLookup.ContainsKey(SectionMagic.SkeletonData))
{
var skeletonSection = SectionLookup[SectionMagic.SkeletonData];
reader.SeekBegin(skeletonSection.Position);
//Read all sub sections
while (reader.Position < skeletonSection.Position + skeletonSection.Size)
{
uint magic = reader.ReadUInt32();
uint sectionSize = reader.ReadUInt32();
long pos = reader.Position;
BoneListEntry entry = new BoneListEntry();
BoneLists.Add(entry);
//Bone hashes appear for each mesh if it uses rigging
//Meshes index these lists for rigging
if ((SectionMagic)magic == SectionMagic.BoneHashes)
{
TreeNode boneListNode = new TreeNode("Mesh Bone List");
parentBoneList.Nodes.Add(boneListNode);
uint numHashes = sectionSize / 4;
for (int i = 0; i < numHashes; i++)
{
entry.Hashes.Add(reader.ReadUInt32());
if (IsGamecube)
reader.ReadUInt32();
string hashName = entry.Hashes[i].ToString("X");
if (HashList.ContainsKey(entry.Hashes[i]))
hashName = HashList[entry.Hashes[i]];
boneListNode.Nodes.Add(hashName);
}
}
if ((SectionMagic)magic == SectionMagic.BoneData)
{
uint numBones = sectionSize / 68;
for (int i = 0; i < numBones; i++)
{
reader.SeekBegin(pos + i * 68);
BoneEntry bone = new BoneEntry();
bone.HashID = reader.ReadUInt32();
reader.ReadUInt32(); //unk
reader.ReadUInt32(); //unk
reader.ReadUInt32(); //unk
reader.ReadSingle(); //0
bone.Scale = new Vector3(
reader.ReadSingle(),
reader.ReadSingle(),
reader.ReadSingle());
reader.ReadSingle(); //0
bone.Rotate = new Vector3(
reader.ReadSingle(),
reader.ReadSingle(),
reader.ReadSingle());
reader.ReadSingle(); //0
bone.Translate = new Vector3(
reader.ReadSingle(),
reader.ReadSingle(),
reader.ReadSingle());
reader.ReadSingle(); //1
entry.Bones.Add(bone);
}
}
reader.SeekBegin(pos + sectionSize);
}
}
List<BoneEntry> BoneListSorted = new List<BoneEntry>();
foreach (var hash in boneHashOrder)
{
foreach (var boneList in BoneLists)
{
foreach (var bone in boneList.Bones)
if (bone.HashID == hash)
BoneListSorted.Add(bone);
}
}
STSkeleton skeleton = new STSkeleton();
DrawableContainer.Drawables.Add(skeleton);
foreach (var boneList in BoneLists)
{
foreach (var bone in boneList.Bones)
{
STBone stBone = new STBone(skeleton);
skeleton.bones.Add(stBone);
stBone.Text = bone.HashID.ToString("X");
if (HashList.ContainsKey(bone.HashID))
stBone.Text = HashList[bone.HashID];
stBone.position = new float[3] { bone.Translate.X, bone.Translate.Z, -bone.Translate.Y };
stBone.rotation = new float[4] { bone.Rotate.X, bone.Rotate.Z, -bone.Rotate.Y, 1 };
// stBone.scale = new float[3] { bone.Scale.X, bone.Scale.Y, bone.Scale.Z };
stBone.scale = new float[3] { 0.2f, 0.2f, 0.2f };
stBone.RotationType = STBone.BoneRotationType.Euler;
}
}
skeleton.reset();
skeleton.update();
TreeNode skeletonNode = new TreeNode("Skeleton");
Nodes.Add(skeletonNode);
foreach (var bone in skeleton.bones)
{
if (bone.Parent == null)
skeletonNode.Nodes.Add(bone);
}
}
}
}
public class Model : STGenericModel
{
public List<MeshData> Meshes = new List<MeshData>();
}
public static Vector3 Read_8_8_8_Snorm(FileReader reader)
{
return new Vector3(reader.ReadSByte() / 255f, reader.ReadSByte() / 255f, reader.ReadSByte() / 255f);
}
public class BoneListEntry
{
public List<uint> Hashes = new List<uint>();
public List<BoneEntry> Bones = new List<BoneEntry>();
}
public class BoneEntry
{
public uint HashID;
public int ParentIndex = -1;
public Vector3 Scale;
public Vector3 Rotate;
public Vector3 Translate;
}
public class RenderableMeshWrapper : GenericRenderedObject
{
public STGenericMaterial Material = new STGenericMaterial();
public override STGenericMaterial GetMaterial()
{
return Material;
}
}
public class VertexAttribute
{
public uint Offset;
public byte Stride;
public byte Type;
public byte Format;
}
public class MeshData
{
public uint[] BoneHashes;
public enum PolygonType : byte
{
Triangles = 0,
TriangleStrips = 1,
}
public uint IndexStartOffset;
public ushort IndexFormat;
public ushort IndexCount;
public ushort VertexCount;
public byte Unknown;
public byte NumAttributePointers;
public uint HashID;
public uint MaterialHashID;
//Only on gamecube (wii uses seperate section)
public uint TexturHashID;
public uint MaterialOffset;
public MaterailPresets MaterailPreset;
public PolygonType FaceType = PolygonType.TriangleStrips;
public MeshData(FileReader reader, bool isGamecube)
{
if (isGamecube)
{
reader.ReadUInt16(); //0
IndexFormat = reader.ReadUInt16();
IndexStartOffset = reader.ReadUInt32();
IndexCount = reader.ReadUInt16();
FaceType = reader.ReadEnum<PolygonType>(false);
NumAttributePointers = reader.ReadByte();
reader.ReadUInt32();
MaterialHashID = reader.ReadUInt32();
reader.ReadUInt32();
reader.ReadUInt32();
reader.ReadUInt32();
MaterialOffset = reader.ReadUInt32();
reader.ReadUInt32();
TexturHashID = reader.ReadUInt32();
reader.ReadUInt32();
}
else
{
IndexStartOffset = reader.ReadUInt32();
IndexFormat = reader.ReadUInt16();
IndexCount = reader.ReadUInt16();
VertexCount = reader.ReadUInt16();
Unknown = reader.ReadByte();
NumAttributePointers = reader.ReadByte();
reader.ReadUInt32();
MaterialHashID = reader.ReadUInt32();
HashID = reader.ReadUInt32();
reader.ReadUInt32();
reader.ReadUInt32();
MaterialOffset = reader.ReadUInt32();
reader.ReadUInt32();
reader.ReadUInt32();
reader.ReadUInt32();
}
MaterailPreset = (MaterailPresets)MaterialHashID;
}
}
public class SectionHeader
{
public long Position;
public uint Size;
public SectionHeader(uint size, long pos)
{
Size = size;
Position = pos;
}
}
public void Unload()
{
}
public void Save(System.IO.Stream stream)
{
}
}
}

View file

@ -0,0 +1,228 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.Forms;
using Toolbox.Library.IO;
using System.Runtime.InteropServices;
namespace FirstPlugin.NLG
{
public class StrikersRLT : TreeNodeFile, IFileFormat, ITextureIconLoader
{
public FileType FileType { get; set; } = FileType.Image;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Strikers Texture Image" };
public string[] Extension { get; set; } = new string[] { "*.glt", "*.rlt" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
using (var reader = new FileReader(stream, true)) {
return reader.CheckSignature(4, "PTLG");
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
public List<STGenericTexture> IconTextureList
{
get
{
List<STGenericTexture> textures = new List<STGenericTexture>();
foreach (STGenericTexture node in Nodes)
textures.Add(node);
return textures;
}
set { }
}
public Dictionary<byte, Decode_Gamecube.TextureFormats> FormatList = new Dictionary<byte, Decode_Gamecube.TextureFormats>
{
{ 0x8, Decode_Gamecube.TextureFormats.RGBA32 },
{ 0x7, Decode_Gamecube.TextureFormats.RGB565 },
{ 0x6, Decode_Gamecube.TextureFormats.CMPR },
{ 0x5, Decode_Gamecube.TextureFormats.RGB5A3 },
{ 0x4, Decode_Gamecube.TextureFormats.IA4 },
{ 0x3, Decode_Gamecube.TextureFormats.I8 },
{ 0x2, Decode_Gamecube.TextureFormats.I4 },
};
private bool IsGamecube = false;
public void Load(System.IO.Stream stream)
{
CanSave = true;
Text = FileName;
using (var reader = new FileReader(stream))
{
reader.SetByteOrder(true);
uint magic = reader.ReadUInt32();
uint numTextures = reader.ReadUInt32();
uint unk = reader.ReadUInt32();
uint padding = reader.ReadUInt32();
if (unk == 0)
IsGamecube = true;
if (reader.ReadUInt32() == 0)
reader.Seek(12);
else
reader.Seek(-4);
if (NLG_Common.HashNames.ContainsKey(unk))
Text = "HASH: " + NLG_Common.HashNames[unk];
var textures = reader.ReadMultipleStructs<TextureHashEntry>(numTextures);
long startPos = reader.Position;
for (int i = 0; i < numTextures; i++)
{
TextureEntry entry = new TextureEntry();
Nodes.Add(entry);
PluginRuntime.stikersTextures.Add(entry);
reader.SeekBegin(startPos + textures[i].ImageOffset);
long pos = reader.Position;
//Texture Info
uint MipCount = reader.ReadUInt32();
uint unknown2 = reader.ReadUInt32(); //1
byte unknown4 = reader.ReadByte(); //5
byte Format = reader.ReadByte();
byte unknown5 = reader.ReadByte(); //5
byte unknown6 = reader.ReadByte(); //3
ushort Width = reader.ReadUInt16();
//Dumb hack. Idk why there's sometimes padding. Aligning doesn't always fix it.
if (Width == 0)
Width = reader.ReadUInt16();
ushort Height = reader.ReadUInt16();
reader.ReadUInt16();
reader.ReadUInt32();
reader.ReadUInt32();
reader.ReadUInt32();
uint headerSize = (uint)(reader.Position - pos);
uint imageSize = textures[i].SectionSize - headerSize;
reader.SeekBegin(pos + headerSize);
entry.ImageData = reader.ReadBytes((int)imageSize);
uint hash = textures[i].Hash;
entry.Text = hash.ToString("X");
entry.ImageKey = "texture";
entry.SelectedImageKey = "texture";
if (NLG_Common.HashNames.ContainsKey(hash))
entry.Text = NLG_Common.HashNames[hash];
// entry.Text += $" {textureInfo.Format} {textureInfo.unknown2} {textureInfo.unknown4} {textureInfo.unknown5} {textureInfo.unknown6} ";
var formatGC = Decode_Gamecube.TextureFormats.CMPR;
if (FormatList.ContainsKey(Format))
formatGC = FormatList[Format];
entry.MipCount = MipCount;
entry.Format = Decode_Gamecube.ToGenericFormat(formatGC);
entry.Width = Width;
entry.Height = Height;
entry.PlatformSwizzle = PlatformSwizzle.Platform_Gamecube;
}
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class TextureHashEntry
{
public uint Hash;
public uint ImageOffset;
public uint SectionSize;
public uint Unknown;
}
public class TextureEntry : STGenericTexture
{
public byte[] ImageData { get; set; }
public override TEX_FORMAT[] SupportedFormats
{
get
{
return new TEX_FORMAT[]
{
TEX_FORMAT.I4,
TEX_FORMAT.I8,
TEX_FORMAT.IA4,
TEX_FORMAT.IA8,
TEX_FORMAT.RGB565,
TEX_FORMAT.RGB5A3,
TEX_FORMAT.RGBA32,
TEX_FORMAT.C4,
TEX_FORMAT.C8,
TEX_FORMAT.C14X2,
TEX_FORMAT.CMPR,
};
}
}
public override bool CanEdit { get; set; } = false;
public override void SetImageData(System.Drawing.Bitmap bitmap, int ArrayLevel)
{
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
{
return Decode_Gamecube.GetMipLevel(ImageData, Width, Height, MipCount, (uint)MipLevel, Format);
}
public override void OnClick(TreeView treeView)
{
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
if (editor == null)
{
editor = new ImageEditorBase();
editor.Dock = DockStyle.Fill;
LibraryGUI.LoadEditor(editor);
}
editor.LoadProperties(GenericProperties);
editor.LoadImage(this);
}
}
public void Save(System.IO.Stream stream)
{
using (var writer = new FileWriter(stream))
{
}
}
public void Unload()
{
foreach (TextureEntry tex in Nodes)
if (PluginRuntime.stikersTextures.Contains(tex))
PluginRuntime.stikersTextures.Remove(tex);
}
}
}

View file

@ -9,6 +9,61 @@ namespace FirstPlugin
{
public class NLG_Common
{
private static Dictionary<uint, string> hashNames;
public static Dictionary<uint, string> HashNames
{
get
{
if (hashNames.Count == 0)
LoadHashes();
return hashNames;
}
}
public static void LoadHashes()
{
foreach (string hashStr in Properties.Resources.LM3_Hashes.Split('\n'))
{
string HashString = hashStr.TrimEnd();
uint hash = (uint)NLG_Common.StringToHash(HashString);
if (!HashNames.ContainsKey(hash))
HashNames.Add(hash, HashString);
string[] hashPaths = HashString.Split('/');
for (int i = 0; i < hashPaths?.Length; i++)
{
hash = (uint)NLG_Common.StringToHash(hashPaths[i]);
if (!HashNames.ContainsKey(hash))
HashNames.Add(hash, HashString);
}
}
}
public static void SearchHashMatch()
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
using (var reader = new FileReader(ofd.FileName))
{
reader.SetByteOrder(true);
while (reader.Position <= reader.BaseStream.Length - 4)
{
uint hashCheck = reader.ReadUInt32();
if (NLG_Common.HashNames.ContainsKey(hashCheck) && hashCheck > 0x50)
{
Console.WriteLine($"HASH MATCH {hashCheck.ToString("X")} {NLG_Common.HashNames[hashCheck]} | {reader.Position}");
}
else
reader.Seek(-3);
}
}
}
}
public static void PrintHashIdBin()
{
OpenFileDialog ofd = new OpenFileDialog();

View file

@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Toolbox.Library.IO;
using Toolbox.Library;
using Toolbox.Library.Forms;
using System.Windows.Forms;
namespace FirstPlugin
{
public class NLG_NLOC : IEditor<TextEditor>, IFileFormat, IContextMenuNode, IConvertableTextFormat
{
public FileType FileType { get; set; } = FileType.Effect;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "NLG Localization Text" };
public string[] Extension { get; set; } = new string[] { "*.nloc" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
using (var reader = new Toolbox.Library.IO.FileReader(stream, true))
{
return reader.CheckSignature(4, "NLOC");
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
public TextEditor OpenForm()
{
return new TextEditor();
}
public void FillEditor(UserControl control)
{
((TextEditor)control).FileFormat = this;
((TextEditor)control).FillEditor(ConvertToString());
}
#region Text Converter Interface
public TextFileType TextFileType => TextFileType.Xml;
public bool CanConvertBack => false;
public string ConvertToString()
{
StringBuilder strBuilder = new StringBuilder();
using (var textWriter = new System.IO.StringWriter(strBuilder))
{
textWriter.Write($"Language: {header.LanguageText}");
for (int i = 0; i < header.Entries.Count; i++)
{
textWriter.WriteLine($"ID: [{header.Entries[i].ID}] [{header.Entries[i].Text}]");
}
}
return strBuilder.ToString();
}
public void ConvertFromString(string text)
{
}
#endregion
private Header header;
public void Load(System.IO.Stream stream)
{
CanSave = true;
header = new Header();
header.Read(new FileReader(stream));
}
public ToolStripItem[] GetContextMenuItems()
{
return new ToolStripItem[]
{
new ToolStripMenuItem("Save", null, SaveAction, Keys.Control | Keys.S),
};
}
private void SaveAction(object sender, EventArgs args)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = Utils.GetAllFilters(typeof(EFF));
sfd.FileName = FileName;
if (sfd.ShowDialog() == DialogResult.OK)
STFileSaver.SaveFileFormat(this, sfd.FileName);
}
public void Unload()
{
}
public void Save(System.IO.Stream stream) {
header.Write(new FileWriter(stream));
}
public class Header
{
public List<TextEntry> Entries = new List<TextEntry>();
public uint LanguageID;
public uint Unknown0x4;
public uint Unknown0x10;
public string LanguageText;
public bool IsBigEndian = false;
public void Read(FileReader reader)
{
reader.ReadSignature(4, "NLOC");
Unknown0x4 = reader.ReadUInt32();
if (Unknown0x4 != 1)
{
IsBigEndian = true;
reader.SetByteOrder(true);
}
LanguageID = reader.ReadUInt32();
uint numEntries = reader.ReadUInt32();
Unknown0x10 = reader.ReadUInt32();
var hashes = NLG_Common.HashNames;
LanguageText = LanguageID.ToString("X");
if (hashes.ContainsKey(LanguageID))
LanguageText = hashes[LanguageID];
uint stringTableOfs = 0x14 + 8 * numEntries;
reader.SeekBegin(stringTableOfs);
List<string> ListStrings = new List<string>();
for (int i = 0; i < numEntries; i++)
ListStrings.Add(reader.ReadUTF16String());
reader.SeekBegin(0x14);
for (int i = 0; i < numEntries; i++)
{
TextEntry textEntry = new TextEntry();
Entries.Add(textEntry);
textEntry.ID = reader.ReadUInt32();
uint offset = reader.ReadUInt32();
textEntry.Text = ListStrings[i];
}
}
public void Write(FileWriter writer)
{
writer.WriteSignature("NLOC");
writer.SetByteOrder(IsBigEndian);
writer.Write(Unknown0x4);
writer.Write(LanguageID);
writer.Write(Entries.Count);
writer.Write(Unknown0x10);
//Write empty data first
writer.Write(new byte[8 * Entries.Count]);
//Write string table
List<uint> positions = new List<uint>();
uint pos = 0;
for (int i = 0; i < Entries.Count; i++)
{
positions.Add(pos);
long startPos = writer.Position;
for (int j = 0; j < Entries[i].Text.Length; j++)
writer.Write(Entries[i].Text[j]);
writer.Align(4);
long endPos = writer.Position;
pos += (uint)(endPos - startPos);
}
writer.SeekBegin(0x14);
for (int i = 0; i < Entries.Count; i++)
{
writer.Write(Entries[i].ID);
writer.Write(positions[i]);
}
}
}
public class TextEntry
{
public string Text;
public uint ID;
}
}
}

View file

@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Forms;
namespace FirstPlugin
{
public class NLG_PCK : TreeNodeFile, IFileFormat
{
public FileType FileType { get; set; } = FileType.Archive;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Audio Archive" };
public string[] Extension { get; set; } = new string[] { "*.pck" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
using (var reader = new Toolbox.Library.IO.FileReader(stream, true))
{
return reader.CheckSignature(4, "AKPK");
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
public List<AudioEntry> Entries = new List<AudioEntry>();
public void Load(System.IO.Stream stream)
{
Text = FileName;
using (var reader = new FileReader(stream))
{
uint magic = reader.ReadUInt32();
uint audioInfoSize = reader.ReadUInt32();
reader.SeekBegin(48);
uint numEntries = reader.ReadUInt32();
uint audioOffset = audioInfoSize + 12;
for (int i = 0; i < numEntries; i++)
{
AudioEntry entry = new AudioEntry();
entry.ImageKey = "bfwav";
entry.SelectedImageKey = "bfwav";
Nodes.Add(entry);
entry.HashID = reader.ReadUInt32();
uint alignment = reader.ReadUInt32();
uint AudioSize = reader.ReadUInt32();
uint unk = reader.ReadUInt32();
reader.ReadUInt32(); //0
entry.Text = entry.HashID.ToString("X") + ".wav";
using (reader.TemporarySeek(audioOffset, System.IO.SeekOrigin.Begin))
{
reader.Align((int)alignment);
entry.AudioData = reader.ReadBytes((int)AudioSize);
audioOffset = (uint)reader.Position;
}
}
}
}
public void Unload()
{
}
public void Save(System.IO.Stream stream)
{
}
public class AudioEntry : TreeNodeCustom, IContextMenuNode
{
public uint HashID { get; set; }
public byte[] AudioData { get; set; }
public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new ToolStripMenuItem("Export", null, ExportAction, Keys.Control | Keys.E));
return Items.ToArray();
}
private void ExportAction(object sender, EventArgs args)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = Text;
sfd.Filter = "Raw Data (*.*)|*.*";
if (sfd.ShowDialog() == DialogResult.OK)
{
System.IO.File.WriteAllBytes(sfd.FileName, AudioData);
}
}
public override void OnClick(TreeView treeview)
{
HexEditor editor = (HexEditor)LibraryGUI.GetActiveContent(typeof(HexEditor));
if (editor == null)
{
editor = new HexEditor();
LibraryGUI.LoadEditor(editor);
}
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.LoadData(AudioData);
}
}
}
}

View file

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Forms;
namespace FirstPlugin
{
public class NLOC_Wrapper : TreeNodeCustom
{
public Stream DataStream;
public NLG_NLOC LocFile;
public NLOC_Wrapper(string name, Stream stream)
{
Text = name;
DataStream = stream;
}
public override void OnClick(TreeView treeview)
{
if (LocFile == null) {
LocFile = (NLG_NLOC)STFileLoader.OpenFileFormat(DataStream, "", true, true);
}
TextEditor editor = (TextEditor)LibraryGUI.GetActiveContent(typeof(TextEditor));
if (editor == null)
{
editor = new TextEditor();
LibraryGUI.LoadEditor(editor);
}
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.FillEditor(LocFile.ConvertToString());
}
}
}

View file

@ -2,12 +2,628 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Forms;
using Toolbox.Library.Rendering;
namespace FirstPlugin.PunchOutWii
{
public class PO_DICT
public enum MaterailPresets : uint
{
EnvDiffuseDamage = 0x1ACE1D01,
}
public class PO_DICT : TreeNodeFile, IFileFormat
{
public FileType FileType { get; set; } = FileType.Archive;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Punch Out Wii Dictionary" };
public string[] Extension { get; set; } = new string[] { "*.dict" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool CanAddFiles { get; set; }
public bool CanRenameFiles { get; set; }
public bool CanReplaceFiles { get; set; }
public bool CanDeleteFiles { get; set; }
public bool Identify(System.IO.Stream stream)
{
using (var reader = new Toolbox.Library.IO.FileReader(stream, true))
{
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
return reader.ReadUInt32() == 0xA9F32458;
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
private bool DrawablesLoaded;
public override void OnAfterAdded()
{
if (!DrawablesLoaded)
{
ObjectEditor.AddContainer(DrawableContainer);
DrawablesLoaded = true;
}
}
public DrawableContainer DrawableContainer = new DrawableContainer();
public PunchOutWii_Renderer Renderer;
private DictionaryFile HeaderFile;
public void Load(System.IO.Stream stream)
{
DrawableContainer.Name = FileName;
Renderer = new PunchOutWii_Renderer();
DrawableContainer.Drawables.Add(Renderer);
Text = FileName;
HeaderFile = new DictionaryFile();
HeaderFile.Read(new FileReader(stream), FilePath);
var HashList = NLG_Common.HashNames;
string DataFile = $"{FilePath.Replace(".dict", ".data")}";
if (System.IO.File.Exists(DataFile)) {
using (var reader = new FileReader(DataFile, true))
{
reader.SetByteOrder(true);
TreeNode blocks = new TreeNode("Blocks");
TreeNode chunks = new TreeNode("Chunks");
TreeNode modelFolder = new TreeNode("Models");
foreach (var blockInfo in HeaderFile.Blocks)
{
ChunkViewer chunkNode = new ChunkViewer("block");
if (blockInfo.Size > 0)
blocks.Nodes.Add(chunkNode);
chunkNode.FileData = new SubStream(reader.BaseStream, blockInfo.Offset, blockInfo.Size);
}
List<PO_Texture> currentTextures = new List<PO_Texture>();
List<ModelFileData> modelData = new List<ModelFileData>();
ModelFileData currentModel = null;
STTextureFolder textureFolder = new STTextureFolder("Textures");
Nodes.Add(blocks);
Nodes.Add(chunks);
Nodes.Add(textureFolder);
Nodes.Add(modelFolder);
foreach (var chunk in HeaderFile.DataChunks)
{
if (chunk.BlockIndex == -1)
continue;
ChunkViewer chunkNode = new ChunkViewer(chunk.Type.ToString("") + " " + chunk.Type.ToString("X"));
chunks.Nodes.Add(chunkNode);
var blockInfo = HeaderFile.Blocks[chunk.BlockIndex];
if (blockInfo.Offset + chunk.Offset + chunk.Size > reader.BaseStream.Length)
continue;
chunkNode.FileData = new SubStream(reader.BaseStream, blockInfo.Offset + chunk.Offset, chunk.Size);
uint chunkPos = blockInfo.Offset + chunk.Offset;
reader.SeekBegin(chunkPos);
switch (chunk.Type)
{
case SectionMagic.MaterialData:
currentModel = new ModelFileData();
currentModel.MaterialOffset = chunkPos;
modelData.Add(currentModel);
break;
case SectionMagic.TextureHeaders:
uint numTextures = chunk.Size / 96;
for (int i = 0; i < numTextures; i++)
{
var tex = new PO_Texture();
tex.ImageKey = "texture";
tex.SelectedImageKey = "texture";
tex.Read(reader);
tex.Text = tex.HashID.ToString("X");
if (HashList.ContainsKey(tex.HashID))
tex.Text = HashList[tex.HashID];
currentTextures.Add(tex);
Renderer.TextureList.Add(tex.Text, tex);
textureFolder.Nodes.Add(tex);
}
break;
case SectionMagic.TextureData:
for (int i = 0; i < currentTextures.Count; i++)
{
reader.SeekBegin(chunkPos + currentTextures[i].DataOffset);
currentTextures[i].ImageData = reader.ReadBytes((int)currentTextures[i].ImageSize);
}
break;
case SectionMagic.IndexData:
currentModel.indexBufferOffset = chunkPos;
break;
case SectionMagic.VertexData:
currentModel.vertexBufferOffset = chunkPos;
break;
case SectionMagic.MeshData:
uint numMeshes = chunk.Size / 52;
for (int i = 0; i < numMeshes; i++)
{
reader.SeekBegin(chunkPos + (i * 52));
PO_Mesh mesh = new PO_Mesh(reader);
currentModel.meshes.Add(mesh);
}
break;
case SectionMagic.VertexAttributePointerData:
uint numAttributes = chunk.Size / 8;
for (int i = 0; i < numAttributes; i++)
{
PO_VertexAttribute att = new PO_VertexAttribute();
att.Offset = reader.ReadUInt32();
att.Type = reader.ReadByte();
att.Stride = reader.ReadByte();
reader.ReadUInt16();
currentModel.attributes.Add(att);
}
break;
case SectionMagic.ModelData:
uint numModels = chunk.Size / 12;
Console.WriteLine($"numModels {numModels}");
for (int i = 0; i < numModels; i++)
{
PO_Model mdl = new PO_Model();
mdl.ParentDictionary = this;
mdl.HashID = reader.ReadUInt32();
mdl.NumMeshes = reader.ReadUInt32();
reader.ReadUInt32(); //0
currentModel.models.Add(mdl);
}
break;
case SectionMagic.BoneData:
STSkeleton Skeleton = new STSkeleton();
DrawableContainer.Drawables.Add(Skeleton);
uint numBones = chunk.Size / 68;
for (int i = 0; i < numBones; i++)
{
reader.SeekBegin(chunkPos + (i * 68));
uint HashID = reader.ReadUInt32();
reader.ReadUInt32(); //unk
reader.ReadUInt32(); //unk
reader.ReadUInt32(); //unk
reader.ReadSingle(); //0
var Scale = new OpenTK.Vector3(
reader.ReadSingle(),
reader.ReadSingle(),
reader.ReadSingle());
reader.ReadSingle(); //0
var Rotate = new OpenTK.Vector3(
reader.ReadSingle(),
reader.ReadSingle(),
reader.ReadSingle());
reader.ReadSingle(); //0
var Position = new OpenTK.Vector3(
reader.ReadSingle(),
reader.ReadSingle(),
reader.ReadSingle());
reader.ReadSingle(); //1
STBone bone = new STBone(Skeleton);
bone.Text = HashID.ToString("X");
if (NLG_Common.HashNames.ContainsKey(HashID))
bone.Text = NLG_Common.HashNames[HashID];
else
Console.WriteLine($"bone hash {HashID}");
bone.position = new float[3] { Position.X, Position.Z, -Position.Y };
bone.rotation = new float[4] { Rotate.X, Rotate.Z, -Rotate.Y, 1 };
bone.scale = new float[3] { 0.2f, 0.2f, 0.2f };
bone.RotationType = STBone.BoneRotationType.Euler;
Skeleton.bones.Add(bone);
}
Skeleton.reset();
Skeleton.update();
break;
}
}
foreach (var modelFile in modelData)
{
int pointerIndex = 0;
foreach (var model in modelFile.models)
{
model.Text = model.HashID.ToString("X");
if (HashList.ContainsKey(model.HashID))
model.Text = HashList[model.HashID];
modelFolder.Nodes.Add(model);
for (int i = 0; i < model.NumMeshes; i++)
{
var mesh = modelFile.meshes[i];
RenderableMeshWrapper genericMesh = new RenderableMeshWrapper();
model.Nodes.Add(genericMesh);
model.RenderedMeshes.Add(genericMesh);
Renderer.Meshes.Add(genericMesh);
genericMesh.Text = mesh.HashID.ToString("X");
if (HashList.ContainsKey(mesh.HashID))
genericMesh.Text = HashList[mesh.HashID];
string material = mesh.MaterialHashID.ToString("X");
if (HashList.ContainsKey(mesh.MaterialHashID))
material = HashList[mesh.MaterialHashID];
genericMesh.Nodes.Add(material);
genericMesh.Material = new STGenericMaterial();
reader.SeekBegin(modelFile.MaterialOffset + mesh.MaterialOffset);
switch (mesh.MaterailPreset)
{
case MaterailPresets.EnvDiffuseDamage:
{
uint diffuseMapHashID = reader.ReadUInt32();
uint diffuseMapParam = reader.ReadUInt32();
uint envSpecMapHashID = reader.ReadUInt32();
uint envSpecMapParam = reader.ReadUInt32();
uint specMapHashID = reader.ReadUInt32();
uint specMapParam = reader.ReadUInt32();
uint megaStrikeMapHashID = reader.ReadUInt32();
uint megaStrikeMapParam = reader.ReadUInt32();
uint dirtMapHashID = reader.ReadUInt32();
uint dirtMapParam = reader.ReadUInt32();
uint iceMapHashID = reader.ReadUInt32();
uint iceMapParam = reader.ReadUInt32();
string diffuseName = diffuseMapHashID.ToString("X");
if (HashList.ContainsKey(diffuseMapHashID))
diffuseName = HashList[diffuseMapHashID];
var texUnit = 1;
genericMesh.Material.TextureMaps.Add(new STGenericMatTexture()
{
textureUnit = texUnit++,
Type = STGenericMatTexture.TextureType.Diffuse,
Name = diffuseName,
});
}
break;
default:
{
uint diffuseMapHashID = reader.ReadUInt32();
string diffuseName = diffuseMapHashID.ToString("X");
if (HashList.ContainsKey(diffuseMapHashID))
diffuseName = HashList[diffuseMapHashID];
Console.WriteLine($"diffuseName {diffuseName}");
var texUnit = 1;
genericMesh.Material.TextureMaps.Add(new STGenericMatTexture()
{
textureUnit = texUnit++,
Type = STGenericMatTexture.TextureType.Diffuse,
Name = diffuseName,
});
}
break;
}
Console.WriteLine($"mesh {i}");
STGenericPolygonGroup polyGroup = new STGenericPolygonGroup();
genericMesh.PolygonGroups.Add(polyGroup);
reader.SeekBegin(modelFile.indexBufferOffset + mesh.IndexStartOffset);
List<int> faces = new List<int>();
for (int f = 0; f < mesh.IndexCount; f++)
{
if (mesh.IndexFormat == 0)
polyGroup.faces.Add(reader.ReadUInt16());
else
polyGroup.faces.Add(reader.ReadByte());
}
if (mesh.FaceType == PO_Mesh.PolygonType.TriangleStrips)
polyGroup.PrimativeType = STPrimativeType.TrangleStrips;
else
polyGroup.PrimativeType = STPrimativeType.Triangles;
for (int a = 0; a < mesh.NumAttributePointers; a++)
Console.WriteLine($"pointer {genericMesh.Text} { modelFile.vertexBufferOffset + modelFile.attributes[pointerIndex + a].Offset}");
for (int v = 0; v < mesh.VertexCount; v++)
{
Vertex vert = new Vertex();
genericMesh.vertices.Add(vert);
int attributeIndex = 0;
for (int a = 0; a < mesh.NumAttributePointers; a++)
{
var pointer = modelFile.attributes[pointerIndex + a];
reader.SeekBegin(modelFile.vertexBufferOffset + pointer.Offset + (pointer.Stride * v));
if (attributeIndex == 0)
{
if (pointer.Stride == 12)
vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
if (attributeIndex == 1)
{
if (pointer.Stride == 12)
vert.nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
if (attributeIndex == 2)
{
if (pointer.Stride == 4)
vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f);
}
/* if (pointer.Type == 0xD4)
{
vert.boneIds = new List<int>() { reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte() };
}
if (pointer.Type == 0xB0)
{
vert.boneWeights = new List<float>() { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() };
}*/
attributeIndex++;
}
}
genericMesh.TransformPosition(new Vector3(0), new Vector3(-90, 0, 0), new Vector3(1));
pointerIndex += mesh.NumAttributePointers;
}
}
}
}
}
}
public void Save(System.IO.Stream stream)
{
}
public void Unload()
{
}
public class ChunkViewer : TreeNodeCustom, IContextMenuNode
{
public System.IO.Stream FileData;
public ChunkViewer(string text) {
Text = text;
}
public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new STToolStipMenuItem("Export Raw Data", null, Export, Keys.Control | Keys.E));
return Items.ToArray();
}
private void Export(object sender, EventArgs args)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = Text;
sfd.Filter = "Raw Data (*.*)|*.*";
if (sfd.ShowDialog() == DialogResult.OK) {
FileData.ExportToFile(sfd.FileName);
}
}
public override void OnClick(TreeView treeView)
{
HexEditor editor = (HexEditor)LibraryGUI.GetActiveContent(typeof(HexEditor));
if (editor == null)
{
editor = new HexEditor();
LibraryGUI.LoadEditor(editor);
}
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.LoadData(FileData);
}
}
public class ModelFileData
{
public uint MaterialOffset;
public List<PO_Mesh> meshes = new List<PO_Mesh>();
public List<PO_Model> models = new List<PO_Model>();
public List<PO_VertexAttribute> attributes = new List<PO_VertexAttribute>();
public uint vertexBufferOffset = 0;
public uint indexBufferOffset = 0;
}
public class DictionaryFile
{
public List<BlockInfo> Blocks = new List<BlockInfo>();
public List<ChunkDataInfo> DataChunks = new List<ChunkDataInfo>();
public bool IsCompressed;
public uint NumFileEntries;
public uint FileTableOffset;
public uint FileTableSize;
public void Read(FileReader reader, string filePath)
{
reader.SetByteOrder(true);
uint magic = reader.ReadUInt32();
ushort Unknown = reader.ReadUInt16(); //Could also be 2 bytes, not sure. Always 0x0601
IsCompressed = reader.ReadByte() == 1;
reader.ReadByte(); //Padding
reader.ReadUInt32(); //1
reader.ReadUInt32(); //0
NumFileEntries = reader.ReadUInt32();
FileTableSize = reader.ReadUInt32();
//Loop through all possible blocks which makeup the data file.
//They don't have a counter for these but it's always 8 total.
//If there's 0 in place for size, data is unused
uint offset = 0;
for (int i = 0; i < 8; i++)
{
BlockInfo block = new BlockInfo();
block.Offset = offset;
block.Size = reader.ReadUInt32();
block.Parameter = reader.ReadUInt32(); //4 or 32
Blocks.Add(block);
offset += block.Size;
}
//Now use the last offset for the file table in .data files
//The file table also is located in .debug files, however those are
// not necessary and likely left over for debug purposes
FileTableOffset = offset;
string DataFile = $"{filePath.Replace(".dict", ".data")}";
if (System.IO.File.Exists(DataFile))
ParseData(DataFile);
}
private void ParseData(string fileName)
{
using (var reader = new FileReader(fileName))
{
reader.SetByteOrder(true);
//Now for the chunk table. It basically has 2 sections.
//One is for files
//The second contains the data
List<ChunkFileInfo> fileChunks = new List<ChunkFileInfo>();
reader.SeekBegin(FileTableOffset);
for (int i = 0; i < NumFileEntries; i++)
{
ChunkDataInfo chunk = new ChunkDataInfo();
DataChunks.Add(chunk);
byte chunkFlags = reader.ReadByte();
byte unk = reader.ReadByte(); //1
chunk.Type = (SectionMagic)reader.ReadUInt16();
chunk.Size = reader.ReadUInt32();
chunk.Offset = reader.ReadUInt32();
if (chunkFlags == 0x12)
chunk.BlockIndex = 0;
if (chunkFlags == 0x25)
chunk.BlockIndex = 1;
if (chunkFlags == 2)
chunk.BlockIndex = 2;
if (chunkFlags == 0x42)
chunk.BlockIndex = 3;
if (chunkFlags == 3)
chunk.BlockIndex = 0;
}
while (reader.Position <= reader.BaseStream.Length - 12)
{
ChunkDataInfo chunk = new ChunkDataInfo();
DataChunks.Add(chunk);
byte chunkFlags = reader.ReadByte();
byte unk = reader.ReadByte(); //1
chunk.Type = (SectionMagic)reader.ReadUInt16();
chunk.Size = reader.ReadUInt32();
chunk.Offset = reader.ReadUInt32();
byte blockFlag = (byte)(chunkFlags >> 4);
if (blockFlag < 7)
chunk.BlockIndex = (sbyte)blockFlag;
/* Console.WriteLine($"chunkFlags { chunkFlags }");
Console.WriteLine($"unk { unk }");
Console.WriteLine($"Type { chunk.Type }");
Console.WriteLine($"Offset { chunk.Offset }");
Console.WriteLine($"Size { chunk.Size }");*/
}
return;
}
}
}
public enum SectionMagic : ushort
{
TextureHeaders = 0xB601,
TextureData = 0xB603,
MaterialData = 0xB016,
IndexData = 0xB007,
VertexData = 0xB006,
VertexAttributePointerData = 0xB005,
MeshData = 0xB004,
ModelData = 0xB003,
MatrixData = 0xB002,
SkeletonData = 0xB008,
BoneHashes = 0xB00B,
BoneData = 0xB00A,
UnknownHashList = 0xB00C,
}
public class BlockInfo
{
public uint Offset;
public uint Size;
public uint Parameter;
}
public class ChunkFileInfo
{
public uint Type;
public uint NumberEntries;
public uint NumberSubEntries;
}
public class ChunkDataInfo
{
public sbyte BlockIndex = -1;
public SectionMagic Type;
public uint Offset;
public uint Size;
}
}
}

View file

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Toolbox.Library.IO;
namespace FirstPlugin.PunchOutWii
{
public class PO_Mesh
{
public uint[] BoneHashes;
public enum PolygonType : byte
{
Triangles = 0,
TriangleStrips = 1,
}
public uint IndexStartOffset;
public ushort IndexFormat;
public uint IndexCount;
public ushort VertexCount;
public byte Unknown;
public byte NumAttributePointers;
public uint HashID;
public uint MaterialHashID;
//Only on gamecube (wii uses seperate section)
public uint TexturHashID;
public uint MaterialOffset;
public PolygonType FaceType = PolygonType.TriangleStrips;
public MaterailPresets MaterailPreset;
public PO_Mesh(FileReader reader)
{
IndexStartOffset = reader.ReadUInt32();
uint indexFlags = reader.ReadUInt32();
IndexCount = (indexFlags & 0xffffff);
IndexFormat = (ushort)(indexFlags >> 24);
VertexCount = reader.ReadUInt16();
Unknown = reader.ReadByte();
NumAttributePointers = reader.ReadByte();
reader.ReadUInt32();
MaterialHashID = reader.ReadUInt32();
HashID = reader.ReadUInt32();
reader.ReadUInt32();
reader.ReadUInt32();
reader.ReadUInt32();
MaterialOffset = reader.ReadUInt32();
reader.ReadUInt32();
reader.ReadUInt32();
MaterailPreset = (MaterailPresets)MaterialHashID;
}
}
}

View file

@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.Forms;
using Toolbox.Library.Rendering;
namespace FirstPlugin.PunchOutWii
{
public class RenderableMeshWrapper : GenericRenderedObject
{
public STGenericMaterial Material = new STGenericMaterial();
public override STGenericMaterial GetMaterial()
{
return Material;
}
}
public class PO_Model : TreeNodeCustom, IContextMenuNode
{
public PO_DICT ParentDictionary;
public uint NumMeshes;
public uint HashID { get; set; }
public List<PO_Mesh> Meshes = new List<PO_Mesh>();
public List<RenderableMeshWrapper> RenderedMeshes = new List<RenderableMeshWrapper>();
Viewport viewport
{
get
{
var editor = LibraryGUI.GetObjectEditor();
return editor.GetViewport();
}
set
{
var editor = LibraryGUI.GetObjectEditor();
editor.LoadViewport(value);
}
}
private bool loaded = false;
public override void OnClick(TreeView treeView)
{
if (!loaded)
UpdateVertexData();
if (Runtime.UseOpenGL)
{
if (viewport == null)
{
viewport = new Viewport(ObjectEditor.GetDrawableContainers());
viewport.Dock = DockStyle.Fill;
}
Viewport editor = (Viewport)LibraryGUI.GetActiveContent(typeof(Viewport));
if (editor == null)
{
editor = viewport;
LibraryGUI.LoadEditor(viewport);
}
viewport.ReloadDrawables(ParentDictionary.DrawableContainer);
viewport.Text = Text;
}
}
private void UpdateVertexData()
{
ParentDictionary.Renderer.UpdateVertexData();
}
public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new ToolStripMenuItem("Export", null, ExportModelAction, Keys.Control | Keys.E));
return Items.ToArray();
}
private void ExportModelAction(object sender, EventArgs args)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Supported Formats|*.dae;";
if (sfd.ShowDialog() == DialogResult.OK)
{
ExportModel(sfd.FileName);
}
}
private void ExportModel(string FileName)
{
AssimpSaver assimp = new AssimpSaver();
ExportModelSettings settings = new ExportModelSettings();
List<STGenericMaterial> Materials = new List<STGenericMaterial>();
// foreach (var msh in DataDictionary.Renderer.Meshes)
// Materials.Add(msh.GetMaterial());
var model = new STGenericModel();
model.Materials = Materials;
model.Objects = RenderedMeshes;
assimp.SaveFromModel(model, FileName, new List<STGenericTexture>(), new STSkeleton());
}
}
}

View file

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Forms;
namespace FirstPlugin.PunchOutWii
{
public class PO_Texture : STGenericTexture, ISingleTextureIconLoader
{
public byte[] ImageData;
public STGenericTexture IconTexture => this;
public Dictionary<byte, Decode_Gamecube.TextureFormats> FormatList = new Dictionary<byte, Decode_Gamecube.TextureFormats>
{
{ 0x8, Decode_Gamecube.TextureFormats.RGBA32 },
{ 0x7, Decode_Gamecube.TextureFormats.RGB565 },
{ 0x6, Decode_Gamecube.TextureFormats.CMPR },
{ 0x5, Decode_Gamecube.TextureFormats.RGB5A3 },
{ 0x4, Decode_Gamecube.TextureFormats.IA4 },
{ 0x3, Decode_Gamecube.TextureFormats.I8 },
{ 0x2, Decode_Gamecube.TextureFormats.I4 },
};
public override bool CanEdit { get; set; } = false;
public override void SetImageData(System.Drawing.Bitmap bitmap, int ArrayLevel)
{
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
{
return Decode_Gamecube.GetMipLevel(ImageData, Width, Height, MipCount, (uint)MipLevel, Format);
}
public override void OnClick(TreeView treeView)
{
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
if (editor == null)
{
editor = new ImageEditorBase();
editor.Dock = DockStyle.Fill;
LibraryGUI.LoadEditor(editor);
}
editor.LoadProperties(GenericProperties);
editor.LoadImage(this);
}
public uint HashID { get; set; }
public uint DataOffset { get; set; }
public uint ImageSize { get; set; }
public void Read(FileReader reader)
{
long pos = reader.Position;
HashID = reader.ReadUInt32();
Width = reader.ReadUInt16();
Height = reader.ReadUInt16();
reader.ReadUInt16(); //0
reader.ReadByte(); //unk
reader.ReadByte(); //unk
reader.ReadByte(); //unk
byte format = reader.ReadByte();
reader.ReadUInt16(); //unk
reader.ReadUInt16(); //unk
reader.ReadUInt16(); //unk
DataOffset = reader.ReadUInt32();
reader.ReadUInt32(); //unk 0x00412BA1
var formatGC = Decode_Gamecube.TextureFormats.CMPR;
if (FormatList.ContainsKey(format))
formatGC = FormatList[format];
Format = Decode_Gamecube.ToGenericFormat(formatGC);
PlatformSwizzle = PlatformSwizzle.Platform_Gamecube;
ImageSize = (uint)Decode_Gamecube.GetDataSize(formatGC, (int)Width, (int)Height);
reader.SeekBegin(pos + 96);
}
public override TEX_FORMAT[] SupportedFormats
{
get
{
return new TEX_FORMAT[]
{
TEX_FORMAT.I4,
TEX_FORMAT.I8,
TEX_FORMAT.IA4,
TEX_FORMAT.IA8,
TEX_FORMAT.RGB565,
TEX_FORMAT.RGB5A3,
TEX_FORMAT.RGBA32,
TEX_FORMAT.C4,
TEX_FORMAT.C8,
TEX_FORMAT.C14X2,
TEX_FORMAT.CMPR,
};
}
}
}
}

View file

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FirstPlugin.PunchOutWii
{
public class PO_VertexAttribute
{
public uint Offset;
public byte Stride;
public byte Type;
public byte Format;
}
}

View file

@ -213,6 +213,7 @@
<Compile Include="FileFormats\Archives\DARC.cs" />
<Compile Include="FileFormats\Archives\DAT_Bayonetta.cs" />
<Compile Include="FileFormats\Archives\GFA.cs" />
<Compile Include="FileFormats\MKAGPDX\LM2_ARCADE_Model.cs" />
<Compile Include="FileFormats\NLG\LM2\LM2_Material.cs" />
<Compile Include="FileFormats\NLG\LM3\LM3_ChunkTable.cs" />
<Compile Include="FileFormats\NLG\LM3\LM3_DICT.cs" />
@ -221,7 +222,12 @@
<Compile Include="FileFormats\NLG\LM3\LM3_Model.cs" />
<Compile Include="FileFormats\NLG\LM3\TexturePOWE.cs" />
<Compile Include="FileFormats\Archives\PKZ.cs" />
<Compile Include="FileFormats\NLG\MarioStrikers\StrikersRLG.cs" />
<Compile Include="FileFormats\NLG\MarioStrikers\StrikersRLT.cs" />
<Compile Include="FileFormats\NLG\NLG_Common.cs" />
<Compile Include="FileFormats\NLG\NLG_NLOC.cs" />
<Compile Include="FileFormats\NLG\NLOC_Wrapper.cs" />
<Compile Include="FileFormats\NLG\NLG_PCK.cs" />
<Compile Include="FileFormats\NLG\PunchOutWii\PO_DICT.cs" />
<Compile Include="FileFormats\Archives\VIBS.cs" />
<Compile Include="FileFormats\Audio\Archives\AudioCommon.cs" />
@ -340,6 +346,10 @@
<Compile Include="FileFormats\Layout\Wrappers\MatWrapper.cs" />
<Compile Include="FileFormats\Message\MSBP.cs" />
<Compile Include="FileFormats\CrashBandicoot\IGZ_TEX.cs" />
<Compile Include="FileFormats\NLG\PunchOutWii\PO_Mesh.cs" />
<Compile Include="FileFormats\NLG\PunchOutWii\PO_Model.cs" />
<Compile Include="FileFormats\NLG\PunchOutWii\PO_Texture.cs" />
<Compile Include="FileFormats\NLG\PunchOutWii\PO_VertexAttribute.cs" />
<Compile Include="FileFormats\Pikmin1\MOD.cs" />
<Compile Include="FileFormats\Pikmin1\TXE.cs" />
<Compile Include="FileFormats\Rom\3DS\NCSDStructs.cs" />
@ -364,6 +374,8 @@
<Compile Include="FileFormats\Layout\CAFE\BflytShader.cs" />
<Compile Include="GL\Custom2D\KCLRendering2D.cs" />
<Compile Include="GL\LM3_Renderer.cs" />
<Compile Include="GL\PunchOutWii_Renderer.cs" />
<Compile Include="GL\Strikers_Renderer.cs" />
<Compile Include="GUI\BFLYT\Animations\Basic\AddAnimGroupDialog.cs">
<SubType>Form</SubType>
</Compile>
@ -1874,7 +1886,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="FileFormats\EvemtFlow\" />
<Folder Include="FileFormats\NLG\MarioStrikers\" />
<Folder Include="FileFormats\NLG\Common\" />
<Folder Include="GUI\Byaml\MuuntEditor\Renderables\" />
</ItemGroup>
<ItemGroup>

View file

@ -765,18 +765,18 @@ namespace FirstPlugin
PrimitiveType primitiveType = PrimitiveType.Triangles;
switch (m.lodMeshes[m.DisplayLODIndex].PrimitiveType)
switch (m.lodMeshes[m.DisplayLODIndex].PrimativeType)
{
case STPolygonType.Line:
case STPrimativeType.Lines:
primitiveType = PrimitiveType.Lines;
break;
case STPolygonType.LineStrip:
case STPrimativeType.LineStrips:
primitiveType = PrimitiveType.LineStrip;
break;
case STPolygonType.Point:
case STPrimativeType.Points:
primitiveType = PrimitiveType.Points;
break;
case STPolygonType.Triangle:
case STPrimativeType.Triangles:
primitiveType = PrimitiveType.Triangles;
break;
}

View file

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Toolbox.Library.Rendering;
using GL_EditorFramework.GL_Core;
using GL_EditorFramework.Interfaces;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using Toolbox.Library;
namespace FirstPlugin.PunchOutWii
{
public class PunchOutWii_Renderer : GenericModelRenderer
{
public Dictionary<string, STGenericTexture> TextureList = new Dictionary<string, STGenericTexture>();
public override void OnRender(GLControl control)
{
}
public override int BindTexture(STGenericMatTexture tex, ShaderProgram shader)
{
GL.ActiveTexture(TextureUnit.Texture0 + tex.textureUnit + 1);
GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.RenderableTex.TexID);
string activeTex = tex.Name;
foreach (var texture in TextureList.Values)
{
if (texture.Text == tex.Name)
{
BindGLTexture(tex, shader, texture);
return tex.textureUnit + 1;
}
}
return tex.textureUnit + 1;
}
}
}

View file

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Toolbox.Library.Rendering;
using GL_EditorFramework.GL_Core;
using GL_EditorFramework.Interfaces;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using Toolbox.Library;
namespace FirstPlugin.NLG
{
public class Strikers_Renderer : GenericModelRenderer
{
public override void OnRender(GLControl control)
{
}
public override int BindTexture(STGenericMatTexture tex, ShaderProgram shader)
{
GL.ActiveTexture(TextureUnit.Texture0 + tex.textureUnit + 1);
GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.RenderableTex.TexID);
string activeTex = tex.Name;
foreach (var texture in PluginRuntime.stikersTextures)
{
if (texture.Text == tex.Name)
{
BindGLTexture(tex, shader, texture);
return tex.textureUnit + 1;
}
}
return tex.textureUnit + 1;
}
}
}

View file

@ -287,8 +287,8 @@ namespace FirstPlugin
lodFormatCB.Bind(typeof(STIndexFormat), activeLodMesh, "IndexFormat");
lodFormatCB.SelectedItem = activeLodMesh.IndexFormat;
lodPrimativeTypeCB.Bind(typeof(STPolygonType), activeLodMesh, "PrimitiveType");
lodPrimativeTypeCB.SelectedItem = activeLodMesh.PrimitiveType;
lodPrimativeTypeCB.Bind(typeof(STPrimativeType), activeLodMesh, "PrimitiveType");
lodPrimativeTypeCB.SelectedItem = activeLodMesh.PrimativeType;
lodVertexSkipUD.Value = activeLodMesh.FirstVertex;
lodFaceCountUD.Value = activeLodMesh.faces.Count;

View file

@ -391,7 +391,15 @@ namespace FirstPlugin
Formats.Add(typeof(DAT_Bayonetta));
Formats.Add(typeof(XCI));
Formats.Add(typeof(VIBS));
Formats.Add(typeof(NLG.StrikersRLT));
Formats.Add(typeof(NLG.StrikersRLG));
Formats.Add(typeof(PunchOutWii.PO_DICT));
Formats.Add(typeof(LM2_ARCADE_Model));
Formats.Add(typeof(NLG_NLOC));
Formats.Add(typeof(NLG_PCK));
// Formats.Add(typeof(MSBP));
// Formats.Add(typeof(BFGRP));

View file

@ -28,6 +28,8 @@ namespace FirstPlugin
public static List<BNTX> bntxContainers = new List<BNTX>();
public static List<BFRESGroupNode> ftexContainers = new List<BFRESGroupNode>();
public static List<BCRESGroupNode> bcresTexContainers = new List<BCRESGroupNode>();
public static List<NLG.StrikersRLT.TextureEntry> stikersTextures = new List<NLG.StrikersRLT.TextureEntry>();
public static string ExternalFMATPath = "";
public static string OdysseyGamePath = "";
public static string Mk8GamePath = "";

View file

@ -29681,4 +29681,828 @@ fe_circuit_button
LeftJabSuccess
crowd_dk_copy0
GTHugStunWindow
BullChargePresentation
BullChargePresentation
LuigiEyeMaterial/Default
LuigiEyeMaterial/DepthShell
LuigiEyeMaterial/PixelMap
LuigiEyeMaterial/CastSilhouette
LuigiEyeMaterial/WithTransparency
LuigiEyeMaterial/Unlit
LuigiEyeMaterial/FadeTransition
LuigiEyeMaterial/WithAdditiveAlpha
LuigiEyeMaterial/ShadowCast
LuigiEyeMaterial/LightingOnly
LuigiEyeMaterial/ColorShift
GhostMaterial/Default
GhostMaterial/DepthShell
GhostMaterial/PixelMap
GhostMaterial/WithTransparency
GhostMaterial/WithAdditiveAlpha
EnvironmentMaterial/Default
EnvironmentMaterial/DepthShell
EnvironmentMaterial/PixelMap
EnvironmentMaterial/DiffuseNonLit
EnvironmentMaterial/LightmapsOnly
EnvironmentMaterial/LightingOnly
EnvironmentMaterial/DiffuseLightingOnly
EnvironmentMaterial/NoSilhouette
EnvironmentMaterial/CastSilhouette
EnvironmentMaterial/NoSilhouetteBackface
EnvironmentMaterial/NoSilhouetteAdditiveAlpha
EnvironmentMaterial/Default_NoShadows
EnvironmentMaterial/NoSilhouette_NoShadows
EnvironmentMaterial/WithTransparency_NoShadows
EnvironmentMaterial/CastSilhouette_NoShadows
EnvironmentMaterial/WithTransparency
EnvironmentMaterial/WithAdditiveAlpha
EnvironmentMaterial/ShadowCast
EnvironmentSpecularRigidSkin/Default
EnvironmentSpecularRigidSkin/DepthShell
EnvironmentSpecularRigidSkin/PixelMap
EnvironmentSpecularRigidSkin/DiffuseNonLit
EnvironmentSpecularRigidSkin/LightmapsOnly
EnvironmentSpecularRigidSkin/LightingOnly
EnvironmentSpecularRigidSkin/DiffuseLightingOnly
EnvironmentSpecularRigidSkin/NoSilhouette
EnvironmentSpecularRigidSkin/CastSilhouette
EnvironmentSpecularRigidSkin/NoSilhouetteBackface
EnvironmentSpecularRigidSkin/NoSilhouetteAdditiveAlpha
EnvironmentSpecularRigidSkin/Default_NoShadows
EnvironmentSpecularRigidSkin/NoSilhouette_NoShadows
EnvironmentSpecularRigidSkin/WithTransparency_NoShadows
EnvironmentSpecularRigidSkin/CastSilhouette_NoShadows
EnvironmentSpecularRigidSkin/WithTransparency
EnvironmentSpecularRigidSkin/WithAdditiveAlpha
EnvironmentSpecularRigidSkin/ShadowCast
EnvironmentPTMaterial/ProceduralTexture
EnvironmentPTMaterial/Default
EnvironmentPTMaterial/DepthShell
EnvironmentPTMaterial/PixelMap
EnvironmentPTMaterial/DiffuseNonLit
EnvironmentPTMaterial/LightmapsOnly
EnvironmentPTMaterial/LightingOnly
EnvironmentPTMaterial/DiffuseLightingOnly
EnvironmentPTMaterial/NoSilhouette
EnvironmentPTMaterial/CastSilhouette
EnvironmentPTMaterial/NoSilhouetteBackface
EnvironmentPTMaterial/NoSilhouetteAdditiveAlpha
EnvironmentPTMaterial/Default_NoShadows
EnvironmentPTMaterial/NoSilhouette_NoShadows
EnvironmentPTMaterial/WithTransparency_NoShadows
EnvironmentPTMaterial/CastSilhouette_NoShadows
EnvironmentPTMaterial/WithTransparency
EnvironmentPTMaterial/WithAdditiveAlpha
EnvironmentPTMaterial/ShadowCast
DiffuseSkin/DepthShell
DiffuseSkin/PixelMap
DiffuseSkin/Default
DiffuseSkin/WithTransparency
DiffuseSkin/WithAdditiveAlpha
DiffuseSkin/CastSilhouette
EnvironmentRigidSkin/Default
EnvironmentRigidSkin/DepthShell
EnvironmentRigidSkin/PixelMap
EnvironmentRigidSkin/DiffuseNonLit
EnvironmentRigidSkin/LightmapsOnly
EnvironmentRigidSkin/LightingOnly
EnvironmentRigidSkin/DiffuseLightingOnly
EnvironmentRigidSkin/NoSilhouette
EnvironmentRigidSkin/CastSilhouette
EnvironmentRigidSkin/NoSilhouetteBackface
EnvironmentRigidSkin/NoSilhouetteAdditiveAlpha
EnvironmentRigidSkin/Default_NoShadows
EnvironmentRigidSkin/NoSilhouette_NoShadows
EnvironmentRigidSkin/WithTransparency_NoShadows
EnvironmentRigidSkin/CastSilhouette_NoShadows
EnvironmentRigidSkin/WithTransparency
EnvironmentRigidSkin/WithAdditiveAlpha
EnvironmentRigidSkin/ShadowCast
ClothMaterial/Default
ClothMaterial/DepthShell
ClothMaterial/PixelMap
ClothMaterial/Silhouette
ClothMaterial/CastSilhouette
ClothMaterial/WithTransparency
ClothMaterial/WithAdditiveAlpha
ClothMaterial/ShadowCast
MoolahMaterial/Default
MoolahMaterial/DepthShell
MoolahMaterial/PixelMap
MoolahMaterial/Silhouette
MoolahMaterial/Debug
MoolahMaterial/WithTransparency
MoolahMaterial/WithAdditiveAlpha
MoolahMaterial/ShadowCast
UVSlidingRigidSkin/Default
UVSlidingRigidSkin/AlphaBlend
UVSlidingRigidSkin/AddBlend
UVSlidingRigidSkin/TwoSided
UVSlidingRigidSkin/AlphaBlendTwoSided
UVSlidingRigidSkin/AddBlendTwoSided
UVSlidingRigidSkin/DepthShell
UVSlidingRigidSkin/PixelMap
WindowMaterial/Default
WindowMaterial/PixelMap
WindowMaterial/DepthShell
DiffuseVertColor/Default
DiffuseVertColor/PixelMap
DiffuseVertColor/DepthClear
DiffuseVertColor/WithTransparency
DiffuseVertColor/WithTransparencyNoAlphaWrites
DiffuseVertColor/TwoSidedAlpha
DiffuseVertColor/AdditiveTwoSidedAlpha
DiffuseVertColor/Clamped
DiffuseVertColor/ClampedWithTransparency
DiffuseVertColor/ParticleAlphaDepth
DiffuseVertColor/ParticleAlphaNoDepth
DiffuseVertColor/ParticleAdditiveDepth
DiffuseVertColor/ParticleAdditiveNoDepth
DiffuseVertColor/ClampedWithTransparencyNoAlphaWrites
DiffuseVertColor/ClampedAdditive
DiffuseVertColor/PrePortalStencil
DiffuseVertColor/PostPortalStencil
EnvironmentSphereMapRigidSkin/Default
EnvironmentSphereMapRigidSkin/DepthShell
EnvironmentSphereMapRigidSkin/PixelMap
EnvironmentSphereMapRigidSkin/DiffuseNonLit
EnvironmentSphereMapRigidSkin/LightmapsOnly
EnvironmentSphereMapRigidSkin/LightingOnly
EnvironmentSphereMapRigidSkin/DiffuseLightingOnly
EnvironmentSphereMapRigidSkin/NoSilhouette
EnvironmentSphereMapRigidSkin/CastSilhouette
EnvironmentSphereMapRigidSkin/NoSilhouetteBackface
EnvironmentSphereMapRigidSkin/NoSilhouetteAdditiveAlpha
EnvironmentSphereMapRigidSkin/Default_NoShadows
EnvironmentSphereMapRigidSkin/NoSilhouette_NoShadows
EnvironmentSphereMapRigidSkin/WithTransparency_NoShadows
EnvironmentSphereMapRigidSkin/CastSilhouette_NoShadows
EnvironmentSphereMapRigidSkin/WithTransparency
EnvironmentSphereMapRigidSkin/WithAdditiveAlpha
EnvironmentSphereMapRigidSkin/ShadowCast
EnvironmentSphereMapRigidSkin/StatueBack
EnvironmentSphereMapRigidSkin/StatueFront
DiffuseConstColor/Default
DiffuseConstColor/DepthShell
DiffuseConstColor/PixelMap
DiffuseConstColor/ClampedWithTransparency
DiffuseConstColor/ParticleAlphaDepth
DiffuseConstColor/ParticleAlphaNoDepth
DiffuseConstColor/ParticleAdditiveDepth
DiffuseConstColor/WithTransparency
DiffuseConstColor/WithAdditiveAlpha
DiffuseConstColor/PortalStencil
PestMaterial/Default
PestMaterial/DepthShell
PestMaterial/PixelMap
PestMaterial/CastSilhouette
PestMaterial/Silhouette
PestMaterial/WithTransparency
PestMaterial/WithAlphaTestBlend
PestMaterial/WithAdditiveAlpha
PestMaterial/TwoSided
PestMaterial/WithTransparencyTwoSided
PestMaterial/WithAlphaTestBlendTwoSided
PestMaterial/WithAdditiveAlphaTwoSided
PestMaterial/ShadowCast
DarklightRevealMaterial/Default
UVSlidingMaterialGS/Default
SkyboxMaterial/Default
SkyboxMaterial/PixelMap
SkyboxMaterial/WithTransparency
GhostNonSkinMaterial/Default
GhostNonSkinMaterial/DepthShell
GhostNonSkinMaterial/PixelMap
GhostNonSkinMaterial/WithTransparency
GhostNonSkinMaterial/WithAdditiveAlpha
HurricaneMaterial/Default
HurricaneMaterial/WithBackCulling
MorphLuigiMaterial/Default
MorphLuigiMaterial/DepthShell
MorphLuigiMaterial/PixelMap
MorphLuigiMaterial/CastSilhouette
MorphLuigiMaterial/WithTransparency
MorphLuigiMaterial/FadeTransition
MorphLuigiMaterial/WithAdditiveAlpha
MorphLuigiMaterial/ShadowCast
MorphLuigiMaterial/LightingOnly
MorphLuigiMaterial/ColorShift
PropsMaterial/Default
PropsMaterial/DepthShell
PropsMaterial/PixelMap
PropsMaterial/Silhouette
PropsMaterial/Debug
PropsMaterial/WithTransparency
PropsMaterial/WithAdditiveAlpha
PropsMaterial/ShadowCast
FrontEndMaterial/Default
FrontEndMaterial/WithTransparency
FrontEndMaterial/WithTransparencyNoAlphaWrites
UVSlidingMaterial/Default
UVSlidingMaterial/AlphaBlend
UVSlidingMaterial/AddBlend
UVSlidingMaterial/TwoSided
UVSlidingMaterial/AlphaBlendTwoSided
UVSlidingMaterial/AddBlendTwoSided
UVSlidingMaterial/DepthShell
UVSlidingMaterial/PixelMap
WindowRigidSkin/Default
WindowRigidSkin/PixelMap
WindowRigidSkin/DepthShell
VertColor/Default
VertColor/PixelMap
LuigiMaterial/Default
LuigiMaterial/DepthShell
LuigiMaterial/PixelMap
LuigiMaterial/CastSilhouette
LuigiMaterial/WithTransparency
LuigiMaterial/FadeTransition
LuigiMaterial/WithAdditiveAlpha
LuigiMaterial/ShadowCast
LuigiMaterial/LightingOnly
LuigiMaterial/ColorShift
EnvironmentSphereMap/Default
EnvironmentSphereMap/DepthShell
EnvironmentSphereMap/PixelMap
EnvironmentSphereMap/DiffuseNonLit
EnvironmentSphereMap/LightmapsOnly
EnvironmentSphereMap/LightingOnly
EnvironmentSphereMap/DiffuseLightingOnly
EnvironmentSphereMap/NoSilhouette
EnvironmentSphereMap/CastSilhouette
EnvironmentSphereMap/NoSilhouetteBackface
EnvironmentSphereMap/NoSilhouetteAdditiveAlpha
EnvironmentSphereMap/Default_NoShadows
EnvironmentSphereMap/NoSilhouette_NoShadows
EnvironmentSphereMap/WithTransparency_NoShadows
EnvironmentSphereMap/CastSilhouette_NoShadows
EnvironmentSphereMap/WithTransparency
EnvironmentSphereMap/WithAdditiveAlpha
EnvironmentSphereMap/ShadowCast
EnvironmentSphereMap/StatueBack
EnvironmentSphereMap/StatueFront
MorphPestMaterial/Default
MorphPestMaterial/DepthShell
MorphPestMaterial/PixelMap
MorphPestMaterial/CastSilhouette
MorphPestMaterial/Silhouette
MorphPestMaterial/WithTransparency
MorphPestMaterial/WithAlphaTestBlend
MorphPestMaterial/WithAdditiveAlpha
MorphPestMaterial/TwoSided
MorphPestMaterial/WithTransparencyTwoSided
MorphPestMaterial/WithAlphaTestBlendTwoSided
MorphPestMaterial/WithAdditiveAlphaTwoSided
MorphPestMaterial/ShadowCast
MorphGhostMaterial/Default
MorphGhostMaterial/DepthShell
MorphGhostMaterial/PixelMap
MorphGhostMaterial/WithTransparency
MorphGhostMaterial/WithAdditiveAlpha
EnvironmentSpecularMaterial/Default
EnvironmentSpecularMaterial/DepthShell
EnvironmentSpecularMaterial/PixelMap
EnvironmentSpecularMaterial/DiffuseNonLit
EnvironmentSpecularMaterial/LightmapsOnly
EnvironmentSpecularMaterial/LightingOnly
EnvironmentSpecularMaterial/DiffuseLightingOnly
EnvironmentSpecularMaterial/NoSilhouette
EnvironmentSpecularMaterial/CastSilhouette
EnvironmentSpecularMaterial/NoSilhouetteBackface
EnvironmentSpecularMaterial/NoSilhouetteAdditiveAlpha
EnvironmentSpecularMaterial/Default_NoShadows
EnvironmentSpecularMaterial/NoSilhouette_NoShadows
EnvironmentSpecularMaterial/WithTransparency_NoShadows
EnvironmentSpecularMaterial/CastSilhouette_NoShadows
EnvironmentSpecularMaterial/WithTransparency
EnvironmentSpecularMaterial/WithAdditiveAlpha
EnvironmentSpecularMaterial/ShadowCast
luigieyematerial/default
luigieyematerial/depthshell
luigieyematerial/pixelmap
luigieyematerial/castsilhouette
luigieyematerial/withtransparency
luigieyematerial/unlit
luigieyematerial/fadetransition
luigieyematerial/withadditivealpha
luigieyematerial/shadowcast
luigieyematerial/lightingonly
luigieyematerial/colorshift
ghostmaterial/default
ghostmaterial/depthshell
ghostmaterial/pixelmap
ghostmaterial/withtransparency
ghostmaterial/withadditivealpha
environmentmaterial/default
environmentmaterial/depthshell
environmentmaterial/pixelmap
environmentmaterial/diffusenonlit
environmentmaterial/lightmapsonly
environmentmaterial/lightingonly
environmentmaterial/diffuselightingonly
environmentmaterial/nosilhouette
environmentmaterial/castsilhouette
environmentmaterial/nosilhouettebackface
environmentmaterial/nosilhouetteadditivealpha
environmentmaterial/default_noshadows
environmentmaterial/nosilhouette_noshadows
environmentmaterial/withtransparency_noshadows
environmentmaterial/castsilhouette_noshadows
environmentmaterial/withtransparency
environmentmaterial/withadditivealpha
environmentmaterial/shadowcast
environmentspecularrigidskin/default
environmentspecularrigidskin/depthshell
environmentspecularrigidskin/pixelmap
environmentspecularrigidskin/diffusenonlit
environmentspecularrigidskin/lightmapsonly
environmentspecularrigidskin/lightingonly
environmentspecularrigidskin/diffuselightingonly
environmentspecularrigidskin/nosilhouette
environmentspecularrigidskin/castsilhouette
environmentspecularrigidskin/nosilhouettebackface
environmentspecularrigidskin/nosilhouetteadditivealpha
environmentspecularrigidskin/default_noshadows
environmentspecularrigidskin/nosilhouette_noshadows
environmentspecularrigidskin/withtransparency_noshadows
environmentspecularrigidskin/castsilhouette_noshadows
environmentspecularrigidskin/withtransparency
environmentspecularrigidskin/withadditivealpha
environmentspecularrigidskin/shadowcast
environmentptmaterial/proceduraltexture
environmentptmaterial/default
environmentptmaterial/depthshell
environmentptmaterial/pixelmap
environmentptmaterial/diffusenonlit
environmentptmaterial/lightmapsonly
environmentptmaterial/lightingonly
environmentptmaterial/diffuselightingonly
environmentptmaterial/nosilhouette
environmentptmaterial/castsilhouette
environmentptmaterial/nosilhouettebackface
environmentptmaterial/nosilhouetteadditivealpha
environmentptmaterial/default_noshadows
environmentptmaterial/nosilhouette_noshadows
environmentptmaterial/withtransparency_noshadows
environmentptmaterial/castsilhouette_noshadows
environmentptmaterial/withtransparency
environmentptmaterial/withadditivealpha
environmentptmaterial/shadowcast
diffuseskin/depthshell
diffuseskin/pixelmap
diffuseskin/default
diffuseskin/withtransparency
diffuseskin/withadditivealpha
diffuseskin/castsilhouette
environmentrigidskin/default
environmentrigidskin/depthshell
environmentrigidskin/pixelmap
environmentrigidskin/diffusenonlit
environmentrigidskin/lightmapsonly
environmentrigidskin/lightingonly
environmentrigidskin/diffuselightingonly
environmentrigidskin/nosilhouette
environmentrigidskin/castsilhouette
environmentrigidskin/nosilhouettebackface
environmentrigidskin/nosilhouetteadditivealpha
environmentrigidskin/default_noshadows
environmentrigidskin/nosilhouette_noshadows
environmentrigidskin/withtransparency_noshadows
environmentrigidskin/castsilhouette_noshadows
environmentrigidskin/withtransparency
environmentrigidskin/withadditivealpha
environmentrigidskin/shadowcast
clothmaterial/default
clothmaterial/depthshell
clothmaterial/pixelmap
clothmaterial/silhouette
clothmaterial/castsilhouette
clothmaterial/withtransparency
clothmaterial/withadditivealpha
clothmaterial/shadowcast
moolahmaterial/default
moolahmaterial/depthshell
moolahmaterial/pixelmap
moolahmaterial/silhouette
moolahmaterial/debug
moolahmaterial/withtransparency
moolahmaterial/withadditivealpha
moolahmaterial/shadowcast
uvslidingrigidskin/default
uvslidingrigidskin/alphablend
uvslidingrigidskin/addblend
uvslidingrigidskin/twosided
uvslidingrigidskin/alphablendtwosided
uvslidingrigidskin/addblendtwosided
uvslidingrigidskin/depthshell
uvslidingrigidskin/pixelmap
windowmaterial/default
windowmaterial/pixelmap
windowmaterial/depthshell
diffusevertcolor/default
diffusevertcolor/pixelmap
diffusevertcolor/depthclear
diffusevertcolor/withtransparency
diffusevertcolor/withtransparencynoalphawrites
diffusevertcolor/twosidedalpha
diffusevertcolor/additivetwosidedalpha
diffusevertcolor/clamped
diffusevertcolor/clampedwithtransparency
diffusevertcolor/particlealphadepth
diffusevertcolor/particlealphanodepth
diffusevertcolor/particleadditivedepth
diffusevertcolor/particleadditivenodepth
diffusevertcolor/clampedwithtransparencynoalphawrites
diffusevertcolor/clampedadditive
diffusevertcolor/preportalstencil
diffusevertcolor/postportalstencil
environmentspheremaprigidskin/default
environmentspheremaprigidskin/depthshell
environmentspheremaprigidskin/pixelmap
environmentspheremaprigidskin/diffusenonlit
environmentspheremaprigidskin/lightmapsonly
environmentspheremaprigidskin/lightingonly
environmentspheremaprigidskin/diffuselightingonly
environmentspheremaprigidskin/nosilhouette
environmentspheremaprigidskin/castsilhouette
environmentspheremaprigidskin/nosilhouettebackface
environmentspheremaprigidskin/nosilhouetteadditivealpha
environmentspheremaprigidskin/default_noshadows
environmentspheremaprigidskin/nosilhouette_noshadows
environmentspheremaprigidskin/withtransparency_noshadows
environmentspheremaprigidskin/castsilhouette_noshadows
environmentspheremaprigidskin/withtransparency
environmentspheremaprigidskin/withadditivealpha
environmentspheremaprigidskin/shadowcast
environmentspheremaprigidskin/statueback
environmentspheremaprigidskin/statuefront
diffuseconstcolor/default
diffuseconstcolor/depthshell
diffuseconstcolor/pixelmap
diffuseconstcolor/clampedwithtransparency
diffuseconstcolor/particlealphadepth
diffuseconstcolor/particlealphanodepth
diffuseconstcolor/particleadditivedepth
diffuseconstcolor/withtransparency
diffuseconstcolor/withadditivealpha
diffuseconstcolor/portalstencil
pestmaterial/default
pestmaterial/depthshell
pestmaterial/pixelmap
pestmaterial/castsilhouette
pestmaterial/silhouette
pestmaterial/withtransparency
pestmaterial/withalphatestblend
pestmaterial/withadditivealpha
pestmaterial/twosided
pestmaterial/withtransparencytwosided
pestmaterial/withalphatestblendtwosided
pestmaterial/withadditivealphatwosided
pestmaterial/shadowcast
darklightrevealmaterial/default
uvslidingmaterialgs/default
skyboxmaterial/default
skyboxmaterial/pixelmap
skyboxmaterial/withtransparency
ghostnonskinmaterial/default
ghostnonskinmaterial/depthshell
ghostnonskinmaterial/pixelmap
ghostnonskinmaterial/withtransparency
ghostnonskinmaterial/withadditivealpha
hurricanematerial/default
hurricanematerial/withbackculling
morphluigimaterial/default
morphluigimaterial/depthshell
morphluigimaterial/pixelmap
morphluigimaterial/castsilhouette
morphluigimaterial/withtransparency
morphluigimaterial/fadetransition
morphluigimaterial/withadditivealpha
morphluigimaterial/shadowcast
morphluigimaterial/lightingonly
morphluigimaterial/colorshift
propsmaterial/default
propsmaterial/depthshell
propsmaterial/pixelmap
propsmaterial/silhouette
propsmaterial/debug
propsmaterial/withtransparency
propsmaterial/withadditivealpha
propsmaterial/shadowcast
frontendmaterial/default
frontendmaterial/withtransparency
frontendmaterial/withtransparencynoalphawrites
uvslidingmaterial/default
uvslidingmaterial/alphablend
uvslidingmaterial/addblend
uvslidingmaterial/twosided
uvslidingmaterial/alphablendtwosided
uvslidingmaterial/addblendtwosided
uvslidingmaterial/depthshell
uvslidingmaterial/pixelmap
windowrigidskin/default
windowrigidskin/pixelmap
windowrigidskin/depthshell
vertcolor/default
vertcolor/pixelmap
luigimaterial/default
luigimaterial/depthshell
luigimaterial/pixelmap
luigimaterial/castsilhouette
luigimaterial/withtransparency
luigimaterial/fadetransition
luigimaterial/withadditivealpha
luigimaterial/shadowcast
luigimaterial/lightingonly
luigimaterial/colorshift
environmentspheremap/default
environmentspheremap/depthshell
environmentspheremap/pixelmap
environmentspheremap/diffusenonlit
environmentspheremap/lightmapsonly
environmentspheremap/lightingonly
environmentspheremap/diffuselightingonly
environmentspheremap/nosilhouette
environmentspheremap/castsilhouette
environmentspheremap/nosilhouettebackface
environmentspheremap/nosilhouetteadditivealpha
environmentspheremap/default_noshadows
environmentspheremap/nosilhouette_noshadows
environmentspheremap/withtransparency_noshadows
environmentspheremap/castsilhouette_noshadows
environmentspheremap/withtransparency
environmentspheremap/withadditivealpha
environmentspheremap/shadowcast
environmentspheremap/statueback
environmentspheremap/statuefront
morphpestmaterial/default
morphpestmaterial/depthshell
morphpestmaterial/pixelmap
morphpestmaterial/castsilhouette
morphpestmaterial/silhouette
morphpestmaterial/withtransparency
morphpestmaterial/withalphatestblend
morphpestmaterial/withadditivealpha
morphpestmaterial/twosided
morphpestmaterial/withtransparencytwosided
morphpestmaterial/withalphatestblendtwosided
morphpestmaterial/withadditivealphatwosided
morphpestmaterial/shadowcast
morphghostmaterial/default
morphghostmaterial/depthshell
morphghostmaterial/pixelmap
morphghostmaterial/withtransparency
morphghostmaterial/withadditivealpha
environmentspecularmaterial/default
environmentspecularmaterial/depthshell
environmentspecularmaterial/pixelmap
environmentspecularmaterial/diffusenonlit
environmentspecularmaterial/lightmapsonly
environmentspecularmaterial/lightingonly
environmentspecularmaterial/diffuselightingonly
environmentspecularmaterial/nosilhouette
environmentspecularmaterial/castsilhouette
environmentspecularmaterial/nosilhouettebackface
environmentspecularmaterial/nosilhouetteadditivealpha
environmentspecularmaterial/default_noshadows
environmentspecularmaterial/nosilhouette_noshadows
environmentspecularmaterial/withtransparency_noshadows
environmentspecularmaterial/castsilhouette_noshadows
environmentspecularmaterial/withtransparency
environmentspecularmaterial/withadditivealpha
environmentspecularmaterial/shadowcast
Boo/boo
boo/boo
boo/Boo
polterpup
luigicleaner
flashlight
bloo
bloo_gold
bully
chaser
ghost
wood
metal
chaseronline
creeper
gobber
gobber_strong
ghosthider
possessor
poltergeist
poltergeist_strong
sneaker
sister01
sister02
sister03
sister04
bellhop
caveman
headmaid
chef
dj
king
bat
boolossus
boo
bat
boo
bill
cone
leaf
toad
bill
toad
egadd
grump
mario
peach
king/boo
paper
rixer
towel
toad
grump
amysuo
anniee
aouqae
luigi/akvi
art/feghosts
nisasset-art/feghosts/boo.nlg/boo
EN_bo_KingBoo
Bip01
Bip01_Footsteps
Bip01_Pelvis
Bip01_Spine
Bip01_L_Thigh
Bip01_L_Calf
Bip01_L_Foot
Bip01_L_Toe0
Bip01_L_Toe0Nub
Bip01_R_Thigh
Bip01_R_Calf
Bip01_R_Foot
Bip01_R_Toe0
Bip01_R_Toe0Nub
Bip01_Neck
Bip01_L_Clavicle
Bip01_L_UpperArm
Bip01_L_Forearm
Bip01_L_Hand
Bip01_L_Finger0
Bip01_L_Finger0Nub
Bip01_R_Clavicle
Bip01_R_UpperArm
Bip01_R_Forearm
Bip01_R_Hand
Bip01_R_Finger0
Bip01_R_Finger0Nub
Bip01_Head
Bip01_HeadNub
Bip01_Tail
Bip01_TailNub
Bip01_zMouthCorner_L
Bip01_zMouthCorner_LNub
Bip01_zMouthCorner_R
Bip01_zMouthCorner_RNub
Bip01_Crown
Bip01_CrownNub
Bip01_Jewel
Bip01_JewelNub
kingBooMorphs_NS_
kingBooMorphs_NS_Stun_Brow
Bip01_Tongue
Bip01_Tongue02
Bip01_Tongue03
Bip01_Tongue04
Bip01_TongueNub
GhostKingBoo
Bip01
Bip01 Footsteps
Bip01 Pelvis
Bip01 Spine
Bip01 L Thigh
Bip01 L Calf
Bip01 L Foot
Bip01 L Toe0
Bip01 L Toe0Nub
Bip01 R Thigh
Bip01 R Calf
Bip01 R Foot
Bip01 R Toe0
Bip01 R Toe0Nub
Bip01 Neck
Bip01 L Clavicle
Bip01 L UpperArm
Bip01 L Forearm
Bip01 L Hand
Bip01 L Finger0
Bip01 L Finger0Nub
Bip01 R Clavicle
Bip01 R UpperArm
Bip01 R Forearm
Bip01 R Hand
Bip01 R Finger0
Bip01 R Finger0Nub
Bip01 Head
Bip01 HeadNub
Bip01 Tail
Bip01 TailNub
Bip01 zMouthCorneR L
Bip01 zMouthCorneR LNub
Bip01 zMouthCorneR R
Bip01 zMouthCorneR RNub
Bip01 Crown
Bip01 CrownNub
Bip01 Jewel
Bip01 JewelNub
kingBooMorphs_NS_
kingBooMorphs_NS_Stun_Brow
Bip01 Tongue
Bip01 Tongue02
Bip01 Tongue03
Bip01 Tongue04
Bip01 TongueNub
GhostKingBoo
bip01 footsteps
bip01 pelvis
bip01 spine
bip01 l thigh
bip01 l calf
bip01 l foot
bip01 l toe0
bip01 l toe0nub
bip01 r thigh
bip01 r calf
bip01 r foot
bip01 r toe0
bip01 r toe0nub
bip01 neck
bip01 l clavicle
bip01 l upperarm
bip01 l forearm
bip01 l hand
bip01 l finger0
bip01 l finger0nub
bip01 r clavicle
bip01 r upperarm
bip01 r forearm
bip01 r hand
bip01 r finger0
bip01 r finger0nub
bip01 head
bip01 headnub
bip01 tail
bip01 tailnub
bip01 zmouthcorner l
bip01 zmouthcorner lnub
bip01 zmouthcorner r
bip01 zmouthcorner rnub
bip01 crown
bip01 crownnub
bip01 jewel
bip01 jewelnub
bip01 tongue
bip01 tongue02
bip01 tongue03
bip01 tongue04
bip01 tonguenub
bip01
bip01_footsteps
bip01_pelvis
bip01_spine
bip01_l_thigh
bip01_l_calf
bip01_l_foot
bip01_l_toe0
bip01_l_toe0nub
bip01_r_thigh
bip01_r_calf
bip01_r_foot
bip01_r_toe0
bip01_r_toe0nub
bip01_neck
bip01_l_clavicle
bip01_l_upperarm
bip01_l_forearm
bip01_l_hand
bip01_l_finger0
bip01_l_finger0nub
bip01_r_clavicle
bip01_r_upperarm
bip01_r_forearm
bip01_r_hand
bip01_r_finger0
bip01_r_finger0nub
bip01_head
bip01_headnub
bip01_tail
bip01_tailnub
bip01_zmouthcorner_l
bip01_zmouthcorner_lnub
bip01_zmouthcorner_r
bip01_zmouthcorner_rnub
bip01_crown
bip01_crownnub
bip01_jewel
bip01_jewelnub

View file

@ -27,7 +27,7 @@ namespace Toolbox.Library
ushort magicNumber = reader.ReadUInt16();
// reader.Position = stream.Position + 4;
reader.Position = startPosition + 4;
ushort magicNumber2 = reader.ReadUInt16();
//Check 2 cases which the file is zlibbed.

View file

@ -604,7 +604,7 @@ namespace Toolbox.Library
STGenericObject.LOD_Mesh lod = new STGenericObject.LOD_Mesh();
lod.faces = GetFaces(msh);
lod.IndexFormat = STIndexFormat.UInt16;
lod.PrimitiveType = STPolygonType.Triangle;
lod.PrimativeType = STPrimativeType.Triangles;
lod.GenerateSubMesh();
obj.lodMeshes.Add(lod);
obj.vertices = GetVertices(msh, transform, obj);

View file

@ -19,6 +19,9 @@ namespace Toolbox.Library
public class ExportSettings
{
public Version FileVersion = new Version();
public string ImageExtension = ".png";
public string ImageFolder = "";
}
public class Version

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.IO;
namespace Toolbox.Library
{
@ -13,6 +14,8 @@ namespace Toolbox.Library
private DAE.ExportSettings Settings;
private DAE.Version Version;
private Dictionary<string, int> AttriubteIdList = new Dictionary<string, int>();
public ColladaWriter(string fileName, DAE.ExportSettings settings)
{
Settings = settings;
@ -24,7 +27,7 @@ namespace Toolbox.Library
};
}
public void WriteHeader()
public void WriteDAEHeader()
{
Writer.WriteStartDocument();
Writer.WriteStartElement("COLLADA");
@ -38,9 +41,47 @@ namespace Toolbox.Library
Writer.WriteEndElement();
}
public static void WriteSectionAsset()
public void WriteFileSettings()
{
Writer.WriteStartElement("asset");
{
Writer.WriteStartElement("contributor");
Writer.WriteElementString("authoring_tool", System.Windows.Forms.Application.ProductName);
Writer.WriteEndElement();
Writer.WriteStartElement("created");
Writer.WriteString(DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture) + "Z");
Writer.WriteEndElement();
Writer.WriteStartElement("modified");
Writer.WriteString(DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture) + "Z");
Writer.WriteEndElement();
Writer.WriteStartElement("unit");
Writer.WriteAttributeString("meter", "0.01");
Writer.WriteAttributeString("name", "centimeter");
Writer.WriteEndElement();
Writer.WriteStartElement("up_axis");
Writer.WriteString("Y_UP");
Writer.WriteEndElement();
}
Writer.WriteEndElement();
}
public void WriteLibraryImages(string[] textureNames)
{
Writer.WriteStartElement("library_images");
for (int i = 0; i < textureNames?.Length; i++)
{
Writer.WriteStartElement("image");
Writer.WriteAttributeString("id", textureNames[i]);
Writer.WriteStartElement("init_from");
Writer.WriteString($"{Settings.ImageFolder}{textureNames[i]}.{Settings.ImageExtension}");
Writer.WriteEndElement();
Writer.WriteEndElement();
}
Writer.WriteEndElement();
}
public void Dispose()

View file

@ -182,7 +182,7 @@ namespace Toolbox.Library
mesh.lodMeshes = new List<STGenericObject.LOD_Mesh>();
var lodMesh = new STGenericObject.LOD_Mesh();
lodMesh.PrimitiveType = STPolygonType.Triangle;
lodMesh.PrimativeType = STPrimativeType.Triangles;
mesh.lodMeshes.Add(lodMesh);
for (int f = 0; f < seMesh.FaceCount; f++)
{

View file

@ -91,7 +91,7 @@ namespace Toolbox.Library
public List<LOD_Mesh> lodMeshes = new List<LOD_Mesh>();
public class LOD_Mesh
{
public STPolygonType PrimitiveType = STPolygonType.Triangle;
public STPrimativeType PrimativeType = STPrimativeType.Triangles;
public STIndexFormat IndexFormat = STIndexFormat.UInt16;
public uint FirstVertex;

View file

@ -437,7 +437,7 @@ namespace Toolbox.Library.Rendering
{
if (Runtime.RenderModels)
{
GL.DrawElements(PrimitiveType.Triangles, group.displayFaceSize, DrawElementsType.UnsignedInt, group.Offset);
GL.DrawElements(GetPrimitiveType(group), group.displayFaceSize, DrawElementsType.UnsignedInt, group.Offset);
}
}
}
@ -465,7 +465,7 @@ namespace Toolbox.Library.Rendering
{
if (Runtime.RenderModels)
{
GL.DrawElements(PrimitiveType.Triangles, m.lodMeshes[m.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, m.Offset);
GL.DrawElements(GetPrimitiveType(m.lodMeshes[m.DisplayLODIndex]), m.lodMeshes[m.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, m.Offset);
}
}
}
@ -484,6 +484,34 @@ namespace Toolbox.Library.Rendering
shader.SetInt("colorOverride", 0);
}
private static PrimitiveType GetPrimitiveType(STGenericObject.LOD_Mesh p)
{
switch (p.PrimativeType)
{
case STPrimativeType.Triangles: return PrimitiveType.Triangles;
case STPrimativeType.TrangleStrips: return PrimitiveType.TriangleStrip;
case STPrimativeType.Quads: return PrimitiveType.Quads;
case STPrimativeType.Points: return PrimitiveType.Points;
case STPrimativeType.LineStrips: return PrimitiveType.LineStrip;
case STPrimativeType.Lines: return PrimitiveType.Lines;
default: return PrimitiveType.Triangles;
}
}
private static PrimitiveType GetPrimitiveType(STGenericPolygonGroup p)
{
switch (p.PrimativeType)
{
case STPrimativeType.Triangles: return PrimitiveType.Triangles;
case STPrimativeType.TrangleStrips: return PrimitiveType.TriangleStrip;
case STPrimativeType.Quads: return PrimitiveType.Quads;
case STPrimativeType.Points: return PrimitiveType.Points;
case STPrimativeType.LineStrips: return PrimitiveType.LineStrip;
case STPrimativeType.Lines: return PrimitiveType.Lines;
default: return PrimitiveType.Triangles;
}
}
private static void DrawModelWireframe(STGenericPolygonGroup p, ShaderProgram shader)
{
// use vertex color for wireframe color
@ -491,7 +519,7 @@ namespace Toolbox.Library.Rendering
GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
GL.Enable(EnableCap.LineSmooth);
GL.LineWidth(1.5f);
GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
GL.DrawElements(GetPrimitiveType(p), p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
shader.SetInt("colorOverride", 0);
}
@ -503,11 +531,11 @@ namespace Toolbox.Library.Rendering
GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
GL.Enable(EnableCap.LineSmooth);
GL.LineWidth(1.3f);
GL.DrawElements(PrimitiveType.Triangles, p.lodMeshes[p.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
GL.DrawElements(GetPrimitiveType(p.lodMeshes[p.DisplayLODIndex]), p.lodMeshes[p.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
GL.Uniform1(shader["colorOverride"], 0);
GL.DrawElements(PrimitiveType.Triangles, p.lodMeshes[p.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
GL.DrawElements(GetPrimitiveType(p.lodMeshes[p.DisplayLODIndex]), p.lodMeshes[p.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
}
private static void DrawModelSelection(STGenericPolygonGroup p, ShaderProgram shader)
@ -516,11 +544,11 @@ namespace Toolbox.Library.Rendering
GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
GL.Enable(EnableCap.LineSmooth);
GL.LineWidth(1.3f);
GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
GL.DrawElements(GetPrimitiveType(p), p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
GL.Uniform1(shader["colorOverride"], 0);
GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
GL.DrawElements(GetPrimitiveType(p), p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
}
}
}

View file

@ -11,13 +11,6 @@ using System.Windows.Forms;
namespace Toolbox.Library.Rendering
{
public enum STPolygonType : uint
{
Point = 0,
Line = 1,
LineStrip = 2,
Triangle = 3
}
public enum STIndexFormat : uint
{
UnsignedByte = 0,