add light source / sky light spreading lighter implementation (port)
This commit is contained in:
parent
6e2bb80b32
commit
7118479528
|
@ -210,6 +210,7 @@
|
||||||
<Compile Include="TileMap\Lighting\BaseTileMapLighter.cs" />
|
<Compile Include="TileMap\Lighting\BaseTileMapLighter.cs" />
|
||||||
<Compile Include="TileMap\Lighting\SimpleTileMapLighter.cs" />
|
<Compile Include="TileMap\Lighting\SimpleTileMapLighter.cs" />
|
||||||
<Compile Include="TileMap\Lighting\LitChunkVertexGenerator.cs" />
|
<Compile Include="TileMap\Lighting\LitChunkVertexGenerator.cs" />
|
||||||
|
<Compile Include="TileMap\Lighting\LightSpreadingTileMapLighter.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
using System;
|
||||||
|
using Blarg.GameFramework.TileMap.Meshes;
|
||||||
|
|
||||||
|
namespace Blarg.GameFramework.TileMap.Lighting
|
||||||
|
{
|
||||||
|
public class LightSpreadingTileMapLighter : BaseTileMapLighter
|
||||||
|
{
|
||||||
|
bool _doSkyLight;
|
||||||
|
bool _doTileLight;
|
||||||
|
|
||||||
|
public LightSpreadingTileMapLighter(bool doSkyLight, bool doTileLight)
|
||||||
|
{
|
||||||
|
_doSkyLight = doSkyLight;
|
||||||
|
_doTileLight = doTileLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LightSpreadingTileMapLighter()
|
||||||
|
: this(true, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spreadSkyLight(int x, int y, int z, Tile tile, byte light, TileMap tileMap)
|
||||||
|
{
|
||||||
|
if (light > 0)
|
||||||
|
{
|
||||||
|
tile.SkyLight = light;
|
||||||
|
--light;
|
||||||
|
|
||||||
|
var left = tileMap.GetSafe(x - 1, y, z);
|
||||||
|
var right = tileMap.GetSafe(x + 1, y, z);
|
||||||
|
var forward = tileMap.GetSafe(x, y, z - 1);
|
||||||
|
var backward = tileMap.GetSafe(x, y, z + 1);
|
||||||
|
var up = tileMap.GetSafe(x, y + 1, z);
|
||||||
|
var down = tileMap.GetSafe(x, y - 1, z);
|
||||||
|
|
||||||
|
if (left != null && (left.IsEmptySpace || !tileMap.TileMeshes.Get(left).IsOpaque(TileMesh.SIDE_RIGHT)) && left.SkyLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!left.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(left).Translucency);
|
||||||
|
spreadSkyLight(x - 1, y, z, left, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
if (right != null && (right.IsEmptySpace || !tileMap.TileMeshes.Get(right).IsOpaque(TileMesh.SIDE_LEFT)) && right.SkyLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!right.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(right).Translucency);
|
||||||
|
spreadSkyLight(x + 1, y, z, right, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
if (forward != null && (forward.IsEmptySpace || !tileMap.TileMeshes.Get(forward).IsOpaque(TileMesh.SIDE_BACK)) && forward.SkyLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!forward.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(forward).Translucency);
|
||||||
|
spreadSkyLight(x, y, z - 1, forward, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
if (backward != null && (backward.IsEmptySpace || !tileMap.TileMeshes.Get(backward).IsOpaque(TileMesh.SIDE_FRONT)) && backward.SkyLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!backward.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(backward).Translucency);
|
||||||
|
spreadSkyLight(x, y, z + 1, backward, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
if (up != null && (up.IsEmptySpace || !tileMap.TileMeshes.Get(up).IsOpaque(TileMesh.SIDE_BOTTOM)) && up.SkyLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!up.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(up).Translucency);
|
||||||
|
spreadSkyLight(x, y + 1, z, up, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
if (down != null && (down.IsEmptySpace || !tileMap.TileMeshes.Get(down).IsOpaque(TileMesh.SIDE_TOP)) && down.SkyLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!down.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(down).Translucency);
|
||||||
|
spreadSkyLight(x, y - 1, z, down, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spreadTileLight(int x, int y, int z, Tile tile, byte light, TileMap tileMap)
|
||||||
|
{
|
||||||
|
if (light > 0)
|
||||||
|
{
|
||||||
|
tile.TileLight = light;
|
||||||
|
--light;
|
||||||
|
|
||||||
|
Tile left = tileMap.GetSafe(x - 1, y, z);
|
||||||
|
Tile right = tileMap.GetSafe(x + 1, y, z);
|
||||||
|
Tile forward = tileMap.GetSafe(x, y, z - 1);
|
||||||
|
Tile backward = tileMap.GetSafe(x, y, z + 1);
|
||||||
|
Tile up = tileMap.GetSafe(x, y + 1, z);
|
||||||
|
Tile down = tileMap.GetSafe(x, y - 1, z);
|
||||||
|
|
||||||
|
if (left != null && (left.IsEmptySpace || !tileMap.TileMeshes.Get(left).IsOpaque(TileMesh.SIDE_RIGHT)) && left.TileLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!left.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(left).Translucency);
|
||||||
|
spreadTileLight(x - 1, y, z, left, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
if (right != null && (right.IsEmptySpace || !tileMap.TileMeshes.Get(right).IsOpaque(TileMesh.SIDE_LEFT)) && right.TileLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!right.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(right).Translucency);
|
||||||
|
spreadTileLight(x + 1, y, z, right, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
if (forward != null && (forward.IsEmptySpace || !tileMap.TileMeshes.Get(forward).IsOpaque(TileMesh.SIDE_BACK)) && forward.TileLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!forward.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(forward).Translucency);
|
||||||
|
spreadTileLight(x, y, z - 1, forward, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
if (backward != null && (backward.IsEmptySpace || !tileMap.TileMeshes.Get(backward).IsOpaque(TileMesh.SIDE_FRONT)) && backward.TileLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!backward.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(backward).Translucency);
|
||||||
|
spreadTileLight(x, y, z + 1, backward, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
if (up != null && (up.IsEmptySpace || !tileMap.TileMeshes.Get(up).IsOpaque(TileMesh.SIDE_BOTTOM)) && up.TileLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!up.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(up).Translucency);
|
||||||
|
spreadTileLight(x, y + 1, z, up, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
if (down != null && (down.IsEmptySpace || !tileMap.TileMeshes.Get(down).IsOpaque(TileMesh.SIDE_TOP)) && down.TileLight < light)
|
||||||
|
{
|
||||||
|
byte spreadLight = light;
|
||||||
|
if (!down.IsEmptySpace)
|
||||||
|
spreadLight = Tile.AdjustLightForTranslucency(spreadLight, tileMap.TileMeshes.Get(down).Translucency);
|
||||||
|
spreadTileLight(x, y - 1, z, down, spreadLight, tileMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Light(TileMap tileMap)
|
||||||
|
{
|
||||||
|
ResetLightValues(tileMap);
|
||||||
|
|
||||||
|
if (_doSkyLight)
|
||||||
|
CastSkyLightDown(tileMap);
|
||||||
|
|
||||||
|
// for each light source (sky or not), recursively go through and set
|
||||||
|
// appropriate lighting for each adjacent tile
|
||||||
|
for (int y = 0; y < tileMap.Height; ++y)
|
||||||
|
{
|
||||||
|
for (int z = 0; z < tileMap.Depth; ++z)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < tileMap.Width; ++x)
|
||||||
|
{
|
||||||
|
Tile tile = tileMap.Get(x, y, z);
|
||||||
|
if (tile.IsEmptySpace)
|
||||||
|
{
|
||||||
|
if (_doSkyLight && tile.IsSkyLit)
|
||||||
|
spreadSkyLight(x, y, z, tile, tile.SkyLight, tileMap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_doTileLight)
|
||||||
|
{
|
||||||
|
TileMesh mesh = tileMap.TileMeshes.Get(tile);
|
||||||
|
if (mesh.IsLightSource)
|
||||||
|
spreadTileLight(x, y, z, tile, mesh.LightValue, tileMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Reference in a new issue