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.Tile;
|
||||||
import com.blarg.gdx.tilemap3d.TileMap;
|
import com.blarg.gdx.tilemap3d.TileMap;
|
||||||
import com.blarg.gdx.tilemap3d.lighting.SimpleTileMapLighter;
|
|
||||||
import com.blarg.gdx.tilemap3d.tilemesh.TileMesh;
|
import com.blarg.gdx.tilemap3d.tilemesh.TileMesh;
|
||||||
|
|
||||||
public class PositionAndSkyTileMapLighter extends SimpleTileMapLighter {
|
public class LightSpreadingTileMapLighter extends BaseTileMapLighter {
|
||||||
public PositionAndSkyTileMapLighter() {
|
private boolean doSkyLight;
|
||||||
|
private boolean doTileLight;
|
||||||
|
|
||||||
|
public LightSpreadingTileMapLighter(boolean doSkyLight, boolean doTileLight) {
|
||||||
|
this.doSkyLight = doSkyLight;
|
||||||
|
this.doTileLight = doTileLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyLighting(TileMap tileMap) {
|
public LightSpreadingTileMapLighter() {
|
||||||
// for each light source (sky or not), recursively go through and set
|
this(true, true);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} }
|
|
||||||
|
|
||||||
private void spreadSkyLight(int x, int y, int z, Tile tile, byte light, TileMap tileMap) {
|
private void spreadSkyLight(int x, int y, int z, Tile tile, byte light, TileMap tileMap) {
|
||||||
if (light > 0)
|
if (light > 0)
|
||||||
|
@ -153,7 +136,33 @@ public class PositionAndSkyTileMapLighter extends SimpleTileMapLighter {
|
||||||
@Override
|
@Override
|
||||||
public void light(TileMap tileMap) {
|
public void light(TileMap tileMap) {
|
||||||
resetLightValues(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.lighting.TileMapLighter;
|
||||||
import com.blarg.gdx.tilemap3d.tilemesh.TileMesh;
|
import com.blarg.gdx.tilemap3d.tilemesh.TileMesh;
|
||||||
|
|
||||||
public class SimpleTileMapLighter implements TileMapLighter {
|
public class SimpleTileMapLighter extends BaseTileMapLighter {
|
||||||
public SimpleTileMapLighter() {
|
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
|
@Override
|
||||||
public void light(TileMap tileMap) {
|
public void light(TileMap tileMap) {
|
||||||
resetLightValues(tileMap);
|
resetLightValues(tileMap);
|
||||||
applySkyLight(tileMap);
|
castSkyLightDown(tileMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue