tiling optimisation 2.2ms -> 1.7ms

This commit is contained in:
minjaesong
2023-10-10 18:16:35 +09:00
parent 26936fde09
commit 3b32242a2b
16 changed files with 177 additions and 56 deletions

View File

@@ -10,5 +10,6 @@ interface BlockLayer : Disposable {
val bytesPerBlock: Long
fun unsafeToBytes(x: Int, y: Int): ByteArray
fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray)
fun unsafeGetTile(x: Int, y: Int): Int
}

View File

@@ -59,7 +59,7 @@ open class BlockLayerI16(val width: Int, val height: Int) : BlockLayer {
}
}
internal fun unsafeGetTile(x: Int, y: Int): Int {
override fun unsafeGetTile(x: Int, y: Int): Int {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = ptr[offset]
val msb = ptr[offset + 1]

View File

@@ -1,7 +1,6 @@
package net.torvald.terrarum.gameworld
import net.torvald.terrarum.App
import net.torvald.terrarum.blockproperties.Fluid
import net.torvald.terrarum.gameworld.WorldSimulator.FLUID_MIN_MASS
import net.torvald.terrarum.serialise.toUint
import net.torvald.unsafe.UnsafeHelper
@@ -58,7 +57,17 @@ class BlockLayerI16F16(val width: Int, val height: Int) : BlockLayer {
}
}
internal fun unsafeGetTile(x: Int, y: Int): Pair<Int, Float> {
override fun unsafeGetTile(x: Int, y: Int): Int {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = ptr[offset]
val msb = ptr[offset + 1]
val hbits = (ptr[offset + 2].toUint() or ptr[offset + 3].toUint().shl(8)).toShort()
val fill = Float16.toFloat(hbits)
return lsb.toUint() + msb.toUint().shl(8)
}
internal fun unsafeGetTile1(x: Int, y: Int): Pair<Int, Float> {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = ptr[offset]
val msb = ptr[offset + 1]

View File

@@ -1,6 +1,5 @@
package net.torvald.terrarum.gameworld
import com.badlogic.gdx.utils.Disposable
import net.torvald.terrarum.App
import net.torvald.terrarum.serialise.toUint
import net.torvald.unsafe.UnsafeHelper
@@ -55,7 +54,16 @@ class BlockLayerI16I8 (val width: Int, val height: Int) : BlockLayer {
}
}
internal fun unsafeGetTile(x: Int, y: Int): Pair<Int, Int> {
override fun unsafeGetTile(x: Int, y: Int): Int {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = ptr[offset]
val msb = ptr[offset + 1]
val placement = ptr[offset + 2]
return lsb.toUint() + msb.toUint().shl(8)
}
internal fun unsafeGetTile1(x: Int, y: Int): Pair<Int, Int> {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = ptr[offset]
val msb = ptr[offset + 1]
@@ -94,6 +102,16 @@ class BlockLayerI16I8 (val width: Int, val height: Int) : BlockLayer {
ptr[offset + 2] = bytes[2]
}
internal fun unsafeSetTileKeepPlacement(x: Int, y: Int, tile: Int) {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = tile.and(0xff).toByte()
val msb = tile.ushr(8).and(0xff).toByte()
ptr[offset] = lsb
ptr[offset + 1] = msb
}
/**
* @param blockOffset Offset in blocks. BlockOffset of 0x100 is equal to ```layerPtr + 0x200```
*/

View File

@@ -10,7 +10,6 @@ import net.torvald.terrarum.blockproperties.Fluid
import net.torvald.terrarum.gameactors.ActorID
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.gameitems.isFluid
import net.torvald.terrarum.gameitems.isOre
import net.torvald.terrarum.itemproperties.ItemRemapTable
import net.torvald.terrarum.itemproperties.ItemTable
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
@@ -18,6 +17,7 @@ import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.utils.*
import net.torvald.terrarum.weather.WeatherMixer
import net.torvald.terrarum.weather.Weatherbox
import net.torvald.terrarum.worlddrawer.BlocksDrawer
import net.torvald.util.SortedArrayList
import org.dyn4j.geometry.Vector2
import java.util.*
@@ -235,7 +235,7 @@ open class GameWorld(
if (App.tileMaker != null) {
App.tileMaker.tags.forEach {
if (!forcedTileNumberToNames.contains(it.key)) {
printdbg(this, "tileNumber ${it.value.tileNumber} <-> tileName ${it.key}")
printdbg(this, "newworld tileNumber ${it.value.tileNumber} <-> tileName ${it.key}")
tileNumberToNameMap[it.value.tileNumber.toLong()] = it.key
tileNameToNumberMap[it.key] = it.value.tileNumber
@@ -253,6 +253,8 @@ open class GameWorld(
tileNumberToNameMap.clear()
tileNameToNumberMap.clear()
App.tileMaker.tags.forEach {
printdbg(this, "afterload tileNumber ${it.value.tileNumber} <-> tileName ${it.key}")
tileNumberToNameMap[it.value.tileNumber.toLong()] = it.key
tileNameToNumberMap[it.key] = it.value.tileNumber
}
@@ -262,6 +264,7 @@ open class GameWorld(
for (x in 0 until layerTerrain.width) {
layerTerrain.unsafeSetTile(x, y, tileNameToNumberMap[oldTileNumberToNameMap[layerTerrain.unsafeGetTile(x, y).toLong()]]!!)
layerWall.unsafeSetTile(x, y, tileNameToNumberMap[oldTileNumberToNameMap[layerWall.unsafeGetTile(x, y).toLong()]]!!)
layerOres.unsafeSetTileKeepPlacement(x, y, tileNameToNumberMap[oldTileNumberToNameMap[layerOres.unsafeGetTile(x, y).toLong()]]!!)
}
}
@@ -272,6 +275,9 @@ open class GameWorld(
tileNameToNumberMap[Block.UPDATE] = 2
fluidNumberToNameMap[0] = Fluid.NULL
fluidNameToNumberMap[Fluid.NULL] = 0
BlocksDrawer.rebuildInternalPrecalculations()
}
/**
@@ -559,7 +565,7 @@ open class GameWorld(
fun getTileFromOre(rawX: Int, rawY: Int): OrePlacement {
val (x, y) = coerceXY(rawX, rawY)
val (tileNum, placement) = layerOres.unsafeGetTile(x, y)
val (tileNum, placement) = layerOres.unsafeGetTile1(x, y)
val tileName = tileNumberToNameMap[tileNum.toLong()]
return OrePlacement(tileName ?: Block.UPDATE, placement)
}
@@ -709,7 +715,7 @@ open class GameWorld(
fun getFluid(x: Int, y: Int): FluidInfo {
val (x, y) = coerceXY(x, y)
val (type, fill) = layerFluids.unsafeGetTile(x, y)
val (type, fill) = layerFluids.unsafeGetTile1(x, y)
val fluidID = fluidNumberToNameMap[type.toLong()] ?: throw NullPointerException("No such fluid: $type")
return FluidInfo(fluidID, fill)