Reset lighting table and lightmaps
This commit is contained in:
parent
ea72c3af4a
commit
ab738203d6
|
@ -274,16 +274,16 @@ public class WorldRep : IChunk
|
||||||
AddLight(layer, x, y, c.Z, c.Y, c.X);
|
AddLight(layer, x, y, c.Z, c.Y, c.X);
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly void Reset(Vector3 ambientLight, bool hdr)
|
public void Reset(Vector3 ambientLight, bool hdr)
|
||||||
{
|
{
|
||||||
// TODO: This should set to one layer when we write our own lighttable etc
|
|
||||||
var bytesPerLayer = Width * Height * Bpp;
|
var bytesPerLayer = Width * Height * Bpp;
|
||||||
for (var i = 0; i < Layers; i++)
|
Pixels.Clear();
|
||||||
{
|
Pixels.Add(new byte[bytesPerLayer]);
|
||||||
|
Layers = 1;
|
||||||
|
|
||||||
for (var j = 0; j < bytesPerLayer; j++)
|
for (var j = 0; j < bytesPerLayer; j++)
|
||||||
{
|
{
|
||||||
Pixels[i][j] = 0;
|
Pixels[0][j] = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var y = 0; y < Height; y++)
|
for (var y = 0; y < Height; y++)
|
||||||
|
@ -568,30 +568,31 @@ public class WorldRep : IChunk
|
||||||
public int LightCount;
|
public int LightCount;
|
||||||
public int DynamicLightCount;
|
public int DynamicLightCount;
|
||||||
public int AnimMapCount;
|
public int AnimMapCount;
|
||||||
public LightData[] Lights;
|
public List<LightData> Lights;
|
||||||
public LightData[] ScratchpadLights;
|
public LightData[] ScratchpadLights;
|
||||||
public AnimCellMap[] AnimCellMaps;
|
public List<AnimCellMap> AnimCellMaps;
|
||||||
|
|
||||||
// TODO: Support olddark
|
// TODO: Support olddark
|
||||||
public LightTable(BinaryReader reader)
|
public LightTable(BinaryReader reader)
|
||||||
{
|
{
|
||||||
LightCount = reader.ReadInt32();
|
LightCount = reader.ReadInt32();
|
||||||
DynamicLightCount = reader.ReadInt32();
|
DynamicLightCount = reader.ReadInt32();
|
||||||
Lights = new LightData[LightCount + DynamicLightCount];
|
var totalLightCount = LightCount + DynamicLightCount;
|
||||||
for (var i = 0; i < Lights.Length; i++)
|
Lights = new List<LightData>(totalLightCount);
|
||||||
|
for (var i = 0; i < totalLightCount; i++)
|
||||||
{
|
{
|
||||||
Lights[i] = new LightData(reader);
|
Lights.Add(new LightData(reader));
|
||||||
}
|
}
|
||||||
ScratchpadLights = new LightData[32];
|
ScratchpadLights = new LightData[32];
|
||||||
for (var i = 0; i < ScratchpadLights.Length; i++)
|
for (var i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
ScratchpadLights[i] = new LightData(reader);
|
ScratchpadLights[i] = new LightData(reader);
|
||||||
}
|
}
|
||||||
AnimMapCount = reader.ReadInt32();
|
AnimMapCount = reader.ReadInt32();
|
||||||
AnimCellMaps = new AnimCellMap[AnimMapCount];
|
AnimCellMaps = new List<AnimCellMap>(AnimMapCount);
|
||||||
for (var i = 0; i < AnimCellMaps.Length; i++)
|
for (var i = 0; i < AnimMapCount; i++)
|
||||||
{
|
{
|
||||||
AnimCellMaps[i] = new AnimCellMap(reader);
|
AnimCellMaps.Add(new AnimCellMap(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,6 +614,29 @@ public class WorldRep : IChunk
|
||||||
map.Write(writer);
|
map.Write(writer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
LightCount = 0;
|
||||||
|
DynamicLightCount = 0;
|
||||||
|
AnimMapCount = 0;
|
||||||
|
Lights.Clear();
|
||||||
|
AnimCellMaps.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddLight(LightData data, bool dynamicLight = false)
|
||||||
|
{
|
||||||
|
if (dynamicLight)
|
||||||
|
{
|
||||||
|
DynamicLightCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LightCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lights.Add(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkHeader Header { get; set; }
|
public ChunkHeader Header { get; set; }
|
||||||
|
|
|
@ -57,8 +57,6 @@ class Program
|
||||||
var mis = Timing.TimeStage("Parse DB", () => new DbFile(misPath));
|
var mis = Timing.TimeStage("Parse DB", () => new DbFile(misPath));
|
||||||
var hierarchy = Timing.TimeStage("Build Hierarchy", () => BuildHierarchy(misPath, mis));
|
var hierarchy = Timing.TimeStage("Build Hierarchy", () => BuildHierarchy(misPath, mis));
|
||||||
|
|
||||||
var lights = Timing.TimeStage("Gather Lights", () => BuildLightList(mis, hierarchy, campaign));
|
|
||||||
|
|
||||||
// Build embree mesh
|
// Build embree mesh
|
||||||
if (!mis.Chunks.TryGetValue("WREXT", out var wrRaw))
|
if (!mis.Chunks.TryGetValue("WREXT", out var wrRaw))
|
||||||
return;
|
return;
|
||||||
|
@ -75,6 +73,7 @@ class Program
|
||||||
if (!mis.Chunks.TryGetValue("RENDPARAMS", out var rendParamsRaw))
|
if (!mis.Chunks.TryGetValue("RENDPARAMS", out var rendParamsRaw))
|
||||||
return;
|
return;
|
||||||
var ambient = ((RendParams)rendParamsRaw).ambientLight * 255;
|
var ambient = ((RendParams)rendParamsRaw).ambientLight * 255;
|
||||||
|
var lights = Timing.TimeStage("Gather Lights", () => BuildLightList(mis, hierarchy, campaign));
|
||||||
Timing.TimeStage("Light", () => CastSceneParallel(scene, worldRep, [.. lights], ambient));
|
Timing.TimeStage("Light", () => CastSceneParallel(scene, worldRep, [.. lights], ambient));
|
||||||
|
|
||||||
var dir = Path.GetDirectoryName(misPath);
|
var dir = Path.GetDirectoryName(misPath);
|
||||||
|
@ -109,25 +108,45 @@ class Program
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get list of brush lights, and object lights (ignore anim lights for now)
|
// Gather all the brush, object, and anim ligths. Resets the lighting table
|
||||||
private static List<Light> BuildLightList(DbFile mis, ObjectHierarchy hierarchy, ResourcePathManager.CampaignResources campaign)
|
// TODO: Handle dynamic lights
|
||||||
|
private static List<Light> BuildLightList(
|
||||||
|
DbFile mis,
|
||||||
|
ObjectHierarchy hierarchy,
|
||||||
|
ResourcePathManager.CampaignResources campaign)
|
||||||
{
|
{
|
||||||
var lights = new List<Light>();
|
var lights = new List<Light>();
|
||||||
|
|
||||||
if (mis.Chunks.TryGetValue("BRLIST", out var brListRaw))
|
// Get the chunks we need
|
||||||
|
if (!mis.TryGetChunk<WorldRep>("WREXT", out var worldRep) ||
|
||||||
|
!mis.TryGetChunk<BrList>("BRLIST", out var brList))
|
||||||
{
|
{
|
||||||
var brList = (BrList)brListRaw;
|
return lights;
|
||||||
|
}
|
||||||
|
|
||||||
|
worldRep.LightingTable.Reset();
|
||||||
|
|
||||||
foreach (var brush in brList.Brushes)
|
foreach (var brush in brList.Brushes)
|
||||||
{
|
{
|
||||||
if (brush.media == BrList.Brush.Media.Light)
|
if (brush.media == BrList.Brush.Media.Light)
|
||||||
{
|
{
|
||||||
var sz = brush.size;
|
var sz = brush.size;
|
||||||
lights.Add(new Light
|
var light = new Light
|
||||||
{
|
{
|
||||||
position = brush.position,
|
position = brush.position,
|
||||||
color = HsbToRgb(sz.Y, sz.Z, Math.Min(sz.X, 255.0f)),
|
color = HsbToRgb(sz.Y, sz.Z, Math.Min(sz.X, 255.0f)),
|
||||||
radius = float.MaxValue,
|
radius = float.MaxValue,
|
||||||
r2 = float.MaxValue,
|
r2 = float.MaxValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
lights.Add(light);
|
||||||
|
worldRep.LightingTable.AddLight(new WorldRep.LightTable.LightData
|
||||||
|
{
|
||||||
|
Location = light.position,
|
||||||
|
Direction = light.spotlightDir,
|
||||||
|
Color = light.color / 32.0f, // TODO: This is based on light_scale config var
|
||||||
|
InnerAngle = -1.0f,
|
||||||
|
Radius = 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (brush.media == BrList.Brush.Media.Object)
|
else if (brush.media == BrList.Brush.Media.Object)
|
||||||
|
@ -146,6 +165,7 @@ class Program
|
||||||
{
|
{
|
||||||
position = brush.position,
|
position = brush.position,
|
||||||
spotlightDir = -Vector3.UnitZ,
|
spotlightDir = -Vector3.UnitZ,
|
||||||
|
spotlightInnerAngle = -1.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (propModelname != null)
|
if (propModelname != null)
|
||||||
|
@ -203,10 +223,22 @@ class Program
|
||||||
}
|
}
|
||||||
|
|
||||||
lights.Add(light);
|
lights.Add(light);
|
||||||
|
worldRep.LightingTable.AddLight(new WorldRep.LightTable.LightData
|
||||||
|
{
|
||||||
|
Location = light.position,
|
||||||
|
Direction = light.spotlightDir,
|
||||||
|
Color = light.color / 32.0f, // TODO: This is based on light_scale config var
|
||||||
|
InnerAngle = light.spotlightInnerAngle,
|
||||||
|
OuterAngle = light.spotlightOuterAngle,
|
||||||
|
Radius = propLight.Radius,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propAnimLight != null)
|
if (propAnimLight != null)
|
||||||
{
|
{
|
||||||
|
var lightIndex = worldRep.LightingTable.LightCount;
|
||||||
|
propAnimLight.LightTableLightIndex = (ushort)lightIndex;
|
||||||
|
|
||||||
var light = new Light
|
var light = new Light
|
||||||
{
|
{
|
||||||
position = baseLight.position + propAnimLight.Offset,
|
position = baseLight.position + propAnimLight.Offset,
|
||||||
|
@ -228,7 +260,15 @@ class Program
|
||||||
}
|
}
|
||||||
|
|
||||||
lights.Add(light);
|
lights.Add(light);
|
||||||
}
|
worldRep.LightingTable.AddLight(new WorldRep.LightTable.LightData
|
||||||
|
{
|
||||||
|
Location = light.position,
|
||||||
|
Direction = light.spotlightDir,
|
||||||
|
Color = light.color / 32.0f, // TODO: This is based on light_scale config var
|
||||||
|
InnerAngle = light.spotlightInnerAngle,
|
||||||
|
OuterAngle = light.spotlightOuterAngle,
|
||||||
|
Radius = propAnimLight.Radius,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,6 +354,8 @@ class Program
|
||||||
|
|
||||||
Parallel.ForEach(wr.Cells, cell =>
|
Parallel.ForEach(wr.Cells, cell =>
|
||||||
{
|
{
|
||||||
|
// TODO: Reset cell anim light count and palette
|
||||||
|
|
||||||
var numPolys = cell.PolyCount;
|
var numPolys = cell.PolyCount;
|
||||||
var numRenderPolys = cell.RenderPolyCount;
|
var numRenderPolys = cell.RenderPolyCount;
|
||||||
var numPortalPolys = cell.PortalPolyCount;
|
var numPortalPolys = cell.PortalPolyCount;
|
||||||
|
@ -335,6 +377,7 @@ class Program
|
||||||
var info = cell.LightList[polyIdx];
|
var info = cell.LightList[polyIdx];
|
||||||
var lightmap = cell.Lightmaps[polyIdx];
|
var lightmap = cell.Lightmaps[polyIdx];
|
||||||
|
|
||||||
|
info.AnimLightBitmask = 0;
|
||||||
lightmap.Reset(ambientLight, hdr);
|
lightmap.Reset(ambientLight, 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)
|
||||||
|
|
Loading…
Reference in New Issue