Fixed render regions actually being repeated for wrapped around chunks
This commit is contained in:
parent
ef838d52c2
commit
96cc44c592
@ -18,6 +18,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.kstarbound.world.positiveModulo
|
||||||
import ru.dbotthepony.kvector.api.IStruct2i
|
import ru.dbotthepony.kvector.api.IStruct2i
|
||||||
import ru.dbotthepony.kvector.util2d.AABB
|
import ru.dbotthepony.kvector.util2d.AABB
|
||||||
import ru.dbotthepony.kvector.vector.RGBAColor
|
import ru.dbotthepony.kvector.vector.RGBAColor
|
||||||
@ -47,6 +48,24 @@ class ClientWorld(
|
|||||||
|
|
||||||
val renderRegionWidth = if (size == null) 16 else determineChunkSize(size.x)
|
val renderRegionWidth = if (size == null) 16 else determineChunkSize(size.x)
|
||||||
val renderRegionHeight = if (size == null) 16 else determineChunkSize(size.y)
|
val renderRegionHeight = if (size == null) 16 else determineChunkSize(size.y)
|
||||||
|
val renderRegionsX = if (size == null) 0 else size.x / renderRegionWidth
|
||||||
|
val renderRegionsY = if (size == null) 0 else size.y / renderRegionHeight
|
||||||
|
|
||||||
|
fun isValidRenderRegionX(value: Int): Boolean {
|
||||||
|
if (size == null || loopX) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return value in 0 .. renderRegionsX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isValidRenderRegionY(value: Int): Boolean {
|
||||||
|
if (size == null || loopY) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return value in 0 .. renderRegionsY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inner class RenderRegion(val x: Int, val y: Int) {
|
inner class RenderRegion(val x: Int, val y: Int) {
|
||||||
inner class Layer(private val view: ITileAccess, private val isBackground: Boolean) {
|
inner class Layer(private val view: ITileAccess, private val isBackground: Boolean) {
|
||||||
@ -170,6 +189,14 @@ class ClientWorld(
|
|||||||
|
|
||||||
val renderRegions = Long2ObjectOpenHashMap<RenderRegion>()
|
val renderRegions = Long2ObjectOpenHashMap<RenderRegion>()
|
||||||
|
|
||||||
|
fun renderRegionKey(x: Int, y: Int): Long {
|
||||||
|
if (size == null) {
|
||||||
|
return x.toLong() shl 32 or y.toLong()
|
||||||
|
} else {
|
||||||
|
return positiveModulo(x, renderRegionsX).toLong() shl 32 or positiveModulo(y, renderRegionsY).toLong()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* all intersecting chunks
|
* all intersecting chunks
|
||||||
*/
|
*/
|
||||||
@ -180,7 +207,7 @@ class ClientWorld(
|
|||||||
|
|
||||||
for (x in ix .. ix + CHUNK_SIZE / renderRegionWidth) {
|
for (x in ix .. ix + CHUNK_SIZE / renderRegionWidth) {
|
||||||
for (y in iy .. iy + CHUNK_SIZE / renderRegionWidth) {
|
for (y in iy .. iy + CHUNK_SIZE / renderRegionWidth) {
|
||||||
renderRegions[x.toLong() shl 32 or y.toLong()]?.let(action)
|
renderRegions[renderRegionKey(x, y)]?.let(action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,7 +225,7 @@ class ClientWorld(
|
|||||||
for ((x, y) in ring) {
|
for ((x, y) in ring) {
|
||||||
val ix = (pos.component1() + x) / renderRegionWidth
|
val ix = (pos.component1() + x) / renderRegionWidth
|
||||||
val iy = (pos.component2() + y) / renderRegionHeight
|
val iy = (pos.component2() + y) / renderRegionHeight
|
||||||
val index = ix.toLong() shl 32 or iy.toLong()
|
val index = renderRegionKey(ix, iy)
|
||||||
|
|
||||||
if (seen.add(index)) {
|
if (seen.add(index)) {
|
||||||
renderRegions[index]?.let(action)
|
renderRegions[index]?.let(action)
|
||||||
@ -207,7 +234,7 @@ class ClientWorld(
|
|||||||
} else {
|
} else {
|
||||||
val ix = pos.component1() / renderRegionWidth
|
val ix = pos.component1() / renderRegionWidth
|
||||||
val iy = pos.component2() / renderRegionHeight
|
val iy = pos.component2() / renderRegionHeight
|
||||||
renderRegions[ix.toLong() shl 32 or iy.toLong()]?.let(action)
|
renderRegions[renderRegionKey(ix, iy)]?.let(action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +254,8 @@ class ClientWorld(
|
|||||||
|
|
||||||
for (x in rx .. rx + dx) {
|
for (x in rx .. rx + dx) {
|
||||||
for (y in ry .. ry + dy) {
|
for (y in ry .. ry + dy) {
|
||||||
val renderer = renderRegions.computeIfAbsent(x.toLong() shl 32 or y.toLong(), Long2ObjectFunction {
|
if (!isValidRenderRegionX(x) || !isValidRenderRegionY(y)) continue
|
||||||
|
val renderer = renderRegions.computeIfAbsent(renderRegionKey(x, y), Long2ObjectFunction {
|
||||||
RenderRegion((it ushr 32).toInt(), it.toInt())
|
RenderRegion((it ushr 32).toInt(), it.toInt())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2,22 +2,22 @@ package ru.dbotthepony.kstarbound.world
|
|||||||
|
|
||||||
import ru.dbotthepony.kstarbound.math.divideUp
|
import ru.dbotthepony.kstarbound.math.divideUp
|
||||||
|
|
||||||
|
fun positiveModulo(a: Int, b: Int): Int {
|
||||||
|
val result = a % b
|
||||||
|
return if (result < 0) result + b else result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun positiveModulo(a: Double, b: Int): Double {
|
||||||
|
val result = a % b
|
||||||
|
return if (result < 0.0) result + b else result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun positiveModulo(a: Float, b: Int): Float {
|
||||||
|
val result = a % b
|
||||||
|
return if (result < 0f) result + b else result
|
||||||
|
}
|
||||||
|
|
||||||
abstract class CoordinateMapper {
|
abstract class CoordinateMapper {
|
||||||
protected fun positiveModulo(a: Int, b: Int): Int {
|
|
||||||
val result = a % b
|
|
||||||
return if (result < 0) result + b else result
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun positiveModulo(a: Double, b: Int): Double {
|
|
||||||
val result = a % b
|
|
||||||
return if (result < 0.0) result + b else result
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun positiveModulo(a: Float, b: Int): Float {
|
|
||||||
val result = a % b
|
|
||||||
return if (result < 0f) result + b else result
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract val chunks: Int
|
abstract val chunks: Int
|
||||||
|
|
||||||
abstract fun cell(value: Int): Int
|
abstract fun cell(value: Int): Int
|
||||||
|
@ -37,8 +37,8 @@ const val CHUNK_SIZEd = CHUNK_SIZE.toDouble()
|
|||||||
abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, ChunkType>>(
|
abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, ChunkType>>(
|
||||||
val seed: Long,
|
val seed: Long,
|
||||||
val size: Vector2i?,
|
val size: Vector2i?,
|
||||||
loopX: Boolean,
|
val loopX: Boolean,
|
||||||
loopY: Boolean
|
val loopY: Boolean
|
||||||
) : ICellAccess {
|
) : ICellAccess {
|
||||||
val x: CoordinateMapper = if (size == null) CoordinateMapper.Infinite else if (loopX) CoordinateMapper.Wrapper(size.x) else CoordinateMapper.Clamper(size.x)
|
val x: CoordinateMapper = if (size == null) CoordinateMapper.Infinite else if (loopX) CoordinateMapper.Wrapper(size.x) else CoordinateMapper.Clamper(size.x)
|
||||||
val y: CoordinateMapper = if (size == null) CoordinateMapper.Infinite else if (loopY) CoordinateMapper.Wrapper(size.y) else CoordinateMapper.Clamper(size.y)
|
val y: CoordinateMapper = if (size == null) CoordinateMapper.Infinite else if (loopY) CoordinateMapper.Wrapper(size.y) else CoordinateMapper.Clamper(size.y)
|
||||||
|
Loading…
Reference in New Issue
Block a user