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">
<configuration default="false" name="Terrarum" type="JarApplication">
<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="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="17" />

View File

@@ -380,6 +380,8 @@ class Cvec {
fun toGdxColor() = Color(r, g, b, a)
fun toFloatArray() = floatArrayOf(r, g, b, a)
/** Extract Hue-Saturation-Value. This is the inverse of [.fromHsv].
* @param hsv The HSV array to be modified.
* @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
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.ReferencingRanges.PREFIX_VIRTUALTILE
import net.torvald.terrarum.gameitems.ItemID
@@ -190,7 +191,7 @@ class BlockCodex {
prop.shadeColG = record.floatVal("shdg")
prop.shadeColB = record.floatVal("shdb")
prop.shadeColA = record.floatVal("shduv")
prop.opacity = Cvec(prop.shadeColR, prop.shadeColG, prop.shadeColB, prop.shadeColA)
prop.strength = record.intVal("str")
prop.density = record.intVal("dsty")
@@ -199,7 +200,13 @@ class BlockCodex {
prop.baseLumColG = record.floatVal("lumg")
prop.baseLumColB = record.floatVal("lumb")
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.viscosity = record.intVal("vscs")

View File

@@ -1,6 +1,8 @@
package net.torvald.terrarum.blockproperties
import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.Cvec
import net.torvald.gdx.graphics.VectorArray.Companion.NULLVEC
import net.torvald.random.XXHash32
import net.torvald.terrarum.*
import net.torvald.terrarum.gameitems.ItemID
@@ -22,7 +24,7 @@ class BlockProp {
var shadeColB = 0f
var shadeColA = 0f
lateinit var opacity: Cvec
lateinit var opacity: FloatVector
fun getOpacity(channel: Int) = when (channel) {
0 -> shadeColR
@@ -54,12 +56,12 @@ class BlockProp {
internal var baseLumColG = 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 val baseLumCol = Cvec(0)
internal var baseLumCol: FloatVector = NULLVEC
//var lumColR = 0f // memoised value of dynamic luminosity
//var lumColG = 0f // memoised value of dynamic luminosity
//var lumColB = 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())
fun getLumCol(x: Int, y: Int) = if (dynamicLuminosityFunction == 0) {
baseLumCol

View File

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

View File

@@ -1,15 +1,16 @@
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!
*/
class Lightbox() {
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.light = light
}

View File

@@ -3,7 +3,10 @@ package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.jme3.math.FastMath
import jdk.incubator.vector.FloatVector
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.HasAssembledSprite
import net.torvald.spriteanimation.SheetSpriteAnimation
@@ -65,32 +68,32 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
if (houseDesignation != null) houseDesignation!!.clear()
}
var actorValueColour: Cvec
get() = Cvec(
var actorValueColour: FloatVector
get() = FloatVector.fromArray(VectorArray.SPECIES, floatArrayOf(
(actorValue.getAsFloat(AVKey.LUMR) ?: 0f),
(actorValue.getAsFloat(AVKey.LUMG) ?: 0f),
(actorValue.getAsFloat(AVKey.LUMB) ?: 0f),
(actorValue.getAsFloat(AVKey.LUMA) ?: 0f)
)
), 0)
set(value) {
actorValue[AVKey.LUMR] = value.r
actorValue[AVKey.LUMG] = value.g
actorValue[AVKey.LUMB] = value.b
actorValue[AVKey.LUMA] = value.a
actorValue[AVKey.LUMR] = value.lane(0)
actorValue[AVKey.LUMG] = value.lane(1)
actorValue[AVKey.LUMB] = value.lane(2)
actorValue[AVKey.LUMA] = value.lane(3)
}
var actorValueShade: Cvec
get() = Cvec(
var actorValueShade: FloatVector
get() = FloatVector.fromArray(VectorArray.SPECIES, floatArrayOf(
(actorValue.getAsFloat(AVKey.OPAR) ?: 0f),
(actorValue.getAsFloat(AVKey.OPAG) ?: 0f),
(actorValue.getAsFloat(AVKey.OPAB) ?: 0f),
(actorValue.getAsFloat(AVKey.OPAA) ?: 0f)
)
), 0)
set(value) {
actorValue[AVKey.OPAR] = value.r
actorValue[AVKey.OPAG] = value.g
actorValue[AVKey.OPAB] = value.b
actorValue[AVKey.OPAA] = value.a
actorValue[AVKey.OPAR] = value.lane(0)
actorValue[AVKey.OPAG] = value.lane(1)
actorValue[AVKey.OPAB] = value.lane(2)
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)
* (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()
@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()
@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.jme3.math.FastMath
import net.torvald.gdx.graphics.Cvec
import net.torvald.gdx.graphics.VectorArray.Companion.NULLVEC
import net.torvald.terrarum.BlockCodex
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.ItemCodex
@@ -39,9 +40,9 @@ open class DroppedItem : ActorWithBody {
private val randKey1 = (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
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
/**

View File

@@ -1,7 +1,10 @@
package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.Gdx
import jdk.incubator.vector.FloatVector
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.terrarum.*
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 twClosed = 1 // tilewise width of the door when closed
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 moduleName = "basegame"
var texturePath = "sprites/fixtures/door_test.tga"
@@ -43,9 +46,9 @@ open class FixtureSwingingDoorBase : FixtureBase {
private var pixelwiseHitboxHeight = TILE_SIZE * tilewiseHitboxHeight
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
@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
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 doorHoldLength: HashMap<Int, Second>
private fun FloatVector.toCvec() = Cvec(this.lane(0), this.lane(1), this.lane(2), this.lane(3))
constructor() : super(
BlockBox(BlockBox.FULL_COLLISION, 1, 1), // temporary value, will be overwritten by spawn()
nameFun = { "item not loaded properly, alas!" }
@@ -62,7 +68,7 @@ open class FixtureSwingingDoorBase : FixtureBase {
2,
1,
3,
BlockCodex[Block.STONE].opacity,
BlockCodex[Block.STONE].opacity.toCvec(),
false,
"basegame",
"sprites/fixtures/door_test.tga",
@@ -73,18 +79,18 @@ open class FixtureSwingingDoorBase : FixtureBase {
}
protected fun _construct(
tw: Int, // tilewise width of the door when opened
twClosed: Int, // tilewise width of the door when closed
th: Int, // tilewise height of the door
opacity: Cvec,
isOpacityActuallyLuminosity: Boolean,
moduleName: String,
texturePath: String,
textureIdentifier: String,
nameKey: String,
nameKeyReadFromLang: Boolean,
doorCloseHoldLength: Second = 0.1f,
doorOpenedHoldLength: Second = 0.25f
tw: Int, // tilewise width of the door when opened
twClosed: Int, // tilewise width of the door when closed
th: Int, // tilewise height of the door
opacity: Cvec,
isOpacityActuallyLuminosity: Boolean,
moduleName: String,
texturePath: String,
textureIdentifier: String,
nameKey: String,
nameKeyReadFromLang: Boolean,
doorCloseHoldLength: Second = 0.1f,
doorOpenedHoldLength: Second = 0.25f
) {
this.tw = tw
this.twClosed = twClosed
@@ -123,7 +129,7 @@ open class FixtureSwingingDoorBase : FixtureBase {
// define light/shadebox
// 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
setHitboxDimension(TILE_SIZE * tilewiseHitboxWidth, TILE_SIZE * tilewiseHitboxHeight, 0, 0)
@@ -147,16 +153,16 @@ open class FixtureSwingingDoorBase : FixtureBase {
// define light/shadebox
// 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() {
shadeBoxList[0].light = opacity
shadeBoxList[0].light = FloatVector.fromArray(VectorArray.SPECIES, opacity.toFloatArray(), 0)
}
private fun unsetOpacity() {
shadeBoxList[0].light = Cvec(0)
shadeBoxList[0].light = NULLVEC
}
open protected fun closeDoor(doorHandler: Int) {

View File

@@ -1,18 +1,22 @@
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.blockproperties.Block
/**
* 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 {
constructor() : super() {
_construct(
2,
1,
3,
BlockCodex[Block.STONE].opacity,
BlockCodex[Block.STONE].opacity.toCvec(),
false,
"basegame",
"sprites/fixtures/door_basegame-48.tga",
@@ -29,7 +33,7 @@ class FixtureSwingingDoorEbony : FixtureSwingingDoorBase {
2,
1,
3,
BlockCodex[Block.STONE].opacity,
BlockCodex[Block.STONE].opacity.toCvec(),
false,
"basegame",
"sprites/fixtures/door_basegame-49.tga",
@@ -46,7 +50,7 @@ class FixtureSwingingDoorBirch : FixtureSwingingDoorBase {
2,
1,
3,
BlockCodex[Block.STONE].opacity,
BlockCodex[Block.STONE].opacity.toCvec(),
false,
"basegame",
"sprites/fixtures/door_basegame-50.tga",
@@ -63,7 +67,7 @@ class FixtureSwingingDoorRosewood : FixtureSwingingDoorBase {
2,
1,
3,
BlockCodex[Block.STONE].opacity,
BlockCodex[Block.STONE].opacity.toCvec(),
false,
"basegame",
"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.g2d.SpriteBatch
import jdk.incubator.vector.FloatVector
import net.torvald.gdx.graphics.Cvec
import net.torvald.gdx.graphics.VectorArray
import net.torvald.terrarum.BlockCodex
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.Point2d
@@ -29,8 +31,8 @@ open class ProjectileSimple : ActorWithBody, Projectile {
var speed: Int = 0
private var color: Cvec
get() = (bulletDatabase[type][OFFSET_LUMINOSITY] as Cvec).cpy()
private var color: FloatVector
get() = bulletDatabase[type][OFFSET_LUMINOSITY] as FloatVector
set(value) {
}
/**
@@ -115,7 +117,9 @@ open class ProjectileSimple : ActorWithBody, Projectile {
override fun drawGlow(batch: SpriteBatch) = drawBody(batch)
companion object {
private fun Int.toFloatVector() = FloatVector.fromArray(VectorArray.SPECIES, Cvec(this).toFloatArray(), 0)
val OFFSET_DAMAGE = 0
val OFFSET_COL = 1 // Color or SpriteAnimation
val OFFSET_NOGRAVITY = 2
@@ -123,8 +127,8 @@ open class ProjectileSimple : ActorWithBody, Projectile {
val OFFSET_LUMINOSITY = 4
val bulletDatabase = arrayOf(
// damage, display colour, no gravity, speed
arrayOf(7, Cvec(0xFF5429_FF.toInt()), true, 40, 32),
arrayOf(8, Cvec(0xFF5429_FF.toInt()), true, 20, 0)
arrayOf(7, 0xFF5429_FF.toInt().toFloatVector(), true, 40, 32),
arrayOf(8, 0xFF5429_FF.toInt().toFloatVector(), true, 20, 0)
// ...
)
}

View File

@@ -196,10 +196,10 @@ class BasicDebugInfoWindow : UICanvas() {
try {
world?.let {
val valRaw = LightmapRenderer.getLight(mouseTileX, mouseTileY)
val rawR = valRaw?.r?.toDouble().toIntAndFrac(1,3)
val rawG = valRaw?.g?.toDouble().toIntAndFrac(1,3)
val rawB = valRaw?.b?.toDouble().toIntAndFrac(1,3)
val rawA = valRaw?.a?.toDouble().toIntAndFrac(1,3)
val rawR = valRaw?.lane(0)?.toDouble().toIntAndFrac(1,3)
val rawG = valRaw?.lane(1)?.toDouble().toIntAndFrac(1,3)
val rawB = valRaw?.lane(2)?.toDouble().toIntAndFrac(1,3)
val rawA = valRaw?.lane(3)?.toDouble().toIntAndFrac(1,3)
val wallNum = it.getTileFromWall(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.Texture
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.UnsafeCvecArray
import net.torvald.gdx.graphics.VectorArray.Companion.NULLVEC
import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
@@ -48,10 +50,10 @@ object LightmapRenderer {
if (this.world != world) {
printdbg(this, "World change detected -- old world: ${this.world.hashCode()}, new world: ${world.hashCode()}")
lightmap.zerofill()
_mapLightLevelThis.zerofill()
_mapThisTileOpacity.zerofill()
_mapThisTileOpacity2.zerofill()
// lightmap.zerofill()
// _mapLightLevelThis.zerofill()
// _mapThisTileOpacity.zerofill()
// _mapThisTileOpacity2.zerofill()
}
}
catch (e: UninitializedPropertyAccessException) {
@@ -71,8 +73,8 @@ object LightmapRenderer {
//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 shadowMap = 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, FloatVector>((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
@@ -80,10 +82,10 @@ object LightmapRenderer {
* 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)
private var lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var lightmap = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapLightLevelThis = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapThisTileOpacity = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapThisTileOpacity2 = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private const val AIR = Block.AIR
@@ -118,7 +120,7 @@ object LightmapRenderer {
* @param x 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)
x + 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)
private fun _recalculate(actorContainer: List<ActorWithBody>, lightmap: UnsafeCvecArray) {
private fun _recalculate(actorContainer: List<ActorWithBody>, lightmap: VectorArray) {
try {
world.getTileFromTerrain(0, 0) // test inquiry
}
@@ -179,7 +181,8 @@ object LightmapRenderer {
} // usually takes 3000 ns
// 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
/*AppLoader.measureDebugTime("Renderer.LightNoOpMask") {
@@ -204,7 +207,7 @@ object LightmapRenderer {
// 'NEWLIGHT2' LIGHT SWIPER
// O((8*2)n) where n is a size of the map.
/* - */fun r1(lightmap: UnsafeCvecArray) {
/* - */fun r1(lightmap: VectorArray) {
swipeDiag = false
for (line in 1 until LIGHTMAP_HEIGHT - 1) {
swipeLight(
@@ -215,7 +218,7 @@ object LightmapRenderer {
)
}
}
/* | */fun r2(lightmap: UnsafeCvecArray) {
/* | */fun r2(lightmap: VectorArray) {
swipeDiag = false
for (line in 1 until LIGHTMAP_WIDTH - 1) {
swipeLight(
@@ -226,7 +229,7 @@ object LightmapRenderer {
)
}
}
/* \ */fun r3(lightmap: UnsafeCvecArray) {
/* \ */fun r3(lightmap: VectorArray) {
swipeDiag = true
/* construct indices such that:
56789ABC
@@ -264,7 +267,7 @@ object LightmapRenderer {
)
}
}
/* / */fun r4(lightmap: UnsafeCvecArray) {
/* / */fun r4(lightmap: VectorArray) {
swipeDiag = true
/*
1 w-2
@@ -360,10 +363,10 @@ object LightmapRenderer {
for (x in lightBoxX.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
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()
..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
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
private val sunLight = Cvec(0)
private var sunLight = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private var _thisTerrain = 0
private var _thisFluid = GameWorld.FluidInfo(Fluid.NULL, 0f)
private var _thisWall = 0
private val _ambientAccumulator = Cvec(0)
private val _reflectanceAccumulator = Cvec(0)
private val _thisTileOpacity = Cvec(0)
private val _thisTileOpacity2 = Cvec(0) // thisTileOpacity * sqrt(2)
private val _fluidAmountToCol = Cvec(0)
private val _thisTileLuminosity = Cvec(0)
private var _ambientAccumulator = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private var _reflectanceAccumulator = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private var _thisTileOpacity = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private var _thisTileOpacity2 = FloatVector.broadcast(VectorArray.SPECIES, 0f) // thisTileOpacity * sqrt(2)
private var _fluidAmountToCol = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private var _thisTileLuminosity = FloatVector.broadcast(VectorArray.SPECIES, 0f)
private var _thisTerrainProp: BlockProp = BlockProp()
private var _thisWallProp: BlockProp = BlockProp()
private var _thisFluidProp: BlockProp = BlockProp()
@@ -485,24 +488,24 @@ object LightmapRenderer {
}*/
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.maxAndAssign(_thisFluidProp.getLumCol(worldX, worldY).mul(_fluidAmountToCol))
_thisTileLuminosity = _thisTerrainProp.getLumCol(worldX, worldY)
_thisTileLuminosity = _thisTileLuminosity.max(_thisFluidProp.getLumCol(worldX, worldY).mul(_fluidAmountToCol))
_mapThisTileOpacity.setVec(lx, ly, _thisTerrainProp.opacity)
_mapThisTileOpacity.max(lx, ly, _thisFluidProp.opacity.mul(_fluidAmountToCol))
}
else {
_thisTileLuminosity.set(_thisTerrainProp.getLumCol(worldX, worldY))
_thisTileLuminosity = _thisTerrainProp.getLumCol(worldX, worldY)
_mapThisTileOpacity.setVec(lx, ly, _thisTerrainProp.opacity)
}
// 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))
_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
if ((!_thisTerrainProp.isSolid && !_thisWallProp.isSolid) ||
@@ -514,12 +517,12 @@ object LightmapRenderer {
}
// blend lantern
_mapLightLevelThis.max(lx, ly, _thisTileLuminosity.maxAndAssign(
lanternMap[LandUtil.getBlockAddr(world, worldX, worldY)] ?: colourNull
_mapLightLevelThis.max(lx, ly, _thisTileLuminosity.max(
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 (worldX, worldY) = world.coerceXY(rawx, rawy)
@@ -530,17 +533,16 @@ object LightmapRenderer {
// }
// blend nearby 4 lights to get intensity
_ambientAccumulator.set(0)
.maxAndAssign(lightmap.getVec(lx - 1, ly))
.maxAndAssign(lightmap.getVec(lx + 1, ly))
.maxAndAssign(lightmap.getVec(lx, ly - 1))
.maxAndAssign(lightmap.getVec(lx, ly + 1))
_ambientAccumulator = lightmap.getVec(lx - 1, ly)
.max(lightmap.getVec(lx + 1, ly))
.max(lightmap.getVec(lx, ly - 1))
.max(lightmap.getVec(lx, ly + 1))
_thisTerrain = world.getTileFromTerrainRaw(worldX, worldY)
_thisTerrainProp = BlockCodex[world.tileNumberToNameMap[_thisTerrain.toLong()]]
_reflectanceAccumulator.set(App.tileMaker.terrainTileColourMap[_thisTerrainProp.id]!!)
_reflectanceAccumulator.a = 0f // temporarily disabled
_reflectanceAccumulator = FloatVector.fromArray(VectorArray.SPECIES, App.tileMaker.terrainTileColourMap[_thisTerrainProp.id]!!.cpy().mul(1f,1f,1f,0f).toFloatArray(), 0)
// _reflectanceAccumulator.a = 0f // temporarily disabled
_reflectanceAccumulator.mul(_thisTerrainProp.reflectance).mul(giScale)
_mapLightLevelThis.max(lx, ly, _reflectanceAccumulator)
@@ -551,25 +553,25 @@ object LightmapRenderer {
private var swipeY = -1
private var swipeDiag = false
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
// _ambientAccumulator.set(_mapLightLevelThis.getVec(x, y))
_mapLightLevelThis.getAndSet(_ambientAccumulator, x, y)
_ambientAccumulator = _mapLightLevelThis.getVec(x, y)
if (!swipeDiag) {
_mapThisTileOpacity.getAndSet(_thisTileOpacity, x, y)
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity, lightmap))//, distFromLightSrc))
_thisTileOpacity = _mapThisTileOpacity.getVec(x, y)
_ambientAccumulator = _ambientAccumulator.max(darkenColoured(x2, y2, _thisTileOpacity, lightmap))//, distFromLightSrc))
}
else {
_mapThisTileOpacity2.getAndSet(_thisTileOpacity2, x, y)
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity2, lightmap))//, distFromLightSrc))
_thisTileOpacity2 = _mapThisTileOpacity2.getVec(x, y)
_ambientAccumulator = _ambientAccumulator.max(darkenColoured(x2, y2, _thisTileOpacity2, lightmap))//, distFromLightSrc))
}
_mapLightLevelThis.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
// if (App.getConfigBoolean("fx_newlight")) distFromLightSrc.broadcast(0)
while (swipeX*dx <= ex*dx && swipeY*dy <= ey*dy) {
@@ -687,7 +689,9 @@ object LightmapRenderer {
val arrayX = x.convX()
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 grnw = (grn.sqrt() - 1f)
// val bluw = (blu.sqrt() - 1f) * (7f / 72f)
@@ -743,10 +747,10 @@ object LightmapRenderer {
_lightBufferAsTex.dispose()
lightBuffer.dispose()
lightmap.destroy()
_mapLightLevelThis.destroy()
_mapThisTileOpacity.destroy()
_mapThisTileOpacity2.destroy()
// lightmap.destroy()
// _mapLightLevelThis.destroy()
// _mapThisTileOpacity.destroy()
// _mapThisTileOpacity2.destroy()
}
private const val lightScalingMagic = 2f
@@ -783,11 +787,11 @@ object LightmapRenderer {
* @param darken (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
// 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")) {
// val newDarken: Cvec = darken.lanewise { it, ch ->
@@ -799,12 +803,15 @@ object LightmapRenderer {
// }
// }
// else {
return lightmap.getVec(x, y).lanewise { it, ch ->
/*return lightmap.getVec(x, y).lanewise { it, ch ->
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 */
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
@@ -864,14 +871,14 @@ object LightmapRenderer {
lightBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
lightmap.destroy()
_mapLightLevelThis.destroy()
_mapThisTileOpacity.destroy()
_mapThisTileOpacity2.destroy()
lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
_mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
_mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
_mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
// lightmap.destroy()
// _mapLightLevelThis.destroy()
// _mapThisTileOpacity.destroy()
// _mapThisTileOpacity2.destroy()
lightmap = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
_mapLightLevelThis = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
_mapThisTileOpacity = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
_mapThisTileOpacity2 = VectorArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
printdbg(this, "Resize event")
}
@@ -887,10 +894,10 @@ object LightmapRenderer {
inline fun Float.hdnorm() = hdr(this.coerceIn(0f, 1f))
private fun Cvec.nonZero() = this.r.abs() > epsilon ||
this.g.abs() > epsilon ||
this.b.abs() > epsilon ||
this.a.abs() > epsilon
private fun FloatVector.nonZero() = this.lane(0).abs() > epsilon ||
this.lane(1).abs() > epsilon ||
this.lane(2).abs() > epsilon ||
this.lane(3).abs() > epsilon
val histogram: Histogram
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 Color.toRGBA() = (255 * r).toInt() shl 24 or ((255 * g).toInt() shl 16) or ((255 * b).toInt() shl 8) or (255 * a).toInt()