mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-10 10:34:06 +09:00
still working on light, no improvements perf-wise
This commit is contained in:
@@ -155,9 +155,12 @@ open class GameWorld {
|
|||||||
val damageDataArray: ByteArray
|
val damageDataArray: ByteArray
|
||||||
get() = layerTerrainLowBits.data
|
get() = layerTerrainLowBits.data
|
||||||
|
|
||||||
|
private fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceWorld())
|
||||||
|
|
||||||
fun getTileFromWall(x: Int, y: Int): Int? {
|
fun getTileFromWall(x: Int, y: Int): Int? {
|
||||||
val wall: Int? = layerWall.getTile(x fmod width, y.coerceWorld().coerceWorld())
|
val (x, y) = coerceXY(x, y)
|
||||||
val wallDamage: Int? = getWallLowBits(x fmod width, y.coerceWorld())
|
val wall: Int? = layerWall.getTile(x, y)
|
||||||
|
val wallDamage: Int? = getWallLowBits(x, y)
|
||||||
return if (wall == null || wallDamage == null)
|
return if (wall == null || wallDamage == null)
|
||||||
null
|
null
|
||||||
else
|
else
|
||||||
@@ -165,8 +168,9 @@ open class GameWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getTileFromTerrain(x: Int, y: Int): Int? {
|
fun getTileFromTerrain(x: Int, y: Int): Int? {
|
||||||
val terrain: Int? = layerTerrain.getTile(x fmod width, y.coerceWorld())
|
val (x, y) = coerceXY(x, y)
|
||||||
val terrainDamage: Int? = getTerrainLowBits(x fmod width, y.coerceWorld())
|
val terrain: Int? = layerTerrain.getTile(x, y)
|
||||||
|
val terrainDamage: Int? = getTerrainLowBits(x, y)
|
||||||
return if (terrain == null || terrainDamage == null)
|
return if (terrain == null || terrainDamage == null)
|
||||||
null
|
null
|
||||||
else
|
else
|
||||||
@@ -174,15 +178,18 @@ open class GameWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getTileFromWire(x: Int, y: Int): Int? {
|
fun getTileFromWire(x: Int, y: Int): Int? {
|
||||||
return layerWire.getTile(x fmod width, y.coerceWorld())
|
val (x, y) = coerceXY(x, y)
|
||||||
|
return layerWire.getTile(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getWallLowBits(x: Int, y: Int): Int? {
|
fun getWallLowBits(x: Int, y: Int): Int? {
|
||||||
return layerWallLowBits.getData(x fmod width, y.coerceWorld())
|
val (x, y) = coerceXY(x, y)
|
||||||
|
return layerWallLowBits.getData(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTerrainLowBits(x: Int, y: Int): Int? {
|
fun getTerrainLowBits(x: Int, y: Int): Int? {
|
||||||
return layerTerrainLowBits.getData(x fmod width, y.coerceWorld())
|
val (x, y) = coerceXY(x, y)
|
||||||
|
return layerTerrainLowBits.getData(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -194,7 +201,8 @@ open class GameWorld {
|
|||||||
* @param combinedTilenum (tilenum * 16) + damage
|
* @param combinedTilenum (tilenum * 16) + damage
|
||||||
*/
|
*/
|
||||||
fun setTileWall(x: Int, y: Int, combinedTilenum: Int) {
|
fun setTileWall(x: Int, y: Int, combinedTilenum: Int) {
|
||||||
setTileWall(x fmod width, y.coerceWorld(), (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
|
val (x, y) = coerceXY(x, y)
|
||||||
|
setTileWall(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,12 +214,14 @@ open class GameWorld {
|
|||||||
* @param combinedTilenum (tilenum * 16) + damage
|
* @param combinedTilenum (tilenum * 16) + damage
|
||||||
*/
|
*/
|
||||||
fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) {
|
fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) {
|
||||||
setTileTerrain(x fmod width, y.coerceWorld(), (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
|
val (x, y) = coerceXY(x, y)
|
||||||
|
setTileTerrain(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) {
|
fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) {
|
||||||
layerWall.setTile(x fmod width, y.coerceWorld(), tile)
|
val (x, y) = coerceXY(x, y)
|
||||||
layerWallLowBits.setData(x fmod width, y.coerceWorld(), damage)
|
layerWall.setTile(x, y, tile)
|
||||||
|
layerWallLowBits.setData(x, y, damage)
|
||||||
wallDamages.remove(LandUtil.getBlockAddr(this, x, y))
|
wallDamages.remove(LandUtil.getBlockAddr(this, x, y))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,8 +229,9 @@ open class GameWorld {
|
|||||||
* Warning: this function alters fluid lists: be wary of call order!
|
* Warning: this function alters fluid lists: be wary of call order!
|
||||||
*/
|
*/
|
||||||
fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) {
|
fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) {
|
||||||
layerTerrain.setTile(x fmod width, y.coerceWorld(), tile)
|
val (x, y) = coerceXY(x, y)
|
||||||
layerTerrainLowBits.setData(x fmod width, y.coerceWorld(), damage)
|
layerTerrain.setTile(x, y, tile)
|
||||||
|
layerTerrainLowBits.setData(x, y, damage)
|
||||||
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
||||||
terrainDamages.remove(blockAddr)
|
terrainDamages.remove(blockAddr)
|
||||||
|
|
||||||
@@ -232,7 +243,8 @@ open class GameWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setTileWire(x: Int, y: Int, tile: Byte) {
|
fun setTileWire(x: Int, y: Int, tile: Byte) {
|
||||||
layerWire.setTile(x fmod width, y.coerceWorld(), tile)
|
val (x, y) = coerceXY(x, y)
|
||||||
|
layerWire.setTile(x, y, tile)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTileFrom(mode: Int, x: Int, y: Int): Int? {
|
fun getTileFrom(mode: Int, x: Int, y: Int): Int? {
|
||||||
|
|||||||
@@ -228,6 +228,8 @@ object LightmapRenderer {
|
|||||||
// wipe out lightmap
|
// wipe out lightmap
|
||||||
AppLoader.debugTimers["Renderer.Light0"] = measureNanoTime {
|
AppLoader.debugTimers["Renderer.Light0"] = measureNanoTime {
|
||||||
for (k in 0 until lightmap.size) lightmap[k] = colourNull
|
for (k in 0 until lightmap.size) lightmap[k] = colourNull
|
||||||
|
// when disabled, light will "decay out" instead of "instantly out", which can have a cool effect
|
||||||
|
// but the performance boost is measly 0.1 ms on 6700K
|
||||||
}
|
}
|
||||||
|
|
||||||
// O((5*9)n) == O(n) where n is a size of the map.
|
// O((5*9)n) == O(n) where n is a size of the map.
|
||||||
@@ -428,11 +430,13 @@ object LightmapRenderer {
|
|||||||
* @param pass one-based
|
* @param pass one-based
|
||||||
*/
|
*/
|
||||||
private fun calculate(x: Int, y: Int): Color {
|
private fun calculate(x: Int, y: Int): Color {
|
||||||
|
|
||||||
// O(9n) == O(n) where n is a size of the map
|
// O(9n) == O(n) where n is a size of the map
|
||||||
// TODO devise multithreading on this
|
// TODO devise multithreading on this
|
||||||
|
|
||||||
ambientAccumulator.set(0f,0f,0f,0f)
|
ambientAccumulator.set(0f,0f,0f,0f)
|
||||||
|
|
||||||
|
// this six fetch tasks take 2 ms ?!
|
||||||
lightLevelThis.set(0f,0f,0f,0f)
|
lightLevelThis.set(0f,0f,0f,0f)
|
||||||
thisTerrain = world.getTileFromTerrain(x, y) ?: Block.STONE
|
thisTerrain = world.getTileFromTerrain(x, y) ?: Block.STONE
|
||||||
thisWall = world.getTileFromWall(x, y) ?: Block.STONE
|
thisWall = world.getTileFromWall(x, y) ?: Block.STONE
|
||||||
@@ -446,13 +450,14 @@ object LightmapRenderer {
|
|||||||
if (thisTerrain == AIR && thisWall == AIR) {
|
if (thisTerrain == AIR && thisWall == AIR) {
|
||||||
lightLevelThis.set(sunLight)
|
lightLevelThis.set(sunLight)
|
||||||
}
|
}
|
||||||
// luminous tile on top of air
|
// luminous tile
|
||||||
else if (thisWall == AIR && thisTileLuminosity.nonZero()) {
|
else if (thisTileLuminosity.nonZero()) {
|
||||||
lightLevelThis.set(sunLight maxBlend thisTileLuminosity) // maximise to not exceed 1.0 with normal (<= 1.0) light
|
// luminous tile on top of air
|
||||||
}
|
if (thisWall == AIR)
|
||||||
// opaque wall and luminous tile
|
lightLevelThis.set(sunLight maxBlend thisTileLuminosity) // maximise to not exceed 1.0 with normal (<= 1.0) light
|
||||||
else if (thisWall != AIR && thisTileLuminosity.nonZero()) {
|
// opaque wall and luminous tile
|
||||||
lightLevelThis.set(thisTileLuminosity)
|
else
|
||||||
|
lightLevelThis.set(thisTileLuminosity)
|
||||||
}
|
}
|
||||||
// END MIX TILE
|
// END MIX TILE
|
||||||
|
|
||||||
@@ -468,16 +473,16 @@ object LightmapRenderer {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// will "overwrite" what's there in the lightmap if it's the first pass
|
// will "overwrite" what's there in the lightmap if it's the first pass
|
||||||
// TODO colour math against integers
|
// takes about 2 ms
|
||||||
/* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y - 1) ?: Color.CLEAR, scaleSqrt2(thisTileOpacity)))
|
/* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y - 1) ?: colourNull, scaleSqrt2(thisTileOpacity)))
|
||||||
/* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y - 1) ?: Color.CLEAR, scaleSqrt2(thisTileOpacity)))
|
/* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y - 1) ?: colourNull, scaleSqrt2(thisTileOpacity)))
|
||||||
/* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y + 1) ?: Color.CLEAR, scaleSqrt2(thisTileOpacity)))
|
/* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y + 1) ?: colourNull, scaleSqrt2(thisTileOpacity)))
|
||||||
/* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y + 1) ?: Color.CLEAR, scaleSqrt2(thisTileOpacity)))
|
/* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y + 1) ?: colourNull, scaleSqrt2(thisTileOpacity)))
|
||||||
|
|
||||||
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x, y - 1) ?: Color.CLEAR, thisTileOpacity))
|
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x, y - 1) ?: colourNull, thisTileOpacity))
|
||||||
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x, y + 1) ?: Color.CLEAR, thisTileOpacity))
|
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x, y + 1) ?: colourNull, thisTileOpacity))
|
||||||
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y) ?: Color.CLEAR, thisTileOpacity))
|
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y) ?: colourNull, thisTileOpacity))
|
||||||
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y) ?: Color.CLEAR, thisTileOpacity))
|
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y) ?: colourNull, thisTileOpacity))
|
||||||
|
|
||||||
val ret = lightLevelThis maxBlend ambientAccumulator
|
val ret = lightLevelThis maxBlend ambientAccumulator
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user