Parse lightmaps as flat array rather than multidimensional array

This commit is contained in:
Jarrod Doyle 2024-08-27 07:10:38 +01:00
parent efb15c19dd
commit d125fb2cd3
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
2 changed files with 21 additions and 24 deletions

View File

@ -97,45 +97,42 @@ public class WorldRep : IChunk
public struct Lightmap public struct Lightmap
{ {
public byte[,,,] Pixels { get; set; } public byte[] Pixels { get; set; }
public int Layers;
public int Width;
public int Height;
public int Bpp;
public Lightmap(BinaryReader reader, byte width, byte height, uint bitmask, int bytesPerPixel) public Lightmap(BinaryReader reader, byte width, byte height, uint bitmask, int bytesPerPixel)
{ {
var count = 1 + BitOperations.PopCount(bitmask); var count = 1 + BitOperations.PopCount(bitmask);
Pixels = new byte[count, height, width, bytesPerPixel]; var length = bytesPerPixel * width * height * count;
for (var c = 0; c < count; c++) Pixels = reader.ReadBytes(length);
{ Layers = count;
for (var y = 0; y < height; y++) Width = width;
{ Height = height;
for (var x = 0; x < width; x++) Bpp = bytesPerPixel;
{
for (var b = 0; b < bytesPerPixel; b++)
{
Pixels[c, y, x, b] = reader.ReadByte();
}
}
}
}
} }
public readonly Vector4 GetPixel(uint layer, uint x, uint y) public readonly Vector4 GetPixel(uint layer, uint x, uint y)
{ {
if (layer >= Pixels.GetLength(0) || x >= Pixels.GetLength(2) || y >= Pixels.GetLength(1)) if (layer >= Layers || x >= Width || y >= Height)
{ {
return Vector4.Zero; return Vector4.Zero;
} }
switch (Pixels.GetLength(3)) var idx = 0 + x * Bpp + y * Bpp * Width + layer * Bpp * Width * Height;
switch (Bpp)
{ {
case 1: case 1:
var raw1 = Pixels[layer, y, x, 0]; var raw1 = Pixels[idx];
return new Vector4(raw1, raw1, raw1, 255) / 255.0f; return new Vector4(raw1, raw1, raw1, 255) / 255.0f;
case 2: case 2:
var raw2 = Pixels[layer, y, x, 0] + (Pixels[layer, y, x, 1] << 8); var raw2 = Pixels[idx] + (Pixels[idx + 1] << 8);
return new Vector4(raw2 & 31, (raw2 >> 5) & 31, (raw2 >> 10) & 31, 31) / 31.0f; return new Vector4(raw2 & 31, (raw2 >> 5) & 31, (raw2 >> 10) & 31, 31) / 31.0f;
case 4: case 4:
// 4bpp stored as BGRA return new Vector4(Pixels[idx + 2], Pixels[idx + 1], Pixels[idx], Pixels[idx + 3]) / 255.0f;
return new Vector4(Pixels[layer, y, x, 2], Pixels[layer, y, x, 1], Pixels[layer, y, x, 0], Pixels[layer, y, x, 3]) / 255.0f;
default: default:
return Vector4.Zero; return Vector4.Zero;
} }

View File

@ -299,9 +299,9 @@ public partial class Mission : Node3D
if (info.cellIndex >= cells.Length) GD.Print($"CellIndex too big: {info.cellIndex}/{cells.Length}"); if (info.cellIndex >= cells.Length) GD.Print($"CellIndex too big: {info.cellIndex}/{cells.Length}");
if (info.lightmapIndex >= cells[info.cellIndex].Lightmaps.Length) GD.Print($"LightmapIndex too big: {info.lightmapIndex}/{cells[info.cellIndex].Lightmaps.Length}"); if (info.lightmapIndex >= cells[info.cellIndex].Lightmaps.Length) GD.Print($"LightmapIndex too big: {info.lightmapIndex}/{cells[info.cellIndex].Lightmaps.Length}");
var lightmap = cells[info.cellIndex].Lightmaps[info.lightmapIndex]; var lightmap = cells[info.cellIndex].Lightmaps[info.lightmapIndex];
var layers = (uint)lightmap.Pixels.GetLength(0); var layers = (uint)lightmap.Layers;
var height = (uint)lightmap.Pixels.GetLength(1); var height = (uint)lightmap.Height;
var width = (uint)lightmap.Pixels.GetLength(2); var width = (uint)lightmap.Width;
for (uint y = 0; y < height; y++) for (uint y = 0; y < height; y++)
{ {
for (uint x = 0; x < width; x++) for (uint x = 0; x < width; x++)