Compare commits

..

2 Commits

Author SHA1 Message Date
Jarrod Doyle 2e1c90b88a
Close #10: Apply ambient light zones 2024-12-26 17:12:28 +00:00
Jarrod Doyle 40ea7cce0e
Parse per cell fog/ambient zones 2024-12-26 17:10:41 +00:00
2 changed files with 59 additions and 8 deletions

View File

@ -352,6 +352,9 @@ public class WorldRep : IChunk
public int LightIndexCount { get; set; } public int LightIndexCount { get; set; }
public List<ushort> LightIndices { get; set; } public List<ushort> LightIndices { get; set; }
// Bonus data to make parallel iteration of cells easier
public CellZone ZoneInfo { get; set; } = new();
public Cell(BinaryReader reader, int bpp) public Cell(BinaryReader reader, int bpp)
{ {
VertexCount = reader.ReadByte(); VertexCount = reader.ReadByte();
@ -471,6 +474,37 @@ public class WorldRep : IChunk
} }
} }
// Readonly for now
public record CellZone
{
private readonly byte _data;
public CellZone()
{
_data = 0;
}
public CellZone(BinaryReader reader)
{
_data = reader.ReadByte();
}
public int GetAmbientLightZoneIndex()
{
return _data >> 4;
}
public int GetFogZoneIndex()
{
return _data & 0x0F;
}
public void Write(BinaryWriter writer)
{
writer.Write(_data);
}
}
public struct BspTree public struct BspTree
{ {
public struct Node public struct Node
@ -670,8 +704,8 @@ public class WorldRep : IChunk
public WrHeader DataHeader { get; set; } public WrHeader DataHeader { get; set; }
public Cell[] Cells { get; set; } public Cell[] Cells { get; set; }
public BspTree Bsp { get; set; } public BspTree Bsp { get; set; }
public CellZone[] CellZones { get; set; }
public LightTable LightingTable { get; set; } public LightTable LightingTable { get; set; }
private byte[] _unknown;
private byte[] _unreadData; private byte[] _unreadData;
public void ReadData(BinaryReader reader, DbFile.TableOfContents.Entry entry) public void ReadData(BinaryReader reader, DbFile.TableOfContents.Entry entry)
@ -686,9 +720,14 @@ public class WorldRep : IChunk
} }
Bsp = new BspTree(reader); Bsp = new BspTree(reader);
CellZones = new CellZone[Cells.Length];
for (var i = 0; i < Cells.Length; i++)
{
var zone = new CellZone(reader);
CellZones[i] = zone;
Cells[i].ZoneInfo = zone;
}
// TODO: Work out what this is
_unknown = reader.ReadBytes(Cells.Length);
LightingTable = new LightTable(reader); LightingTable = new LightTable(reader);
// TODO: All the other info lol // TODO: All the other info lol
@ -704,7 +743,10 @@ public class WorldRep : IChunk
cell.Write(writer); cell.Write(writer);
} }
Bsp.Write(writer); Bsp.Write(writer);
writer.Write(_unknown); foreach (var cellZone in CellZones)
{
cellZone.Write(writer);
}
LightingTable.Write(writer); LightingTable.Write(writer);
writer.Write(_unreadData); writer.Write(_unreadData);
} }

View File

@ -19,7 +19,7 @@ public class LightMapper
private struct Settings private struct Settings
{ {
public Vector3 AmbientLight; public Vector3[] AmbientLight;
public bool Hdr; public bool Hdr;
public SoftnessMode MultiSampling; public SoftnessMode MultiSampling;
public float MultiSamplingCenterWeight; public float MultiSamplingCenterWeight;
@ -77,11 +77,18 @@ public class LightMapper
Color = Utils.HsbToRgb(rendParams.sunlightHue, rendParams.sunlightSaturation, rendParams.sunlightBrightness), Color = Utils.HsbToRgb(rendParams.sunlightHue, rendParams.sunlightSaturation, rendParams.sunlightBrightness),
}; };
var ambientLight = rendParams.ambientLightZones.ToList();
ambientLight.Insert(0, rendParams.ambientLight);
for (var i = 0; i < ambientLight.Count; i++)
{
ambientLight[i] *= 255;
}
// TODO: lmParams LightmappedWater doesn't mean the game will actually *use* the lightmapped water hmm // TODO: lmParams LightmappedWater doesn't mean the game will actually *use* the lightmapped water hmm
var settings = new Settings var settings = new Settings
{ {
Hdr = worldRep.DataHeader.LightmapFormat == 2, Hdr = worldRep.DataHeader.LightmapFormat == 2,
AmbientLight = rendParams.ambientLight * 255, AmbientLight = [..ambientLight],
MultiSampling = lmParams.ShadowSoftness, MultiSampling = lmParams.ShadowSoftness,
MultiSamplingCenterWeight = lmParams.CenterWeight, MultiSamplingCenterWeight = lmParams.CenterWeight,
LightmappedWater = lmParams.LightmappedWater, LightmappedWater = lmParams.LightmappedWater,
@ -475,7 +482,9 @@ public class LightMapper
lightmap.Reset(Vector3.One * 255f, settings.Hdr); lightmap.Reset(Vector3.One * 255f, settings.Hdr);
continue; continue;
} }
lightmap.Reset(settings.AmbientLight, settings.Hdr);
var ambientLight = settings.AmbientLight[cell.ZoneInfo.GetAmbientLightZoneIndex()];
lightmap.Reset(ambientLight, settings.Hdr);
// Get world position of lightmap (0, 0) (+0.5 so we cast from the center of a pixel) // Get world position of lightmap (0, 0) (+0.5 so we cast from the center of a pixel)
var topLeft = cell.Vertices[cell.Indices[cellIdxOffset]]; var topLeft = cell.Vertices[cell.Indices[cellIdxOffset]];