From 961d48b608a4e33a3e4b3ca3984830f0251f2cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sun, 24 Nov 2024 02:13:48 +0100 Subject: [PATCH] Fixes of invisible meshes and repeating coords --- Src/GBX.NET/Engines/Plug/CPlugCrystal.cs | 47 +++++++++++++++++------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/Src/GBX.NET/Engines/Plug/CPlugCrystal.cs b/Src/GBX.NET/Engines/Plug/CPlugCrystal.cs index c783493f2..a5fbfd616 100644 --- a/Src/GBX.NET/Engines/Plug/CPlugCrystal.cs +++ b/Src/GBX.NET/Engines/Plug/CPlugCrystal.cs @@ -159,6 +159,7 @@ public override void Read(CPlugCrystal n, GbxReader r) Version = r.ReadInt32(); var faces = n.Layers.OfType() + .Where(x => x.IsVisible) .Select(x => x.Crystal) .OfType() .SelectMany(c => c.Faces); @@ -190,30 +191,41 @@ public override void Read(CPlugCrystal n, GbxReader r) if (Version >= 1) { - var lightmaps = new Vec2[lightmapCoordCount]; + var lightmapCoords = new Vec2[lightmapCoordCount]; for (int i = 0; i < lightmapCoordCount; i++) { - lightmaps[i] = (r.ReadUInt16() / (float)ushort.MaxValue, r.ReadUInt16() / (float)ushort.MaxValue); + lightmapCoords[i] = (r.ReadUInt16() / (float)ushort.MaxValue, r.ReadUInt16() / (float)ushort.MaxValue); } + // indices of lightmap coords var indices = Version >= 2 ? r.ReadArrayOptimizedInt() : null; + var lightmapCount = indices?.Length ?? lightmapCoordCount; + var counter = 0; foreach (var face in faces) { for (int i = 0; i < face.Vertices.Length; i++) { - face.Vertices[i] = face.Vertices[i] with { LightmapCoord = lightmaps[indices?[counter++] ?? counter] }; + try + { + var index = indices?[counter++] ?? counter; + face.Vertices[i] = face.Vertices[i] with { LightmapCoord = lightmapCoords[index] }; - if (counter > lightmapCoordCount) + if (counter > lightmapCount) + { + throw new Exception("LightmapCoord count exceeded"); + } + } + catch { - throw new Exception("LightmapCoord count exceeded"); + } } } - if (counter != lightmapCoordCount) + if (counter != lightmapCount) { throw new Exception("LightmapCoord count mismatch"); } @@ -225,17 +237,18 @@ public override void Write(CPlugCrystal n, GbxWriter w) w.Write(Version); var faces = n.Layers.OfType() + .Where(x => x.IsVisible) .Select(x => x.Crystal) .OfType() .SelectMany(c => c.Faces); - var lightmaps = faces.SelectMany(f => f.Vertices.Select(v => v.LightmapCoord)).ToArray(); + var lightmapCoords = faces.SelectMany(f => f.Vertices.Select(v => v.LightmapCoord)).ToArray(); - w.Write(lightmaps.Length); + w.Write(lightmapCoords.Length); if (Version == 0) { - foreach (var lightmap in lightmaps) + foreach (var lightmap in lightmapCoords) { w.Write(lightmap); } @@ -243,7 +256,7 @@ public override void Write(CPlugCrystal n, GbxWriter w) if (Version >= 1) { - foreach (var lightmap in lightmaps) + foreach (var lightmap in lightmapCoords) { w.Write((ushort)(lightmap.X * ushort.MaxValue)); w.Write((ushort)(lightmap.Y * ushort.MaxValue)); @@ -251,8 +264,10 @@ public override void Write(CPlugCrystal n, GbxWriter w) if (Version >= 2) { - // subject to optimization due to IndexOf complexity - var indices = faces.SelectMany(f => f.Vertices.Select(v => Array.IndexOf(lightmaps, v.LightmapCoord))).ToArray(); + var lightmapCoordIndices = lightmapCoords.Distinct() + .Select((x, i) => (x, i)) + .ToDictionary(x => x.x, x => x.i); + var indices = faces.SelectMany(f => f.Vertices.Select(v => lightmapCoordIndices[v.LightmapCoord])).ToArray(); w.WriteArrayOptimizedInt(indices); } @@ -779,7 +794,13 @@ public void Write(GbxWriter w, CPlugCrystal n, int v = 0) } } - public sealed record Face(Vertex[] Vertices, Part Group, Material? Material, Vec3? U01); + public sealed record Face(Vertex[] Vertices, Part Group, Material? Material, Vec3? U01) + { + public override string ToString() + { + return $"{Vertices.Length} vertices, material: {Material?.MaterialUserInst?.Link ?? Material?.MaterialName ?? "none"}"; + } + } public readonly record struct Vertex(int Index, Vec2 TexCoord, Vec2 LightmapCoord); }