Faster forEachRenderRegion
This commit is contained in:
parent
538f8a9b72
commit
36d83b6a8e
@ -95,32 +95,20 @@ class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, Client
|
|||||||
private val foregroundRenderer = TileLayerRenderer(worldForegroundView, isBackground = false)
|
private val foregroundRenderer = TileLayerRenderer(worldForegroundView, isBackground = false)
|
||||||
private val backgroundRenderer = TileLayerRenderer(worldBackgroundView, isBackground = true)
|
private val backgroundRenderer = TileLayerRenderer(worldBackgroundView, isBackground = true)
|
||||||
|
|
||||||
override fun foregroundChanges() {
|
override fun foregroundChanges(cell: Cell) {
|
||||||
super.foregroundChanges()
|
super.foregroundChanges(cell)
|
||||||
|
|
||||||
world.forEachRenderRegion(pos) {
|
world.forEachRenderRegion(cell) {
|
||||||
it.foreground.isDirty = true
|
it.foreground.isDirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachNeighbour {
|
|
||||||
world.forEachRenderRegion(it.pos) {
|
|
||||||
it.foreground.isDirty = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun backgroundChanges() {
|
override fun backgroundChanges(cell: Cell) {
|
||||||
super.backgroundChanges()
|
super.backgroundChanges(cell)
|
||||||
|
|
||||||
world.forEachRenderRegion(pos) {
|
world.forEachRenderRegion(cell) {
|
||||||
it.background.isDirty = true
|
it.background.isDirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachNeighbour {
|
|
||||||
world.forEachRenderRegion(it.pos) {
|
|
||||||
it.background.isDirty = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bake() {
|
fun bake() {
|
||||||
|
@ -2,6 +2,7 @@ package ru.dbotthepony.kstarbound.client
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectFunction
|
import it.unimi.dsi.fastutil.longs.Long2ObjectFunction
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongArraySet
|
||||||
import ru.dbotthepony.kstarbound.client.render.ConfiguredStaticMesh
|
import ru.dbotthepony.kstarbound.client.render.ConfiguredStaticMesh
|
||||||
import ru.dbotthepony.kstarbound.client.render.LayeredRenderer
|
import ru.dbotthepony.kstarbound.client.render.LayeredRenderer
|
||||||
import ru.dbotthepony.kstarbound.client.render.TileLayerList
|
import ru.dbotthepony.kstarbound.client.render.TileLayerList
|
||||||
@ -12,6 +13,7 @@ import ru.dbotthepony.kstarbound.world.api.ITileAccess
|
|||||||
import ru.dbotthepony.kstarbound.world.api.OffsetCellAccess
|
import ru.dbotthepony.kstarbound.world.api.OffsetCellAccess
|
||||||
import ru.dbotthepony.kstarbound.world.api.TileView
|
import ru.dbotthepony.kstarbound.world.api.TileView
|
||||||
import ru.dbotthepony.kstarbound.world.entities.Entity
|
import ru.dbotthepony.kstarbound.world.entities.Entity
|
||||||
|
import ru.dbotthepony.kvector.api.IStruct2i
|
||||||
import ru.dbotthepony.kvector.util2d.AABB
|
import ru.dbotthepony.kvector.util2d.AABB
|
||||||
import ru.dbotthepony.kvector.vector.Vector2d
|
import ru.dbotthepony.kvector.vector.Vector2d
|
||||||
import ru.dbotthepony.kvector.vector.Vector2f
|
import ru.dbotthepony.kvector.vector.Vector2f
|
||||||
@ -176,6 +178,9 @@ class ClientWorld(
|
|||||||
|
|
||||||
val renderRegions = Long2ObjectOpenHashMap<RenderRegion>()
|
val renderRegions = Long2ObjectOpenHashMap<RenderRegion>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* all intersecting chunks
|
||||||
|
*/
|
||||||
inline fun forEachRenderRegion(pos: ChunkPos, action: (RenderRegion) -> Unit) {
|
inline fun forEachRenderRegion(pos: ChunkPos, action: (RenderRegion) -> Unit) {
|
||||||
var (ix, iy) = pos.tile
|
var (ix, iy) = pos.tile
|
||||||
ix /= renderRegionWidth
|
ix /= renderRegionWidth
|
||||||
@ -188,6 +193,32 @@ class ClientWorld(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cell and cells around
|
||||||
|
*/
|
||||||
|
inline fun forEachRenderRegion(pos: IStruct2i, action: (RenderRegion) -> Unit) {
|
||||||
|
val dx = pos.component1() % renderRegionWidth
|
||||||
|
val dy = pos.component2() % renderRegionHeight
|
||||||
|
|
||||||
|
if (dx == 1 || dx == renderRegionWidth - 1 || dy == 1 || dy == renderRegionHeight - 1) {
|
||||||
|
val seen = LongArraySet(8)
|
||||||
|
|
||||||
|
for ((x, y) in ring) {
|
||||||
|
val ix = (pos.component1() + x) / renderRegionWidth
|
||||||
|
val iy = (pos.component2() + y) / renderRegionHeight
|
||||||
|
val index = ix.toLong() shl 32 or iy.toLong()
|
||||||
|
|
||||||
|
if (seen.add(index)) {
|
||||||
|
renderRegions[index]?.let(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val ix = pos.component1() / renderRegionWidth
|
||||||
|
val iy = pos.component2() / renderRegionHeight
|
||||||
|
renderRegions[ix.toLong() shl 32 or iy.toLong()]?.let(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun chunkFactory(pos: ChunkPos): ClientChunk {
|
override fun chunkFactory(pos: ChunkPos): ClientChunk {
|
||||||
return ClientChunk(this, pos)
|
return ClientChunk(this, pos)
|
||||||
}
|
}
|
||||||
@ -364,4 +395,16 @@ class ClientWorld(
|
|||||||
ent!!.think(delta)
|
ent!!.think(delta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ring = listOf(
|
||||||
|
Vector2i(0, 0),
|
||||||
|
Vector2i(1, 0),
|
||||||
|
Vector2i(1, 1),
|
||||||
|
Vector2i(1, -1),
|
||||||
|
Vector2i(-1, 0),
|
||||||
|
Vector2i(-1, 1),
|
||||||
|
Vector2i(-1, -1),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,10 @@ package ru.dbotthepony.kstarbound.world
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet
|
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet
|
||||||
import ru.dbotthepony.kbox2d.api.BodyDef
|
import ru.dbotthepony.kbox2d.api.BodyDef
|
||||||
import ru.dbotthepony.kbox2d.api.FixtureDef
|
|
||||||
import ru.dbotthepony.kbox2d.collision.shapes.PolygonShape
|
|
||||||
import ru.dbotthepony.kbox2d.dynamics.B2Fixture
|
import ru.dbotthepony.kbox2d.dynamics.B2Fixture
|
||||||
import ru.dbotthepony.kstarbound.defs.tile.LiquidDefinition
|
import ru.dbotthepony.kstarbound.defs.tile.LiquidDefinition
|
||||||
import ru.dbotthepony.kstarbound.defs.tile.MaterialModifier
|
import ru.dbotthepony.kstarbound.defs.tile.MaterialModifier
|
||||||
import ru.dbotthepony.kstarbound.defs.tile.TileDefinition
|
import ru.dbotthepony.kstarbound.defs.tile.TileDefinition
|
||||||
import ru.dbotthepony.kstarbound.world.CHUNK_SIZE_BITS
|
|
||||||
import ru.dbotthepony.kstarbound.world.CHUNK_SIZE
|
|
||||||
import ru.dbotthepony.kstarbound.world.CHUNK_SIZE_FF
|
|
||||||
import ru.dbotthepony.kstarbound.world.CHUNK_SIZEd
|
|
||||||
import ru.dbotthepony.kstarbound.world.api.ICellAccess
|
import ru.dbotthepony.kstarbound.world.api.ICellAccess
|
||||||
import ru.dbotthepony.kstarbound.world.api.IChunkCell
|
import ru.dbotthepony.kstarbound.world.api.IChunkCell
|
||||||
import ru.dbotthepony.kstarbound.world.api.ILiquidState
|
import ru.dbotthepony.kstarbound.world.api.ILiquidState
|
||||||
@ -20,14 +14,11 @@ import ru.dbotthepony.kstarbound.world.api.OffsetCellAccess
|
|||||||
import ru.dbotthepony.kstarbound.world.api.TileColor
|
import ru.dbotthepony.kstarbound.world.api.TileColor
|
||||||
import ru.dbotthepony.kstarbound.world.api.TileView
|
import ru.dbotthepony.kstarbound.world.api.TileView
|
||||||
import ru.dbotthepony.kstarbound.world.entities.Entity
|
import ru.dbotthepony.kstarbound.world.entities.Entity
|
||||||
import ru.dbotthepony.kstarbound.world.phys.RectTileFlooderDepthFirst
|
|
||||||
import ru.dbotthepony.kstarbound.world.phys.RectTileFlooderSizeFirst
|
|
||||||
import ru.dbotthepony.kvector.arrays.Object2DArray
|
import ru.dbotthepony.kvector.arrays.Object2DArray
|
||||||
import ru.dbotthepony.kvector.util2d.AABB
|
import ru.dbotthepony.kvector.util2d.AABB
|
||||||
import ru.dbotthepony.kvector.vector.Vector2d
|
import ru.dbotthepony.kvector.vector.Vector2d
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.collections.HashSet
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Чанк мира
|
* Чанк мира
|
||||||
@ -109,9 +100,8 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
|
|
||||||
private val collisionChains = ArrayList<B2Fixture>()
|
private val collisionChains = ArrayList<B2Fixture>()
|
||||||
|
|
||||||
protected open fun foregroundChanges() {
|
protected open fun foregroundChanges(cell: Cell) {
|
||||||
changeset++
|
cellChanges(cell)
|
||||||
cellChangeset++
|
|
||||||
tileChangeset++
|
tileChangeset++
|
||||||
|
|
||||||
collisionChangeset++
|
collisionChangeset++
|
||||||
@ -119,14 +109,23 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
markPhysicsDirty()
|
markPhysicsDirty()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun backgroundChanges() {
|
protected open fun backgroundChanges(cell: Cell) {
|
||||||
changeset++
|
cellChanges(cell)
|
||||||
cellChangeset++
|
|
||||||
tileChangeset++
|
tileChangeset++
|
||||||
|
|
||||||
backgroundChangeset++
|
backgroundChangeset++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun liquidChanges(cell: Cell) {
|
||||||
|
cellChanges(cell)
|
||||||
|
liquidChangeset++
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun cellChanges(cell: Cell) {
|
||||||
|
changeset++
|
||||||
|
cellChangeset++
|
||||||
|
}
|
||||||
|
|
||||||
protected inline fun forEachNeighbour(block: (This) -> Unit) {
|
protected inline fun forEachNeighbour(block: (This) -> Unit) {
|
||||||
world.chunkMap[pos.left]?.let(block)
|
world.chunkMap[pos.left]?.let(block)
|
||||||
world.chunkMap[pos.right]?.let(block)
|
world.chunkMap[pos.right]?.let(block)
|
||||||
@ -153,9 +152,9 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
inner class Tile(private val foreground: Boolean) : ITileState {
|
inner class Tile(private val foreground: Boolean) : ITileState {
|
||||||
private fun change() {
|
private fun change() {
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
foregroundChanges()
|
foregroundChanges(this@Cell)
|
||||||
} else {
|
} else {
|
||||||
backgroundChanges()
|
backgroundChanges(this@Cell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,17 +199,11 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class Liquid : ILiquidState {
|
inner class Liquid : ILiquidState {
|
||||||
private fun change() {
|
|
||||||
changeset++
|
|
||||||
cellChangeset++
|
|
||||||
liquidChangeset++
|
|
||||||
}
|
|
||||||
|
|
||||||
override var def: LiquidDefinition? = null
|
override var def: LiquidDefinition? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
if (field !== value) {
|
if (field !== value) {
|
||||||
field = value
|
field = value
|
||||||
change()
|
liquidChanges(this@Cell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +211,7 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
field = value
|
field = value
|
||||||
change()
|
liquidChanges(this@Cell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +219,7 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
field = value
|
field = value
|
||||||
change()
|
liquidChanges(this@Cell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,16 +227,11 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
field = value
|
field = value
|
||||||
change()
|
liquidChanges(this@Cell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun change() {
|
|
||||||
changeset++
|
|
||||||
cellChangeset++
|
|
||||||
}
|
|
||||||
|
|
||||||
override val foreground = Tile(true)
|
override val foreground = Tile(true)
|
||||||
override val background = Tile(false)
|
override val background = Tile(false)
|
||||||
override val liquid = Liquid()
|
override val liquid = Liquid()
|
||||||
@ -252,7 +240,7 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
field = value
|
field = value
|
||||||
change()
|
cellChanges(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +248,7 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
field = value
|
field = value
|
||||||
change()
|
cellChanges(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +256,7 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
field = value
|
field = value
|
||||||
change()
|
cellChanges(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +264,7 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
field = value
|
field = value
|
||||||
change()
|
cellChanges(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,28 @@ import ru.dbotthepony.kstarbound.RegistryObject
|
|||||||
import ru.dbotthepony.kstarbound.defs.tile.LiquidDefinition
|
import ru.dbotthepony.kstarbound.defs.tile.LiquidDefinition
|
||||||
import ru.dbotthepony.kstarbound.defs.tile.MaterialModifier
|
import ru.dbotthepony.kstarbound.defs.tile.MaterialModifier
|
||||||
import ru.dbotthepony.kstarbound.defs.tile.TileDefinition
|
import ru.dbotthepony.kstarbound.defs.tile.TileDefinition
|
||||||
|
import ru.dbotthepony.kvector.api.IStruct2i
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
|
|
||||||
interface IChunkCell {
|
interface IChunkCell : IStruct2i {
|
||||||
// absolute in-world coordinates
|
/**
|
||||||
|
* absolute (in world)
|
||||||
|
*/
|
||||||
val x: Int
|
val x: Int
|
||||||
|
|
||||||
|
/**
|
||||||
|
* absolute (in world)
|
||||||
|
*/
|
||||||
val y: Int
|
val y: Int
|
||||||
|
|
||||||
|
override fun component1(): Int {
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun component2(): Int {
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
||||||
val foreground: ITileState
|
val foreground: ITileState
|
||||||
val background: ITileState
|
val background: ITileState
|
||||||
val liquid: ILiquidState
|
val liquid: ILiquidState
|
||||||
|
Loading…
Reference in New Issue
Block a user