Tentatively fixed the issue #35

if it's truly been fixed, the culprit was the mixed use of lx/ly and worldx/worldy
This commit is contained in:
minjaesong
2020-03-07 02:39:01 +09:00
parent 4c77ccb548
commit 0b57a995a5
2 changed files with 101 additions and 23 deletions

View File

@@ -27,7 +27,7 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) {
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 getVec(x: Int, y: Int) = Cvec(
inline fun getVec(x: Int, y: Int) = Cvec(
array.getFloat(toAddr(x, y)),
array.getFloat(toAddr(x, y) + 4),
array.getFloat(toAddr(x, y) + 8),
@@ -36,7 +36,7 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) {
/**
* @param channel 0 for R, 1 for G, 2 for B, 3 for A
*/
inline fun channelGet(x: Int, y: Int, channel: Int) = array.getFloat(toAddr(x, y) + 4L * channel)
fun channelGet(x: Int, y: Int, channel: Int) = array.getFloat(toAddr(x, y) + 4L * channel)
// setters
fun zerofill() = array.fillWith(0)
@@ -44,13 +44,13 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) {
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 setVec(x: Int, y: Int, value: Cvec) {
inline fun setVec(x: Int, y: Int, value: Cvec) {
array.setFloat(toAddr(x, y), value.r)
array.setFloat(toAddr(x, y) + 4, value.g)
array.setFloat(toAddr(x, y) + 8, value.b)
array.setFloat(toAddr(x, y) + 12, value.a)
}
fun setScalar(x: Int, y: Int, value: Float) {
inline fun setScalar(x: Int, y: Int, value: Float) {
array.setFloat(toAddr(x, y), value)
array.setFloat(toAddr(x, y) + 4, value)
array.setFloat(toAddr(x, y) + 8, value)
@@ -59,18 +59,99 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) {
/**
* @param channel 0 for R, 1 for G, 2 for B, 3 for A
*/
inline fun channelSet(x: Int, y: Int, channel: Int, value: Float) {
fun channelSet(x: Int, y: Int, channel: Int, value: Float) {
array.setFloat(toAddr(x, y) + 4L * channel, value)
}
// operators
fun max(x: Int, y: Int, other: Cvec) {
inline 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))
}
inline fun mul(x: Int, y: Int, scalar: Float) {
setR(x, y, getR(x, y) * scalar)
setG(x, y, getG(x, y) * scalar)
setB(x, y, getB(x, y) * scalar)
setA(x, y, getA(x, y) * scalar)
}
fun destroy() = this.array.destroy()
}
/**
* Safe (and slower) version of UnsafeCvecArray utilised to tackle down the SEGFAULT
*/
internal class TestCvecArr(val width: Int, val height: Int) {
val TOTAL_SIZE_IN_BYTES = 4 * width * height
val array = FloatArray(TOTAL_SIZE_IN_BYTES)
private inline fun toAddr(x: Int, y: Int) = 4 * (y * width + x)
init {
zerofill()
}
// getters
fun getR(x: Int, y: Int) = array.get(toAddr(x, y))
fun getG(x: Int, y: Int) = array.get(toAddr(x, y) + 1)
fun getB(x: Int, y: Int) = array.get(toAddr(x, y) + 2)
fun getA(x: Int, y: Int) = array.get(toAddr(x, y) + 3)
inline fun getVec(x: Int, y: Int) = Cvec(
array.get(toAddr(x, y)),
array.get(toAddr(x, y) + 1),
array.get(toAddr(x, y) + 2),
array.get(toAddr(x, y) + 3)
)
/**
* @param channel 0 for R, 1 for G, 2 for B, 3 for A
*/
fun channelGet(x: Int, y: Int, channel: Int) = array.get(toAddr(x, y) + 1 * channel)
// setters
fun zerofill() = array.fill(0f)
fun setR(x: Int, y: Int, value: Float) { array.set(toAddr(x, y), value) }
fun setG(x: Int, y: Int, value: Float) { array.set(toAddr(x, y) + 1, value) }
fun setB(x: Int, y: Int, value: Float) { array.set(toAddr(x, y) + 2, value) }
fun setA(x: Int, y: Int, value: Float) { array.set(toAddr(x, y) + 3, value) }
inline fun setVec(x: Int, y: Int, value: Cvec) {
array.set(toAddr(x, y), value.r)
array.set(toAddr(x, y) + 1, value.g)
array.set(toAddr(x, y) + 2, value.b)
array.set(toAddr(x, y) + 3, value.a)
}
inline fun setScalar(x: Int, y: Int, value: Float) {
array.set(toAddr(x, y), value)
array.set(toAddr(x, y) + 1, value)
array.set(toAddr(x, y) + 2, value)
array.set(toAddr(x, y) + 3, value)
}
/**
* @param channel 0 for R, 1 for G, 2 for B, 3 for A
*/
fun channelSet(x: Int, y: Int, channel: Int, value: Float) {
array.set(toAddr(x, y) + 1 * channel, value)
}
// operators
inline 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))
}
inline fun mul(x: Int, y: Int, scalar: Float) {
setR(x, y, getR(x, y) * scalar)
setG(x, y, getG(x, y) * scalar)
setB(x, y, getB(x, y) * scalar)
setA(x, y, getA(x, y) * scalar)
}
fun destroy() = {}
}

View File

@@ -7,6 +7,7 @@ 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.gdx.graphics.TestCvecArr
import net.torvald.terrarum.*
import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.blockproperties.Block
@@ -23,10 +24,6 @@ import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.modulebasegame.IngameRenderer
import net.torvald.terrarum.modulebasegame.ui.abs
import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.worlddrawer.LightmapRenderer.convX
import net.torvald.terrarum.worlddrawer.LightmapRenderer.convY
import net.torvald.util.SortedArrayList
import kotlin.math.sign
import kotlin.system.exitProcess
/**
@@ -761,7 +758,7 @@ object LightmapRenderer {
fun precalculate(rawx: Int, rawy: Int) {
val lx = rawx.convX(); val ly = rawy.convY()
val (x, y) = world.coerceXY(rawx, rawy)
val (worldX, worldY) = world.coerceXY(rawx, rawy)
//printdbg(this, "precalculate ($rawx, $rawy) -> ($lx, $ly) | ($LIGHTMAP_WIDTH, $LIGHTMAP_HEIGHT)")
@@ -771,23 +768,23 @@ object LightmapRenderer {
}
_thisTerrain = world.getTileFromTerrainRaw(x, y)
_thisFluid = world.getFluid(x, y)
_thisWall = world.getTileFromWallRaw(x, y)
_thisTerrain = world.getTileFromTerrainRaw(worldX, worldY)
_thisFluid = world.getFluid(worldX, worldY)
_thisWall = world.getTileFromWallRaw(worldX, worldY)
// regarding the issue #26
// uncomment this and/or run JVM with -ea if you're facing diabolically indescribable bugs
try {
val fuck = BlockCodex[_thisTerrain].getLumCol(x, y)
val fuck = BlockCodex[_thisTerrain].getLumCol(worldX, worldY)
}
catch (e: NullPointerException) {
System.err.println("## NPE -- x: $x, y: $y, value: $_thisTerrain")
System.err.println("## NPE -- x: $worldX, y: $worldY, 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)
for (xx in worldX - 16 until worldX + 16) {
val raw = world.getTileFromTerrain(xx, worldY)
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)
@@ -803,14 +800,14 @@ object LightmapRenderer {
if (_thisFluid.type != Fluid.NULL) {
_fluidAmountToCol.set(_thisFluid.amount, _thisFluid.amount, _thisFluid.amount, _thisFluid.amount)
_thisTileLuminosity.set(BlockCodex[_thisTerrain].getLumCol(x, y))
_thisTileLuminosity.maxAndAssign(BlockCodex[_thisFluid.type].getLumCol(x, y).mul(_fluidAmountToCol)) // already been div by four
_thisTileLuminosity.set(BlockCodex[_thisTerrain].getLumCol(worldX, worldY))
_thisTileLuminosity.maxAndAssign(BlockCodex[_thisFluid.type].getLumCol(worldX, worldY).mul(_fluidAmountToCol)) // already been div by four
_mapThisTileOpacity.setVec(lx, ly, BlockCodex[_thisTerrain].opacity)
_mapThisTileOpacity.max(lx, ly, BlockCodex[_thisFluid.type].opacity.mul(_fluidAmountToCol))// already been div by four
}
else {
_thisTileLuminosity.set(BlockCodex[_thisTerrain].getLumCol(x, y))
_mapThisTileOpacity.setVec(x, y, BlockCodex[_thisTerrain].opacity)
_thisTileLuminosity.set(BlockCodex[_thisTerrain].getLumCol(worldX, worldY))
_mapThisTileOpacity.setVec(lx, ly, BlockCodex[_thisTerrain].opacity)
}
_mapThisTileOpacity2.setR(lx, ly, _mapThisTileOpacity.getR(lx, ly) * 1.41421356f)
@@ -827,7 +824,7 @@ object LightmapRenderer {
// blend lantern
_mapLightLevelThis.max(lx, ly, _thisTileLuminosity.maxAndAssign(
lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: colourNull
lanternMap[LandUtil.getBlockAddr(world, worldX, worldY)] ?: colourNull
))
}