Light flood test
This commit is contained in:
parent
45b3e203ba
commit
96068d483c
@ -42,8 +42,10 @@ fun main() {
|
|||||||
var set = 0L
|
var set = 0L
|
||||||
var parse = 0L
|
var parse = 0L
|
||||||
|
|
||||||
for (chunkX in 17 .. 18) {
|
//for (chunkX in 17 .. 18) {
|
||||||
for (chunkY in 21 .. 21) {
|
for (chunkX in 0 .. 60) {
|
||||||
|
// for (chunkY in 21 .. 21) {
|
||||||
|
for (chunkY in 0 .. 60) {
|
||||||
var t = System.currentTimeMillis()
|
var t = System.currentTimeMillis()
|
||||||
val data = db.read(byteArrayOf(1, 0, chunkX.toByte(), 0, chunkY.toByte()))
|
val data = db.read(byteArrayOf(1, 0, chunkX.toByte(), 0, chunkY.toByte()))
|
||||||
find += System.currentTimeMillis() - t
|
find += System.currentTimeMillis() - t
|
||||||
|
@ -4,6 +4,7 @@ import org.lwjgl.opengl.GL46.*
|
|||||||
import ru.dbotthepony.kstarbound.PIXELS_IN_STARBOUND_UNITf
|
import ru.dbotthepony.kstarbound.PIXELS_IN_STARBOUND_UNITf
|
||||||
import ru.dbotthepony.kstarbound.client.gl.BlendFunc
|
import ru.dbotthepony.kstarbound.client.gl.BlendFunc
|
||||||
import ru.dbotthepony.kstarbound.client.gl.vertex.QuadTransformers
|
import ru.dbotthepony.kstarbound.client.gl.vertex.QuadTransformers
|
||||||
|
import ru.dbotthepony.kstarbound.client.gl.vertex.quad
|
||||||
import ru.dbotthepony.kstarbound.client.gl.vertex.quadZ
|
import ru.dbotthepony.kstarbound.client.gl.vertex.quadZ
|
||||||
import ru.dbotthepony.kstarbound.client.render.ILayeredRenderer
|
import ru.dbotthepony.kstarbound.client.render.ILayeredRenderer
|
||||||
import ru.dbotthepony.kstarbound.client.render.renderLayeredList
|
import ru.dbotthepony.kstarbound.client.render.renderLayeredList
|
||||||
@ -15,6 +16,8 @@ import ru.dbotthepony.kstarbound.world.entities.Entity
|
|||||||
import ru.dbotthepony.kvector.util2d.AABB
|
import ru.dbotthepony.kvector.util2d.AABB
|
||||||
import ru.dbotthepony.kvector.vector.Color
|
import ru.dbotthepony.kvector.vector.Color
|
||||||
import ru.dbotthepony.kvector.vector.nfloat.Vector2f
|
import ru.dbotthepony.kvector.vector.nfloat.Vector2f
|
||||||
|
import ru.dbotthepony.kvector.vector.nint.Vector2i
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class ClientWorld(
|
class ClientWorld(
|
||||||
val client: StarboundClient,
|
val client: StarboundClient,
|
||||||
@ -127,7 +130,7 @@ class ClientWorld(
|
|||||||
client.pushScissorRect(x, client.viewportHeight - y, x2 - x, y - y2)
|
client.pushScissorRect(x, client.viewportHeight - y, x2 - x, y - y2)
|
||||||
}
|
}
|
||||||
|
|
||||||
client.lightRenderer.renderSoftLight(lightPosition, color, radius = 20f, innerRadius = 1f)
|
//client.lightRenderer.renderSoftLight(lightPosition, color, radius = 20f, innerRadius = 1f)
|
||||||
|
|
||||||
if (isScreenspaceRender) {
|
if (isScreenspaceRender) {
|
||||||
client.popScissorRect()
|
client.popScissorRect()
|
||||||
@ -137,12 +140,30 @@ class ClientWorld(
|
|||||||
val old = client.gl.blendFunc
|
val old = client.gl.blendFunc
|
||||||
client.gl.blendFunc = BlendFunc.MULTIPLY_BY_SRC
|
client.gl.blendFunc = BlendFunc.MULTIPLY_BY_SRC
|
||||||
|
|
||||||
client.gl.activeTexture = 0
|
// client.gl.activeTexture = 0
|
||||||
client.gl.texture2D = client.lightRenderer.outputTexture
|
// client.gl.texture2D = client.lightRenderer.outputTexture
|
||||||
client.gl.programs.textureQuad.run()
|
// client.gl.programs.textureQuad.run()
|
||||||
|
|
||||||
client.gl.blendFunc = old
|
client.gl.blendFunc = old
|
||||||
|
|
||||||
|
val pos = client.screenToWorld(client.mouseCoordinatesF)
|
||||||
|
|
||||||
|
val lightsize = 16
|
||||||
|
|
||||||
|
val lightmap = floodLight(
|
||||||
|
Vector2i(pos.x.roundToInt(), pos.y.roundToInt()), lightsize
|
||||||
|
)
|
||||||
|
|
||||||
|
client.gl.quadWireframe {
|
||||||
|
for (column in 0 until lightmap.columns) {
|
||||||
|
for (row in 0 until lightmap.rows) {
|
||||||
|
if (lightmap[column, row] > 0) {
|
||||||
|
it.quad(pos.x.roundToInt() + column.toFloat() - lightsize, pos.y.roundToInt() + row.toFloat() - lightsize, pos.x.roundToInt() + column + 1f - lightsize, pos.y.roundToInt() + row + 1f - lightsize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
physics.debugDraw()
|
physics.debugDraw()
|
||||||
|
|
||||||
/*for (renderer in determineRenderers) {
|
/*for (renderer in determineRenderers) {
|
||||||
|
@ -29,9 +29,19 @@ private fun circulate(value: Int, bounds: Int): Int {
|
|||||||
class ChunkPos(val x: Int, val y: Int) : Comparable<ChunkPos> {
|
class ChunkPos(val x: Int, val y: Int) : Comparable<ChunkPos> {
|
||||||
constructor(pos: IStruct2i) : this(pos.component1(), pos.component2())
|
constructor(pos: IStruct2i) : this(pos.component1(), pos.component2())
|
||||||
|
|
||||||
val firstBlock get() = Vector2i(x shl CHUNK_SHIFT, y shl CHUNK_SHIFT)
|
val firstBlock get() = Vector2i(tileX, tileY)
|
||||||
val lastBlock get() = Vector2i(((x + 1) shl CHUNK_SHIFT) - 1, ((y + 1) shl CHUNK_SHIFT) - 1)
|
val lastBlock get() = Vector2i(((x + 1) shl CHUNK_SHIFT) - 1, ((y + 1) shl CHUNK_SHIFT) - 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Координата тайла на 0 позиции по оси X внутри чанка в мире
|
||||||
|
*/
|
||||||
|
val tileX: Int get() = x shl CHUNK_SHIFT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Координата тайла на 0 позиции по оси Y внутри чанка в мире
|
||||||
|
*/
|
||||||
|
val tileY: Int get() = y shl CHUNK_SHIFT
|
||||||
|
|
||||||
val top: ChunkPos
|
val top: ChunkPos
|
||||||
get() {
|
get() {
|
||||||
return ChunkPos(x, y + 1)
|
return ChunkPos(x, y + 1)
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package ru.dbotthepony.kstarbound.world
|
||||||
|
|
||||||
|
import ru.dbotthepony.kstarbound.util.NotNullTwoDimensionalArray
|
||||||
|
import ru.dbotthepony.kstarbound.util.TwoDimensionalArray
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Предоставляет доступ к чанку и его соседям
|
||||||
|
*
|
||||||
|
* Данный вариант отличается от [TileView] тем, что данный класс *копирует* список тайлов из всех чанков, которые ему известны
|
||||||
|
* в единый массив.
|
||||||
|
*
|
||||||
|
* Полезно в ситуациях, когда необходимо максимально быстрое получение данных о тайлах.
|
||||||
|
*/
|
||||||
|
class RigidTileView(
|
||||||
|
view: TileView,
|
||||||
|
) : ITileChunk {
|
||||||
|
constructor(
|
||||||
|
pos: ChunkPos,
|
||||||
|
center: ITileChunk?,
|
||||||
|
|
||||||
|
right: ITileChunk?,
|
||||||
|
top: ITileChunk?,
|
||||||
|
topRight: ITileChunk?,
|
||||||
|
topLeft: ITileChunk?,
|
||||||
|
|
||||||
|
left: ITileChunk?,
|
||||||
|
bottom: ITileChunk?,
|
||||||
|
bottomLeft: ITileChunk?,
|
||||||
|
bottomRight: ITileChunk?,
|
||||||
|
) : this(TileView(pos, center, right, top, topRight, topLeft, left, bottom, bottomLeft, bottomRight))
|
||||||
|
|
||||||
|
override val pos: ChunkPos = view.pos
|
||||||
|
|
||||||
|
private val memory: NotNullTwoDimensionalArray<ITileState>
|
||||||
|
|
||||||
|
init {
|
||||||
|
memory = NotNullTwoDimensionalArray(CHUNK_SIZE * 3, CHUNK_SIZE * 3) { a, b -> view[a - CHUNK_SIZE, b - CHUNK_SIZE] }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(x: Int, y: Int): ITileState {
|
||||||
|
return memory[x + CHUNK_SIZE, y + CHUNK_SIZE]
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,8 @@ import ru.dbotthepony.kstarbound.defs.tile.TileDefinition
|
|||||||
* с желанием получить тайл из соседнего чанка
|
* с желанием получить тайл из соседнего чанка
|
||||||
*/
|
*/
|
||||||
open class TileView(
|
open class TileView(
|
||||||
open val center: ITileChunk,
|
override val pos: ChunkPos,
|
||||||
|
open val center: ITileChunk?,
|
||||||
|
|
||||||
open val right: ITileChunk?,
|
open val right: ITileChunk?,
|
||||||
open val top: ITileChunk?,
|
open val top: ITileChunk?,
|
||||||
@ -25,7 +26,7 @@ open class TileView(
|
|||||||
override fun get(x: Int, y: Int): ITileState {
|
override fun get(x: Int, y: Int): ITileState {
|
||||||
if (x in 0 ..CHUNK_SIZE_FF) {
|
if (x in 0 ..CHUNK_SIZE_FF) {
|
||||||
if (y in 0 ..CHUNK_SIZE_FF) {
|
if (y in 0 ..CHUNK_SIZE_FF) {
|
||||||
return center[x, y]
|
return center?.get(x, y) ?: EmptyTileState
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y < 0) {
|
if (y < 0) {
|
||||||
@ -57,13 +58,11 @@ open class TileView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val pos: ChunkPos
|
|
||||||
get() = center.pos
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MutableTileView(
|
class MutableTileView(
|
||||||
override val center: IMutableTileChunk,
|
pos: ChunkPos,
|
||||||
|
override val center: IMutableTileChunk?,
|
||||||
|
|
||||||
override val right: IMutableTileChunk?,
|
override val right: IMutableTileChunk?,
|
||||||
override val top: IMutableTileChunk?,
|
override val top: IMutableTileChunk?,
|
||||||
@ -74,7 +73,7 @@ class MutableTileView(
|
|||||||
override val bottom: IMutableTileChunk?,
|
override val bottom: IMutableTileChunk?,
|
||||||
override val bottomLeft: IMutableTileChunk?,
|
override val bottomLeft: IMutableTileChunk?,
|
||||||
override val bottomRight: IMutableTileChunk?,
|
override val bottomRight: IMutableTileChunk?,
|
||||||
) : TileView(center, right, top, topRight, topLeft, left, bottom, bottomLeft, bottomRight), IMutableTileChunk {
|
) : TileView(pos, center, right, top, topRight, topLeft, left, bottom, bottomLeft, bottomRight), IMutableTileChunk {
|
||||||
override fun get(x: Int, y: Int): IMutableTileState {
|
override fun get(x: Int, y: Int): IMutableTileState {
|
||||||
return super<TileView>.get(x, y) as IMutableTileState
|
return super<TileView>.get(x, y) as IMutableTileState
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import ru.dbotthepony.kstarbound.util.Timer
|
|||||||
import ru.dbotthepony.kstarbound.world.entities.CollisionResolution
|
import ru.dbotthepony.kstarbound.world.entities.CollisionResolution
|
||||||
import ru.dbotthepony.kstarbound.world.entities.Entity
|
import ru.dbotthepony.kstarbound.world.entities.Entity
|
||||||
import ru.dbotthepony.kstarbound.world.entities.projectile.AbstractProjectileMovementController
|
import ru.dbotthepony.kstarbound.world.entities.projectile.AbstractProjectileMovementController
|
||||||
|
import ru.dbotthepony.kvector.narray.Int2Dimensional
|
||||||
import ru.dbotthepony.kvector.util2d.AABB
|
import ru.dbotthepony.kvector.util2d.AABB
|
||||||
import ru.dbotthepony.kvector.util2d.AABBi
|
import ru.dbotthepony.kvector.util2d.AABBi
|
||||||
import ru.dbotthepony.kvector.vector.ndouble.Vector2d
|
import ru.dbotthepony.kvector.vector.ndouble.Vector2d
|
||||||
@ -41,6 +42,8 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
return@cmp a.compareTo(b)
|
return@cmp a.compareTo(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//protected val chunkMap = HashMap<ChunkPos, ChunkType>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Является ли мир "сферическим"
|
* Является ли мир "сферическим"
|
||||||
*
|
*
|
||||||
@ -56,6 +59,7 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
val dirtyPhysicsChunks = HashSet<ChunkType>()
|
val dirtyPhysicsChunks = HashSet<ChunkType>()
|
||||||
|
|
||||||
protected var lastAccessedChunk: ChunkType? = null
|
protected var lastAccessedChunk: ChunkType? = null
|
||||||
|
protected var lastAccessedChunkPos: ChunkPos? = null
|
||||||
|
|
||||||
val physics = B2World(Vector2d(0.0, -EARTH_FREEFALL_ACCELERATION))
|
val physics = B2World(Vector2d(0.0, -EARTH_FREEFALL_ACCELERATION))
|
||||||
|
|
||||||
@ -226,21 +230,19 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
*/
|
*/
|
||||||
open operator fun get(pos: ChunkPos): ChunkType? {
|
open operator fun get(pos: ChunkPos): ChunkType? {
|
||||||
if (!isCircular) {
|
if (!isCircular) {
|
||||||
val lastAccessedChunk = lastAccessedChunk
|
//if (lastAccessedChunkPos == pos) {
|
||||||
|
// return lastAccessedChunk
|
||||||
|
//}
|
||||||
|
|
||||||
if (lastAccessedChunk?.pos == pos) {
|
//lastAccessedChunkPos = pos
|
||||||
return lastAccessedChunk
|
lastAccessedChunk = chunkMap[pos]
|
||||||
}
|
return this.lastAccessedChunk
|
||||||
|
|
||||||
return chunkMap[pos]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("Name_Shadowing")
|
@Suppress("Name_Shadowing")
|
||||||
val pos = pos.circular(widthInChunks)
|
val pos = pos.circular(widthInChunks)
|
||||||
|
|
||||||
val lastAccessedChunk = lastAccessedChunk
|
if (lastAccessedChunkPos == pos) {
|
||||||
|
|
||||||
if (lastAccessedChunk?.pos == pos) {
|
|
||||||
return lastAccessedChunk
|
return lastAccessedChunk
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,6 +272,7 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
val chunk = chunkFactory(pos)
|
val chunk = chunkFactory(pos)
|
||||||
|
|
||||||
lastAccessedChunk = chunk
|
lastAccessedChunk = chunk
|
||||||
|
lastAccessedChunkPos = pos
|
||||||
|
|
||||||
val orphanedInThisChunk = ArrayList<Entity>()
|
val orphanedInThisChunk = ArrayList<Entity>()
|
||||||
|
|
||||||
@ -289,40 +292,48 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun getForegroundView(pos: ChunkPos): TileView? {
|
open fun getForegroundView(pos: ChunkPos): TileView {
|
||||||
val get = get(pos) ?: return null
|
val tuple = get(pos)?.let { InstantWorldChunkTuple(this as This, it) }
|
||||||
val tuple = InstantWorldChunkTuple(this as This, get)
|
|
||||||
|
|
||||||
return TileView(
|
return TileView(
|
||||||
center = tuple.chunk.foreground,
|
pos = pos,
|
||||||
left = tuple.left?.chunk?.foreground,
|
center = tuple?.chunk?.foreground,
|
||||||
top = tuple.top?.chunk?.foreground,
|
left = tuple?.left?.chunk?.foreground,
|
||||||
topLeft = tuple.topLeft?.chunk?.foreground,
|
top = tuple?.top?.chunk?.foreground,
|
||||||
topRight = tuple.topRight?.chunk?.foreground,
|
topLeft = tuple?.topLeft?.chunk?.foreground,
|
||||||
right = tuple.right?.chunk?.foreground,
|
topRight = tuple?.topRight?.chunk?.foreground,
|
||||||
bottom = tuple.bottom?.chunk?.foreground,
|
right = tuple?.right?.chunk?.foreground,
|
||||||
bottomLeft = tuple.bottomLeft?.chunk?.foreground,
|
bottom = tuple?.bottom?.chunk?.foreground,
|
||||||
bottomRight = tuple.bottomRight?.chunk?.foreground,
|
bottomLeft = tuple?.bottomLeft?.chunk?.foreground,
|
||||||
|
bottomRight = tuple?.bottomRight?.chunk?.foreground,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun getBackgroundView(pos: ChunkPos): TileView? {
|
open fun getBackgroundView(pos: ChunkPos): TileView {
|
||||||
val get = get(pos) ?: return null
|
val tuple = get(pos)?.let { InstantWorldChunkTuple(this as This, it) }
|
||||||
val tuple = InstantWorldChunkTuple(this as This, get)
|
|
||||||
|
|
||||||
return TileView(
|
return TileView(
|
||||||
center = tuple.chunk.background,
|
pos = pos,
|
||||||
left = tuple.left?.chunk?.background,
|
center = tuple?.chunk?.background,
|
||||||
top = tuple.top?.chunk?.background,
|
left = tuple?.left?.chunk?.background,
|
||||||
topLeft = tuple.topLeft?.chunk?.background,
|
top = tuple?.top?.chunk?.background,
|
||||||
topRight = tuple.topRight?.chunk?.background,
|
topLeft = tuple?.topLeft?.chunk?.background,
|
||||||
right = tuple.right?.chunk?.background,
|
topRight = tuple?.topRight?.chunk?.background,
|
||||||
bottom = tuple.bottom?.chunk?.background,
|
right = tuple?.right?.chunk?.background,
|
||||||
bottomLeft = tuple.bottomLeft?.chunk?.background,
|
bottom = tuple?.bottom?.chunk?.background,
|
||||||
bottomRight = tuple.bottomRight?.chunk?.background,
|
bottomLeft = tuple?.bottomLeft?.chunk?.background,
|
||||||
|
bottomRight = tuple?.bottomRight?.chunk?.background,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun getRigidForegroundView(pos: ChunkPos): RigidTileView {
|
||||||
|
return RigidTileView(getForegroundView(pos))
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun getRigidBackgroundView(pos: ChunkPos): RigidTileView {
|
||||||
|
return RigidTileView(getBackgroundView(pos))
|
||||||
|
}
|
||||||
|
|
||||||
fun getTile(pos: Vector2i): ITileState? {
|
fun getTile(pos: Vector2i): ITileState? {
|
||||||
return get(ChunkPos.fromTilePosition(pos))?.foreground?.get(ChunkPos.normalizeCoordinate(pos.x), ChunkPos.normalizeCoordinate(pos.y))
|
return get(ChunkPos.fromTilePosition(pos))?.foreground?.get(ChunkPos.normalizeCoordinate(pos.x), ChunkPos.normalizeCoordinate(pos.y))
|
||||||
}
|
}
|
||||||
@ -559,4 +570,110 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Свет
|
||||||
|
|
||||||
|
private fun floodLightInto(
|
||||||
|
lightmap: Int2Dimensional,
|
||||||
|
view: RigidTileView,
|
||||||
|
thisIntensity: Int,
|
||||||
|
lightBlockerStrength: Int,
|
||||||
|
posX: Int,
|
||||||
|
worldPosX: Int,
|
||||||
|
posY: Int,
|
||||||
|
worldPosY: Int,
|
||||||
|
): Int {
|
||||||
|
if (lightmap[posX, posY] >= thisIntensity) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
val tile = view[worldPosX, worldPosY]
|
||||||
|
|
||||||
|
val newIntensity: Int
|
||||||
|
|
||||||
|
if (tile.material?.renderParameters?.lightTransparent == false) {
|
||||||
|
newIntensity = thisIntensity - lightBlockerStrength
|
||||||
|
} else {
|
||||||
|
newIntensity = thisIntensity - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
lightmap[posX, posY] = newIntensity.coerceAtLeast(0)
|
||||||
|
|
||||||
|
if (newIntensity > 1) {
|
||||||
|
var c = 1
|
||||||
|
|
||||||
|
c += floodLightInto(
|
||||||
|
lightmap, view, newIntensity, lightBlockerStrength,
|
||||||
|
posX + 1,
|
||||||
|
worldPosX + 1,
|
||||||
|
posY,
|
||||||
|
worldPosY,
|
||||||
|
)
|
||||||
|
|
||||||
|
c += floodLightInto(
|
||||||
|
lightmap, view, newIntensity, lightBlockerStrength,
|
||||||
|
posX - 1,
|
||||||
|
worldPosX - 1,
|
||||||
|
posY,
|
||||||
|
worldPosY,
|
||||||
|
)
|
||||||
|
|
||||||
|
c += floodLightInto(
|
||||||
|
lightmap, view, newIntensity, lightBlockerStrength,
|
||||||
|
posX,
|
||||||
|
worldPosX,
|
||||||
|
posY + 1,
|
||||||
|
worldPosY + 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
c += floodLightInto(
|
||||||
|
lightmap, view, newIntensity, lightBlockerStrength,
|
||||||
|
posX,
|
||||||
|
worldPosX,
|
||||||
|
posY - 1,
|
||||||
|
worldPosY - 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Просчитывает распространение света во все стороны на указанной позиции (в тайлах)
|
||||||
|
*
|
||||||
|
* [lightIntensity] - максимальное расстояние, которое может пройти свет из точки своего появления.
|
||||||
|
* Имеет жёсткое ограничение в [CHUNK_SIZE].
|
||||||
|
*
|
||||||
|
* [lightBlockerStrength] - какова стоимость "пробития" тайла насквозь, который не пропускает свет
|
||||||
|
*/
|
||||||
|
fun floodLight(
|
||||||
|
lightPosition: Vector2i,
|
||||||
|
lightIntensity: Int,
|
||||||
|
lightBlockerStrength: Int = 4,
|
||||||
|
): Int2Dimensional {
|
||||||
|
require(lightIntensity >= 1) { "Invalid light intensity $lightIntensity" }
|
||||||
|
require(lightBlockerStrength >= 1) { "Invalid light blocker strength $lightBlockerStrength" }
|
||||||
|
require(lightIntensity <= CHUNK_SIZE) { "Too intensive light! $lightIntensity" }
|
||||||
|
|
||||||
|
val lightmap = Int2Dimensional(lightIntensity * 2 + 1, lightIntensity * 2 + 1)
|
||||||
|
|
||||||
|
val view = getRigidForegroundView(ChunkPos.fromTilePosition(lightPosition))
|
||||||
|
|
||||||
|
val calls = floodLightInto(
|
||||||
|
lightmap,
|
||||||
|
view,
|
||||||
|
lightIntensity,
|
||||||
|
lightBlockerStrength,
|
||||||
|
lightIntensity,
|
||||||
|
lightPosition.x - view.pos.tileX,
|
||||||
|
lightIntensity,
|
||||||
|
lightPosition.y - view.pos.tileY,
|
||||||
|
)
|
||||||
|
|
||||||
|
println(calls)
|
||||||
|
|
||||||
|
return lightmap
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user