From 7f0246f996c3100943f36b5febc9a96b87b7826a Mon Sep 17 00:00:00 2001 From: bird_egop Date: Wed, 3 Sep 2025 01:30:54 +0300 Subject: [PATCH] update docs on wea. correctly parse msh --- ParkanPlayground/Msh0D.cs | 6 ++- ParkanPlayground/MshConverter.cs | 89 ++------------------------------ ParkanPlayground/Program.cs | 1 + README.md | 22 +++++++- 4 files changed, 30 insertions(+), 88 deletions(-) diff --git a/ParkanPlayground/Msh0D.cs b/ParkanPlayground/Msh0D.cs index 1ce8b4a..9f64526 100644 --- a/ParkanPlayground/Msh0D.cs +++ b/ParkanPlayground/Msh0D.cs @@ -26,7 +26,8 @@ public static class Msh0D var elements = elementBytes.Select(x => new Msh0DElement() { Flags = BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0)), - Magic04 = BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(4)), + Magic04 = x.AsSpan(4)[0], + Magic05 = x.AsSpan(5)[0], Magic06 = BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(6)), CountOf06 = BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(8)), IndexInto06 = BinaryPrimitives.ReadInt32LittleEndian(x.AsSpan(0xA)), @@ -43,7 +44,8 @@ public static class Msh0D // Magic04 и Magic06 обрабатываются вместе - public ushort Magic04 { get; set; } + public byte Magic04 { get; set; } + public byte Magic05 { get; set; } public ushort Magic06 { get; set; } public ushort CountOf06 { get; set; } public int IndexInto06 { get; set; } diff --git a/ParkanPlayground/MshConverter.cs b/ParkanPlayground/MshConverter.cs index e125784..7fb63d5 100644 --- a/ParkanPlayground/MshConverter.cs +++ b/ParkanPlayground/MshConverter.cs @@ -1,5 +1,3 @@ -using System.Buffers.Binary; -using System.Globalization; using System.Text; using Common; using NResLib; @@ -41,6 +39,7 @@ public class MshConverter // 01 - это части меша (Piece) for (var pieceIndex = 0; pieceIndex < component01.Elements.Count; pieceIndex++) { + Console.WriteLine($"Piece {pieceIndex}"); var piece01 = component01.Elements[pieceIndex]; // var state = (piece.State00 == 0xffff) ? 0 : piece.State00; @@ -49,7 +48,7 @@ public class MshConverter var lod = piece01.Lod[lodIndex]; if (lod == 0xffff) { - Console.WriteLine($"Piece {pieceIndex} has lod -1 at {lodIndex}. Skipping"); + // Console.WriteLine($"Piece {pieceIndex} has lod -1 at {lodIndex}. Skipping"); continue; } @@ -58,6 +57,9 @@ public class MshConverter var part02 = component02.Elements[lod]; int indexInto07 = part02.StartIndexIn07; + var comp07 = component07[indexInto07]; + Console.WriteLine($"Lod {lodIndex}"); + Console.WriteLine($"Comp07: {comp07.OffsetX}, {comp07.OffsetY}, {comp07.OffsetZ}"); var element0Dstart = part02.StartOffsetIn0d; var element0Dcount = part02.ByteLengthIn0D; @@ -88,7 +90,6 @@ public class MshConverter // sw.WriteLine($"o piece_{pieceIndex}_of_mesh_{comp0Dindex}_tri_{ind}"); - var comp07 = component07[indexInto07]; var i1 = indexInto03 + component06[indexInto06]; var i2 = indexInto03 + component06[indexInto06 + 1]; @@ -120,86 +121,6 @@ public class MshConverter } } - public void Convert2(string mshPath) - { - var mshNresResult = NResParser.ReadFile(mshPath); - var mshNres = mshNresResult.Archive!; - - using var mshFs = new FileStream(mshPath, FileMode.Open, FileAccess.Read, FileShare.Read); - - var component01 = Msh01.ReadComponent(mshFs, mshNres); - var component02 = Msh02.ReadComponent(mshFs, mshNres); - var component0A = Msh0A.ReadComponent(mshFs, mshNres); - var component07 = Msh07.ReadComponent(mshFs, mshNres); - var component0D = Msh0D.ReadComponent(mshFs, mshNres); - - // Triangle Vertex Indices - var component06 = Msh06.ReadComponent(mshFs, mshNres); - - // vertices - var component03 = Msh03.ReadComponent(mshFs, mshNres); - - var csv06 = new StreamWriter("06.csv", false, Encoding.UTF8); - - for (var i = 0; i < component06.Count; i += 3) - { - // csv06.WriteLine($"{component06[i]}"); - csv06.WriteLine($"{component06[i]}, {component06[i + 1]}, {component06[i + 2]}"); - } - - csv06.Dispose(); - - var csv03 = new StreamWriter("03.obj", false, Encoding.UTF8); - - csv03.WriteLine(); - for (var i = 7525; i < component03.Count; i++) - { - // csv06.WriteLine($"{component06[i]}"); - // csv03.WriteAsync($"o {i - 7525}"); - csv03.WriteLine( - $"v {component03[i].X.ToString("F2", CultureInfo.InvariantCulture)} {component03[i].Y.ToString("F2", CultureInfo.InvariantCulture)} {component03[i].Z.ToString("F2", CultureInfo.InvariantCulture)}"); - } - - for (var i = 10485; i < component06.Count; i += 3) - { - csv03.WriteLine($"f {component06[i] + 1} {component06[i + 1] + 1} {component06[i + 2] + 1}"); - } - - csv03.Dispose(); - - // --- Write OBJ --- - using var sw = new StreamWriter("test.obj", false, Encoding.UTF8); - - for (var index = 0; index < component03.Count; index++) - { - var v = component03[index]; - sw.WriteLine($"v {v.X:F8} {v.Y:F8} {v.Z:F8}"); - } - - for (var i = 0; i < 1; i++) - { - sw.WriteLine($"o elem_0d_{i}"); - var element0D = component0D[i]; - - Console.WriteLine($"Processing element 0D [{i}]:"); - - var elementsOf06 = component06 - .Skip(element0D.IndexInto06) - .Take(element0D.CountOf06) - .ToList(); - - Console.WriteLine($"\tCount of 06: {elementsOf06.Count}, starting from {element0D.IndexInto06}"); - var indexInto03 = element0D.IndexInto03; - - Console.WriteLine($"\tIndexInto03: {indexInto03}"); - - if (elementsOf06.Count < 3) - { - throw new Exception("Less than 3 points"); - } - } - } - public record Face(Vector3 P1, Vector3 P2, Vector3 P3); public static void ExportCube(string filePath, Vector3[] points) diff --git a/ParkanPlayground/Program.cs b/ParkanPlayground/Program.cs index 3d41a33..691e96b 100644 --- a/ParkanPlayground/Program.cs +++ b/ParkanPlayground/Program.cs @@ -10,6 +10,7 @@ using ParkanPlayground; var converter = new MshConverter(); converter.Convert("E:\\ParkanUnpacked\\fortif.rlb\\133_fr_m_bunker.msh"); +// converter.Convert("C:\\Program Files (x86)\\Nikita\\Iron Strategy\\DATA\\MAPS\\SC_1\\Land.msh"); // converter.Convert("E:\\ParkanUnpacked\\fortif.rlb\\73_fr_m_brige.msh"); // converter.Convert("E:\\ParkanUnpacked\\intsys.rlb\\277_MESH_o_pws_l_01.msh"); // converter.Convert("E:\\ParkanUnpacked\\static.rlb\\2_MESH_s_stn_0_01.msh"); diff --git a/README.md b/README.md index 21934f9..bef959e 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,9 @@ IComponent ** LoadSomething(undefined4, undefined4, undefined4, undefined4) ## `.msh` +### Описание ниже валидно только для моделей роботов и зданий. +##### Land.msh использует другой формат, хотя 03 файл это всё ещё точки. + Загружается в `AniMesh.dll/LoadAniMesh` - Тип 01 - заголовок. Он хранит список деталей (submesh) в разных LOD @@ -277,6 +280,22 @@ IComponent ** LoadSomething(undefined4, undefined4, undefined4, undefined4) Загружается в `World3D.dll/LoadMatManager` +По сути это текстовый файл состоящий из 2 частей: +- Материалы + ``` + {count} + {id} {name} + ``` +- Карты освещения + ``` + LIGHTMAPS + {count} + {id} {name} + ``` + +Может как-то анимироваться. Как - пока не понятно. + + # Внутренняя система ID - `1` - @@ -309,6 +328,7 @@ IComponent ** LoadSomething(undefined4, undefined4, undefined4, undefined4) - `0x28` - ICollObject - `0x101` - 3DRender - `0x105` - NResFile +- `0x106` - NResFileMetadata - `0x201` - IWizard - `0x202` - IItemManager - `0x203` - ICollManager @@ -317,8 +337,6 @@ IComponent ** LoadSomething(undefined4, undefined4, undefined4, undefined4) - `0x303` - IHallway - `0x304` - Distributor - `0x401` - ISuperAI -- `0x105` - NResFile -- `0x106` - NResFileMetadata - `0x501` - MissionData - `0x502` - ResTree - `0x700` - NetWatcher