mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-15 16:16:10 +09:00
some code pruning
This commit is contained in:
@@ -7,14 +7,11 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
|||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.gdx.graphics.Cvec
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.gdx.graphics.UnsafeCvecArray
|
import net.torvald.gdx.graphics.UnsafeCvecArray
|
||||||
import net.torvald.gdx.graphics.TestCvecArr
|
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.AppLoader.printdbg
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
import net.torvald.terrarum.blockproperties.Fluid
|
import net.torvald.terrarum.blockproperties.Fluid
|
||||||
import net.torvald.terrarum.concurrent.ThreadExecutor
|
|
||||||
import net.torvald.terrarum.concurrent.ThreadParallel
|
|
||||||
import net.torvald.terrarum.concurrent.sliceEvenly
|
import net.torvald.terrarum.concurrent.sliceEvenly
|
||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
@@ -54,16 +51,6 @@ object LightmapRenderer {
|
|||||||
if (this.world != world) {
|
if (this.world != world) {
|
||||||
printdbg(this, "World change detected -- old world: ${this.world.hashCode()}, new world: ${world.hashCode()}")
|
printdbg(this, "World change detected -- old world: ${this.world.hashCode()}, new world: ${world.hashCode()}")
|
||||||
|
|
||||||
/*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()
|
lightmap.zerofill()
|
||||||
_mapLightLevelThis.zerofill()
|
_mapLightLevelThis.zerofill()
|
||||||
_mapThisTileOpacity.zerofill()
|
_mapThisTileOpacity.zerofill()
|
||||||
@@ -85,31 +72,23 @@ object LightmapRenderer {
|
|||||||
const val overscan_open: Int = 40
|
const val overscan_open: Int = 40
|
||||||
const val overscan_opaque: Int = 10
|
const val overscan_opaque: Int = 10
|
||||||
|
|
||||||
|
|
||||||
// TODO resize(int, int) -aware
|
|
||||||
|
|
||||||
var LIGHTMAP_WIDTH = (Terrarum.ingame?.ZOOM_MINIMUM ?: 1f).inv().times(AppLoader.screenW).div(TILE_SIZE).ceil() + overscan_open * 2 + 3
|
var LIGHTMAP_WIDTH = (Terrarum.ingame?.ZOOM_MINIMUM ?: 1f).inv().times(AppLoader.screenW).div(TILE_SIZE).ceil() + overscan_open * 2 + 3
|
||||||
var LIGHTMAP_HEIGHT = (Terrarum.ingame?.ZOOM_MINIMUM ?: 1f).inv().times(AppLoader.screenH).div(TILE_SIZE).ceil() + overscan_open * 2 + 3
|
var LIGHTMAP_HEIGHT = (Terrarum.ingame?.ZOOM_MINIMUM ?: 1f).inv().times(AppLoader.screenH).div(TILE_SIZE).ceil() + overscan_open * 2 + 3
|
||||||
|
|
||||||
private val noopMask = HashSet<Point2i>((LIGHTMAP_WIDTH + LIGHTMAP_HEIGHT) * 2)
|
private val noopMask = HashSet<Point2i>((LIGHTMAP_WIDTH + LIGHTMAP_HEIGHT) * 2)
|
||||||
|
|
||||||
|
private val lanternMap = HashMap<BlockAddress, Cvec>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
|
||||||
/**
|
/**
|
||||||
* Float value, 1.0 for 1023
|
* Float value, 1.0 for 1023
|
||||||
|
*
|
||||||
|
* Note: using UnsafeCvecArray does not actually show great performance improvement
|
||||||
*/
|
*/
|
||||||
// it utilises alpha channel to determine brightness of "glow" sprites (so that alpha channel works like UV light)
|
// 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 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
private var lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
//private var lightmap: Array<Array<Cvec>> = 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<Cvec> = 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<BlockAddress, Cvec>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
|
|
||||||
private var _mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
private var _mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
//private var _mapFluidAmountToCol = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
|
||||||
//private var _mapThisTileLuminosity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
|
||||||
private var _mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
private var _mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
private var _mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
private var _mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
|
|
||||||
//private val lightsourceMap = ArrayList<Pair<BlockAddress, Cvec>>(256)
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
LightmapHDRMap.invoke()
|
LightmapHDRMap.invoke()
|
||||||
printdbg(this, "Overscan open: $overscan_open; opaque: $overscan_opaque")
|
printdbg(this, "Overscan open: $overscan_open; opaque: $overscan_opaque")
|
||||||
@@ -138,40 +117,6 @@ object LightmapRenderer {
|
|||||||
internal var for_draw_x_end = 0
|
internal var for_draw_x_end = 0
|
||||||
internal var for_draw_y_end = 0
|
internal var for_draw_y_end = 0
|
||||||
|
|
||||||
private val executor0 = LightCalculatorContext(world, lightmap, lanternMap)
|
|
||||||
private val executor1 = LightCalculatorContext(world, lightmap, lanternMap)
|
|
||||||
private val executor2 = LightCalculatorContext(world, lightmap, lanternMap)
|
|
||||||
private val executor3 = LightCalculatorContext(world, lightmap, lanternMap)
|
|
||||||
|
|
||||||
private val exec0 = {
|
|
||||||
for (y in for_y_start - overscan_open..for_y_end) {
|
|
||||||
for (x in for_x_start - overscan_open..for_x_end) {
|
|
||||||
executor0.calculateAndAssign(x, y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private val exec1 = {
|
|
||||||
for (y in for_y_end + overscan_open downTo for_y_start) {
|
|
||||||
for (x in for_x_start - overscan_open..for_x_end) {
|
|
||||||
executor1.calculateAndAssign(x, y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private val exec2 = {
|
|
||||||
for (y in for_y_end + overscan_open downTo for_y_start) {
|
|
||||||
for (x in for_x_end + overscan_open downTo for_x_start) {
|
|
||||||
executor2.calculateAndAssign(x, y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private val exec3 = {
|
|
||||||
for (y in for_y_start - overscan_open..for_y_end) {
|
|
||||||
for (x in for_x_end + overscan_open downTo for_x_start) {
|
|
||||||
executor3.calculateAndAssign(x, y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param x world coord
|
* @param x world coord
|
||||||
* @param y world coord
|
* @param y world coord
|
||||||
@@ -207,8 +152,6 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val cellsToUpdate = ArrayList<Long>()
|
|
||||||
|
|
||||||
internal fun fireRecalculateEvent(vararg actorContainers: List<ActorWithBody>?) {
|
internal fun fireRecalculateEvent(vararg actorContainers: List<ActorWithBody>?) {
|
||||||
try {
|
try {
|
||||||
world.getTileFromTerrain(0, 0) // test inquiry
|
world.getTileFromTerrain(0, 0) // test inquiry
|
||||||
@@ -270,43 +213,12 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
// wipe out lightmap
|
// wipe out lightmap
|
||||||
AppLoader.measureDebugTime("Renderer.Light0") {
|
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
|
|
||||||
// when disabled, light will "decay out" instead of "instantly out", which can have a cool effect
|
// 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
|
// but the performance boost is measly 0.1 ms on 6700K
|
||||||
lightmap.zerofill()
|
lightmap.zerofill()
|
||||||
_mapLightLevelThis.zerofill()
|
_mapLightLevelThis.zerofill()
|
||||||
//lightsourceMap.clear()
|
//lightsourceMap.clear()
|
||||||
|
|
||||||
|
|
||||||
// pre-seed the lightmap with known value
|
|
||||||
/*for (x in for_x_start - overscan_open..for_x_end + overscan_open) {
|
|
||||||
for (y in for_y_start - overscan_open..for_y_end + overscan_open) {
|
|
||||||
val tile = world.getTileFromTerrain(x, y)
|
|
||||||
val wall = world.getTileFromWall(x, y)
|
|
||||||
|
|
||||||
val lightlevel = if (!BlockCodex[tile].isSolid && !BlockCodex[wall].isSolid)
|
|
||||||
sunLight.cpy()
|
|
||||||
else
|
|
||||||
colourNull.cpy()
|
|
||||||
// are you a light source?
|
|
||||||
lightlevel.maxAndAssign(BlockCodex[tile].lumCol)
|
|
||||||
// there will be a way to slightly optimise this following line but hey, let's make everything working right first...
|
|
||||||
lightlevel.maxAndAssign(lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: colourNull)
|
|
||||||
|
|
||||||
if (lightlevel.nonZero()) {
|
|
||||||
// mark the tile as a light source
|
|
||||||
lightsourceMap.add(LandUtil.getBlockAddr(world, x, y) to lightlevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
//val lx = x.convX(); val ly = y.convY()
|
|
||||||
//lightmap.setR(lx, ly, lightlevel.r)
|
|
||||||
//lightmap.setG(lx, ly, lightlevel.g)
|
|
||||||
//lightmap.setB(lx, ly, lightlevel.b)
|
|
||||||
//lightmap.setA(lx, ly, lightlevel.a)
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
for (y in for_y_start - overscan_open..for_y_end + overscan_open) {
|
for (y in for_y_start - overscan_open..for_y_end + overscan_open) {
|
||||||
for (x in for_x_start - overscan_open..for_x_end + overscan_open) {
|
for (x in for_x_start - overscan_open..for_x_end + overscan_open) {
|
||||||
precalculate(x, y)
|
precalculate(x, y)
|
||||||
@@ -350,270 +262,29 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// each usually takes 8 000 000..12 000 000 miliseconds total when not threaded
|
// each usually takes 8..12 ms total when not threaded
|
||||||
|
// - with direct memory access of world array and pre-calculating things in the start of the frame,
|
||||||
|
// I was able to pull out 3.5..5.5 ms! With abhorrently many occurrences of segfaults I had to track down...
|
||||||
|
|
||||||
if (!AppLoader.getConfigBoolean("multithreadedlight")) {
|
if (!AppLoader.getConfigBoolean("multithreadedlight")) {
|
||||||
|
|
||||||
// The skipping is dependent on how you get ambient light,
|
|
||||||
// in this case we have 'spillage' due to the fact calculate() samples 3x3 area.
|
|
||||||
|
|
||||||
AppLoader.measureDebugTime("Renderer.LightTotal") {
|
AppLoader.measureDebugTime("Renderer.LightTotal") {
|
||||||
|
|
||||||
|
// To save you from pains:
|
||||||
|
// - Per-channel light updating is actually slower
|
||||||
|
// - It seems 5-pass lighting is needed to resonably eliminate the dark spot (of which I have zero idea
|
||||||
|
// why dark spots appear in the first place)
|
||||||
|
// - Multithreading? I have absolutely no idea.
|
||||||
|
// - If you naively slice the screen (job area) to multithread, the seam will appear.
|
||||||
|
|
||||||
r3();r4();r1();r2();r3();
|
r3();r4();r1();r2();r3();
|
||||||
|
|
||||||
/*ThreadExecutor.submit(exec0)
|
|
||||||
ThreadExecutor.submit(exec1)
|
|
||||||
ThreadExecutor.submit(exec2)
|
|
||||||
ThreadExecutor.submit(exec3)
|
|
||||||
ThreadExecutor.join()*/
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME right now parallel execution share single static variables
|
|
||||||
// multithread per channel: slower AND that cursed noisy output
|
|
||||||
/*for (channel in 0..3) {
|
|
||||||
ThreadExecutor.submit {
|
|
||||||
// Round 1
|
|
||||||
for (y in for_y_start - overscan_open..for_y_end) {
|
|
||||||
for (x in for_x_start - overscan_open..for_x_end) {
|
|
||||||
calculateAndAssignCh(lightmap, x, y, channel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Round 2
|
|
||||||
for (y in for_y_end + overscan_open downTo for_y_start) {
|
|
||||||
for (x in for_x_start - overscan_open..for_x_end) {
|
|
||||||
calculateAndAssignCh(lightmap, x, y, channel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Round 3
|
|
||||||
for (y in for_y_end + overscan_open downTo for_y_start) {
|
|
||||||
for (x in for_x_end + overscan_open downTo for_x_start) {
|
|
||||||
calculateAndAssignCh(lightmap, x, y, channel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Round 4
|
|
||||||
for (y in for_y_start - overscan_open..for_y_end) {
|
|
||||||
for (x in for_x_end + overscan_open downTo for_x_start) {
|
|
||||||
calculateAndAssignCh(lightmap, x, y, channel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ThreadExecutor.join()*/
|
|
||||||
|
|
||||||
|
|
||||||
// ANECDOTES
|
|
||||||
// * Radiate-from-light-source idea is doomed because skippable cells are completely random
|
|
||||||
// * Spread-every-cell idea might work as skippable cells are predictable, and they're related
|
|
||||||
// to the pos of lightsources
|
|
||||||
// * No-op masks cause some ambient ray to disappear when they're on the screen edge
|
|
||||||
// * Naive optimisation (mark-and-iterate) attempt was a disaster
|
|
||||||
|
|
||||||
//mark cells to update
|
|
||||||
// Round 1
|
|
||||||
/*cellsToUpdate.clear()
|
|
||||||
lightsourceMap.forEach { (addr, light) ->
|
|
||||||
val (wx, wy) = LandUtil.resolveBlockAddr(world, addr)
|
|
||||||
// mark cells to update
|
|
||||||
for (y in 0 until overscan_open) {
|
|
||||||
for (x in 0 until overscan_open - y) {
|
|
||||||
val lx = (wx + x).convX(); val ly = (wy + y).convY()
|
|
||||||
if (lx in 0 until LIGHTMAP_WIDTH && ly in 0 until LIGHTMAP_HEIGHT)
|
|
||||||
cellsToUpdate.add((ly.toLong() shl 32) or lx.toLong())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cellsToUpdate.forEach {
|
|
||||||
calculateAndAssign(lightmap, it.toInt(), (it shr 32).toInt())
|
|
||||||
}
|
|
||||||
// Round 2
|
|
||||||
cellsToUpdate.clear()
|
|
||||||
lightsourceMap.forEach { (addr, light) ->
|
|
||||||
val (wx, wy) = LandUtil.resolveBlockAddr(world, addr)
|
|
||||||
|
|
||||||
// mark cells to update
|
|
||||||
for (y in 0 downTo -overscan_open + 1) {
|
|
||||||
for (x in 0 until overscan_open + y) {
|
|
||||||
val lx = (wx + x).convX(); val ly = (wy + y).convY()
|
|
||||||
if (lx in 0 until LIGHTMAP_WIDTH && ly in 0 until LIGHTMAP_HEIGHT)
|
|
||||||
cellsToUpdate.add((ly.toLong() shl 32) or lx.toLong())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cellsToUpdate.forEach {
|
|
||||||
calculateAndAssign(lightmap, it.toInt(), (it shr 32).toInt())
|
|
||||||
}
|
|
||||||
// Round 3
|
|
||||||
cellsToUpdate.clear()
|
|
||||||
lightsourceMap.forEach { (addr, light) ->
|
|
||||||
val (wx, wy) = LandUtil.resolveBlockAddr(world, addr)
|
|
||||||
|
|
||||||
// mark cells to update
|
|
||||||
for (y in 0 downTo -overscan_open + 1) {
|
|
||||||
for (x in 0 downTo -overscan_open + 1 - y) {
|
|
||||||
val lx = (wx + x).convX(); val ly = (wy + y).convY()
|
|
||||||
if (lx in 0 until LIGHTMAP_WIDTH && ly in 0 until LIGHTMAP_HEIGHT)
|
|
||||||
cellsToUpdate.add((ly.toLong() shl 32) or lx.toLong())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cellsToUpdate.forEach {
|
|
||||||
calculateAndAssign(lightmap, it.toInt(), (it shr 32).toInt())
|
|
||||||
}
|
|
||||||
// Round 4
|
|
||||||
cellsToUpdate.clear()
|
|
||||||
lightsourceMap.forEach { (addr, light) ->
|
|
||||||
val (wx, wy) = LandUtil.resolveBlockAddr(world, addr)
|
|
||||||
|
|
||||||
// mark cells to update
|
|
||||||
for (y in 0 until overscan_open) {
|
|
||||||
for (x in 0 downTo -overscan_open + 1 + y) {
|
|
||||||
val lx = (wx + x).convX(); val ly = (wy + y).convY()
|
|
||||||
if (lx in 0 until LIGHTMAP_WIDTH && ly in 0 until LIGHTMAP_HEIGHT)
|
|
||||||
cellsToUpdate.add((ly.toLong() shl 32) or lx.toLong())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cellsToUpdate.forEach {
|
|
||||||
calculateAndAssign(lightmap, it.toInt(), (it shr 32).toInt())
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
// per-channel operation for bit more aggressive optimisation
|
|
||||||
/*for (lightsource in lightsourceMap) {
|
|
||||||
val (lsx, lsy) = LandUtil.resolveBlockAddr(world, lightsource.first)
|
|
||||||
|
|
||||||
// lightmap MUST BE PRE-SEEDED from known lightsources!
|
|
||||||
repeat(4) { rgbaOffset ->
|
|
||||||
for (genus in 1..6) { // use of overscan_open for loop limit is completely arbitrary
|
|
||||||
val rimSize = 1 + 2 * genus
|
|
||||||
|
|
||||||
var skip = true
|
|
||||||
// left side, counterclockwise
|
|
||||||
for (k in 0 until rimSize) {
|
|
||||||
val wx = lsx - genus; val wy = lsy - genus + k
|
|
||||||
skip = skip and radiate(rgbaOffset, wx, wy, lightsource.second,(lsx - wx)*(lsx - wx) + (lsy - wy)*(lsy - wy))
|
|
||||||
// whenever radiate() returns false (not-skip), skip is permanently fixated as false
|
|
||||||
}
|
|
||||||
// bottom side, counterclockwise
|
|
||||||
for (k in 1 until rimSize) {
|
|
||||||
val wx = lsx - genus + k; val wy = lsy + genus
|
|
||||||
skip = skip and radiate(rgbaOffset, wx, wy, lightsource.second,(lsx - wx)*(lsx - wx) + (lsy - wy)*(lsy - wy))
|
|
||||||
}
|
|
||||||
// right side, counterclockwise
|
|
||||||
for (k in 1 until rimSize) {
|
|
||||||
val wx = lsx + genus; val wy = lsy + genus - k
|
|
||||||
skip = skip and radiate(rgbaOffset, wx, wy, lightsource.second,(lsx - wx)*(lsx - wx) + (lsy - wy)*(lsy - wy))
|
|
||||||
}
|
|
||||||
// top side, counterclockwise
|
|
||||||
for (k in 1 until rimSize - 1) {
|
|
||||||
val wx = lsx + genus - k; val wy = lsy - genus
|
|
||||||
skip = skip and radiate(rgbaOffset, wx, wy, lightsource.second,(lsx - wx)*(lsx - wx) + (lsy - wy)*(lsy - wy))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skip) break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (world.worldIndex != -1) { // to avoid updating on the null world
|
else if (world.worldIndex != -1) { // to avoid updating on the null world
|
||||||
val roundsY = arrayOf(
|
AppLoader.measureDebugTime("Renderer.LightTotal") {
|
||||||
(for_y_end + overscan_open downTo for_y_start).sliceEvenly(ThreadParallel.threadCount),
|
|
||||||
(for_y_end + overscan_open downTo for_y_start).sliceEvenly(ThreadParallel.threadCount),
|
|
||||||
(for_y_start - overscan_open..for_y_end).sliceEvenly(ThreadParallel.threadCount),
|
|
||||||
(for_y_start - overscan_open..for_y_end).sliceEvenly(ThreadParallel.threadCount)
|
|
||||||
)
|
|
||||||
val roundsX = arrayOf(
|
|
||||||
(for_x_start - overscan_open..for_x_end),
|
|
||||||
(for_x_end + overscan_open downTo for_x_start),
|
|
||||||
(for_x_end + overscan_open downTo for_x_start),
|
|
||||||
(for_x_start - overscan_open..for_x_end)
|
|
||||||
)
|
|
||||||
|
|
||||||
AppLoader.measureDebugTime("Renderer.LightParallelPre") {
|
|
||||||
for (round in 0..roundsY.lastIndex) {
|
|
||||||
roundsY[round].forEachIndexed { index, yRange ->
|
|
||||||
ThreadParallel.map(index, "lightrender-round${round + 1}") {
|
|
||||||
for (y in yRange) {
|
|
||||||
for (x in roundsX[round]) {
|
|
||||||
calculateAndAssign(lightmap, x, y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AppLoader.measureDebugTime("Renderer.LightParallelRun") {
|
|
||||||
ThreadParallel.startAllWaitForDie()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the lightmap is already been seeded with lightsource.
|
|
||||||
*
|
|
||||||
* @return true if skip
|
|
||||||
*/
|
|
||||||
/*private fun radiate(channel: Int, wx: Int, wy: Int, lightsource: Cvec, distSqr: Int): Boolean {
|
|
||||||
val lx = wx.convX(); val ly = wy.convY()
|
|
||||||
|
|
||||||
if (lx !in 0 until LIGHTMAP_WIDTH || ly !in 0 until LIGHTMAP_HEIGHT)
|
|
||||||
return true
|
|
||||||
|
|
||||||
val currentLightLevel = lightmap.channelGet(lx, ly, channel)
|
|
||||||
val attenuate = BlockCodex[world.getTileFromTerrain(wx, wy)].getOpacity(channel)
|
|
||||||
|
|
||||||
var brightestNeighbour = lightmap.channelGet(lx, ly - 1, channel)
|
|
||||||
brightestNeighbour = maxOf(brightestNeighbour, lightmap.channelGet(lx, ly + 1, channel))
|
|
||||||
brightestNeighbour = maxOf(brightestNeighbour, lightmap.channelGet(lx - 1, ly, channel))
|
|
||||||
brightestNeighbour = maxOf(brightestNeighbour, lightmap.channelGet(lx + 1, ly, channel))
|
|
||||||
//brightestNeighbour = maxOf(brightestNeighbour, lightmap.channelGet(lx - 1, ly - 1, channel) * 0.70710678f)
|
|
||||||
//brightestNeighbour = maxOf(brightestNeighbour, lightmap.channelGet(lx - 1, ly + 1, channel) * 0.70710678f)
|
|
||||||
//brightestNeighbour = maxOf(brightestNeighbour, lightmap.channelGet(lx + 1, ly - 1, channel) * 0.70710678f)
|
|
||||||
//brightestNeighbour = maxOf(brightestNeighbour, lightmap.channelGet(lx + 1, ly + 1, channel) * 0.70710678f)
|
|
||||||
|
|
||||||
val newLight = brightestNeighbour * (1f - attenuate * lightScalingMagic)
|
|
||||||
|
|
||||||
if (newLight <= currentLightLevel || newLight < 0.125f) return true
|
|
||||||
|
|
||||||
lightmap.channelSet(lx, ly, channel, newLight)
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun radiate2(lightmap: UnsafeCvecArray, worldX: Int, worldY: Int, lightsource: Cvec): Boolean {
|
|
||||||
if (inNoopMask(worldX, worldY)) return false
|
|
||||||
|
|
||||||
// just quick snippets to make test work
|
|
||||||
lightLevelThis.set(colourNull)
|
|
||||||
thisTileOpacity.set(BlockCodex[world.getTileFromTerrain(worldX, worldY)].opacity)
|
|
||||||
|
|
||||||
val x = worldX.convX()
|
|
||||||
val y = worldY.convY()
|
|
||||||
|
|
||||||
/* + *///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))
|
|
||||||
|
|
||||||
lightmap.setR(x, y, lightLevelThis.r)
|
|
||||||
lightmap.setG(x, y, lightLevelThis.g)
|
|
||||||
lightmap.setB(x, y, lightLevelThis.b)
|
|
||||||
lightmap.setA(x, y, lightLevelThis.a)
|
|
||||||
|
|
||||||
return false
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
// TODO re-init at every resize
|
// TODO re-init at every resize
|
||||||
private lateinit var updateMessages: List<Array<ThreadedLightmapUpdateMessage>>
|
private lateinit var updateMessages: List<Array<ThreadedLightmapUpdateMessage>>
|
||||||
|
|
||||||
@@ -678,10 +349,6 @@ object LightmapRenderer {
|
|||||||
val normalisedCvec = it.color//.cpy().mul(DIV_FLOAT)
|
val normalisedCvec = it.color//.cpy().mul(DIV_FLOAT)
|
||||||
|
|
||||||
lanternMap[LandUtil.getBlockAddr(world, x, y)] = normalisedCvec
|
lanternMap[LandUtil.getBlockAddr(world, x, y)] = normalisedCvec
|
||||||
//lanternMap[Point2i(x, y)] = normalisedCvec
|
|
||||||
// Q&D fix for Roundworld anomaly
|
|
||||||
//lanternMap[Point2i(x + world.width, y)] = normalisedCvec
|
|
||||||
//lanternMap[Point2i(x - world.width, y)] = normalisedCvec
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -728,15 +395,6 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//private val ambientAccumulator = Cvec(0f,0f,0f,0f)
|
|
||||||
//private val lightLevelThis = Cvec(0)
|
|
||||||
//private val fluidAmountToCol = Cvec(0)
|
|
||||||
//private val thisTileLuminosity = Cvec(0)
|
|
||||||
//private val thisTileOpacity = Cvec(0)
|
|
||||||
//private val thisTileOpacity2 = Cvec(0) // thisTileOpacity * sqrt(2)
|
|
||||||
|
|
||||||
// local variables that are made static
|
// local variables that are made static
|
||||||
private val sunLight = Cvec(0)
|
private val sunLight = Cvec(0)
|
||||||
private var _thisTerrain = 0
|
private var _thisTerrain = 0
|
||||||
@@ -748,14 +406,6 @@ object LightmapRenderer {
|
|||||||
private val _fluidAmountToCol = Cvec(0)
|
private val _fluidAmountToCol = Cvec(0)
|
||||||
private val _thisTileLuminosity = Cvec(0)
|
private val _thisTileLuminosity = Cvec(0)
|
||||||
|
|
||||||
// per-channel variants
|
|
||||||
/*private var lightLevelThisCh = 0f
|
|
||||||
private var fluidAmountToColCh = 0f
|
|
||||||
private var thisTileLuminosityCh = 0f
|
|
||||||
private var thisTileOpacityCh = 0f
|
|
||||||
private var thisTileOpacity2Ch = 0f*/
|
|
||||||
|
|
||||||
|
|
||||||
fun precalculate(rawx: Int, rawy: Int) {
|
fun precalculate(rawx: Int, rawy: Int) {
|
||||||
val lx = rawx.convX(); val ly = rawy.convY()
|
val lx = rawx.convX(); val ly = rawy.convY()
|
||||||
val (worldX, worldY) = world.coerceXY(rawx, rawy)
|
val (worldX, worldY) = world.coerceXY(rawx, rawy)
|
||||||
@@ -775,7 +425,7 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
// regarding the issue #26
|
// regarding the issue #26
|
||||||
// uncomment this and/or run JVM with -ea if you're facing diabolically indescribable bugs
|
// uncomment this and/or run JVM with -ea if you're facing diabolically indescribable bugs
|
||||||
try {
|
/*try {
|
||||||
val fuck = BlockCodex[_thisTerrain].getLumCol(worldX, worldY)
|
val fuck = BlockCodex[_thisTerrain].getLumCol(worldX, worldY)
|
||||||
}
|
}
|
||||||
catch (e: NullPointerException) {
|
catch (e: NullPointerException) {
|
||||||
@@ -794,7 +444,7 @@ object LightmapRenderer {
|
|||||||
System.err.println("\nMINIMINIDUMP END")
|
System.err.println("\nMINIMINIDUMP END")
|
||||||
|
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
if (_thisFluid.type != Fluid.NULL) {
|
if (_thisFluid.type != Fluid.NULL) {
|
||||||
@@ -814,7 +464,6 @@ object LightmapRenderer {
|
|||||||
_mapThisTileOpacity2.setG(lx, ly, _mapThisTileOpacity.getG(lx, ly) * 1.41421356f)
|
_mapThisTileOpacity2.setG(lx, ly, _mapThisTileOpacity.getG(lx, ly) * 1.41421356f)
|
||||||
_mapThisTileOpacity2.setB(lx, ly, _mapThisTileOpacity.getB(lx, ly) * 1.41421356f)
|
_mapThisTileOpacity2.setB(lx, ly, _mapThisTileOpacity.getB(lx, ly) * 1.41421356f)
|
||||||
_mapThisTileOpacity2.setA(lx, ly, _mapThisTileOpacity.getA(lx, ly) * 1.41421356f)
|
_mapThisTileOpacity2.setA(lx, ly, _mapThisTileOpacity.getA(lx, ly) * 1.41421356f)
|
||||||
//sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT) // moved to fireRecalculateEvent()
|
|
||||||
|
|
||||||
|
|
||||||
// open air || luminous tile backed by sunlight
|
// open air || luminous tile backed by sunlight
|
||||||
@@ -828,134 +477,9 @@ object LightmapRenderer {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will alter following variables:
|
|
||||||
* - lightLevelThis
|
|
||||||
* - thisTerrain
|
|
||||||
* - thisFluid
|
|
||||||
* - thisWall
|
|
||||||
* - thisTileLuminosity
|
|
||||||
* - thisTileOpacity
|
|
||||||
* - thisTileOpacity2
|
|
||||||
* - sunlight
|
|
||||||
*/
|
|
||||||
/*private fun getLightsAndShades(x: Int, y: Int) {
|
|
||||||
val (x, y) = world.coerceXY(x, y)
|
|
||||||
|
|
||||||
lightLevelThis.set(colourNull)
|
|
||||||
_thisTerrain = world.getTileFromTerrainRaw(x, y)
|
|
||||||
_thisFluid = world.getFluid(x, y)
|
|
||||||
_thisWall = world.getTileFromWallRaw(x, y)
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
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")
|
|
||||||
|
|
||||||
exitProcess(1)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
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
|
|
||||||
thisTileOpacity.set(BlockCodex[_thisTerrain].opacity)
|
|
||||||
thisTileOpacity.maxAndAssign(BlockCodex[_thisFluid.type].opacity.mul(fluidAmountToCol)) // already been div by four
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
thisTileLuminosity.set(BlockCodex[_thisTerrain].getLumCol(x, y))
|
|
||||||
thisTileOpacity.set(BlockCodex[_thisTerrain].opacity)
|
|
||||||
}
|
|
||||||
|
|
||||||
thisTileOpacity2.set(thisTileOpacity); thisTileOpacity2.mul(1.41421356f)
|
|
||||||
//sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT) // moved to fireRecalculateEvent()
|
|
||||||
|
|
||||||
|
|
||||||
// open air || luminous tile backed by sunlight
|
|
||||||
if ((_thisTerrain == AIR && _thisWall == AIR) || (thisTileLuminosity.nonZero() && _thisWall == AIR)) {
|
|
||||||
lightLevelThis.set(sunLight)
|
|
||||||
}
|
|
||||||
|
|
||||||
// blend lantern
|
|
||||||
lightLevelThis.maxAndAssign(thisTileLuminosity).maxAndAssign(lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: colourNull)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*private fun getLightsAndShadesCh(x: Int, y: Int, channel: Int) {
|
|
||||||
lightLevelThisCh = 0f
|
|
||||||
thisTerrain = world.getTileFromTerrain(x, y) ?: Block.STONE
|
|
||||||
thisFluid = world.getFluid(x, y)
|
|
||||||
thisWall = world.getTileFromWall(x, y) ?: Block.STONE
|
|
||||||
|
|
||||||
// regarding the issue #26
|
|
||||||
try {
|
|
||||||
val fuck = BlockCodex[thisTerrain].getLumCol(x, y)
|
|
||||||
}
|
|
||||||
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")
|
|
||||||
|
|
||||||
exitProcess(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thisFluid.type != Fluid.NULL) {
|
|
||||||
fluidAmountToColCh = thisFluid.amount
|
|
||||||
|
|
||||||
thisTileLuminosityCh = BlockCodex[thisTerrain].getLumCol(x, y, channel)
|
|
||||||
thisTileLuminosityCh = maxOf(BlockCodex[thisFluid.type].getLumCol(x, y, channel) * fluidAmountToColCh, thisTileLuminosityCh) // already been div by four
|
|
||||||
thisTileOpacityCh = BlockCodex[thisTerrain].getOpacity(channel)
|
|
||||||
thisTileOpacityCh = maxOf(BlockCodex[thisFluid.type].getOpacity(channel) * fluidAmountToColCh, thisTileOpacityCh) // already been div by four
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
thisTileLuminosityCh = BlockCodex[thisTerrain].getLumCol(x, y, channel)
|
|
||||||
thisTileOpacityCh = BlockCodex[thisTerrain].getOpacity(channel)
|
|
||||||
}
|
|
||||||
|
|
||||||
thisTileOpacity2Ch = thisTileOpacityCh * 1.41421356f
|
|
||||||
//sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT) // moved to fireRecalculateEvent()
|
|
||||||
|
|
||||||
|
|
||||||
// open air || luminous tile backed by sunlight
|
|
||||||
if ((thisTerrain == AIR && thisWall == AIR) || (thisTileLuminosityCh > epsilon && thisWall == AIR)) {
|
|
||||||
lightLevelThisCh = sunLight.getElem(channel)
|
|
||||||
}
|
|
||||||
|
|
||||||
// blend lantern
|
|
||||||
lightLevelThisCh = maxOf(thisTileLuminosityCh, lightLevelThisCh)
|
|
||||||
lightLevelThisCh = maxOf(lanternMap[LandUtil.getBlockAddr(world, x, y)]?.getElem(channel) ?: 0f, lightLevelThisCh)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
private val inNoopMaskp = Point2i(0,0)
|
private val inNoopMaskp = Point2i(0,0)
|
||||||
|
|
||||||
private fun inNoopMask(x: Int, y: Int): Boolean {
|
private fun inNoopMask(x: Int, y: Int): Boolean {
|
||||||
|
|
||||||
// TODO: digitise your note of the idea of No-op Mask (date unknown, prob before 2017-03-17)
|
|
||||||
if (x in for_x_start..for_x_end) {
|
if (x in for_x_start..for_x_end) {
|
||||||
// if it's in the top flange
|
// if it's in the top flange
|
||||||
inNoopMaskp.set(x, for_y_start)
|
inNoopMaskp.set(x, for_y_start)
|
||||||
@@ -1049,48 +573,9 @@ object LightmapRenderer {
|
|||||||
/* * */_ambientAccumulator.maxAndAssign(darkenColoured(x - 1, y, _thisTileOpacity))
|
/* * */_ambientAccumulator.maxAndAssign(darkenColoured(x - 1, y, _thisTileOpacity))
|
||||||
/* * */_ambientAccumulator.maxAndAssign(darkenColoured(x + 1, y, _thisTileOpacity))
|
/* * */_ambientAccumulator.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())
|
|
||||||
|
|
||||||
lightmap.setVec(x, y, _ambientAccumulator)
|
lightmap.setVec(x, y, _ambientAccumulator)
|
||||||
}
|
}
|
||||||
|
|
||||||
// per-channel version is slower...
|
|
||||||
/*private fun calculateAndAssignCh(lightmap: UnsafeCvecArray, worldX: Int, worldY: Int, channel: Int) {
|
|
||||||
|
|
||||||
if (inNoopMask(worldX, worldY)) return
|
|
||||||
|
|
||||||
// O(9n) == O(n) where n is a size of the map
|
|
||||||
|
|
||||||
getLightsAndShadesCh(worldX, worldY, channel)
|
|
||||||
|
|
||||||
val x = worldX.convX()
|
|
||||||
val y = worldY.convY()
|
|
||||||
|
|
||||||
// calculate ambient
|
|
||||||
/* + * + 0 4 1
|
|
||||||
* * @ * 6 @ 7
|
|
||||||
* + * + 2 5 3
|
|
||||||
* sample ambient for eight points and apply attenuation for those
|
|
||||||
* maxblend eight values and use it
|
|
||||||
*/
|
|
||||||
|
|
||||||
// will "overwrite" what's there in the lightmap if it's the first pass
|
|
||||||
// takes about 2 ms on 6700K
|
|
||||||
/* + *///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))
|
|
||||||
|
|
||||||
lightLevelThisCh = maxOf(darken(x, y - 1, thisTileOpacityCh, channel), lightLevelThisCh)
|
|
||||||
lightLevelThisCh = maxOf(darken(x, y + 1, thisTileOpacityCh, channel), lightLevelThisCh)
|
|
||||||
lightLevelThisCh = maxOf(darken(x - 1, y, thisTileOpacityCh, channel), lightLevelThisCh)
|
|
||||||
lightLevelThisCh = maxOf(darken(x + 1, y, thisTileOpacityCh, channel), lightLevelThisCh)
|
|
||||||
|
|
||||||
lightmap.channelSet(x, y, channel, lightLevelThisCh)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
private fun isSolid(x: Int, y: Int): Float? { // ...so that they wouldn't appear too dark
|
private fun isSolid(x: Int, y: Int): Float? { // ...so that they wouldn't appear too dark
|
||||||
if (!inBounds(x, y)) return null
|
if (!inBounds(x, y)) return null
|
||||||
|
|
||||||
@@ -1177,8 +662,6 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
lightmap.destroy()
|
lightmap.destroy()
|
||||||
_mapLightLevelThis.destroy()
|
_mapLightLevelThis.destroy()
|
||||||
//_mapFluidAmountToCol.destroy()
|
|
||||||
//_mapThisTileLuminosity.destroy()
|
|
||||||
_mapThisTileOpacity.destroy()
|
_mapThisTileOpacity.destroy()
|
||||||
_mapThisTileOpacity2.destroy()
|
_mapThisTileOpacity2.destroy()
|
||||||
}
|
}
|
||||||
@@ -1197,12 +680,6 @@ object LightmapRenderer {
|
|||||||
// use equation with magic number 8.0
|
// 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)
|
// this function, when done recursively (A_x = darken(A_x-1, C)), draws exponential curve. (R^2 = 1)
|
||||||
|
|
||||||
/*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))*/
|
|
||||||
|
|
||||||
if (x !in 0 until LIGHTMAP_WIDTH || y !in 0 until LIGHTMAP_HEIGHT) return colourNull
|
if (x !in 0 until LIGHTMAP_WIDTH || y !in 0 until LIGHTMAP_HEIGHT) return colourNull
|
||||||
|
|
||||||
return Cvec(
|
return Cvec(
|
||||||
@@ -1214,11 +691,6 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun darken(x: Int, y: Int, darken: Float, channel: Int): Float {
|
|
||||||
if (x !in 0 until LIGHTMAP_WIDTH || y !in 0 until LIGHTMAP_HEIGHT) return 0f
|
|
||||||
return lightmap.channelGet(x, y, channel) * (1f - darken * lightScalingMagic)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** infix is removed to clarify the association direction */
|
/** infix is removed to clarify the association direction */
|
||||||
private fun Cvec.maxAndAssign(other: Cvec): Cvec {
|
private fun Cvec.maxAndAssign(other: Cvec): Cvec {
|
||||||
// TODO investigate: if I use assignment instead of set(), it blackens like the vector branch. --Torvald, 2019-06-07
|
// TODO investigate: if I use assignment instead of set(), it blackens like the vector branch. --Torvald, 2019-06-07
|
||||||
@@ -1283,14 +755,10 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
lightmap.destroy()
|
lightmap.destroy()
|
||||||
_mapLightLevelThis.destroy()
|
_mapLightLevelThis.destroy()
|
||||||
//_mapFluidAmountToCol.destroy()
|
|
||||||
//_mapThisTileLuminosity.destroy()
|
|
||||||
_mapThisTileOpacity.destroy()
|
_mapThisTileOpacity.destroy()
|
||||||
_mapThisTileOpacity2.destroy()
|
_mapThisTileOpacity2.destroy()
|
||||||
lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
_mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
_mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
//_mapFluidAmountToCol = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
|
||||||
//_mapThisTileLuminosity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
|
||||||
_mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
_mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
_mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
_mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user