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--;
|
||||
}
|
||||
}
|
||||
|
||||
[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 newLight = 0;
|
||||
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 (chunk.GetHeight((byte)adjustedCoords.X, (byte)adjustedCoords.Z) <= y)
|
||||
if (y >= chunk.GetHeight((byte)adjustedCoords.X, (byte)adjustedCoords.Z))
|
||||
emissiveness = 15;
|
||||
}
|
||||
else
|
||||
emissiveness = provider.Luminance;
|
||||
if (opacity < 15 || emissiveness != 0)
|
||||
{
|
||||
byte max = 0;
|
||||
@ -116,7 +118,7 @@ namespace TrueCraft.Core.Lighting
|
||||
else
|
||||
val = c.GetBlockLight(adjusted);
|
||||
var p = BlockRepository.GetBlockProvider(c.GetBlockID(adjusted));
|
||||
val -= p.LightModifier;
|
||||
val -= Math.Max(0, p.LightModifier - 1);
|
||||
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
|
||||
&& op.Box.Volume - box.Volume <= 2)
|
||||
{
|
||||
// Merge
|
||||
op.Box = new BoundingBox(Vector3.Min(op.Box.Min, box.Min), Vector3.Max(op.Box.Max, box.Max));
|
||||
return;
|
||||
// TODO: Merge
|
||||
//op.Box = new BoundingBox(Vector3.Min(op.Box.Min, box.Min), Vector3.Max(op.Box.Max, box.Max));
|
||||
//return;
|
||||
}
|
||||
}
|
||||
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 is needed since some "partial" transparent blocks remove more than 1 level from light passing through such as Ice.
|
||||
/// </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; } }
|
||||
|
||||
|
@ -16,8 +16,6 @@ namespace TrueCraft.Core.Logic.Blocks
|
||||
|
||||
public override bool Opaque { get { return false; } }
|
||||
|
||||
public override byte LightModifier { get { return 0; } }
|
||||
|
||||
public override byte Luminance { get { return 0; } }
|
||||
|
||||
public override string DisplayName { get { return "Air"; } }
|
||||
|
@ -20,7 +20,9 @@ namespace TrueCraft.Core.Logic.Blocks
|
||||
|
||||
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"; } }
|
||||
|
||||
|
@ -89,6 +89,7 @@ namespace TrueCraft
|
||||
Server.Log(LogCategory.Notice, "{0}% complete", progress + 10);
|
||||
}
|
||||
}
|
||||
world.Save();
|
||||
CommandManager = new CommandManager();
|
||||
Server.ChatMessageReceived += HandleChatMessageReceived;
|
||||
Server.Start(new IPEndPoint(IPAddress.Parse(ServerConfiguration.ServerAddress), ServerConfiguration.ServerPort));
|
||||
|
Reference in New Issue
Block a user