From 9ba2a0a1421da16643eb48f5cae44526108b8d0c Mon Sep 17 00:00:00 2001 From: gered Date: Mon, 22 Jul 2013 18:25:06 -0400 Subject: [PATCH] bit of refactoring with the TileMapLighter classes --- .../lighting/BaseTileMapLighter.java | 61 ++++++++++++++++ ...java => LightSpreadingTileMapLighter.java} | 69 +++++++++++-------- .../lighting/SimpleTileMapLighter.java | 60 +--------------- 3 files changed, 102 insertions(+), 88 deletions(-) create mode 100644 src/com/blarg/gdx/tilemap3d/lighting/BaseTileMapLighter.java rename src/com/blarg/gdx/tilemap3d/lighting/{PositionAndSkyTileMapLighter.java => LightSpreadingTileMapLighter.java} (90%) diff --git a/src/com/blarg/gdx/tilemap3d/lighting/BaseTileMapLighter.java b/src/com/blarg/gdx/tilemap3d/lighting/BaseTileMapLighter.java new file mode 100644 index 0000000..6d92c8f --- /dev/null +++ b/src/com/blarg/gdx/tilemap3d/lighting/BaseTileMapLighter.java @@ -0,0 +1,61 @@ +package com.blarg.gdx.tilemap3d.lighting; + +import com.blarg.gdx.Bitfield; +import com.blarg.gdx.tilemap3d.Tile; +import com.blarg.gdx.tilemap3d.TileMap; +import com.blarg.gdx.tilemap3d.tilemesh.TileMesh; + +public abstract class BaseTileMapLighter implements TileMapLighter { + protected void resetLightValues(TileMap tileMap) { + for (int y = 0; y < tileMap.getHeight(); ++y) + { + for (int z = 0; z < tileMap.getDepth(); ++z) + { + for (int x = 0; x < tileMap.getWidth(); ++x) + { + Tile tile = tileMap.get(x, y, z); + + // sky lighting will be recalculated, and other types of light sources + // info stays as they were + tile.flags = Bitfield.clear(Tile.FLAG_LIGHT_SKY, tile.flags); + tile.skyLight = 0; + tile.tileLight = tileMap.ambientLightValue; + } + } + } + } + + protected void castSkyLightDown(TileMap tileMap) { + // go through each vertical column one at a time from top to bottom + for (int x = 0; x < tileMap.getWidth(); ++x) + { + for (int z = 0; z < tileMap.getDepth(); ++z) + { + boolean stillSkyLit = true; + byte currentSkyLightValue = tileMap.skyLightValue; + + for (int y = tileMap.getHeight() - 1; y >= 0 && stillSkyLit; --y) + { + Tile tile = tileMap.get(x, y, z); + TileMesh mesh = tileMap.tileMeshes.get(tile); + if (mesh == null || (mesh != null && !mesh.isOpaque(TileMesh.SIDE_TOP) && !mesh.isOpaque(TileMesh.SIDE_BOTTOM))) + { + // tile is partially transparent or this tile is empty space + tile.flags = Bitfield.set(Tile.FLAG_LIGHT_SKY, tile.flags); + + if (mesh != null) + currentSkyLightValue = Tile.adjustLightForTranslucency(currentSkyLightValue, mesh.translucency); + + tile.skyLight = currentSkyLightValue; + } + else + { + // tile is present and is fully solid, sky lighting stops + // at the tile above this one + stillSkyLit = false; + } + } + } + } + } +} diff --git a/src/com/blarg/gdx/tilemap3d/lighting/PositionAndSkyTileMapLighter.java b/src/com/blarg/gdx/tilemap3d/lighting/LightSpreadingTileMapLighter.java similarity index 90% rename from src/com/blarg/gdx/tilemap3d/lighting/PositionAndSkyTileMapLighter.java rename to src/com/blarg/gdx/tilemap3d/lighting/LightSpreadingTileMapLighter.java index 549a5eb..a5e6b5f 100644 --- a/src/com/blarg/gdx/tilemap3d/lighting/PositionAndSkyTileMapLighter.java +++ b/src/com/blarg/gdx/tilemap3d/lighting/LightSpreadingTileMapLighter.java @@ -2,37 +2,20 @@ package com.blarg.gdx.tilemap3d.lighting; import com.blarg.gdx.tilemap3d.Tile; import com.blarg.gdx.tilemap3d.TileMap; -import com.blarg.gdx.tilemap3d.lighting.SimpleTileMapLighter; import com.blarg.gdx.tilemap3d.tilemesh.TileMesh; -public class PositionAndSkyTileMapLighter extends SimpleTileMapLighter { - public PositionAndSkyTileMapLighter() { +public class LightSpreadingTileMapLighter extends BaseTileMapLighter { + private boolean doSkyLight; + private boolean doTileLight; + + public LightSpreadingTileMapLighter(boolean doSkyLight, boolean doTileLight) { + this.doSkyLight = doSkyLight; + this.doTileLight = doTileLight; } - private void applyLighting(TileMap 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.getHeight(); ++y) - { - for (int z = 0; z < tileMap.getDepth(); ++z) - { - for (int x = 0; x < tileMap.getWidth(); ++x) - { - Tile tile = tileMap.get(x, y, z); - if (tile.isEmptySpace()) - { - if (tile.isSkyLit()) - spreadSkyLight(x, y, z, tile, tile.skyLight, tileMap); - } - else - { - TileMesh mesh = tileMap.tileMeshes.get(tile); - if (mesh.isLightSource()) - spreadTileLight(x, y, z, tile, mesh.lightValue, tileMap); - } - } - } - } } + public LightSpreadingTileMapLighter() { + this(true, true); + } private void spreadSkyLight(int x, int y, int z, Tile tile, byte light, TileMap tileMap) { if (light > 0) @@ -153,7 +136,33 @@ public class PositionAndSkyTileMapLighter extends SimpleTileMapLighter { @Override public void light(TileMap tileMap) { resetLightValues(tileMap); - applySkyLight(tileMap); - applyLighting(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.getHeight(); ++y) + { + for (int z = 0; z < tileMap.getDepth(); ++z) + { + for (int x = 0; x < tileMap.getWidth(); ++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); + } + } + } + } + } } } diff --git a/src/com/blarg/gdx/tilemap3d/lighting/SimpleTileMapLighter.java b/src/com/blarg/gdx/tilemap3d/lighting/SimpleTileMapLighter.java index 278736b..17ee7a0 100644 --- a/src/com/blarg/gdx/tilemap3d/lighting/SimpleTileMapLighter.java +++ b/src/com/blarg/gdx/tilemap3d/lighting/SimpleTileMapLighter.java @@ -6,69 +6,13 @@ import com.blarg.gdx.tilemap3d.TileMap; import com.blarg.gdx.tilemap3d.lighting.TileMapLighter; import com.blarg.gdx.tilemap3d.tilemesh.TileMesh; -public class SimpleTileMapLighter implements TileMapLighter { +public class SimpleTileMapLighter extends BaseTileMapLighter { public SimpleTileMapLighter() { } - protected void resetLightValues(TileMap tileMap) { - for (int y = 0; y < tileMap.getHeight(); ++y) - { - for (int z = 0; z < tileMap.getDepth(); ++z) - { - for (int x = 0; x < tileMap.getWidth(); ++x) - { - Tile tile = tileMap.get(x, y, z); - - // sky lighting will be recalculated, and other types of light sources - // info stays as they were - tile.flags = Bitfield.clear(Tile.FLAG_LIGHT_SKY, tile.flags); - tile.skyLight = 0; - tile.tileLight = tileMap.ambientLightValue; - } - } - } - } - - protected void applySkyLight(TileMap tileMap) { - // NOTE: resetLightValues() clears sky light data in such a way that - // doesn't require us to flood-fill 0 light values here for everything - // that isn't sky-lit - // go through each vertical column one at a time from top to bottom - for (int x = 0; x < tileMap.getWidth(); ++x) - { - for (int z = 0; z < tileMap.getDepth(); ++z) - { - boolean stillSkyLit = true; - byte currentSkyLightValue = tileMap.skyLightValue; - - for (int y = tileMap.getHeight() - 1; y >= 0 && stillSkyLit; --y) - { - Tile tile = tileMap.get(x, y, z); - TileMesh mesh = tileMap.tileMeshes.get(tile); - if (mesh == null || (mesh != null && !mesh.isOpaque(TileMesh.SIDE_TOP) && !mesh.isOpaque(TileMesh.SIDE_BOTTOM))) - { - // tile is partially transparent or this tile is empty space - tile.flags = Bitfield.set(Tile.FLAG_LIGHT_SKY, tile.flags); - - if (mesh != null) - currentSkyLightValue = Tile.adjustLightForTranslucency(currentSkyLightValue, mesh.translucency); - - tile.skyLight = currentSkyLightValue; - } - else - { - // tile is present and is fully solid, sky lighting stops - // at the tile above this one - stillSkyLit = false; - } - } - } - } - } - @Override public void light(TileMap tileMap) { resetLightValues(tileMap); - applySkyLight(tileMap); + castSkyLightDown(tileMap); } }