bit of refactoring with the TileMapLighter classes
This commit is contained in:
parent
2cc12276f0
commit
9ba2a0a142
61
src/com/blarg/gdx/tilemap3d/lighting/BaseTileMapLighter.java
Normal file
61
src/com/blarg/gdx/tilemap3d/lighting/BaseTileMapLighter.java
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
public LightSpreadingTileMapLighter() {
|
||||
this(true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
TileMesh mesh = tileMap.tileMeshes.get(tile);
|
||||
if (mesh.isLightSource())
|
||||
spreadTileLight(x, y, z, tile, mesh.lightValue, tileMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue