diff --git a/.idea/misc.xml b/.idea/misc.xml
index f125deeb7..c3fc748c8 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -38,7 +38,7 @@
-
+
\ No newline at end of file
diff --git a/src/net/torvald/UnsafePtr.kt b/src/net/torvald/UnsafePtr.kt
new file mode 100644
index 000000000..721115894
--- /dev/null
+++ b/src/net/torvald/UnsafePtr.kt
@@ -0,0 +1,66 @@
+package net.torvald
+
+import sun.misc.Unsafe
+
+/**
+ * Created by minjaesong on 2019-06-21.
+ */
+
+object UnsafeHelper {
+ internal val unsafe: Unsafe
+
+ init {
+ val unsafeConstructor = Unsafe::class.java.getDeclaredConstructor()
+ unsafeConstructor.isAccessible = true
+ unsafe = unsafeConstructor.newInstance()
+ }
+
+
+ fun allocate(size: Long): UnsafePtr {
+ val ptr = unsafe.allocateMemory(size)
+ return UnsafePtr(ptr, size)
+ }
+}
+
+/**
+ * To allocate a memory, use UnsafeHelper.allocate(long)
+ */
+class UnsafePtr(val ptr: Long, val allocSize: Long) {
+ var destroyed = false
+ private set
+
+ fun destroy() {
+ if (!destroyed) {
+ UnsafeHelper.unsafe.freeMemory(ptr)
+ destroyed = true
+ }
+ }
+
+ private inline fun checkNullPtr(index: Long) {
+ if (destroyed) throw NullPointerException()
+
+ // OOB Check: debugging purposes only -- comment out for the production
+ //if (index !in 0 until allocSize) throw NullPointerException("Out of bounds: $index; alloc size: $allocSize")
+ }
+
+ operator fun get(index: Long): Byte {
+ checkNullPtr(index)
+ return UnsafeHelper.unsafe.getByte(ptr + index)
+ }
+
+ fun getFloat(index: Long): Float {
+ checkNullPtr(index)
+ return UnsafeHelper.unsafe.getFloat(ptr + index)
+ }
+
+ operator fun set(index: Long, value: Byte) {
+ checkNullPtr(index)
+ UnsafeHelper.unsafe.putByte(ptr + index, value)
+ }
+
+ fun setFloat(index: Long, value: Float) {
+ checkNullPtr(index)
+ UnsafeHelper.unsafe.putFloat(ptr + index, value)
+ }
+
+}
\ No newline at end of file
diff --git a/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt b/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt
new file mode 100644
index 000000000..c1bbba2b5
--- /dev/null
+++ b/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt
@@ -0,0 +1,41 @@
+package net.torvald.gdx.graphics
+
+import net.torvald.UnsafeHelper
+
+/**
+ * Created by minjaesong on 2019-06-21.
+ */
+internal class UnsafeCvecArray(val width: Int, val height: Int) {
+
+ val TOTAL_SIZE_IN_BYTES = 16L * width * height
+
+ val array = UnsafeHelper.allocate(TOTAL_SIZE_IN_BYTES)
+
+ private inline fun toAddr(x: Int, y: Int) = 16L * (y * width + x)
+
+ fun zerofill() = UnsafeHelper.unsafe.setMemory(this.array.ptr, TOTAL_SIZE_IN_BYTES, 0)
+
+ init {
+ zerofill()
+ }
+
+ fun getR(x: Int, y: Int) = array.getFloat(toAddr(x, y))
+ fun getG(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 4)
+ fun getB(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 8)
+ fun getA(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 12)
+
+ fun setR(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y), value) }
+ fun setG(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 4, value) }
+ fun setB(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 8, value) }
+ fun setA(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 12, value) }
+
+ fun max(x: Int, y: Int, other: Cvec) {
+ setR(x, y, maxOf(getR(x, y), other.r))
+ setG(x, y, maxOf(getG(x, y), other.g))
+ setB(x, y, maxOf(getB(x, y), other.b))
+ setA(x, y, maxOf(getA(x, y), other.a))
+ }
+
+ fun destroy() = this.array.destroy()
+
+}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/gameworld/BlockLayer.kt b/src/net/torvald/terrarum/gameworld/BlockLayer.kt
index 17ba29026..8f2f480c9 100644
--- a/src/net/torvald/terrarum/gameworld/BlockLayer.kt
+++ b/src/net/torvald/terrarum/gameworld/BlockLayer.kt
@@ -22,7 +22,7 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable {
private var layerPtr = unsafe.allocateMemory(width * height * BYTES_PER_BLOCK.toLong())
init {
- unsafe.setMemory(layerPtr, width * height * BYTES_PER_BLOCK.toLong(), 0) // sometimes does not work?!
+ unsafe.setMemory(layerPtr, width * height * BYTES_PER_BLOCK.toLong(), 0) // does reliably fill the memory with zeroes
}
/**
@@ -89,12 +89,9 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable {
}
override fun next(): Byte {
- val y = iteratorCount / width
- val x = iteratorCount % width
- // advance counter
iteratorCount += 1
- return unsafe.getByte(layerPtr + 1)
+ return unsafe.getByte(layerPtr + iteratorCount)
}
}
}
diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt
index 71af8f3c1..67e4a6af8 100644
--- a/src/net/torvald/terrarum/gameworld/GameWorld.kt
+++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt
@@ -165,17 +165,13 @@ open class GameWorld : Disposable {
private fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceIn(0, height - 1))
- fun getTileFromWall(x: Int, y: Int): Int {
- val (x, y) = coerceXY(x, y)
- if (y !in 0 until height) throw Error("Y coord out of world boundary: $y")
-
+ fun getTileFromWall(rawX: Int, rawY: Int): Int {
+ val (x, y) = coerceXY(rawX, rawY)
return layerWall.unsafeGetTile(x, y)
}
- fun getTileFromTerrain(x: Int, y: Int): Int {
- val (x, y) = coerceXY(x, y)
- if (y !in 0 until height) throw Error("Y coord out of world boundary: $y")
-
+ fun getTileFromTerrain(rawX: Int, rawY: Int): Int {
+ val (x, y) = coerceXY(rawX, rawY)
return layerTerrain.unsafeGetTile(x, y)
}
diff --git a/src/net/torvald/terrarum/tests/UnsafeTest.kt b/src/net/torvald/terrarum/tests/UnsafeTest.kt
new file mode 100644
index 000000000..449953baa
--- /dev/null
+++ b/src/net/torvald/terrarum/tests/UnsafeTest.kt
@@ -0,0 +1,49 @@
+package net.torvald.terrarum.tests
+
+import net.torvald.terrarum.gameworld.toUint
+import sun.misc.Unsafe
+
+/**
+ * Created by minjaesong on 2019-06-22.
+ */
+class UnsafeTest {
+
+ private val unsafe: Unsafe
+ init {
+ val unsafeConstructor = Unsafe::class.java.getDeclaredConstructor()
+ unsafeConstructor.isAccessible = true
+ unsafe = unsafeConstructor.newInstance()
+ }
+
+ private val memsize = 2048L // must be big enough value so that your OS won't always return zero-filled pieces
+
+ fun main() {
+ val ptr = unsafe.allocateMemory(memsize)
+ printDump(ptr)
+
+ unsafe.setMemory(ptr, memsize, 0x00.toByte())
+ printDump(ptr)
+
+ for (k in 0 until memsize step 4) {
+ unsafe.putInt(ptr + k, 0xcafebabe.toInt())
+ }
+ printDump(ptr)
+
+ unsafe.freeMemory(ptr)
+ }
+
+
+ fun printDump(ptr: Long) {
+ println("MINIMINIDUMP START")
+ for (i in 0 until memsize) {
+ val b = unsafe.getByte(ptr + i).toUint().toString(16).padStart(2, '0')
+ print("$b ")
+ }
+ println("\nMINIMINIDUMP END")
+ }
+
+}
+
+fun main(args: Array) {
+ UnsafeTest().main()
+}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt
index 0562780f3..9d0c3ecc1 100644
--- a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt
+++ b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt
@@ -6,13 +6,14 @@ import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.glutils.ShaderProgram
import com.jme3.math.FastMath
import net.torvald.gdx.graphics.Cvec
+import net.torvald.gdx.graphics.UnsafeCvecArray
import net.torvald.terrarum.*
import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.blockproperties.Fluid
-import net.torvald.terrarum.concurrent.sliceEvenly
import net.torvald.terrarum.concurrent.ThreadParallel
+import net.torvald.terrarum.concurrent.sliceEvenly
import net.torvald.terrarum.gameactors.ActorWBMovable
import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.gameactors.Luminous
@@ -47,16 +48,18 @@ object LightmapRenderer {
if (this.world != world) {
printdbg(this, "World change detected -- old world: ${this.world.hashCode()}, new world: ${world.hashCode()}")
- for (y in 0 until LIGHTMAP_HEIGHT) {
+ /*for (y in 0 until LIGHTMAP_HEIGHT) {
for (x in 0 until LIGHTMAP_WIDTH) {
lightmap[y][x] = colourNull
}
- }
+ }*/
/*for (i in 0 until lightmap.size) {
lightmap[i] = colourNull
}*/
+ lightmap.zerofill()
+
makeUpdateTaskList()
}
}
@@ -84,7 +87,8 @@ object LightmapRenderer {
*/
// it utilises alpha channel to determine brightness of "glow" sprites (so that alpha channel works like UV light)
// will use array of array from now on because fuck it; debug-ability > slight framerate drop. 2019-06-01
- private var lightmap: Array> = Array(LIGHTMAP_HEIGHT) { Array(LIGHTMAP_WIDTH) { Cvec(0) } } // Can't use framebuffer/pixmap -- this is a fvec4 array, whereas they are ivec4.
+ private var lightmap: UnsafeCvecArray = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
+ //private var lightmap: Array> = Array(LIGHTMAP_HEIGHT) { Array(LIGHTMAP_WIDTH) { Cvec(0) } } // Can't use framebuffer/pixmap -- this is a fvec4 array, whereas they are ivec4.
//private var lightmap: Array = Array(LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT) { Cvec(0) } // Can't use framebuffer/pixmap -- this is a fvec4 array, whereas they are ivec4.
private val lanternMap = HashMap((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
@@ -124,15 +128,34 @@ object LightmapRenderer {
* @param y world tile coord
*/
internal fun getLight(x: Int, y: Int): Cvec? {
- val col = getLightInternal(x, y)
- if (col == null) {
+ if (!inBounds(x, y)) {
return null
}
else {
- return Cvec(col.r * MUL_FLOAT, col.g * MUL_FLOAT, col.b * MUL_FLOAT, col.a * MUL_FLOAT)
+ val x = x.convX()
+ val y = y.convY()
+
+ return Cvec(
+ lightmap.getR(x, y) * MUL_FLOAT,
+ lightmap.getG(x, y) * MUL_FLOAT,
+ lightmap.getB(x, y) * MUL_FLOAT,
+ lightmap.getA(x, y) * MUL_FLOAT
+ )
}
}
+ /**
+ * @param x world coord
+ * @param y world coord
+ */
+ private fun inBounds(x: Int, y: Int) =
+ (y - for_y_start + overscan_open in 0 until LIGHTMAP_HEIGHT &&
+ x - for_x_start + overscan_open in 0 until LIGHTMAP_WIDTH)
+ /** World coord to array coord */
+ private inline fun Int.convX() = this - for_x_start + overscan_open
+ /** World coord to array coord */
+ private inline fun Int.convY() = this - for_y_start + overscan_open
+
/**
* Internal level (0..1)
*
@@ -140,7 +163,7 @@ object LightmapRenderer {
* @param y world tile coord
*/
// TODO in regard of "colour math against integers", return Int?
- private fun getLightInternal(x: Int, y: Int): Cvec? {
+ /*private fun getLightInternal(x: Int, y: Int): Cvec? {
if (y - for_y_start + overscan_open in 0 until LIGHTMAP_HEIGHT &&
x - for_x_start + overscan_open in 0 until LIGHTMAP_WIDTH) {
@@ -153,7 +176,7 @@ object LightmapRenderer {
}
return null
- }
+ }*/
/**
@@ -168,7 +191,7 @@ object LightmapRenderer {
* @param colour Cvec to write
* @param applyFun A function ```foo(old_colour, given_colour)```
*/
- private fun setLightOf(list: Array>, x: Int, y: Int, colour: Cvec, applyFun: (Cvec, Cvec) -> Cvec = { _, c -> c }) {
+ /*private fun setLightOf(list: Array>, x: Int, y: Int, colour: Cvec, applyFun: (Cvec, Cvec) -> Cvec = { _, c -> c }) {
if (y - for_y_start + overscan_open in 0 until LIGHTMAP_HEIGHT &&
x - for_x_start + overscan_open in 0 until LIGHTMAP_WIDTH) {
@@ -179,7 +202,7 @@ object LightmapRenderer {
lightmap[ypos][xpos] = applyFun.invoke(list[ypos][xpos], colour)
//list[ypos * LIGHTMAP_WIDTH + xpos] = applyFun.invoke(list[ypos * LIGHTMAP_WIDTH + xpos], colour)
}
- }
+ }*/
internal fun fireRecalculateEvent(vararg actorContainers: List?) {
try {
@@ -238,9 +261,10 @@ object LightmapRenderer {
// wipe out lightmap
AppLoader.measureDebugTime("Renderer.Light0") {
//for (k in 0 until lightmap.size) lightmap[k] = colourNull
- for (y in 0 until lightmap.size) for (x in 0 until lightmap[0].size) lightmap[y][x] = colourNull
+ //for (y in 0 until lightmap.size) for (x in 0 until lightmap[0].size) lightmap[y][x] = 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
+ lightmap.zerofill()
}
// O((5*9)n) == O(n) where n is a size of the map.
// Because of inevitable overlaps on the area, it only works with MAX blend
@@ -404,7 +428,7 @@ object LightmapRenderer {
BlockCodex[world.getTileFromTerrain(x, y)].isSolid
}
catch (e: NullPointerException) {
- System.err.println("Invalid block id ${world.getTileFromTerrain(x, y)} from coord ($x, $y)")
+ System.err.println("[LightmapRendererNew.buildNoopMask] Invalid block id ${world.getTileFromTerrain(x, y)} from coord ($x, $y)")
e.printStackTrace()
false
@@ -466,6 +490,28 @@ object LightmapRenderer {
thisFluid = world.getFluid(x, y)
thisWall = world.getTileFromWall(x, y) ?: Block.STONE
+ // regarding the issue #26
+ try {
+ val fuck = BlockCodex[thisTerrain].luminosity
+ }
+ catch (e: NullPointerException) {
+ System.err.println("## NPE -- x: $x, y: $y, value: $thisTerrain")
+ e.printStackTrace()
+ // create shitty minidump
+ System.err.println("MINIMINIDUMP START")
+ for (xx in x - 16 until x + 16) {
+ val raw = world.getTileFromTerrain(xx, y)
+ val lsb = raw.and(0xff).toString(16).padStart(2, '0')
+ val msb = raw.ushr(8).and(0xff).toString(16).padStart(2, '0')
+ System.err.print(lsb)
+ System.err.print(msb)
+ System.err.print(" ")
+ }
+ System.err.println("\nMINIMINIDUMP END")
+
+ System.exit(1)
+ }
+
if (thisFluid.type != Fluid.NULL) {
fluidAmountToCol.set(thisFluid.amount, thisFluid.amount, thisFluid.amount, thisFluid.amount)
@@ -544,13 +590,16 @@ object LightmapRenderer {
/**
* Calculates the light simulation, using main lightmap as one of the input.
*/
- private fun calculateAndAssign(lightmap: Array>, x: Int, y: Int) {
+ private fun calculateAndAssign(lightmap: UnsafeCvecArray, worldX: Int, worldY: Int) {
- if (inNoopMask(x, y)) return
+ if (inNoopMask(worldX, worldY)) return
// O(9n) == O(n) where n is a size of the map
- getLightsAndShades(x, y)
+ getLightsAndShades(worldX, worldY)
+
+ val x = worldX.convX()
+ val y = worldY.convY()
// calculate ambient
/* + * + 0 4 1
@@ -562,41 +611,36 @@ object LightmapRenderer {
// will "overwrite" what's there in the lightmap if it's the first pass
// takes about 2 ms on 6700K
- /* + */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x - 1, y - 1) ?: colourNull, thisTileOpacity2))
- /* + */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x + 1, y - 1) ?: colourNull, thisTileOpacity2))
- /* + */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x - 1, y + 1) ?: colourNull, thisTileOpacity2))
- /* + */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x + 1, y + 1) ?: colourNull, thisTileOpacity2))
- /* * */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x, y - 1) ?: colourNull, thisTileOpacity))
- /* * */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x, y + 1) ?: colourNull, thisTileOpacity))
- /* * */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x - 1, y) ?: colourNull, thisTileOpacity))
- /* * */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x + 1, y) ?: colourNull, thisTileOpacity))
+ /* + */lightLevelThis.maxAndAssign(darkenColoured(x - 1, y - 1, thisTileOpacity2))
+ /* + */lightLevelThis.maxAndAssign(darkenColoured(x + 1, y - 1, thisTileOpacity2))
+ /* + */lightLevelThis.maxAndAssign(darkenColoured(x - 1, y + 1, thisTileOpacity2))
+ /* + */lightLevelThis.maxAndAssign(darkenColoured(x + 1, y + 1, thisTileOpacity2))
+ /* * */lightLevelThis.maxAndAssign(darkenColoured(x, y - 1, thisTileOpacity))
+ /* * */lightLevelThis.maxAndAssign(darkenColoured(x, y + 1, thisTileOpacity))
+ /* * */lightLevelThis.maxAndAssign(darkenColoured(x - 1, y, thisTileOpacity))
+ /* * */lightLevelThis.maxAndAssign(darkenColoured(x + 1, y, thisTileOpacity))
//return lightLevelThis.cpy() // it HAS to be a cpy(), otherwise all cells gets the same instance
- setLightOf(lightmap, x, y, lightLevelThis.cpy())
+ //setLightOf(lightmap, x, y, lightLevelThis.cpy())
+
+ lightmap.setR(x, y, lightLevelThis.r)
+ lightmap.setG(x, y, lightLevelThis.g)
+ lightmap.setB(x, y, lightLevelThis.b)
+ lightmap.setA(x, y, lightLevelThis.a)
}
- private fun getLightForOpaque(x: Int, y: Int): Cvec? { // ...so that they wouldn't appear too dark
- val l = getLightInternal(x, y)
- if (l == null) return null
+ private fun isSolid(x: Int, y: Int): Float? { // ...so that they wouldn't appear too dark
+ if (!inBounds(x, y)) return null
// brighten if solid
- if (BlockCodex[world.getTileFromTerrain(x, y)].isSolid) {
- return Cvec(
- (l.r * 1.2f),
- (l.g * 1.2f),
- (l.b * 1.2f),
- (l.a * 1.2f)
- )
- }
- else {
- return l
- }
+ return if (BlockCodex[world.getTileFromTerrain(x, y)].isSolid) 1.2f else 1f
}
var lightBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
private val colourNull = Cvec(0)
+ private val gdxColorNull = Color(0)
private val epsilon = 1f/1024f
private var _lightBufferAsTex: Texture = Texture(1, 1, Pixmap.Format.RGBA8888)
@@ -626,7 +670,20 @@ object LightmapRenderer {
for (x in this_x_start..this_x_end) {
- val color = (getLightForOpaque(x, y) ?: Cvec(0f, 0f, 0f, 0f)).normaliseToHDR()
+ val solidMultMagic = isSolid(x, y)
+
+ val arrayX = x.convX()
+ val arrayY = y.convY()
+
+ val color = if (solidMultMagic == null)
+ gdxColorNull
+ else
+ Color(
+ lightmap.getR(arrayX, arrayY) * solidMultMagic,
+ lightmap.getG(arrayX, arrayY) * solidMultMagic,
+ lightmap.getB(arrayX, arrayY) * solidMultMagic,
+ lightmap.getA(arrayX, arrayY) * solidMultMagic
+ ).normaliseToHDR()
lightBuffer.setColor(color)
@@ -661,34 +718,30 @@ object LightmapRenderer {
/**
* Subtract each channel's RGB value.
*
- * @param data Raw channel value (0-255) per channel
+ * @param x array coord
+ * @param y array coord
* @param darken (0-255) per channel
* @return darkened data (0-255) per channel
*/
- fun darkenColoured(data: Cvec, darken: Cvec): Cvec {
+ fun darkenColoured(x: Int, y: Int, darken: Cvec): Cvec {
// use equation with magic number 8.0
// this function, when done recursively (A_x = darken(A_x-1, C)), draws exponential curve. (R^2 = 1)
- return Cvec(
+ /*return Cvec(
data.r * (1f - darken.r * lightScalingMagic),//.clampZero(),
data.g * (1f - darken.g * lightScalingMagic),//.clampZero(),
data.b * (1f - darken.b * lightScalingMagic),//.clampZero(),
- data.a * (1f - darken.a * lightScalingMagic))
- }
+ data.a * (1f - darken.a * lightScalingMagic))*/
- /**
- * Darken each channel by 'darken' argument
- *
- * @param data Raw channel value (0-255) per channel
- * @param darken (0-255)
- * @return
- */
- fun darkenUniformInt(data: Cvec, darken: Float): Cvec {
- if (darken < 0 || darken > CHANNEL_MAX)
- throw IllegalArgumentException("darken: out of range ($darken)")
+ if (x !in 0 until LIGHTMAP_WIDTH || y !in 0 until LIGHTMAP_HEIGHT) return colourNull
+
+ return Cvec(
+ lightmap.getR(x, y) * (1f - darken.r * lightScalingMagic),
+ lightmap.getG(x, y) * (1f - darken.g * lightScalingMagic),
+ lightmap.getB(x, y) * (1f - darken.b * lightScalingMagic),
+ lightmap.getA(x, y) * (1f - darken.a * lightScalingMagic)
+ )
- val darkenColoured = Cvec(darken, darken, darken, darken)
- return darkenColoured(data, darkenColoured)
}
/**
@@ -768,7 +821,8 @@ object LightmapRenderer {
_init = true
}
lightBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
- lightmap = Array(LIGHTMAP_HEIGHT) { Array(LIGHTMAP_WIDTH) { Cvec(0) } }
+ lightmap.destroy()
+ lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
//lightmap = Array(LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT) { Cvec(0) }
@@ -843,7 +897,7 @@ object LightmapRenderer {
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f // isn't it beautiful?
)
/** To eliminated visible edge on the gradient when 255/1023 is exceeded */
- internal fun Cvec.normaliseToHDR() = Color(
+ internal fun Color.normaliseToHDR() = Color(
hdr(this.r.coerceIn(0f, 1f)),
hdr(this.g.coerceIn(0f, 1f)),
hdr(this.b.coerceIn(0f, 1f)),
@@ -864,12 +918,14 @@ object LightmapRenderer {
for (y in overscan_open..render_height + overscan_open + 1) {
for (x in overscan_open..render_width + overscan_open + 1) {
try {
- val colour = lightmap[y][x]
+ //val colour = lightmap[y][x]
//val colour = lightmap[y * LIGHTMAP_WIDTH + x]
- reds[minOf(CHANNEL_MAX, colour.r.times(MUL).floorInt())] += 1
- greens[minOf(CHANNEL_MAX, colour.g.times(MUL).floorInt())] += 1
- blues[minOf(CHANNEL_MAX, colour.b.times(MUL).floorInt())] += 1
- uvs[minOf(CHANNEL_MAX, colour.a.times(MUL).floorInt())] += 1
+ val x = x.convX()
+ val y = y.convY()
+ //reds[minOf(CHANNEL_MAX, lightmap.getR(x, y).times(MUL).floorInt())] += 1
+ //greens[minOf(CHANNEL_MAX, lightmap.getG(x, y).times(MUL).floorInt())] += 1
+ //blues[minOf(CHANNEL_MAX, lightmap.getB(x, y).floorInt())] += 1
+ //uvs[minOf(CHANNEL_MAX, lightmap.getA(x, y).floorInt())] += 1
}
catch (e: ArrayIndexOutOfBoundsException) { }
}