trying bytebuf and FloatVector

This commit is contained in:
minjaesong
2023-01-18 20:26:50 +09:00
parent eefaa9ec7c
commit 2941a0943f
14 changed files with 250 additions and 148 deletions

View File

@@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Terrarum" type="JarApplication"> <configuration default="false" name="Terrarum" type="JarApplication">
<option name="JAR_PATH" value="$PROJECT_DIR$/out/TerrarumBuild.jar" /> <option name="JAR_PATH" value="$PROJECT_DIR$/out/TerrarumBuild.jar" />
<option name="VM_PARAMETERS" value="-ea -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd" /> <option name="VM_PARAMETERS" value="-ea -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd --add-modules jdk.incubator.vector" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" /> <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="17" /> <option name="ALTERNATIVE_JRE_PATH" value="17" />

View File

@@ -380,6 +380,8 @@ class Cvec {
fun toGdxColor() = Color(r, g, b, a) fun toGdxColor() = Color(r, g, b, a)
fun toFloatArray() = floatArrayOf(r, g, b, a)
/** Extract Hue-Saturation-Value. This is the inverse of [.fromHsv]. /** Extract Hue-Saturation-Value. This is the inverse of [.fromHsv].
* @param hsv The HSV array to be modified. * @param hsv The HSV array to be modified.
* @return HSV components for chaining. * @return HSV components for chaining.

View File

@@ -0,0 +1,67 @@
package net.torvald.gdx.graphics
import jdk.incubator.vector.FloatVector
import jdk.incubator.vector.FloatVector.SPECIES_128
import java.nio.ByteBuffer
import java.nio.ByteOrder
/**
* Created by minjaesong on 2023-01-18.
*/
class VectorArray(val width: Int, val height: Int) {
companion object {
val SPECIES = SPECIES_128
val BO = ByteOrder.nativeOrder()
val NULLVEC = FloatVector.broadcast(VectorArray.SPECIES, 0f)
}
val TOTAL_SIZE_IN_BYTES = 16 * (width + 1) * (height + 1)
private val array = ByteBuffer.allocateDirect(TOTAL_SIZE_IN_BYTES)
private inline fun toAddr(x: Int, y: Int) = 4 * (y * width + x)
init {
array.clear()
array.rewind()
}
private fun _getVec(a: Int) = FloatVector.fromByteBuffer(SPECIES, array, a, BO)
fun getVec(x: Int, y: Int): FloatVector {
val a = toAddr(x, y)
return FloatVector.fromByteBuffer(SPECIES, array, a, BO)
}
private fun _setVec(a: Int, value: FloatVector) {
value.intoByteBuffer(array, a, BO)
}
fun setVec(x: Int, y: Int, value: FloatVector) {
val a = toAddr(x, y)
value.intoByteBuffer(array, a, BO)
}
fun setScalar(x: Int, y: Int, value: Float) {
val a = toAddr(x, y)
array.putFloat(a + 0, value)
array.putFloat(a + 1, value)
array.putFloat(a + 2, value)
array.putFloat(a + 3, value)
}
fun max(x: Int, y: Int, other: FloatVector) {
val a = toAddr(x, y)
val mv = _getVec(a).max(other)
_setVec(a, mv)
}
fun mul(x: Int, y: Int, scalar: Float) {
val a = toAddr(x, y)
val mv = _getVec(a).max(scalar)
_setVec(a, mv)
}
}

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.blockproperties package net.torvald.terrarum.blockproperties
import net.torvald.gdx.graphics.Cvec import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.VectorArray
import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.ReferencingRanges.PREFIX_VIRTUALTILE import net.torvald.terrarum.ReferencingRanges.PREFIX_VIRTUALTILE
import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.ItemID
@@ -190,7 +191,7 @@ class BlockCodex {
prop.shadeColG = record.floatVal("shdg") prop.shadeColG = record.floatVal("shdg")
prop.shadeColB = record.floatVal("shdb") prop.shadeColB = record.floatVal("shdb")
prop.shadeColA = record.floatVal("shduv") prop.shadeColA = record.floatVal("shduv")
prop.opacity = Cvec(prop.shadeColR, prop.shadeColG, prop.shadeColB, prop.shadeColA)
prop.strength = record.intVal("str") prop.strength = record.intVal("str")
prop.density = record.intVal("dsty") prop.density = record.intVal("dsty")
@@ -199,7 +200,13 @@ class BlockCodex {
prop.baseLumColG = record.floatVal("lumg") prop.baseLumColG = record.floatVal("lumg")
prop.baseLumColB = record.floatVal("lumb") prop.baseLumColB = record.floatVal("lumb")
prop.baseLumColA = record.floatVal("lumuv") prop.baseLumColA = record.floatVal("lumuv")
prop.baseLumCol.set(prop.baseLumColR, prop.baseLumColG, prop.baseLumColB, prop.baseLumColA)
val cvec = floatArrayOf(
prop.shadeColR, prop.shadeColG, prop.shadeColB, prop.shadeColA,
prop.baseLumColR, prop.baseLumColG, prop.baseLumColB, prop.baseLumColA
)
prop.opacity = FloatVector.fromArray(VectorArray.SPECIES, cvec, 0)
prop.baseLumCol = FloatVector.fromArray(VectorArray.SPECIES, cvec, 4)
prop.friction = record.intVal("fr") prop.friction = record.intVal("fr")
prop.viscosity = record.intVal("vscs") prop.viscosity = record.intVal("vscs")

View File

@@ -1,6 +1,8 @@
package net.torvald.terrarum.blockproperties package net.torvald.terrarum.blockproperties
import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.Cvec import net.torvald.gdx.graphics.Cvec
import net.torvald.gdx.graphics.VectorArray.Companion.NULLVEC
import net.torvald.random.XXHash32 import net.torvald.random.XXHash32
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.ItemID
@@ -22,7 +24,7 @@ class BlockProp {
var shadeColB = 0f var shadeColB = 0f
var shadeColA = 0f var shadeColA = 0f
lateinit var opacity: Cvec lateinit var opacity: FloatVector
fun getOpacity(channel: Int) = when (channel) { fun getOpacity(channel: Int) = when (channel) {
0 -> shadeColR 0 -> shadeColR
@@ -54,12 +56,12 @@ class BlockProp {
internal var baseLumColG = 0f // base value used to calculate dynamic luminosity internal var baseLumColG = 0f // base value used to calculate dynamic luminosity
internal var baseLumColB = 0f // base value used to calculate dynamic luminosity internal var baseLumColB = 0f // base value used to calculate dynamic luminosity
internal var baseLumColA = 0f // base value used to calculate dynamic luminosity internal var baseLumColA = 0f // base value used to calculate dynamic luminosity
internal val baseLumCol = Cvec(0) internal var baseLumCol: FloatVector = NULLVEC
//var lumColR = 0f // memoised value of dynamic luminosity //var lumColR = 0f // memoised value of dynamic luminosity
//var lumColG = 0f // memoised value of dynamic luminosity //var lumColG = 0f // memoised value of dynamic luminosity
//var lumColB = 0f // memoised value of dynamic luminosity //var lumColB = 0f // memoised value of dynamic luminosity
//var lumColA = 0f // memoised value of dynamic luminosity //var lumColA = 0f // memoised value of dynamic luminosity
internal val _lumCol = Cvec(0) internal var _lumCol: FloatVector = NULLVEC
// X- and Y-value must be treated properly beforehand! (use GameWorld.coerceXY()) // X- and Y-value must be treated properly beforehand! (use GameWorld.coerceXY())
fun getLumCol(x: Int, y: Int) = if (dynamicLuminosityFunction == 0) { fun getLumCol(x: Int, y: Int) = if (dynamicLuminosityFunction == 0) {
baseLumCol baseLumCol

View File

@@ -2,7 +2,9 @@ package net.torvald.terrarum.blockproperties
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.jme3.math.FastMath import com.jme3.math.FastMath
import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.Cvec import net.torvald.gdx.graphics.Cvec
import net.torvald.gdx.graphics.VectorArray
import net.torvald.random.HQRNG import net.torvald.random.HQRNG
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.gameworld.WorldTime import net.torvald.terrarum.gameworld.WorldTime
@@ -33,17 +35,17 @@ object BlockPropUtil {
} }
private fun getTorchFlicker(prop: BlockProp): Cvec { private fun getTorchFlicker(prop: BlockProp): FloatVector {
val funcY = FastMath.interpolateLinear(prop.rngBase0 / flickerFuncDomain, prop.rngBase1, prop.rngBase2) val funcY = FastMath.interpolateLinear(prop.rngBase0 / flickerFuncDomain, prop.rngBase1, prop.rngBase2)
return alterBrightnessUniform(prop.baseLumCol, funcY) return alterBrightnessUniform(prop.baseLumCol, funcY)
} }
private fun getSlowBreath(prop: BlockProp): Cvec { private fun getSlowBreath(prop: BlockProp): FloatVector {
val funcY = FastMath.sin(FastMath.PI * prop.rngBase0 / breathCycleDuration) * breathRange val funcY = FastMath.sin(FastMath.PI * prop.rngBase0 / breathCycleDuration) * breathRange
return alterBrightnessUniform(prop.baseLumCol, funcY) return alterBrightnessUniform(prop.baseLumCol, funcY)
} }
private fun getPulsate(prop: BlockProp): Cvec { private fun getPulsate(prop: BlockProp): FloatVector {
val funcY = FastMath.sin(FastMath.PI * prop.rngBase0 / pulsateCycleDuration) * pulsateRange val funcY = FastMath.sin(FastMath.PI * prop.rngBase0 / pulsateCycleDuration) * pulsateRange
return alterBrightnessUniform(prop.baseLumCol, funcY) return alterBrightnessUniform(prop.baseLumCol, funcY)
} }
@@ -92,7 +94,7 @@ object BlockPropUtil {
prop.rngBase2 = getNewRandom() prop.rngBase2 = getNewRandom()
} }
prop._lumCol.set(getDynamicLumFunc(prop)) prop._lumCol = getDynamicLumFunc(prop)
//prop.lumColR = prop.lumCol.r //prop.lumColR = prop.lumCol.r
//prop.lumColG = prop.lumCol.g //prop.lumColG = prop.lumCol.g
//prop.lumColB = prop.lumCol.b //prop.lumColB = prop.lumCol.b
@@ -104,11 +106,11 @@ object BlockPropUtil {
private fun linearInterpolation1D(a: Float, b: Float, x: Float) = a * (1 - x) + b * x private fun linearInterpolation1D(a: Float, b: Float, x: Float) = a * (1 - x) + b * x
private fun getDynamicLumFunc(prop: BlockProp): Cvec { private fun getDynamicLumFunc(prop: BlockProp): FloatVector {
return when (prop.dynamicLuminosityFunction) { return when (prop.dynamicLuminosityFunction) {
1 -> getTorchFlicker(prop) 1 -> getTorchFlicker(prop)
2 -> (INGAME.world).globalLight.cpy() // current global light 2 -> FloatVector.fromArray(VectorArray.SPECIES, INGAME.world.globalLight.toFloatArray(), 0) // current global light
3 -> WeatherMixer.getGlobalLightOfTime(INGAME.world, WorldTime.DAY_LENGTH / 2).cpy() // daylight at noon 3 -> FloatVector.fromArray(VectorArray.SPECIES, WeatherMixer.getGlobalLightOfTime(INGAME.world, WorldTime.DAY_LENGTH / 2).toFloatArray(), 0) // daylight at noon
4 -> getSlowBreath(prop) 4 -> getSlowBreath(prop)
5 -> getPulsate(prop) 5 -> getPulsate(prop)
else -> prop.baseLumCol else -> prop.baseLumCol
@@ -136,12 +138,7 @@ object BlockPropUtil {
* @param brighten (-1.0 - 1.0) negative means darkening * @param brighten (-1.0 - 1.0) negative means darkening
* @return processed colour * @return processed colour
*/ */
private fun alterBrightnessUniform(data: Cvec, brighten: Float): Cvec { private fun alterBrightnessUniform(data: FloatVector, brighten: Float): FloatVector {
return Cvec( return data.add(brighten)
data.r + brighten,
data.g + brighten,
data.b + brighten,
data.a + brighten
)
} }
} }

View File

@@ -1,15 +1,16 @@
package net.torvald.terrarum.gameactors package net.torvald.terrarum.gameactors
import net.torvald.gdx.graphics.Cvec import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.VectorArray
/** /**
* Lightbox is defined based on pixelwise position in the world! * Lightbox is defined based on pixelwise position in the world!
*/ */
class Lightbox() { class Lightbox() {
var hitbox: Hitbox = Hitbox(0.0,0.0,0.0,0.0) var hitbox: Hitbox = Hitbox(0.0,0.0,0.0,0.0)
var light: Cvec = Cvec() var light: FloatVector = FloatVector.broadcast(VectorArray.SPECIES, 0f)
constructor(hitbox: Hitbox, light: Cvec) : this() { constructor(hitbox: Hitbox, light: FloatVector) : this() {
this.hitbox = hitbox this.hitbox = hitbox
this.light = light this.light = light
} }

View File

@@ -3,7 +3,10 @@ package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.jme3.math.FastMath import com.jme3.math.FastMath
import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.Cvec import net.torvald.gdx.graphics.Cvec
import net.torvald.gdx.graphics.VectorArray
import net.torvald.gdx.graphics.VectorArray.Companion.NULLVEC
import net.torvald.spriteanimation.AssembledSpriteAnimation import net.torvald.spriteanimation.AssembledSpriteAnimation
import net.torvald.spriteanimation.HasAssembledSprite import net.torvald.spriteanimation.HasAssembledSprite
import net.torvald.spriteanimation.SheetSpriteAnimation import net.torvald.spriteanimation.SheetSpriteAnimation
@@ -65,32 +68,32 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
if (houseDesignation != null) houseDesignation!!.clear() if (houseDesignation != null) houseDesignation!!.clear()
} }
var actorValueColour: Cvec var actorValueColour: FloatVector
get() = Cvec( get() = FloatVector.fromArray(VectorArray.SPECIES, floatArrayOf(
(actorValue.getAsFloat(AVKey.LUMR) ?: 0f), (actorValue.getAsFloat(AVKey.LUMR) ?: 0f),
(actorValue.getAsFloat(AVKey.LUMG) ?: 0f), (actorValue.getAsFloat(AVKey.LUMG) ?: 0f),
(actorValue.getAsFloat(AVKey.LUMB) ?: 0f), (actorValue.getAsFloat(AVKey.LUMB) ?: 0f),
(actorValue.getAsFloat(AVKey.LUMA) ?: 0f) (actorValue.getAsFloat(AVKey.LUMA) ?: 0f)
) ), 0)
set(value) { set(value) {
actorValue[AVKey.LUMR] = value.r actorValue[AVKey.LUMR] = value.lane(0)
actorValue[AVKey.LUMG] = value.g actorValue[AVKey.LUMG] = value.lane(1)
actorValue[AVKey.LUMB] = value.b actorValue[AVKey.LUMB] = value.lane(2)
actorValue[AVKey.LUMA] = value.a actorValue[AVKey.LUMA] = value.lane(3)
} }
var actorValueShade: Cvec var actorValueShade: FloatVector
get() = Cvec( get() = FloatVector.fromArray(VectorArray.SPECIES, floatArrayOf(
(actorValue.getAsFloat(AVKey.OPAR) ?: 0f), (actorValue.getAsFloat(AVKey.OPAR) ?: 0f),
(actorValue.getAsFloat(AVKey.OPAG) ?: 0f), (actorValue.getAsFloat(AVKey.OPAG) ?: 0f),
(actorValue.getAsFloat(AVKey.OPAB) ?: 0f), (actorValue.getAsFloat(AVKey.OPAB) ?: 0f),
(actorValue.getAsFloat(AVKey.OPAA) ?: 0f) (actorValue.getAsFloat(AVKey.OPAA) ?: 0f)
) ), 0)
set(value) { set(value) {
actorValue[AVKey.OPAR] = value.r actorValue[AVKey.OPAR] = value.lane(0)
actorValue[AVKey.OPAG] = value.g actorValue[AVKey.OPAG] = value.lane(1)
actorValue[AVKey.OPAB] = value.b actorValue[AVKey.OPAB] = value.lane(2)
actorValue[AVKey.OPAA] = value.a actorValue[AVKey.OPAA] = value.lane(3)
} }
/** /**
@@ -99,9 +102,9 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
* Hitbox(x-offset, y-offset, width, height) * Hitbox(x-offset, y-offset, width, height)
* (Use ArrayList for normal circumstances) * (Use ArrayList for normal circumstances)
*/ */
@Transient override var lightBoxList: List<Lightbox> = listOf(Lightbox(Hitbox(2.0, 2.0, baseHitboxW - 3.0, baseHitboxH - 3.0), Cvec(0))) @Transient override var lightBoxList: List<Lightbox> = listOf(Lightbox(Hitbox(2.0, 2.0, baseHitboxW - 3.0, baseHitboxH - 3.0), NULLVEC))
// the actual values are update on the update() // the actual values are update on the update()
@Transient override var shadeBoxList: List<Lightbox> = listOf(Lightbox(Hitbox(2.0, 2.0, baseHitboxW - 3.0, baseHitboxH - 3.0), Cvec(0))) @Transient override var shadeBoxList: List<Lightbox> = listOf(Lightbox(Hitbox(2.0, 2.0, baseHitboxW - 3.0, baseHitboxH - 3.0), NULLVEC))
// the actual values are update on the update() // the actual values are update on the update()
@Transient val BASE_DENSITY = 980.0 @Transient val BASE_DENSITY = 980.0

View File

@@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.graphics.g2d.TextureRegion
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.VectorArray.Companion.NULLVEC
import net.torvald.terrarum.BlockCodex import net.torvald.terrarum.BlockCodex
import net.torvald.terrarum.INGAME import net.torvald.terrarum.INGAME
import net.torvald.terrarum.ItemCodex import net.torvald.terrarum.ItemCodex
@@ -39,9 +40,9 @@ open class DroppedItem : ActorWithBody {
private val randKey1 = (Math.random() * 256).toInt() private val randKey1 = (Math.random() * 256).toInt()
private val randKey2 = (Math.random() * 256).toInt() private val randKey2 = (Math.random() * 256).toInt()
override var lightBoxList = listOf(Lightbox(this.hitbox.clone().setPosition(0.0, 0.0), Cvec(0))) override var lightBoxList = listOf(Lightbox(this.hitbox.clone().setPosition(0.0, 0.0), NULLVEC))
// the Cvec will be calculated dynamically on Update // the Cvec will be calculated dynamically on Update
override var shadeBoxList = listOf(Lightbox(this.hitbox.clone().setPosition(0.0, 0.0), Cvec(0))) override var shadeBoxList = listOf(Lightbox(this.hitbox.clone().setPosition(0.0, 0.0), NULLVEC))
// the Cvec will be calculated dynamically on Update // the Cvec will be calculated dynamically on Update
/** /**

View File

@@ -1,7 +1,10 @@
package net.torvald.terrarum.modulebasegame.gameactors package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.Cvec import net.torvald.gdx.graphics.Cvec
import net.torvald.gdx.graphics.VectorArray
import net.torvald.gdx.graphics.VectorArray.Companion.NULLVEC
import net.torvald.spriteanimation.SheetSpriteAnimation import net.torvald.spriteanimation.SheetSpriteAnimation
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.App.printdbg
@@ -26,7 +29,7 @@ open class FixtureSwingingDoorBase : FixtureBase {
var tw = 2 // tilewise width of the door when opened var tw = 2 // tilewise width of the door when opened
var twClosed = 1 // tilewise width of the door when closed var twClosed = 1 // tilewise width of the door when closed
var th = 3 // tilewise height of the door var th = 3 // tilewise height of the door
var opacity = BlockCodex[Block.STONE].opacity var opacity = BlockCodex[Block.STONE].opacity.toCvec()
var isOpacityActuallyLuminosity = false var isOpacityActuallyLuminosity = false
var moduleName = "basegame" var moduleName = "basegame"
var texturePath = "sprites/fixtures/door_test.tga" var texturePath = "sprites/fixtures/door_test.tga"
@@ -43,9 +46,9 @@ open class FixtureSwingingDoorBase : FixtureBase {
private var pixelwiseHitboxHeight = TILE_SIZE * tilewiseHitboxHeight private var pixelwiseHitboxHeight = TILE_SIZE * tilewiseHitboxHeight
private var tilewiseDistToAxis = tw - twClosed private var tilewiseDistToAxis = tw - twClosed
@Transient override var lightBoxList = listOf(Lightbox(Hitbox(TILE_SIZED * tilewiseDistToAxis, 0.0, TILE_SIZED * twClosed, TILE_SIZED * th), Cvec(0))) @Transient override var lightBoxList = listOf(Lightbox(Hitbox(TILE_SIZED * tilewiseDistToAxis, 0.0, TILE_SIZED * twClosed, TILE_SIZED * th), NULLVEC))
// the Cvec will be calculated dynamically on Update // the Cvec will be calculated dynamically on Update
@Transient override var shadeBoxList = listOf(Lightbox(Hitbox(TILE_SIZED * tilewiseDistToAxis, 0.0, TILE_SIZED * twClosed, TILE_SIZED * th), Cvec(0))) @Transient override var shadeBoxList = listOf(Lightbox(Hitbox(TILE_SIZED * tilewiseDistToAxis, 0.0, TILE_SIZED * twClosed, TILE_SIZED * th), NULLVEC))
// the Cvec will be calculated dynamically on Update // the Cvec will be calculated dynamically on Update
protected var doorState = 0 // -1: open toward left, 0: closed, 1: open toward right protected var doorState = 0 // -1: open toward left, 0: closed, 1: open toward right
@@ -54,6 +57,9 @@ open class FixtureSwingingDoorBase : FixtureBase {
@Transient private lateinit var customNameFun: () -> String @Transient private lateinit var customNameFun: () -> String
@Transient private lateinit var doorHoldLength: HashMap<Int, Second> @Transient private lateinit var doorHoldLength: HashMap<Int, Second>
private fun FloatVector.toCvec() = Cvec(this.lane(0), this.lane(1), this.lane(2), this.lane(3))
constructor() : super( constructor() : super(
BlockBox(BlockBox.FULL_COLLISION, 1, 1), // temporary value, will be overwritten by spawn() BlockBox(BlockBox.FULL_COLLISION, 1, 1), // temporary value, will be overwritten by spawn()
nameFun = { "item not loaded properly, alas!" } nameFun = { "item not loaded properly, alas!" }
@@ -62,7 +68,7 @@ open class FixtureSwingingDoorBase : FixtureBase {
2, 2,
1, 1,
3, 3,
BlockCodex[Block.STONE].opacity, BlockCodex[Block.STONE].opacity.toCvec(),
false, false,
"basegame", "basegame",
"sprites/fixtures/door_test.tga", "sprites/fixtures/door_test.tga",
@@ -73,18 +79,18 @@ open class FixtureSwingingDoorBase : FixtureBase {
} }
protected fun _construct( protected fun _construct(
tw: Int, // tilewise width of the door when opened tw: Int, // tilewise width of the door when opened
twClosed: Int, // tilewise width of the door when closed twClosed: Int, // tilewise width of the door when closed
th: Int, // tilewise height of the door th: Int, // tilewise height of the door
opacity: Cvec, opacity: Cvec,
isOpacityActuallyLuminosity: Boolean, isOpacityActuallyLuminosity: Boolean,
moduleName: String, moduleName: String,
texturePath: String, texturePath: String,
textureIdentifier: String, textureIdentifier: String,
nameKey: String, nameKey: String,
nameKeyReadFromLang: Boolean, nameKeyReadFromLang: Boolean,
doorCloseHoldLength: Second = 0.1f, doorCloseHoldLength: Second = 0.1f,
doorOpenedHoldLength: Second = 0.25f doorOpenedHoldLength: Second = 0.25f
) { ) {
this.tw = tw this.tw = tw
this.twClosed = twClosed this.twClosed = twClosed
@@ -123,7 +129,7 @@ open class FixtureSwingingDoorBase : FixtureBase {
// define light/shadebox // define light/shadebox
// TODO: redefine when opened to left/right // TODO: redefine when opened to left/right
(if (isOpacityActuallyLuminosity) lightBoxList else shadeBoxList)[0].light = opacity (if (isOpacityActuallyLuminosity) lightBoxList else shadeBoxList)[0].light = FloatVector.fromArray(VectorArray.SPECIES, opacity.toFloatArray(), 0)
// define physical size // define physical size
setHitboxDimension(TILE_SIZE * tilewiseHitboxWidth, TILE_SIZE * tilewiseHitboxHeight, 0, 0) setHitboxDimension(TILE_SIZE * tilewiseHitboxWidth, TILE_SIZE * tilewiseHitboxHeight, 0, 0)
@@ -147,16 +153,16 @@ open class FixtureSwingingDoorBase : FixtureBase {
// define light/shadebox // define light/shadebox
// TODO: redefine when opened to left/right // TODO: redefine when opened to left/right
(if (isOpacityActuallyLuminosity) lightBoxList else shadeBoxList)[0].light = opacity (if (isOpacityActuallyLuminosity) lightBoxList else shadeBoxList)[0].light = FloatVector.fromArray(VectorArray.SPECIES, opacity.toFloatArray(), 0)
} }
private fun setOpacity() { private fun setOpacity() {
shadeBoxList[0].light = opacity shadeBoxList[0].light = FloatVector.fromArray(VectorArray.SPECIES, opacity.toFloatArray(), 0)
} }
private fun unsetOpacity() { private fun unsetOpacity() {
shadeBoxList[0].light = Cvec(0) shadeBoxList[0].light = NULLVEC
} }
open protected fun closeDoor(doorHandler: Int) { open protected fun closeDoor(doorHandler: Int) {

View File

@@ -1,18 +1,22 @@
package net.torvald.terrarum.modulebasegame.gameactors package net.torvald.terrarum.modulebasegame.gameactors
import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.Cvec
import net.torvald.terrarum.BlockCodex import net.torvald.terrarum.BlockCodex
import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.Block
/** /**
* Created by minjaesong on 2022-07-28. * Created by minjaesong on 2022-07-28.
*/ */
private fun FloatVector.toCvec() = Cvec(this.lane(0), this.lane(1), this.lane(2), this.lane(3))
class FixtureSwingingDoorOak : FixtureSwingingDoorBase { class FixtureSwingingDoorOak : FixtureSwingingDoorBase {
constructor() : super() { constructor() : super() {
_construct( _construct(
2, 2,
1, 1,
3, 3,
BlockCodex[Block.STONE].opacity, BlockCodex[Block.STONE].opacity.toCvec(),
false, false,
"basegame", "basegame",
"sprites/fixtures/door_basegame-48.tga", "sprites/fixtures/door_basegame-48.tga",
@@ -29,7 +33,7 @@ class FixtureSwingingDoorEbony : FixtureSwingingDoorBase {
2, 2,
1, 1,
3, 3,
BlockCodex[Block.STONE].opacity, BlockCodex[Block.STONE].opacity.toCvec(),
false, false,
"basegame", "basegame",
"sprites/fixtures/door_basegame-49.tga", "sprites/fixtures/door_basegame-49.tga",
@@ -46,7 +50,7 @@ class FixtureSwingingDoorBirch : FixtureSwingingDoorBase {
2, 2,
1, 1,
3, 3,
BlockCodex[Block.STONE].opacity, BlockCodex[Block.STONE].opacity.toCvec(),
false, false,
"basegame", "basegame",
"sprites/fixtures/door_basegame-50.tga", "sprites/fixtures/door_basegame-50.tga",
@@ -63,7 +67,7 @@ class FixtureSwingingDoorRosewood : FixtureSwingingDoorBase {
2, 2,
1, 1,
3, 3,
BlockCodex[Block.STONE].opacity, BlockCodex[Block.STONE].opacity.toCvec(),
false, false,
"basegame", "basegame",
"sprites/fixtures/door_basegame-51.tga", "sprites/fixtures/door_basegame-51.tga",

View File

@@ -2,7 +2,9 @@ package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.Cvec import net.torvald.gdx.graphics.Cvec
import net.torvald.gdx.graphics.VectorArray
import net.torvald.terrarum.BlockCodex import net.torvald.terrarum.BlockCodex
import net.torvald.terrarum.INGAME import net.torvald.terrarum.INGAME
import net.torvald.terrarum.Point2d import net.torvald.terrarum.Point2d
@@ -29,8 +31,8 @@ open class ProjectileSimple : ActorWithBody, Projectile {
var speed: Int = 0 var speed: Int = 0
private var color: Cvec private var color: FloatVector
get() = (bulletDatabase[type][OFFSET_LUMINOSITY] as Cvec).cpy() get() = bulletDatabase[type][OFFSET_LUMINOSITY] as FloatVector
set(value) { set(value) {
} }
/** /**
@@ -115,7 +117,9 @@ open class ProjectileSimple : ActorWithBody, Projectile {
override fun drawGlow(batch: SpriteBatch) = drawBody(batch) override fun drawGlow(batch: SpriteBatch) = drawBody(batch)
companion object { companion object {
private fun Int.toFloatVector() = FloatVector.fromArray(VectorArray.SPECIES, Cvec(this).toFloatArray(), 0)
val OFFSET_DAMAGE = 0 val OFFSET_DAMAGE = 0
val OFFSET_COL = 1 // Color or SpriteAnimation val OFFSET_COL = 1 // Color or SpriteAnimation
val OFFSET_NOGRAVITY = 2 val OFFSET_NOGRAVITY = 2
@@ -123,8 +127,8 @@ open class ProjectileSimple : ActorWithBody, Projectile {
val OFFSET_LUMINOSITY = 4 val OFFSET_LUMINOSITY = 4
val bulletDatabase = arrayOf( val bulletDatabase = arrayOf(
// damage, display colour, no gravity, speed // damage, display colour, no gravity, speed
arrayOf(7, Cvec(0xFF5429_FF.toInt()), true, 40, 32), arrayOf(7, 0xFF5429_FF.toInt().toFloatVector(), true, 40, 32),
arrayOf(8, Cvec(0xFF5429_FF.toInt()), true, 20, 0) arrayOf(8, 0xFF5429_FF.toInt().toFloatVector(), true, 20, 0)
// ... // ...
) )
} }

View File

@@ -196,10 +196,10 @@ class BasicDebugInfoWindow : UICanvas() {
try { try {
world?.let { world?.let {
val valRaw = LightmapRenderer.getLight(mouseTileX, mouseTileY) val valRaw = LightmapRenderer.getLight(mouseTileX, mouseTileY)
val rawR = valRaw?.r?.toDouble().toIntAndFrac(1,3) val rawR = valRaw?.lane(0)?.toDouble().toIntAndFrac(1,3)
val rawG = valRaw?.g?.toDouble().toIntAndFrac(1,3) val rawG = valRaw?.lane(1)?.toDouble().toIntAndFrac(1,3)
val rawB = valRaw?.b?.toDouble().toIntAndFrac(1,3) val rawB = valRaw?.lane(2)?.toDouble().toIntAndFrac(1,3)
val rawA = valRaw?.a?.toDouble().toIntAndFrac(1,3) val rawA = valRaw?.lane(3)?.toDouble().toIntAndFrac(1,3)
val wallNum = it.getTileFromWall(mouseTileX, mouseTileY) val wallNum = it.getTileFromWall(mouseTileX, mouseTileY)
val tileNum = it.getTileFromTerrain(mouseTileX, mouseTileY) val tileNum = it.getTileFromTerrain(mouseTileX, mouseTileY)

View File

@@ -4,8 +4,10 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.Texture
import com.jme3.math.FastMath import com.jme3.math.FastMath
import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.VectorArray
import net.torvald.gdx.graphics.Cvec import net.torvald.gdx.graphics.Cvec
import net.torvald.gdx.graphics.UnsafeCvecArray import net.torvald.gdx.graphics.VectorArray.Companion.NULLVEC
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
@@ -48,10 +50,10 @@ 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()}")
lightmap.zerofill() // lightmap.zerofill()
_mapLightLevelThis.zerofill() // _mapLightLevelThis.zerofill()
_mapThisTileOpacity.zerofill() // _mapThisTileOpacity.zerofill()
_mapThisTileOpacity2.zerofill() // _mapThisTileOpacity2.zerofill()
} }
} }
catch (e: UninitializedPropertyAccessException) { catch (e: UninitializedPropertyAccessException) {
@@ -71,8 +73,8 @@ object LightmapRenderer {
//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) private val lanternMap = HashMap<BlockAddress, FloatVector>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
private val shadowMap = HashMap<BlockAddress, Cvec>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4) private val shadowMap = HashMap<BlockAddress, FloatVector>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
// private val giMap = HashMap<BlockAddress, Cvec>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4) // private val giMap = HashMap<BlockAddress, Cvec>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
/** /**
* Float value, 1.0 for 1023 * Float value, 1.0 for 1023
@@ -80,10 +82,10 @@ object LightmapRenderer {
* Note: using UnsafeCvecArray does not actually show great performance improvement * 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)
private var lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT) private var lightmap = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT) private var _mapLightLevelThis = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT) private var _mapThisTileOpacity = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT) private var _mapThisTileOpacity2 = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private const val AIR = Block.AIR private const val AIR = Block.AIR
@@ -118,7 +120,7 @@ object LightmapRenderer {
* @param x world tile coord * @param x world tile coord
* @param y world tile coord * @param y world tile coord
*/ */
internal fun getLight(x: Int, y: Int): Cvec? { internal fun getLight(x: Int, y: Int): FloatVector? {
val x = if (for_x_start - overscan_open + LIGHTMAP_WIDTH >= world.width && x - for_x_start + overscan_open < 0) val x = if (for_x_start - overscan_open + LIGHTMAP_WIDTH >= world.width && x - for_x_start + overscan_open < 0)
x + world.width x + world.width
else if (for_x_start - overscan_open + LIGHTMAP_WIDTH < 0 && x - for_x_start + overscan_open >= world.width) else if (for_x_start - overscan_open + LIGHTMAP_WIDTH < 0 && x - for_x_start + overscan_open >= world.width)
@@ -139,7 +141,7 @@ object LightmapRenderer {
fun recalculate(actorContainer: List<ActorWithBody>) = _recalculate(actorContainer, lightmap) fun recalculate(actorContainer: List<ActorWithBody>) = _recalculate(actorContainer, lightmap)
private fun _recalculate(actorContainer: List<ActorWithBody>, lightmap: UnsafeCvecArray) { private fun _recalculate(actorContainer: List<ActorWithBody>, lightmap: VectorArray) {
try { try {
world.getTileFromTerrain(0, 0) // test inquiry world.getTileFromTerrain(0, 0) // test inquiry
} }
@@ -179,7 +181,8 @@ object LightmapRenderer {
} // usually takes 3000 ns } // usually takes 3000 ns
// copy current world's globalLight into this // copy current world's globalLight into this
sunLight.set(world.globalLight) val cvec = world.globalLight.toFloatArray()
sunLight = FloatVector.fromArray(VectorArray.SPECIES, cvec, 0)
// set no-op mask from solidity of the block // set no-op mask from solidity of the block
/*AppLoader.measureDebugTime("Renderer.LightNoOpMask") { /*AppLoader.measureDebugTime("Renderer.LightNoOpMask") {
@@ -204,7 +207,7 @@ object LightmapRenderer {
// 'NEWLIGHT2' LIGHT SWIPER // 'NEWLIGHT2' LIGHT SWIPER
// O((8*2)n) where n is a size of the map. // O((8*2)n) where n is a size of the map.
/* - */fun r1(lightmap: UnsafeCvecArray) { /* - */fun r1(lightmap: VectorArray) {
swipeDiag = false swipeDiag = false
for (line in 1 until LIGHTMAP_HEIGHT - 1) { for (line in 1 until LIGHTMAP_HEIGHT - 1) {
swipeLight( swipeLight(
@@ -215,7 +218,7 @@ object LightmapRenderer {
) )
} }
} }
/* | */fun r2(lightmap: UnsafeCvecArray) { /* | */fun r2(lightmap: VectorArray) {
swipeDiag = false swipeDiag = false
for (line in 1 until LIGHTMAP_WIDTH - 1) { for (line in 1 until LIGHTMAP_WIDTH - 1) {
swipeLight( swipeLight(
@@ -226,7 +229,7 @@ object LightmapRenderer {
) )
} }
} }
/* \ */fun r3(lightmap: UnsafeCvecArray) { /* \ */fun r3(lightmap: VectorArray) {
swipeDiag = true swipeDiag = true
/* construct indices such that: /* construct indices such that:
56789ABC 56789ABC
@@ -264,7 +267,7 @@ object LightmapRenderer {
) )
} }
} }
/* / */fun r4(lightmap: UnsafeCvecArray) { /* / */fun r4(lightmap: VectorArray) {
swipeDiag = true swipeDiag = true
/* /*
1 w-2 1 w-2
@@ -360,10 +363,10 @@ object LightmapRenderer {
for (x in lightBoxX.div(TILE_SIZE).floorInt() for (x in lightBoxX.div(TILE_SIZE).floorInt()
..lightBoxX.plus(lightBoxW).div(TILE_SIZE).floorInt()) { ..lightBoxX.plus(lightBoxW).div(TILE_SIZE).floorInt()) {
val oldLight = lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: Cvec(0) // if two or more luminous actors share the same block, mix the light val oldLight = lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: NULLVEC // if two or more luminous actors share the same block, mix the light
val actorLight = colour val actorLight = colour
lanternMap[LandUtil.getBlockAddr(world, x, y)] = oldLight.maxAndAssign(actorLight) lanternMap[LandUtil.getBlockAddr(world, x, y)] = oldLight.max(actorLight)
} }
} }
} }
@@ -379,10 +382,10 @@ object LightmapRenderer {
for (x in lightBoxX.div(TILE_SIZE).floorInt() for (x in lightBoxX.div(TILE_SIZE).floorInt()
..lightBoxX.plus(lightBoxW).div(TILE_SIZE).floorInt()) { ..lightBoxX.plus(lightBoxW).div(TILE_SIZE).floorInt()) {
val oldLight = shadowMap[LandUtil.getBlockAddr(world, x, y)] ?: Cvec(0) // if two or more luminous actors share the same block, mix the light val oldLight = shadowMap[LandUtil.getBlockAddr(world, x, y)] ?: NULLVEC // if two or more luminous actors share the same block, mix the light
val actorLight = colour val actorLight = colour
shadowMap[LandUtil.getBlockAddr(world, x, y)] = oldLight.maxAndAssign(actorLight) shadowMap[LandUtil.getBlockAddr(world, x, y)] = oldLight.max(actorLight)
} }
} }
} }
@@ -427,16 +430,16 @@ object LightmapRenderer {
}*/ }*/
// local variables that are made static // local variables that are made static
private val sunLight = Cvec(0) private var sunLight = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private var _thisTerrain = 0 private var _thisTerrain = 0
private var _thisFluid = GameWorld.FluidInfo(Fluid.NULL, 0f) private var _thisFluid = GameWorld.FluidInfo(Fluid.NULL, 0f)
private var _thisWall = 0 private var _thisWall = 0
private val _ambientAccumulator = Cvec(0) private var _ambientAccumulator = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private val _reflectanceAccumulator = Cvec(0) private var _reflectanceAccumulator = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private val _thisTileOpacity = Cvec(0) private var _thisTileOpacity = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private val _thisTileOpacity2 = Cvec(0) // thisTileOpacity * sqrt(2) private var _thisTileOpacity2 = FloatVector.broadcast(VectorArray.SPECIES, 0f) // thisTileOpacity * sqrt(2)
private val _fluidAmountToCol = Cvec(0) private var _fluidAmountToCol = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private val _thisTileLuminosity = Cvec(0) private var _thisTileLuminosity = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private var _thisTerrainProp: BlockProp = BlockProp() private var _thisTerrainProp: BlockProp = BlockProp()
private var _thisWallProp: BlockProp = BlockProp() private var _thisWallProp: BlockProp = BlockProp()
private var _thisFluidProp: BlockProp = BlockProp() private var _thisFluidProp: BlockProp = BlockProp()
@@ -485,24 +488,24 @@ object LightmapRenderer {
}*/ }*/
if (_thisFluid.type != Fluid.NULL) { if (_thisFluid.type != Fluid.NULL) {
_fluidAmountToCol.set(_thisFluid.amount, _thisFluid.amount, _thisFluid.amount, _thisFluid.amount) _fluidAmountToCol = FloatVector.broadcast(VectorArray.SPECIES, _thisFluid.amount)
_thisTileLuminosity.set(_thisTerrainProp.getLumCol(worldX, worldY)) _thisTileLuminosity = _thisTerrainProp.getLumCol(worldX, worldY)
_thisTileLuminosity.maxAndAssign(_thisFluidProp.getLumCol(worldX, worldY).mul(_fluidAmountToCol)) _thisTileLuminosity = _thisTileLuminosity.max(_thisFluidProp.getLumCol(worldX, worldY).mul(_fluidAmountToCol))
_mapThisTileOpacity.setVec(lx, ly, _thisTerrainProp.opacity) _mapThisTileOpacity.setVec(lx, ly, _thisTerrainProp.opacity)
_mapThisTileOpacity.max(lx, ly, _thisFluidProp.opacity.mul(_fluidAmountToCol)) _mapThisTileOpacity.max(lx, ly, _thisFluidProp.opacity.mul(_fluidAmountToCol))
} }
else { else {
_thisTileLuminosity.set(_thisTerrainProp.getLumCol(worldX, worldY)) _thisTileLuminosity = _thisTerrainProp.getLumCol(worldX, worldY)
_mapThisTileOpacity.setVec(lx, ly, _thisTerrainProp.opacity) _mapThisTileOpacity.setVec(lx, ly, _thisTerrainProp.opacity)
} }
// blend shade // blend shade
_mapThisTileOpacity.max(lx, ly, shadowMap[LandUtil.getBlockAddr(world, worldX, worldY)] ?: colourNull) _mapThisTileOpacity.max(lx, ly, shadowMap[LandUtil.getBlockAddr(world, worldX, worldY)] ?: NULLVEC)
// _mapThisTileOpacity2.setVec(lx, ly, _mapThisTileOpacity.getVec(lx, ly).mul(1.41421356f)) // _mapThisTileOpacity2.setVec(lx, ly, _mapThisTileOpacity.getVec(lx, ly).mul(1.41421356f))
_mapThisTileOpacity.getAndSetMap(_mapThisTileOpacity2, lx, ly) { it * 1.41421356f } //_mapThisTileOpacity.getAndSetMap(_mapThisTileOpacity2, lx, ly) { it * 1.41421356f }
_mapThisTileOpacity.setVec(lx, ly, _mapThisTileOpacity.getVec(lx, ly).mul(1.41421356f))
// open air || luminous tile backed by sunlight // open air || luminous tile backed by sunlight
if ((!_thisTerrainProp.isSolid && !_thisWallProp.isSolid) || if ((!_thisTerrainProp.isSolid && !_thisWallProp.isSolid) ||
@@ -514,12 +517,12 @@ object LightmapRenderer {
} }
// blend lantern // blend lantern
_mapLightLevelThis.max(lx, ly, _thisTileLuminosity.maxAndAssign( _mapLightLevelThis.max(lx, ly, _thisTileLuminosity.max(
lanternMap[LandUtil.getBlockAddr(world, worldX, worldY)] ?: colourNull lanternMap[LandUtil.getBlockAddr(world, worldX, worldY)] ?: NULLVEC
)) ))
} }
private fun precalculate2(lightmap: UnsafeCvecArray, rawx: Int, rawy: Int) { private fun precalculate2(lightmap: VectorArray, 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)
@@ -530,17 +533,16 @@ object LightmapRenderer {
// } // }
// blend nearby 4 lights to get intensity // blend nearby 4 lights to get intensity
_ambientAccumulator.set(0) _ambientAccumulator = lightmap.getVec(lx - 1, ly)
.maxAndAssign(lightmap.getVec(lx - 1, ly)) .max(lightmap.getVec(lx + 1, ly))
.maxAndAssign(lightmap.getVec(lx + 1, ly)) .max(lightmap.getVec(lx, ly - 1))
.maxAndAssign(lightmap.getVec(lx, ly - 1)) .max(lightmap.getVec(lx, ly + 1))
.maxAndAssign(lightmap.getVec(lx, ly + 1))
_thisTerrain = world.getTileFromTerrainRaw(worldX, worldY) _thisTerrain = world.getTileFromTerrainRaw(worldX, worldY)
_thisTerrainProp = BlockCodex[world.tileNumberToNameMap[_thisTerrain.toLong()]] _thisTerrainProp = BlockCodex[world.tileNumberToNameMap[_thisTerrain.toLong()]]
_reflectanceAccumulator.set(App.tileMaker.terrainTileColourMap[_thisTerrainProp.id]!!) _reflectanceAccumulator = FloatVector.fromArray(VectorArray.SPECIES, App.tileMaker.terrainTileColourMap[_thisTerrainProp.id]!!.cpy().mul(1f,1f,1f,0f).toFloatArray(), 0)
_reflectanceAccumulator.a = 0f // temporarily disabled // _reflectanceAccumulator.a = 0f // temporarily disabled
_reflectanceAccumulator.mul(_thisTerrainProp.reflectance).mul(giScale) _reflectanceAccumulator.mul(_thisTerrainProp.reflectance).mul(giScale)
_mapLightLevelThis.max(lx, ly, _reflectanceAccumulator) _mapLightLevelThis.max(lx, ly, _reflectanceAccumulator)
@@ -551,25 +553,25 @@ object LightmapRenderer {
private var swipeY = -1 private var swipeY = -1
private var swipeDiag = false private var swipeDiag = false
private val distFromLightSrc = Ivec4() private val distFromLightSrc = Ivec4()
private fun _swipeTask(x: Int, y: Int, x2: Int, y2: Int, lightmap: UnsafeCvecArray) {//, distFromLightSrc: Ivec4) { private fun _swipeTask(x: Int, y: Int, x2: Int, y2: Int, lightmap: VectorArray) {//, distFromLightSrc: Ivec4) {
if (x2 < 0 || y2 < 0 || x2 >= LIGHTMAP_WIDTH || y2 >= LIGHTMAP_HEIGHT) return if (x2 < 0 || y2 < 0 || x2 >= LIGHTMAP_WIDTH || y2 >= LIGHTMAP_HEIGHT) return
// _ambientAccumulator.set(_mapLightLevelThis.getVec(x, y)) // _ambientAccumulator.set(_mapLightLevelThis.getVec(x, y))
_mapLightLevelThis.getAndSet(_ambientAccumulator, x, y) _ambientAccumulator = _mapLightLevelThis.getVec(x, y)
if (!swipeDiag) { if (!swipeDiag) {
_mapThisTileOpacity.getAndSet(_thisTileOpacity, x, y) _thisTileOpacity = _mapThisTileOpacity.getVec(x, y)
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity, lightmap))//, distFromLightSrc)) _ambientAccumulator = _ambientAccumulator.max(darkenColoured(x2, y2, _thisTileOpacity, lightmap))//, distFromLightSrc))
} }
else { else {
_mapThisTileOpacity2.getAndSet(_thisTileOpacity2, x, y) _thisTileOpacity2 = _mapThisTileOpacity2.getVec(x, y)
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity2, lightmap))//, distFromLightSrc)) _ambientAccumulator = _ambientAccumulator.max(darkenColoured(x2, y2, _thisTileOpacity2, lightmap))//, distFromLightSrc))
} }
_mapLightLevelThis.setVec(x, y, _ambientAccumulator) _mapLightLevelThis.setVec(x, y, _ambientAccumulator)
lightmap.setVec(x, y, _ambientAccumulator) lightmap.setVec(x, y, _ambientAccumulator)
} }
private fun swipeLight(sx: Int, sy: Int, ex: Int, ey: Int, dx: Int, dy: Int, lightmap: UnsafeCvecArray) { private fun swipeLight(sx: Int, sy: Int, ex: Int, ey: Int, dx: Int, dy: Int, lightmap: VectorArray) {
swipeX = sx; swipeY = sy swipeX = sx; swipeY = sy
// if (App.getConfigBoolean("fx_newlight")) distFromLightSrc.broadcast(0) // if (App.getConfigBoolean("fx_newlight")) distFromLightSrc.broadcast(0)
while (swipeX*dx <= ex*dx && swipeY*dy <= ey*dy) { while (swipeX*dx <= ex*dx && swipeY*dy <= ey*dy) {
@@ -687,7 +689,9 @@ object LightmapRenderer {
val arrayX = x.convX() val arrayX = x.convX()
val arrayY = y.convY() val arrayY = y.convY()
val (red, grn, blu, uvl) = lightmap.getVec(arrayX, arrayY) val arr = FloatArray(4); lightmap.getVec(arrayX, arrayY).intoArray(arr, 0)
val (red, grn, blu, uvl) = arr
// val redw = (red.sqrt() - 1f) * (7f / 24f) // val redw = (red.sqrt() - 1f) * (7f / 24f)
// val grnw = (grn.sqrt() - 1f) // val grnw = (grn.sqrt() - 1f)
// val bluw = (blu.sqrt() - 1f) * (7f / 72f) // val bluw = (blu.sqrt() - 1f) * (7f / 72f)
@@ -743,10 +747,10 @@ object LightmapRenderer {
_lightBufferAsTex.dispose() _lightBufferAsTex.dispose()
lightBuffer.dispose() lightBuffer.dispose()
lightmap.destroy() // lightmap.destroy()
_mapLightLevelThis.destroy() // _mapLightLevelThis.destroy()
_mapThisTileOpacity.destroy() // _mapThisTileOpacity.destroy()
_mapThisTileOpacity2.destroy() // _mapThisTileOpacity2.destroy()
} }
private const val lightScalingMagic = 2f private const val lightScalingMagic = 2f
@@ -783,11 +787,11 @@ object LightmapRenderer {
* @param darken (0-255) per channel * @param darken (0-255) per channel
* @return darkened data (0-255) per channel * @return darkened data (0-255) per channel
*/ */
internal fun darkenColoured(x: Int, y: Int, darken: Cvec, lightmap: UnsafeCvecArray): Cvec {//, distFromLightSrc: Ivec4 = Ivec4()): Cvec { internal fun darkenColoured(x: Int, y: Int, darken: FloatVector, lightmap: VectorArray): FloatVector {//, distFromLightSrc: Ivec4 = Ivec4()): Cvec {
// 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)
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 NULLVEC
// if (App.getConfigBoolean("fx_newlight")) { // if (App.getConfigBoolean("fx_newlight")) {
// val newDarken: Cvec = darken.lanewise { it, ch -> // val newDarken: Cvec = darken.lanewise { it, ch ->
@@ -799,12 +803,15 @@ object LightmapRenderer {
// } // }
// } // }
// else { // else {
return lightmap.getVec(x, y).lanewise { it, ch -> /*return lightmap.getVec(x, y).lanewise { it, ch ->
it * (1f - darken.lane(ch) * lightScalingMagic) it * (1f - darken.lane(ch) * lightScalingMagic)
} }*/
return lightmap.getVec(x, y).mul( vectorOne.sub(darken.mul(lightScalingMagic)) )
// } // }
} }
private val vectorOne = FloatVector.broadcast(VectorArray.SPECIES, 1f)
/** 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
@@ -864,14 +871,14 @@ object LightmapRenderer {
lightBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888) lightBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
lightmap.destroy() // lightmap.destroy()
_mapLightLevelThis.destroy() // _mapLightLevelThis.destroy()
_mapThisTileOpacity.destroy() // _mapThisTileOpacity.destroy()
_mapThisTileOpacity2.destroy() // _mapThisTileOpacity2.destroy()
lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT) lightmap = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
_mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT) _mapLightLevelThis = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
_mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT) _mapThisTileOpacity = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
_mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT) _mapThisTileOpacity2 = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
printdbg(this, "Resize event") printdbg(this, "Resize event")
} }
@@ -887,10 +894,10 @@ object LightmapRenderer {
inline fun Float.hdnorm() = hdr(this.coerceIn(0f, 1f)) inline fun Float.hdnorm() = hdr(this.coerceIn(0f, 1f))
private fun Cvec.nonZero() = this.r.abs() > epsilon || private fun FloatVector.nonZero() = this.lane(0).abs() > epsilon ||
this.g.abs() > epsilon || this.lane(1).abs() > epsilon ||
this.b.abs() > epsilon || this.lane(2).abs() > epsilon ||
this.a.abs() > epsilon this.lane(3).abs() > epsilon
val histogram: Histogram val histogram: Histogram
get() { get() {
@@ -971,6 +978,7 @@ object LightmapRenderer {
} }
} }
fun Cvec.toRGBA() = (255 * r).toInt() shl 24 or ((255 * g).toInt() shl 16) or ((255 * b).toInt() shl 8) or (255 * a).toInt() fun Cvec.toRGBA() = (255 * r).toInt() shl 24 or ((255 * g).toInt() shl 16) or ((255 * b).toInt() shl 8) or (255 * a).toInt()
fun Color.toRGBA() = (255 * r).toInt() shl 24 or ((255 * g).toInt() shl 16) or ((255 * b).toInt() shl 8) or (255 * a).toInt() fun Color.toRGBA() = (255 * r).toInt() shl 24 or ((255 * g).toInt() shl 16) or ((255 * b).toInt() shl 8) or (255 * a).toInt()