diff --git a/BrawlboxHelper/Syroot.NintenTools.Bfres.dll b/BrawlboxHelper/Syroot.NintenTools.Bfres.dll index b398c199..8d612653 100644 Binary files a/BrawlboxHelper/Syroot.NintenTools.Bfres.dll and b/BrawlboxHelper/Syroot.NintenTools.Bfres.dll differ diff --git a/File_Format_Library/FileFormats/Archives/LM2/LM2_ChunkTable.cs b/File_Format_Library/FileFormats/NLG/LM2/LM2_ChunkTable.cs similarity index 100% rename from File_Format_Library/FileFormats/Archives/LM2/LM2_ChunkTable.cs rename to File_Format_Library/FileFormats/NLG/LM2/LM2_ChunkTable.cs diff --git a/File_Format_Library/FileFormats/Archives/LM2/LM2_DICT.cs b/File_Format_Library/FileFormats/NLG/LM2/LM2_DICT.cs similarity index 89% rename from File_Format_Library/FileFormats/Archives/LM2/LM2_DICT.cs rename to File_Format_Library/FileFormats/NLG/LM2/LM2_DICT.cs index 23f32088..ad540e97 100644 --- a/File_Format_Library/FileFormats/Archives/LM2/LM2_DICT.cs +++ b/File_Format_Library/FileFormats/NLG/LM2/LM2_DICT.cs @@ -200,6 +200,40 @@ namespace FirstPlugin.LuigisMansion.DarkMoon currentModel.BufferStart = chunkEntry.Entry.ChunkOffset; currentModel.BufferSize = chunkEntry.Entry.ChunkSize; break; + case SubDataType.BoneData: + if (chunk.ChunkSize > 0x40 && currentModel.Skeleton == null) + { + using (var boneReader = new FileReader(chunkEntry.FileData)) + { + currentModel.Skeleton = new STSkeleton(); + DrawableContainer.Drawables.Add(currentModel.Skeleton); + + uint numBones = chunk.ChunkSize / 68; + for (int i = 0; i < numBones; i++) + { + boneReader.SeekBegin(i * 68); + STBone bone = new STBone(currentModel.Skeleton); + bone.position = new float[3] { 0, 0, 0 }; + bone.rotation = new float[4] { 0, 0, 0, 1 }; + bone.scale = new float[3] { 0.2f, 0.2f, 0.2f }; + + boneReader.SeekBegin(52 + (i * 68)); + var Position = new OpenTK.Vector3(boneReader.ReadSingle(), boneReader.ReadSingle(), boneReader.ReadSingle()); + Position = OpenTK.Vector3.TransformPosition(Position, OpenTK.Matrix4.CreateRotationX(OpenTK.MathHelper.DegreesToRadians(90))); + bone.position[0] = Position.X; + bone.position[2] = Position.Y; + bone.position[1] = Position.Z; + + + bone.RotationType = STBone.BoneRotationType.Euler; + currentModel.Skeleton.bones.Add(bone); + } + + currentModel.Skeleton.reset(); + currentModel.Skeleton.update(); + } + } + break; case SubDataType.VertexStartPointers: using (var vtxPtrReader = new FileReader(chunkEntry.FileData)) { diff --git a/File_Format_Library/FileFormats/Archives/LM2/LM2_Enums.cs b/File_Format_Library/FileFormats/NLG/LM2/LM2_Enums.cs similarity index 96% rename from File_Format_Library/FileFormats/Archives/LM2/LM2_Enums.cs rename to File_Format_Library/FileFormats/NLG/LM2/LM2_Enums.cs index dbaa77f0..810ba975 100644 --- a/File_Format_Library/FileFormats/Archives/LM2/LM2_Enums.cs +++ b/File_Format_Library/FileFormats/NLG/LM2/LM2_Enums.cs @@ -32,6 +32,7 @@ namespace FirstPlugin.LuigisMansion.DarkMoon VertexStartPointers = 0x1201B004, ModelTransform = 0x1301B001, //Matrix4x4. 0x40 in size MeshBuffers = 0x1301B005, //vertex and index buffer + BoneData = 0x1201B102, MaterialName = 0x1201B333, MeshIndexTable = 0x1201B007, MessageData = 0x12027020, diff --git a/File_Format_Library/FileFormats/Archives/LM2/LM2_Material.cs b/File_Format_Library/FileFormats/NLG/LM2/LM2_Material.cs similarity index 100% rename from File_Format_Library/FileFormats/Archives/LM2/LM2_Material.cs rename to File_Format_Library/FileFormats/NLG/LM2/LM2_Material.cs diff --git a/File_Format_Library/FileFormats/Archives/LM2/LM2_Model.cs b/File_Format_Library/FileFormats/NLG/LM2/LM2_Model.cs similarity index 99% rename from File_Format_Library/FileFormats/Archives/LM2/LM2_Model.cs rename to File_Format_Library/FileFormats/NLG/LM2/LM2_Model.cs index a572173e..8701d527 100644 --- a/File_Format_Library/FileFormats/Archives/LM2/LM2_Model.cs +++ b/File_Format_Library/FileFormats/NLG/LM2/LM2_Model.cs @@ -68,6 +68,8 @@ namespace FirstPlugin.LuigisMansion.DarkMoon public List Meshes = new List(); public List VertexBufferPointers = new List(); + public STSkeleton Skeleton; + public uint BufferStart; public uint BufferSize; diff --git a/File_Format_Library/FileFormats/Archives/LM2/TexturePOWE.cs b/File_Format_Library/FileFormats/NLG/LM2/TexturePOWE.cs similarity index 100% rename from File_Format_Library/FileFormats/Archives/LM2/TexturePOWE.cs rename to File_Format_Library/FileFormats/NLG/LM2/TexturePOWE.cs diff --git a/File_Format_Library/FileFormats/Archives/LM3/LM3_ChunkTable.cs b/File_Format_Library/FileFormats/NLG/LM3/LM3_ChunkTable.cs similarity index 96% rename from File_Format_Library/FileFormats/Archives/LM3/LM3_ChunkTable.cs rename to File_Format_Library/FileFormats/NLG/LM3/LM3_ChunkTable.cs index 04afc4ef..10ebaaef 100644 --- a/File_Format_Library/FileFormats/Archives/LM3/LM3_ChunkTable.cs +++ b/File_Format_Library/FileFormats/NLG/LM3/LM3_ChunkTable.cs @@ -44,7 +44,7 @@ namespace FirstPlugin.LuigisMansion3 //Load the first chunk table //These point to sections which usually have magic and a hash //The chunk table afterwards contains the data itself - while (tableReader.ReadUInt16() == ChunkInfoIdenfier) + while (!tableReader.EndOfStream && tableReader.ReadUInt16() == ChunkInfoIdenfier) { tableReader.ReadUInt16(); @@ -62,8 +62,6 @@ namespace FirstPlugin.LuigisMansion3 //This increases by 2 each chunk info, however the starting value is not 0 //Note the last entry does not have this entry.Unknown3 = tableReader.ReadUInt32(); - - Console.WriteLine("ChunkOffset " + entry.ChunkOffset); } if (ChunkEntries.Count > 0) diff --git a/File_Format_Library/FileFormats/Archives/LM3/LM3_DICT.cs b/File_Format_Library/FileFormats/NLG/LM3/LM3_DICT.cs similarity index 97% rename from File_Format_Library/FileFormats/Archives/LM3/LM3_DICT.cs rename to File_Format_Library/FileFormats/NLG/LM3/LM3_DICT.cs index e4d7c17f..817e976b 100644 --- a/File_Format_Library/FileFormats/Archives/LM3/LM3_DICT.cs +++ b/File_Format_Library/FileFormats/NLG/LM3/LM3_DICT.cs @@ -272,14 +272,16 @@ namespace FirstPlugin.LuigisMansion3 currentTexture.Index = ImageHeaderIndex; currentTexture.Read(textureReader); if (DebugMode) - currentTexture.Text = $"Texture {ImageHeaderIndex} {currentTexture.TexFormat.ToString("X")} {currentTexture.Unknown.ToString("X")}"; + currentTexture.Text = $"Texture {ImageHeaderIndex} {currentTexture.Unknown} {currentTexture.Unknown2} {currentTexture.Unknown3.ToString("X")}"; else currentTexture.Text = $"Texture {currentTexture.ID2.ToString("X")}"; if (HashNames.ContainsKey(currentTexture.ID2)) currentTexture.Text = HashNames[currentTexture.ID2]; + textureFolder.Nodes.Add(currentTexture); - Renderer.TextureList.Add(currentTexture); + if (!Renderer.TextureList.ContainsKey(currentTexture.ID2.ToString("x"))) + Renderer.TextureList.Add(currentTexture.ID2.ToString("x"), currentTexture); TextureHashes.Add(currentTexture.ID2); @@ -360,7 +362,7 @@ namespace FirstPlugin.LuigisMansion3 case SubDataType.BoneData: if (chunk.ChunkSize > 0x40 && currentModel.Skeleton == null) { - /* chunkEntry.DataFile = File052Data; + chunkEntry.DataFile = File052Data; using (var boneReader = new FileReader(chunkEntry.FileData)) { currentModel.Skeleton = new STSkeleton(); @@ -389,7 +391,7 @@ namespace FirstPlugin.LuigisMansion3 currentModel.Skeleton.reset(); currentModel.Skeleton.update(); - }*/ + } } break; case (SubDataType)0x5012: @@ -421,7 +423,7 @@ namespace FirstPlugin.LuigisMansion3 foreach (var model in modelFolder.Nodes) { ((LM3_Model)currentModel).ModelInfo.Read(new FileReader( - currentModel.ModelInfo.Data), currentModel.Meshes, TextureHashes); + currentModel.ModelInfo.Data), currentModel, currentModel.Meshes, TextureHashes); } if (havokFolder.Nodes.Count > 0) @@ -532,7 +534,7 @@ namespace FirstPlugin.LuigisMansion3 { if (Entry.ChunkSize == 0) return new System.IO.MemoryStream(); - else if (Entry.ChunkOffset + Entry.ChunkSize < DataFile?.Length) + else if (Entry.ChunkOffset + Entry.ChunkSize <= DataFile?.Length) return new SubStream(DataFile, Entry.ChunkOffset, Entry.ChunkSize); else return new System.IO.MemoryStream(); @@ -670,7 +672,7 @@ namespace FirstPlugin.LuigisMansion3 } else if (DecompressedSize == 0) return new System.IO.MemoryStream(); - else if (Offset + DecompressedSize < reader.BaseStream.Length) + else if (Offset + DecompressedSize <= reader.BaseStream.Length) return new SubStream(reader.BaseStream, Offset, DecompressedSize); } } diff --git a/File_Format_Library/FileFormats/Archives/LM3/LM3_Enums.cs b/File_Format_Library/FileFormats/NLG/LM3/LM3_Enums.cs similarity index 97% rename from File_Format_Library/FileFormats/Archives/LM3/LM3_Enums.cs rename to File_Format_Library/FileFormats/NLG/LM3/LM3_Enums.cs index c2143048..8102d9b5 100644 --- a/File_Format_Library/FileFormats/Archives/LM3/LM3_Enums.cs +++ b/File_Format_Library/FileFormats/NLG/LM3/LM3_Enums.cs @@ -24,8 +24,6 @@ namespace FirstPlugin.LuigisMansion3 public enum IndexFormat : ushort { Index_16 = 0x0, - Index_32 = 0x1, - Index_32_ = 0x2, Index_8 = 0x8000, } diff --git a/File_Format_Library/FileFormats/Archives/LM3/LM3_Material.cs b/File_Format_Library/FileFormats/NLG/LM3/LM3_Material.cs similarity index 100% rename from File_Format_Library/FileFormats/Archives/LM3/LM3_Material.cs rename to File_Format_Library/FileFormats/NLG/LM3/LM3_Material.cs diff --git a/File_Format_Library/FileFormats/Archives/LM3/LM3_Model.cs b/File_Format_Library/FileFormats/NLG/LM3/LM3_Model.cs similarity index 91% rename from File_Format_Library/FileFormats/Archives/LM3/LM3_Model.cs rename to File_Format_Library/FileFormats/NLG/LM3/LM3_Model.cs index d955af56..7159c5ea 100644 --- a/File_Format_Library/FileFormats/Archives/LM3/LM3_Model.cs +++ b/File_Format_Library/FileFormats/NLG/LM3/LM3_Model.cs @@ -63,6 +63,8 @@ namespace FirstPlugin.LuigisMansion3 public class LM3_Model : TreeNodeCustom, IContextMenuNode { + public List TextureHashes = new List(); + public LM3_DICT DataDictionary; public LM3_ModelInfo ModelInfo; public List Meshes = new List(); @@ -211,6 +213,24 @@ namespace FirstPlugin.LuigisMansion3 using (var reader = new FileReader(DataDictionary.GetFileBufferData())) { + TreeNode texturesList = new TreeNode("Texture Maps"); + for (int t = 0; t < TextureHashes.Count; t++) + { + if (DataDictionary.Renderer.TextureList.ContainsKey(TextureHashes[t].ToString("x"))) + { + var tex = DataDictionary.Renderer.TextureList[TextureHashes[t].ToString("x")]; + texturesList.Nodes.Add(new TreeNode(tex.Text) + { + ImageKey = tex.ImageKey, + SelectedImageKey = tex.ImageKey, + Tag = tex + }); + } + } + + if (texturesList.Nodes.Count > 0) + Nodes.Add(texturesList); + for (int i = 0; i < Meshes.Count; i++) { LM3_Mesh mesh = Meshes[i]; @@ -226,6 +246,7 @@ namespace FirstPlugin.LuigisMansion3 RenderedMeshes.Add(genericObj); Nodes.Add(genericObj); + DataDictionary.Renderer.Meshes.Add(genericObj); STGenericPolygonGroup polyGroup = new STGenericPolygonGroup(); @@ -265,10 +286,10 @@ namespace FirstPlugin.LuigisMansion3 for (int f = 0; f < mesh.IndexCount; f++) polyGroup.faces.Add(reader.ReadUInt16()); break; - case IndexFormat.Index_32: + /* case IndexFormat.Index_32: for (int f = 0; f < mesh.IndexCount; f++) polyGroup.faces.Add((int)reader.ReadUInt32()); - break; + break;*/ } Console.WriteLine($"Mesh {genericObj.Text} Format {formatInfo.Format} BufferLength {formatInfo.BufferLength}"); @@ -407,43 +428,43 @@ namespace FirstPlugin.LuigisMansion3 { public byte[] Data; - public void Read(FileReader reader, List Meshes, List Hashes) + public void Read(FileReader reader, LM3_Model model, List Meshes, List Hashes) { - List ModelTexHashes = new List(); + uint meshSize = (uint)(reader.BaseStream.Length / Meshes.Count); - //Read entire section till i find a matching texture hash while (!reader.EndOfStream && reader.Position < reader.BaseStream.Length - 4) { uint HashIDCheck = reader.ReadUInt32(); if (Hashes.Contains(HashIDCheck)) { - using (reader.TemporarySeek(8, System.IO.SeekOrigin.Current)) + if (!model.TextureHashes.Contains(HashIDCheck)) + model.TextureHashes.Add(HashIDCheck); + } + } + + + /* for (int i = 0; i < Meshes.Count; i++) + { + reader.SeekBegin(i * meshSize); + while (!reader.EndOfStream && reader.Position < reader.BaseStream.Length - 4) + { + uint HashIDCheck = reader.ReadUInt32(); + if (Hashes.Contains(HashIDCheck)) { - uint unk = reader.ReadUInt32(); - if (unk == 0xF880BD9F) + Console.WriteLine("HashCheck " + HashIDCheck); + Meshes[i].Material = new LM3_Material(); + var texUnit = 1; + Meshes[i].Material.TextureMaps.Add(new STGenericMatTexture() { - ModelTexHashes.Add(HashIDCheck); - } + textureUnit = texUnit++, + Type = STGenericMatTexture.TextureType.Diffuse, + Name = HashIDCheck.ToString("x"), + }); + + break; } } - } - - for (int i = 0; i < Meshes.Count; i++) - { - if (ModelTexHashes.Count > i) - { - uint TextureHashID = ModelTexHashes[i]; - - Meshes[i].Material = new LM3_Material(); - var texUnit = 1; - Meshes[i].Material.TextureMaps.Add(new STGenericMatTexture() - { - textureUnit = texUnit++, - Type = STGenericMatTexture.TextureType.Diffuse, - Name = TextureHashID.ToString("x"), - }); - } - } + }*/ } } @@ -570,6 +591,9 @@ namespace FirstPlugin.LuigisMansion3 IndexStartOffset = reader.ReadUInt32(); IndexCount = reader.ReadUInt16(); IndexFormat = reader.ReadEnum(false); + if (IndexFormat != (IndexFormat)0x8000 && IndexFormat != 0) + IndexFormat = IndexFormat.Index_16; + VertexCount = reader.ReadUInt32(); reader.ReadUInt32(); //unknown BufferPtrOffset = reader.ReadUInt16(); //I believe this might be for the buffer pointers. It shifts by 4 for each mesh diff --git a/File_Format_Library/FileFormats/Archives/LM3/TexturePOWE.cs b/File_Format_Library/FileFormats/NLG/LM3/TexturePOWE.cs similarity index 99% rename from File_Format_Library/FileFormats/Archives/LM3/TexturePOWE.cs rename to File_Format_Library/FileFormats/NLG/LM3/TexturePOWE.cs index 50a6e433..72c69379 100644 --- a/File_Format_Library/FileFormats/Archives/LM3/TexturePOWE.cs +++ b/File_Format_Library/FileFormats/NLG/LM3/TexturePOWE.cs @@ -101,7 +101,7 @@ namespace FirstPlugin.LuigisMansion3 Console.WriteLine("Unknown Format!" + TexFormat.ToString("X")); } - MipCount = 1; + MipCount = numMips; ArrayCount = numArray; properties = new POWEProperties(); diff --git a/File_Format_Library/FileFormats/NLG/PunchOutWii/PO_DICT.cs b/File_Format_Library/FileFormats/NLG/PunchOutWii/PO_DICT.cs new file mode 100644 index 00000000..2261ec36 --- /dev/null +++ b/File_Format_Library/FileFormats/NLG/PunchOutWii/PO_DICT.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FirstPlugin.PunchOutWii +{ + public class PO_DICT + { + + } +} diff --git a/File_Format_Library/GL/LM3_Renderer.cs b/File_Format_Library/GL/LM3_Renderer.cs index 5fc155f2..8a4397ae 100644 --- a/File_Format_Library/GL/LM3_Renderer.cs +++ b/File_Format_Library/GL/LM3_Renderer.cs @@ -14,7 +14,7 @@ namespace FirstPlugin.LuigisMansion3 { public class LM3_Renderer : GenericModelRenderer { - public List TextureList = new List(); + public Dictionary TextureList = new Dictionary(); public override void OnRender(GLControl control) { @@ -27,12 +27,11 @@ namespace FirstPlugin.LuigisMansion3 GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.RenderableTex.TexID); string activeTex = tex.Name; - foreach (var texture in TextureList) { - if (texture.ID2.ToString("x") == tex.Name) + if (TextureList.ContainsKey(tex.Name)) { - BindGLTexture(tex, shader, texture); + BindGLTexture(tex, shader, TextureList[tex.Name]); return tex.textureUnit + 1; } } diff --git a/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs b/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs index ff5f7fa2..37a0f9ea 100644 --- a/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs +++ b/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs @@ -222,6 +222,9 @@ namespace Toolbox.Library.Forms ((TreeNodeCustom)node).OnClick(treeViewCustom1); } + if (node.Tag != null && node.Tag is TreeNodeCustom) + ((TreeNodeCustom)node.Tag).OnClick(treeViewCustom1); + //Check if it is renderable for updating the viewport if (IsRenderable(node)) {