Fix propegation of light through leaves/etc
This commit is contained in:
parent
61310e6bbb
commit
edf7205050
@ -232,6 +232,94 @@ namespace TrueCraft.Core.Test.Lighting
|
|||||||
expected--;
|
expected--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLeavesAndEtc()
|
||||||
|
{
|
||||||
|
var repository = new BlockRepository();
|
||||||
|
repository.RegisterBlockProvider(new GrassBlock());
|
||||||
|
repository.RegisterBlockProvider(new DirtBlock());
|
||||||
|
repository.RegisterBlockProvider(new AirBlock());
|
||||||
|
repository.RegisterBlockProvider(new BedrockBlock());
|
||||||
|
repository.RegisterBlockProvider(new LeavesBlock());
|
||||||
|
var world = new TrueCraft.Core.World.World("TEST", new FlatlandGenerator());
|
||||||
|
world.BlockRepository = repository;
|
||||||
|
var lighter = new WorldLighter(world, repository);
|
||||||
|
world.GetBlockID(Coordinates3D.Zero); // Generate a chunk
|
||||||
|
|
||||||
|
for (int y = 1; y <= 16; y++)
|
||||||
|
{
|
||||||
|
var coords = new Coordinates3D(5, y, 5);
|
||||||
|
world.SetBlockID(coords, 0);
|
||||||
|
world.SetBlockID(coords + Coordinates3D.East, DirtBlock.BlockID);
|
||||||
|
world.SetBlockID(coords + Coordinates3D.West, DirtBlock.BlockID);
|
||||||
|
world.SetBlockID(coords + Coordinates3D.North, DirtBlock.BlockID);
|
||||||
|
world.SetBlockID(coords + Coordinates3D.South, DirtBlock.BlockID);
|
||||||
|
}
|
||||||
|
world.GetChunk(Coordinates2D.Zero).UpdateHeightMap();
|
||||||
|
|
||||||
|
lighter.EnqueueOperation(new BoundingBox(
|
||||||
|
new Vector3(0, 0, 0),
|
||||||
|
new Vector3(16, 128, 16)), true, true);
|
||||||
|
while (lighter.TryLightNext()) // Initial lighting
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test this layout:
|
||||||
|
// xox o == leaves
|
||||||
|
// x x
|
||||||
|
// xox
|
||||||
|
// x x
|
||||||
|
// xox ...
|
||||||
|
|
||||||
|
for (int y = 1; y <= 16; y++)
|
||||||
|
{
|
||||||
|
if (y % 2 == 1)
|
||||||
|
world.SetBlockID(new Coordinates3D(5, y, 5), LeavesBlock.BlockID);
|
||||||
|
}
|
||||||
|
world.GetChunk(Coordinates2D.Zero).UpdateHeightMap();
|
||||||
|
|
||||||
|
lighter.EnqueueOperation(new BoundingBox(new Vector3(5, 0, 5),
|
||||||
|
new Vector3(6, 16, 6)), true);
|
||||||
|
|
||||||
|
while (lighter.TryLightNext()) // Test lighting
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output lighting
|
||||||
|
for (int y = 16; y >= 0; y--)
|
||||||
|
{
|
||||||
|
Console.Write(world.GetBlockID(new Coordinates3D(5, y, 5)).ToString("D2"));
|
||||||
|
Console.Write(" " + world.GetSkyLight(new Coordinates3D(5, y, 5)).ToString("D2"));
|
||||||
|
Console.WriteLine(" Y={0}", y);
|
||||||
|
}
|
||||||
|
|
||||||
|
var expected = new byte[]
|
||||||
|
{
|
||||||
|
15, // air
|
||||||
|
15, // leaves
|
||||||
|
13, // air
|
||||||
|
11, // leaves
|
||||||
|
9, // air
|
||||||
|
7, // leaves
|
||||||
|
5, // air
|
||||||
|
3, // leaves
|
||||||
|
1, // air
|
||||||
|
0, // leaves
|
||||||
|
0, // air
|
||||||
|
0, // leaves
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int y = 16, i = 0; y >= 0; y--, i++)
|
||||||
|
{
|
||||||
|
byte ex;
|
||||||
|
if (i < expected.Length)
|
||||||
|
ex = expected[i];
|
||||||
|
else
|
||||||
|
ex = 0;
|
||||||
|
Assert.AreEqual(ex, world.GetSkyLight(new Coordinates3D(5, y, 5)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,12 +93,14 @@ namespace TrueCraft.Core.Lighting
|
|||||||
byte current = op.SkyLight ? data.SkyLight : data.BlockLight;
|
byte current = op.SkyLight ? data.SkyLight : data.BlockLight;
|
||||||
byte newLight = 0;
|
byte newLight = 0;
|
||||||
byte opacity = Math.Max(provider.LightModifier, (byte)1);
|
byte opacity = Math.Max(provider.LightModifier, (byte)1);
|
||||||
byte emissiveness = Math.Max(provider.Luminance, op.SkyLight ? data.SkyLight : data.BlockLight);
|
byte emissiveness = provider.Luminance;
|
||||||
if (op.SkyLight)
|
if (op.SkyLight)
|
||||||
{
|
{
|
||||||
if (chunk.GetHeight((byte)adjustedCoords.X, (byte)adjustedCoords.Z) <= y)
|
if (y >= chunk.GetHeight((byte)adjustedCoords.X, (byte)adjustedCoords.Z))
|
||||||
emissiveness = 15;
|
emissiveness = 15;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
emissiveness = provider.Luminance;
|
||||||
if (opacity < 15 || emissiveness != 0)
|
if (opacity < 15 || emissiveness != 0)
|
||||||
{
|
{
|
||||||
byte max = 0;
|
byte max = 0;
|
||||||
@ -116,7 +118,7 @@ namespace TrueCraft.Core.Lighting
|
|||||||
else
|
else
|
||||||
val = c.GetBlockLight(adjusted);
|
val = c.GetBlockLight(adjusted);
|
||||||
var p = BlockRepository.GetBlockProvider(c.GetBlockID(adjusted));
|
var p = BlockRepository.GetBlockProvider(c.GetBlockID(adjusted));
|
||||||
val -= p.LightModifier;
|
val -= Math.Max(0, p.LightModifier - 1);
|
||||||
max = (byte)Math.Max(max, val);
|
max = (byte)Math.Max(max, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,9 +173,9 @@ namespace TrueCraft.Core.Lighting
|
|||||||
if (op.Box.Min.DistanceTo(box.Min) <= 2 && op.Box.Max.DistanceTo(box.Max) <= 2
|
if (op.Box.Min.DistanceTo(box.Min) <= 2 && op.Box.Max.DistanceTo(box.Max) <= 2
|
||||||
&& op.Box.Volume - box.Volume <= 2)
|
&& op.Box.Volume - box.Volume <= 2)
|
||||||
{
|
{
|
||||||
// Merge
|
// TODO: Merge
|
||||||
op.Box = new BoundingBox(Vector3.Min(op.Box.Min, box.Min), Vector3.Max(op.Box.Max, box.Max));
|
//op.Box = new BoundingBox(Vector3.Min(op.Box.Min, box.Min), Vector3.Max(op.Box.Max, box.Max));
|
||||||
return;
|
//return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PendingOperations.Add(new LightingOperation { SkyLight = skyLight, Box = box, Initial = initial });
|
PendingOperations.Add(new LightingOperation { SkyLight = skyLight, Box = box, Initial = initial });
|
||||||
|
@ -208,7 +208,16 @@ namespace TrueCraft.Core.Logic
|
|||||||
/// - This isn't needed for opaque blocks
|
/// - This isn't needed for opaque blocks
|
||||||
/// - This is needed since some "partial" transparent blocks remove more than 1 level from light passing through such as Ice.
|
/// - This is needed since some "partial" transparent blocks remove more than 1 level from light passing through such as Ice.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual byte LightModifier { get { return 255; } }
|
public virtual byte LightModifier
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Opaque)
|
||||||
|
return 255;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual bool DiffuseSkyLight { get { return false; } }
|
public virtual bool DiffuseSkyLight { get { return false; } }
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@ namespace TrueCraft.Core.Logic.Blocks
|
|||||||
|
|
||||||
public override bool Opaque { get { return false; } }
|
public override bool Opaque { get { return false; } }
|
||||||
|
|
||||||
public override byte LightModifier { get { return 0; } }
|
|
||||||
|
|
||||||
public override byte Luminance { get { return 0; } }
|
public override byte Luminance { get { return 0; } }
|
||||||
|
|
||||||
public override string DisplayName { get { return "Air"; } }
|
public override string DisplayName { get { return "Air"; } }
|
||||||
|
@ -20,7 +20,9 @@ namespace TrueCraft.Core.Logic.Blocks
|
|||||||
|
|
||||||
public override bool Opaque { get { return false; } }
|
public override bool Opaque { get { return false; } }
|
||||||
|
|
||||||
//TODO: Mark this as a block that diffuses sun light.
|
public override bool DiffuseSkyLight { get { return true; } }
|
||||||
|
|
||||||
|
public override byte LightModifier { get { return 2; } }
|
||||||
|
|
||||||
public override string DisplayName { get { return "Leaves"; } }
|
public override string DisplayName { get { return "Leaves"; } }
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ namespace TrueCraft
|
|||||||
Server.Log(LogCategory.Notice, "{0}% complete", progress + 10);
|
Server.Log(LogCategory.Notice, "{0}% complete", progress + 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
world.Save();
|
||||||
CommandManager = new CommandManager();
|
CommandManager = new CommandManager();
|
||||||
Server.ChatMessageReceived += HandleChatMessageReceived;
|
Server.ChatMessageReceived += HandleChatMessageReceived;
|
||||||
Server.Start(new IPEndPoint(IPAddress.Parse(ServerConfiguration.ServerAddress), ServerConfiguration.ServerPort));
|
Server.Start(new IPEndPoint(IPAddress.Parse(ServerConfiguration.ServerAddress), ServerConfiguration.ServerPort));
|
||||||
|
Reference in New Issue
Block a user