Skip to content

Commit

Permalink
Fixes of invisible meshes and repeating coords
Browse files Browse the repository at this point in the history
  • Loading branch information
BigBang1112 committed Nov 24, 2024
1 parent 5c87152 commit 961d48b
Showing 1 changed file with 34 additions and 13 deletions.
47 changes: 34 additions & 13 deletions Src/GBX.NET/Engines/Plug/CPlugCrystal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ public override void Read(CPlugCrystal n, GbxReader r)
Version = r.ReadInt32();

var faces = n.Layers.OfType<GeometryLayer>()
.Where(x => x.IsVisible)
.Select(x => x.Crystal)
.OfType<Crystal>()
.SelectMany(c => c.Faces);
Expand Down Expand Up @@ -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");
}
Expand All @@ -225,34 +237,37 @@ public override void Write(CPlugCrystal n, GbxWriter w)
w.Write(Version);

var faces = n.Layers.OfType<GeometryLayer>()
.Where(x => x.IsVisible)
.Select(x => x.Crystal)
.OfType<Crystal>()
.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);
}
}

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));
}

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);
}
Expand Down Expand Up @@ -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);
}

0 comments on commit 961d48b

Please sign in to comment.