diff --git a/.idea/misc.xml b/.idea/misc.xml
index df5a15f37..19568e289 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -38,7 +38,7 @@
-
+
\ No newline at end of file
diff --git a/src/net/torvald/gdx/graphics/Cvec.kt b/src/net/torvald/gdx/graphics/Cvec.kt
index 0812895eb..6cbf36e3e 100644
--- a/src/net/torvald/gdx/graphics/Cvec.kt
+++ b/src/net/torvald/gdx/graphics/Cvec.kt
@@ -16,487 +16,80 @@
package net.torvald.gdx.graphics
-import com.badlogic.gdx.graphics.Color
-import com.badlogic.gdx.utils.NumberUtils
+import jdk.incubator.vector.FloatVector
+import jdk.incubator.vector.VectorOperators
+import kotlin.math.roundToInt
/**
* A Cvec is kind of a Vector4f made compatible with LibGdx's Color class, with the intention of actually utilising
* the JEP 338 VectorInstrinsics later, when the damned thing finally releases.
*
+ * -XX:+UseVectorApiIntrinsics --add-modules=jdk.incubator.vector
+ *
* Before then, the code will be identical to LibGdx's.
*/
+inline class Cvec constructor(val vec: FloatVector) {
-/** A color class, holding the r, g, b and alpha component as floats in the range [0,1]. All methods perform clamping on the
- * internal values after execution.
- *
- * @author mzechner
- */
-class Cvec {
+ constructor(floatArray: FloatArray) : this(FloatVector.fromArray(SPECIES, floatArray, 0))
+ constructor(r: Float, g: Float, b: Float, a: Float) : this(FloatVector.fromValues(SPECIES, r, g, b, a))
+ constructor(scalar: Float) : this(FloatVector.fromValues(SPECIES, scalar, scalar, scalar, scalar))
+ constructor() : this(FloatVector.zero(SPECIES))
+ constructor(rgba8888: Int) : this(FloatVector.fromValues(SPECIES,
+ ((rgba8888 ushr 24) and 0xff) / 255f,
+ ((rgba8888 ushr 16) and 0xff) / 255f,
+ ((rgba8888 ushr 8) and 0xff) / 255f,
+ (rgba8888 and 0xff) / 255f
+ ))
- /** the red, green, blue and alpha components */
- var r: Float = 0.toFloat()
- var g: Float = 0.toFloat()
- var b: Float = 0.toFloat()
- var a: Float = 0.toFloat()
-
- /** Constructs a new Cvec with all components set to 0. */
- constructor() {}
-
- /** @see .rgba8888ToCvec
- */
- constructor(rgba8888: Int) {
- rgba8888ToCvec(this, rgba8888)
+ companion object {
+ private val EPSILON = 1f / 1024f
+ private val SPECIES = FloatVector.SPECIES_128
}
- constructor(color: Color) {
- this.r = color.r
- this.g = color.g
- this.b = color.b
- this.a = color.a
- }
+ //fun cpy(): Cvec = Cvec(this.vec)
- /** Constructor, sets the components of the color
- *
- * @param r the red component
- * @param g the green component
- * @param b the blue component
- * @param a the alpha component
- */
- constructor(r: Float, g: Float, b: Float, a: Float) {
- this.r = r
- this.g = g
- this.b = b
- this.a = a
- }
+ // not using shorthand names to prevent confusion with builtin functions
- /** Constructs a new color using the given color
- *
- * @param color the color
- */
- constructor(color: Cvec) {
- set(color)
+ fun multiply(other: FloatVector) = Cvec(vec.mul(other))
+ infix operator fun times(other: Cvec) = multiply(other.vec)
+ //infix operator fun times(scalar: Float) = Cvec(vec.mul(scalar))
+
+ fun subtract(other: FloatVector) = Cvec(vec.sub(other))
+ infix operator fun minus(other: Cvec) = subtract(other.vec)
+ //infix operator fun minus(scalar: Float) = Cvec(vec.sub(scalar))
+
+ fun addition(other: FloatVector) = Cvec(vec.add(other))
+ infix operator fun plus(other: Cvec) = addition(other.vec)
+ //infix operator fun plus(scalar: Float) = Cvec(vec.add(scalar))
+
+ fun maximum(other: FloatVector): Cvec = Cvec(vec.max(other))
+ infix fun max(other: Cvec): Cvec = maximum(other.vec)
+
+ fun lerp(target: Cvec, t: Float): Cvec {
+ return Cvec(t) * (target - this)
}
/**
- * Get RGBA Element using index, of which:
- * - 0: R
- * - 1: G
- * - 2: B
- * - 3: A
+ * true if at least one element in the vector is not zero.
*/
- fun getElem(index: Int) = when(index) {
- 0 -> r
- 1 -> g
- 2 -> b
- 3 -> a
- else -> throw IndexOutOfBoundsException("Invalid index $index")
+ fun nonZero(): Boolean = vec.reduceLanes(VectorOperators.MUL) != 0f //vec.toArray().fold(false) { acc, fl -> acc or (fl.absoluteValue >= EPSILON) }
+
+ fun toRGBA8888(): Int {
+ var acc = 0
+ for (i in 0..3)
+ acc += vec.lane(i).coerceIn(0f, 1f).times(255f).roundToInt().shl(8 * (3 - i))
+
+ return acc
}
- /** Sets this color to the given color.
- *
- * @param color the Cvec
- */
- fun set(color: Cvec): Cvec {
- this.r = color.r
- this.g = color.g
- this.b = color.b
- this.a = color.a
- return this
- }
+ /*override fun equals(other: Any?): Boolean {
+ return this.vec.equal((other as Cvec).vec).allTrue()
+ }*/
- /** Multiplies the this color and the given color
- *
- * @param color the color
- * @return this color.
- */
- fun mul(color: Cvec): Cvec {
- this.r *= color.r
- this.g *= color.g
- this.b *= color.b
- this.a *= color.a
- return this
- }
-
- /** Multiplies all components of this Cvec with the given value.
- *
- * @param value the value
- * @return this color
- */
- fun mul(value: Float): Cvec {
- this.r *= value
- this.g *= value
- this.b *= value
- this.a *= value
- return this
- }
-
- /** Adds the given color to this color.
- *
- * @param color the color
- * @return this color
- */
- fun add(color: Cvec): Cvec {
- this.r += color.r
- this.g += color.g
- this.b += color.b
- this.a += color.a
- return this
- }
-
- /** Subtracts the given color from this color
- *
- * @param color the color
- * @return this color
- */
- fun sub(color: Cvec): Cvec {
- this.r -= color.r
- this.g -= color.g
- this.b -= color.b
- this.a -= color.a
- return this
- }
-
- /** Sets this Cvec's component values.
- *
- * @param r Red component
- * @param g Green component
- * @param b Blue component
- * @param a Alpha component
- *
- * @return this Cvec for chaining
- */
- operator fun set(r: Float, g: Float, b: Float, a: Float): Cvec {
- this.r = r
- this.g = g
- this.b = b
- this.a = a
- return this
- }
-
- /** Sets this color's component values through an integer representation.
- *
- * @return this Cvec for chaining
- * @see .rgba8888ToCvec
- */
- fun set(rgba: Int): Cvec {
- rgba8888ToCvec(this, rgba)
- return this
- }
-
- /** Adds the given color component values to this Cvec's values.
- *
- * @param r Red component
- * @param g Green component
- * @param b Blue component
- * @param a Alpha component
- *
- * @return this Cvec for chaining
- */
- fun add(r: Float, g: Float, b: Float, a: Float): Cvec {
- this.r += r
- this.g += g
- this.b += b
- this.a += a
- return this
- }
-
- /** Subtracts the given values from this Cvec's component values.
- *
- * @param r Red component
- * @param g Green component
- * @param b Blue component
- * @param a Alpha component
- *
- * @return this Cvec for chaining
- */
- fun sub(r: Float, g: Float, b: Float, a: Float): Cvec {
- this.r -= r
- this.g -= g
- this.b -= b
- this.a -= a
- return this
- }
-
- /** Multiplies this Cvec's color components by the given ones.
- *
- * @param r Red component
- * @param g Green component
- * @param b Blue component
- * @param a Alpha component
- *
- * @return this Cvec for chaining
- */
- fun mul(r: Float, g: Float, b: Float, a: Float): Cvec {
- this.r *= r
- this.g *= g
- this.b *= b
- this.a *= a
- return this
- }
-
- /** Linearly interpolates between this color and the target color by t which is in the range [0,1]. The result is stored in
- * this color.
- * @param target The target color
- * @param t The interpolation coefficient
- * @return This color for chaining.
- */
- fun lerp(target: Cvec, t: Float): Cvec {
- this.r += t * (target.r - this.r)
- this.g += t * (target.g - this.g)
- this.b += t * (target.b - this.b)
- this.a += t * (target.a - this.a)
- return this
- }
-
- /** Linearly interpolates between this color and the target color by t which is in the range [0,1]. The result is stored in
- * this color.
- * @param r The red component of the target color
- * @param g The green component of the target color
- * @param b The blue component of the target color
- * @param a The alpha component of the target color
- * @param t The interpolation coefficient
- * @return This color for chaining.
- */
- fun lerp(r: Float, g: Float, b: Float, a: Float, t: Float): Cvec {
- this.r += t * (r - this.r)
- this.g += t * (g - this.g)
- this.b += t * (b - this.b)
- this.a += t * (a - this.a)
- return this
- }
-
- /** Multiplies the RGB values by the alpha. */
- fun premultiplyAlpha(): Cvec {
- r *= a
- g *= a
- b *= a
- return this
- }
-
- override fun equals(o: Any?): Boolean {
- if (this === o) return true
- if (o == null || javaClass != o.javaClass) return false
- val color = o as Cvec?
- return toIntBits() == color!!.toIntBits()
- }
-
- override fun hashCode(): Int {
- var result = if (r != +0.0f) NumberUtils.floatToIntBits(r) else 0
- result = 31 * result + if (g != +0.0f) NumberUtils.floatToIntBits(g) else 0
- result = 31 * result + if (b != +0.0f) NumberUtils.floatToIntBits(b) else 0
- result = 31 * result + if (a != +0.0f) NumberUtils.floatToIntBits(a) else 0
- return result
- }
-
- /** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float. Alpha is compressed
- * from 0-255 to 0-254 to avoid using float bits in the NaN range (see [NumberUtils.intToFloatColor]).
- * @return the packed color as a 32-bit float
- */
- fun toFloatBits(): Float {
- val color = (255 * a).toInt() shl 24 or ((255 * b).toInt() shl 16) or ((255 * g).toInt() shl 8) or (255 * r).toInt()
- return NumberUtils.intToFloatColor(color)
- }
-
- /** Packs the color components into a 32-bit integer with the format ABGR.
- * @return the packed color as a 32-bit int.
- */
- fun toIntBits(): Int {
- return (255 * a).toInt() shl 24 or ((255 * b).toInt() shl 16) or ((255 * g).toInt() shl 8) or (255 * r).toInt()
- }
-
- /** Returns the color encoded as hex string with the format RRGGBBAA. */
- override fun toString(): String {
- var value = Integer
- .toHexString((255 * r).toInt() shl 24 or ((255 * g).toInt() shl 16) or ((255 * b).toInt() shl 8) or (255 * a).toInt())
- while (value.length < 8)
- value = "0$value"
- return value
- }
-
- /** Sets the RGB Cvec components using the specified Hue-Saturation-Value. Note that HSV components are voluntary not clamped
- * to preserve high range color and can range beyond typical values.
- * @param h The Hue in degree from 0 to 360
- * @param s The Saturation from 0 to 1
- * @param v The Value (brightness) from 0 to 1
- * @return The modified Cvec for chaining.
- */
- fun fromHsv(h: Float, s: Float, v: Float): Cvec {
- val x = (h / 60f + 6) % 6
- val i = x.toInt()
- val f = x - i
- val p = v * (1 - s)
- val q = v * (1 - s * f)
- val t = v * (1 - s * (1 - f))
- when (i) {
- 0 -> {
- r = v
- g = t
- b = p
- }
- 1 -> {
- r = q
- g = v
- b = p
- }
- 2 -> {
- r = p
- g = v
- b = t
- }
- 3 -> {
- r = p
- g = q
- b = v
- }
- 4 -> {
- r = t
- g = p
- b = v
- }
- else -> {
- r = v
- g = p
- b = q
- }
- }
-
- //return clamp();
- return this
- }
-
- /** Sets RGB components using the specified Hue-Saturation-Value. This is a convenient method for
- * [.fromHsv]. This is the inverse of [.toHsv].
- * @param hsv The Hue, Saturation and Value components in that order.
- * @return The modified Cvec for chaining.
- */
- fun fromHsv(hsv: FloatArray): Cvec {
- return fromHsv(hsv[0], hsv[1], hsv[2])
- }
-
- fun toGdxColor() = Color(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.
- */
- fun toHsv(hsv: FloatArray): FloatArray {
- val max = Math.max(Math.max(r, g), b)
- val min = Math.min(Math.min(r, g), b)
- val range = max - min
- if (range == 0f) {
- hsv[0] = 0f
- }
- else if (max == r) {
- hsv[0] = (60 * (g - b) / range + 360) % 360
- }
- else if (max == g) {
- hsv[0] = 60 * (b - r) / range + 120
- }
- else {
- hsv[0] = 60 * (r - g) / range + 240
- }
-
- if (max > 0) {
- hsv[1] = 1 - min / max
- }
- else {
- hsv[1] = 0f
- }
-
- hsv[2] = max
-
- return hsv
- }
-
- /** @return a copy of this color
- */
- fun cpy(): Cvec {
- return Cvec(this)
- }
-
- companion object {
- val WHITE = Cvec(1f, 1f, 1f, 1f)
-
- /** Returns a new color from a hex string with the format RRGGBBAA.
- * @see .toString
- */
- fun valueOf(hex: String): Cvec {
- var hex = hex
- hex = if (hex[0] == '#') hex.substring(1) else hex
- val r = Integer.valueOf(hex.substring(0, 2), 16)
- val g = Integer.valueOf(hex.substring(2, 4), 16)
- val b = Integer.valueOf(hex.substring(4, 6), 16)
- val a = if (hex.length != 8) 255 else Integer.valueOf(hex.substring(6, 8), 16)
- return Cvec(r / 255f, g / 255f, b / 255f, a / 255f)
- }
-
- /** Packs the color components into a 32-bit integer with the format ABGR. Note that no range checking is performed for higher
- * performance.
- * @param r the red component, 0 - 255
- * @param g the green component, 0 - 255
- * @param b the blue component, 0 - 255
- * @param a the alpha component, 0 - 255
- * @return the packed color as a 32-bit int
- */
- fun toIntBits(r: Int, g: Int, b: Int, a: Int): Int {
- return a shl 24 or (b shl 16) or (g shl 8) or r
- }
-
- fun alpha(alpha: Float): Int {
- return (alpha * 255.0f).toInt()
- }
-
- fun rgba8888(r: Float, g: Float, b: Float, a: Float): Int {
- return (r * 255).toInt() shl 24 or ((g * 255).toInt() shl 16) or ((b * 255).toInt() shl 8) or (a * 255).toInt()
- }
-
- fun argb8888(a: Float, r: Float, g: Float, b: Float): Int {
- return (a * 255).toInt() shl 24 or ((r * 255).toInt() shl 16) or ((g * 255).toInt() shl 8) or (b * 255).toInt()
- }
-
- fun rgba8888(color: Cvec): Int {
- return (color.r * 255).toInt() shl 24 or ((color.g * 255).toInt() shl 16) or ((color.b * 255).toInt() shl 8) or (color.a * 255).toInt()
- }
-
- fun argb8888(color: Cvec): Int {
- return (color.a * 255).toInt() shl 24 or ((color.r * 255).toInt() shl 16) or ((color.g * 255).toInt() shl 8) or (color.b * 255).toInt()
- }
-
- /** Sets the Cvec components using the specified integer value in the format RGBA8888. This is inverse to the rgba8888(r, g,
- * b, a) method.
- *
- * @param color The Cvec to be modified.
- * @param value An integer color value in RGBA8888 format.
- */
- fun rgba8888ToCvec(color: Cvec, value: Int) {
- color.r = (value and -0x1000000).ushr(24) / 255f
- color.g = (value and 0x00ff0000).ushr(16) / 255f
- color.b = (value and 0x0000ff00).ushr(8) / 255f
- color.a = (value and 0x000000ff) / 255f
- }
-
- /** Sets the Cvec components using the specified integer value in the format ARGB8888. This is the inverse to the argb8888(a,
- * r, g, b) method
- *
- * @param color The Cvec to be modified.
- * @param value An integer color value in ARGB8888 format.
- */
- fun argb8888ToCvec(color: Cvec, value: Int) {
- color.a = (value and -0x1000000).ushr(24) / 255f
- color.r = (value and 0x00ff0000).ushr(16) / 255f
- color.g = (value and 0x0000ff00).ushr(8) / 255f
- color.b = (value and 0x000000ff) / 255f
- }
-
- /** Sets the Cvec components using the specified float value in the format ABGB8888.
- * @param color The Cvec to be modified.
- */
- fun abgr8888ToCvec(color: Cvec, value: Float) {
- val c = NumberUtils.floatToIntColor(value)
- color.a = (c and -0x1000000).ushr(24) / 255f
- color.b = (c and 0x00ff0000).ushr(16) / 255f
- color.g = (c and 0x0000ff00).ushr(8) / 255f
- color.r = (c and 0x000000ff) / 255f
- }
- }
+ fun toGdxColor() = com.badlogic.gdx.graphics.Color(
+ vec.lane(0),
+ vec.lane(1),
+ vec.lane(2),
+ vec.lane(3)
+ )
}
diff --git a/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt b/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt
index 2c15ccece..9c2ae471a 100644
--- a/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt
+++ b/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt
@@ -12,11 +12,13 @@ import net.torvald.UnsafeHelper
*/
internal class UnsafeCvecArray(val width: Int, val height: Int) {
- val TOTAL_SIZE_IN_BYTES = 16L * width * height
+ val sizeof = 16L
+
+ val TOTAL_SIZE_IN_BYTES = sizeof * width * height
val array = UnsafeHelper.allocate(TOTAL_SIZE_IN_BYTES)
- private inline fun toAddr(x: Int, y: Int) = 16L * (y * width + x)
+ private inline fun toAddr(x: Int, y: Int) = sizeof * (y * width + x)
fun zerofill() = array.fillWith(0)
@@ -24,35 +26,21 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) {
zerofill()
}
- fun getR(x: Int, y: Int) = array.getFloat(toAddr(x, y))
- fun getG(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 4)
- fun getB(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 8)
- fun getA(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 12)
-
- fun setR(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y), value) }
- fun setG(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 4, value) }
- fun setB(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 8, value) }
- fun setA(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 12, value) }
-
- fun addA(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 12, getA(x, y) + value) }
-
- /**
- * @param channel 0 for R, 1 for G, 2 for B, 3 for A
- */
- inline fun channelSet(x: Int, y: Int, channel: Int, value: Float) {
- array.setFloat(toAddr(x, y) + 4L * channel, value)
+ fun getVec(x: Int, y: Int): Cvec {
+ val addr = toAddr(x, y)
+ return Cvec(
+ array.getFloat(addr),
+ array.getFloat(addr + 4),
+ array.getFloat(addr + 8),
+ array.getFloat(addr + 12)
+ )
}
-
- /**
- * @param channel 0 for R, 1 for G, 2 for B, 3 for A
- */
- inline fun channelGet(x: Int, y: Int, channel: Int) = array.getFloat(toAddr(x, y) + 4L * channel)
-
- fun max(x: Int, y: Int, other: Cvec) {
- setR(x, y, maxOf(getR(x, y), other.r))
- setG(x, y, maxOf(getG(x, y), other.g))
- setB(x, y, maxOf(getB(x, y), other.b))
- setA(x, y, maxOf(getA(x, y), other.a))
+ fun setVec(x: Int, y: Int, value: Cvec) {
+ val addr = toAddr(x, y)
+ array.setFloat(addr, value.vec.lane(0))
+ array.setFloat(addr + 4, value.vec.lane(1))
+ array.setFloat(addr + 8, value.vec.lane(2))
+ array.setFloat(addr + 12, value.vec.lane(3))
}
fun destroy() = this.array.destroy()
diff --git a/src/net/torvald/terrarum/GdxColorMap.kt b/src/net/torvald/terrarum/GdxColorMap.kt
index a46a67de7..341163adf 100644
--- a/src/net/torvald/terrarum/GdxColorMap.kt
+++ b/src/net/torvald/terrarum/GdxColorMap.kt
@@ -75,7 +75,7 @@ class GdxColorMap {
fun getRaw(x: Int, y: Int): RGBA8888 = dataRaw[y * width + x]
fun getRaw(x: Int): RGBA8888 = if (is2D) throw UnsupportedOperationException("This is 2D color map") else dataRaw[x]
- //fun getAsCvec(x: Int, y: Int): Cvec = dataCvec[y * width + x]
+ //fun getAsCvec(x: Int, y: Int): Cvec = dataCvec[y * width + x] // for some reason it just returns zero
override fun toString(): String {
val sb = StringBuilder()
diff --git a/src/net/torvald/terrarum/blockproperties/BlockCodex.kt b/src/net/torvald/terrarum/blockproperties/BlockCodex.kt
index c3244c980..51544623e 100644
--- a/src/net/torvald/terrarum/blockproperties/BlockCodex.kt
+++ b/src/net/torvald/terrarum/blockproperties/BlockCodex.kt
@@ -147,7 +147,7 @@ object BlockCodex {
prop.baseLumColG = floatVal(record, "lumg") / LightmapRenderer.MUL_FLOAT
prop.baseLumColB = floatVal(record, "lumb") / LightmapRenderer.MUL_FLOAT
prop.baseLumColA = floatVal(record, "lumuv") / LightmapRenderer.MUL_FLOAT
- prop.baseLumCol.set(prop.baseLumColR, prop.baseLumColG, prop.baseLumColB, prop.baseLumColA)
+ prop.baseLumCol = Cvec(prop.baseLumColR, prop.baseLumColG, prop.baseLumColB, prop.baseLumColA)
prop.friction = intVal(record, "fr")
prop.viscosity = intVal(record, "vscs")
diff --git a/src/net/torvald/terrarum/blockproperties/BlockProp.kt b/src/net/torvald/terrarum/blockproperties/BlockProp.kt
index 4b2de07f0..befbb48db 100644
--- a/src/net/torvald/terrarum/blockproperties/BlockProp.kt
+++ b/src/net/torvald/terrarum/blockproperties/BlockProp.kt
@@ -20,7 +20,7 @@ class BlockProp {
var shadeColB = 0f
var shadeColA = 0f
- lateinit var opacity: Cvec
+ var opacity: Cvec = Cvec(0f)
fun getOpacity(channel: Int) = when (channel) {
0 -> shadeColR
@@ -51,12 +51,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 = Cvec(0f)
//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 = Cvec(0f)
// X- and Y-value must be treated properly beforehand! (use GameWorld.coerceXY())
fun getLumCol(x: Int, y: Int) = if (dynamicLuminosityFunction == 0) {
baseLumCol
@@ -65,12 +65,6 @@ class BlockProp {
BlockCodex[BlockCodex.dynamicToVirtualMap[id]!! - offset]._lumCol
}
- fun getLumCol(x: Int, y: Int, channel: Int): Float = if (dynamicLuminosityFunction == 0) {
- baseLumCol.getElem(channel)
- } else {
- val offset = XXHash32.hash(((x and 0xFFFF).shl(16) or (y and 0xFFFF)).toLittle(), 10000).fmod(BlockCodex.DYNAMIC_RANDOM_CASES)
- BlockCodex[BlockCodex.dynamicToVirtualMap[id]!! - offset]._lumCol.getElem(channel)
- }
/**
* @param luminosity
diff --git a/src/net/torvald/terrarum/blockproperties/BlockPropUtil.kt b/src/net/torvald/terrarum/blockproperties/BlockPropUtil.kt
index 5ec5626fb..401a8fee8 100644
--- a/src/net/torvald/terrarum/blockproperties/BlockPropUtil.kt
+++ b/src/net/torvald/terrarum/blockproperties/BlockPropUtil.kt
@@ -95,7 +95,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
@@ -111,8 +111,8 @@ object BlockPropUtil {
private fun getDynamicLumFunc(prop: BlockProp): Cvec {
return when (prop.dynamicLuminosityFunction) {
1 -> getTorchFlicker(prop)
- 2 -> (Terrarum.ingame!!.world).globalLight.cpy().mul(LightmapRenderer.DIV_FLOAT) // current global light
- 3 -> WeatherMixer.getGlobalLightOfTime(Terrarum.ingame!!.world, WorldTime.DAY_LENGTH / 2).cpy().mul(LightmapRenderer.DIV_FLOAT) // daylight at noon
+ 2 -> (Terrarum.ingame!!.world).globalLight * LightmapRenderer.DIV_FLOAT_VEC // current global light
+ 3 -> WeatherMixer.getGlobalLightOfTime(Terrarum.ingame!!.world, WorldTime.DAY_LENGTH / 2) * LightmapRenderer.DIV_FLOAT_VEC // daylight at noon
4 -> getSlowBreath(prop)
5 -> getPulsate(prop)
else -> prop.baseLumCol
@@ -141,11 +141,6 @@ object BlockPropUtil {
* @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
- )
+ return data + Cvec(brighten)
}
}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt
index da0d6d70b..8cbe103ec 100644
--- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt
+++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt
@@ -74,10 +74,10 @@ open class ActorHumanoid(
(actorValue.getAsFloat(AVKey.LUMA) ?: 0f) / LightmapRenderer.MUL_FLOAT
)
set(value) {
- actorValue[AVKey.LUMR] = value.r * LightmapRenderer.MUL_FLOAT
- actorValue[AVKey.LUMG] = value.g * LightmapRenderer.MUL_FLOAT
- actorValue[AVKey.LUMB] = value.b * LightmapRenderer.MUL_FLOAT
- actorValue[AVKey.LUMA] = value.a * LightmapRenderer.MUL_FLOAT
+ actorValue[AVKey.LUMR] = value.vec.lane(0) * LightmapRenderer.MUL_FLOAT
+ actorValue[AVKey.LUMG] = value.vec.lane(1) * LightmapRenderer.MUL_FLOAT
+ actorValue[AVKey.LUMB] = value.vec.lane(2) * LightmapRenderer.MUL_FLOAT
+ actorValue[AVKey.LUMA] = value.vec.lane(3) * LightmapRenderer.MUL_FLOAT
}
/**
diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ProjectileSimple.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ProjectileSimple.kt
index c4425de6e..bd8f44b47 100644
--- a/src/net/torvald/terrarum/modulebasegame/gameactors/ProjectileSimple.kt
+++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ProjectileSimple.kt
@@ -33,7 +33,7 @@ open class ProjectileSimple(
override var color: Cvec
- get() = (bulletDatabase[type][OFFSET_LUMINOSITY] as Cvec).cpy()
+ get() = (bulletDatabase[type][OFFSET_LUMINOSITY] as Cvec)
set(value) {
}
/**
diff --git a/src/net/torvald/terrarum/modulebasegame/weather/WeatherMixer.kt b/src/net/torvald/terrarum/modulebasegame/weather/WeatherMixer.kt
index 5b6362b44..2890c5850 100644
--- a/src/net/torvald/terrarum/modulebasegame/weather/WeatherMixer.kt
+++ b/src/net/torvald/terrarum/modulebasegame/weather/WeatherMixer.kt
@@ -48,7 +48,7 @@ internal object WeatherMixer : RNGConsumer {
lateinit var mixedWeather: BaseModularWeather
- val globalLightNow = Cvec(0)
+ var globalLightNow = Cvec(0f)
// Weather indices
const val WEATHER_GENERIC = "generic"
@@ -133,7 +133,7 @@ internal object WeatherMixer : RNGConsumer {
// calculate global light
val globalLight = getGradientColour(world, skyboxColourMap, 2, timeNow)
- globalLightNow.set(globalLight)
+ globalLightNow = globalLight
/* (copied from the shader source)
@@ -250,7 +250,7 @@ internal object WeatherMixer : RNGConsumer {
" | ${colourThis.toStringRGB()} -[${scale.times(100).toInt()}%]-> ${colourNext.toStringRGB()}" +
" | * `$r`$g`$b`")*/
- return Cvec(newCol)
+ return Cvec(newCol.r, newCol.g, newCol.b, newCol.a)
}
fun getWeatherList(classification: String) = weatherList[classification]!!
diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt
index 392c543d6..0a8cd0364 100644
--- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt
+++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt
@@ -146,10 +146,10 @@ class BasicDebugInfoWindow : UICanvas() {
val mtX = mouseTileX.toString()
val mtY = mouseTileY.toString()
val valRaw = LightmapRenderer.getLight(mouseTileX, mouseTileY)
- val rawR = valRaw?.r?.times(100f)?.round()?.div(100f)
- val rawG = valRaw?.g?.times(100f)?.round()?.div(100f)
- val rawB = valRaw?.b?.times(100f)?.round()?.div(100f)
- val rawA = valRaw?.a?.times(100f)?.round()?.div(100f)
+ val rawR = valRaw?.vec?.lane(0)?.times(100f)?.round()?.div(100f)
+ val rawG = valRaw?.vec?.lane(1)?.times(100f)?.round()?.div(100f)
+ val rawB = valRaw?.vec?.lane(2)?.times(100f)?.round()?.div(100f)
+ val rawA = valRaw?.vec?.lane(3)?.times(100f)?.round()?.div(100f)
lightVal = if (valRaw == null) "$EMDASH"
else "$rawR $rawG $rawB $rawA"
diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt
index 434e0d9b0..7a47ac1ef 100644
--- a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt
+++ b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt
@@ -122,7 +122,9 @@ object LightmapRenderer {
const val CHANNEL_MAX_FLOAT = CHANNEL_MAX.toFloat()
const val COLOUR_RANGE_SIZE = MUL * MUL_2
const val MUL_FLOAT = MUL / 256f
+ val MUL_FLOAT_VEC = Cvec(MUL_FLOAT)
const val DIV_FLOAT = 256f / MUL
+ val DIV_FLOAT_VEC = Cvec(DIV_FLOAT)
internal var for_x_start = 0
internal var for_y_start = 0
@@ -159,12 +161,7 @@ object LightmapRenderer {
val x = x.convX()
val y = y.convY()
- return Cvec(
- lightmap.getR(x, y) * MUL_FLOAT,
- lightmap.getG(x, y) * MUL_FLOAT,
- lightmap.getB(x, y) * MUL_FLOAT,
- lightmap.getA(x, y) * MUL_FLOAT
- )
+ return lightmap.getVec(x, y) * MUL_FLOAT_VEC
}
}
@@ -221,7 +218,7 @@ object LightmapRenderer {
*/
// set sunlight
- sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT)
+ sunLight = world.globalLight * DIV_FLOAT_VEC
// set no-op mask from solidity of the block
AppLoader.measureDebugTime("Renderer.LightNoOpMask") {
@@ -506,7 +503,7 @@ object LightmapRenderer {
*
* @return true if skip
*/
- private fun radiate(channel: Int, wx: Int, wy: Int, lightsource: Cvec, distSqr: Int): Boolean {
+ /*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)
@@ -537,28 +534,25 @@ object LightmapRenderer {
if (inNoopMask(worldX, worldY)) return false
// just quick snippets to make test work
- lightLevelThis.set(colourNull)
- thisTileOpacity.set(BlockCodex[world.getTileFromTerrain(worldX, worldY)].opacity)
+ thisTileOpacity = 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))
+ lightLevelThis = lightLevelThis max
+ /* + *///darkenColoured(x - 1, y - 1, thisTileOpacity2) max
+ /* + *///darkenColoured(x + 1, y - 1, thisTileOpacity2) max
+ /* + *///darkenColoured(x - 1, y + 1, thisTileOpacity2) max
+ /* + *///darkenColoured(x + 1, y + 1, thisTileOpacity2) max
+ /* * */darkenColoured(x, y - 1, thisTileOpacity) max
+ /* * */darkenColoured(x, y + 1, thisTileOpacity) max
+ /* * */darkenColoured(x - 1, y, thisTileOpacity) max
+ /* * */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)
+ lightmap.setVec(x, y, lightLevelThis)
return false
- }
+ }*/
// TODO re-init at every resize
@@ -677,12 +671,12 @@ 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)
- private val sunLight = Cvec(0)
+ private var lightLevelThis = Cvec(0f)
+ private var fluidAmountToCol = Cvec(0f)
+ private var thisTileLuminosity = Cvec(0f)
+ private var thisTileOpacity = Cvec(0f)
+ private var thisTileOpacity2 = Cvec(0f) // thisTileOpacity * sqrt(2)
+ private var sunLight = Cvec(0f)
private var thisFluid = GameWorld.FluidInfo(Fluid.NULL, 0f)
private var thisTerrain = 0
private var thisWall = 0
@@ -694,6 +688,8 @@ object LightmapRenderer {
private var thisTileOpacityCh = 0f
private var thisTileOpacity2Ch = 0f
+ private val SQRT2_VEC = Cvec(1.41421356f)
+
/**
* This function will alter following variables:
* - lightLevelThis
@@ -708,7 +704,7 @@ object LightmapRenderer {
private fun getLightsAndShades(x: Int, y: Int) {
val (x, y) = world.coerceXY(x, y)
- lightLevelThis.set(colourNull)
+ lightLevelThis = colourNull
thisTerrain = world.getTileFromTerrainRaw(x, y)
thisFluid = world.getFluid(x, y)
thisWall = world.getTileFromWallRaw(x, y)
@@ -736,84 +732,29 @@ object LightmapRenderer {
}
if (thisFluid.type != Fluid.NULL) {
- fluidAmountToCol.set(thisFluid.amount, thisFluid.amount, thisFluid.amount, thisFluid.amount)
+ fluidAmountToCol = Cvec(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
+ thisTileLuminosity = BlockCodex[thisTerrain].getLumCol(x, y) max
+ (BlockCodex[thisFluid.type].getLumCol(x, y) * fluidAmountToCol) // already been div by four
+ thisTileOpacity = BlockCodex[thisTerrain].opacity max
+ (BlockCodex[thisFluid.type].opacity * fluidAmountToCol) // already been div by four
}
else {
- thisTileLuminosity.set(BlockCodex[thisTerrain].getLumCol(x, y))
- thisTileOpacity.set(BlockCodex[thisTerrain].opacity)
+ thisTileLuminosity = BlockCodex[thisTerrain].getLumCol(x, y)
+ thisTileOpacity = BlockCodex[thisTerrain].opacity
}
- thisTileOpacity2.set(thisTileOpacity); thisTileOpacity2.mul(1.41421356f)
+ thisTileOpacity2 = thisTileOpacity * SQRT2_VEC
//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)
+ lightLevelThis = 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)
+ lightLevelThis = lightLevelThis max thisTileLuminosity max (lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: colourNull)
}
private val inNoopMaskp = Point2i(0,0)
@@ -888,70 +829,35 @@ object LightmapRenderer {
// will "overwrite" what's there in the lightmap if it's the first pass
// takes about 2 ms on 6700K
- /* + */lightLevelThis.maxAndAssign(darkenColoured(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))
+ lightLevelThis = lightLevelThis max
+ /* + */darkenColoured(x - 1, y - 1, thisTileOpacity2) max
+ /* + */darkenColoured(x + 1, y - 1, thisTileOpacity2) max
+ /* + */darkenColoured(x - 1, y + 1, thisTileOpacity2) max
+ /* + */darkenColoured(x + 1, y + 1, thisTileOpacity2) max
+ /* * */darkenColoured(x, y - 1, thisTileOpacity) max
+ /* * */darkenColoured(x, y + 1, thisTileOpacity) max
+ /* * */darkenColoured(x - 1, y, thisTileOpacity) max
+ /* * */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.setR(x, y, lightLevelThis.r)
- lightmap.setG(x, y, lightLevelThis.g)
- lightmap.setB(x, y, lightLevelThis.b)
- lightmap.setA(x, y, lightLevelThis.a)
+ lightmap.setVec(x, y, lightLevelThis)
}
- // 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 val SOLIDMULTMAGIC_FALSE = Cvec(1f)
+ private val SOLIDMULTMAGIC_TRUE = Cvec(1.2f)
+ private fun isSolid(x: Int, y: Int): Cvec? { // ...so that they wouldn't appear too dark
if (!inBounds(x, y)) return null
// brighten if solid
- return if (BlockCodex[world.getTileFromTerrain(x, y)].isSolid) 1.2f else 1f
+ return if (BlockCodex[world.getTileFromTerrain(x, y)].isSolid) SOLIDMULTMAGIC_TRUE else SOLIDMULTMAGIC_FALSE
}
var lightBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
- private val colourNull = Cvec(0)
+ private val colourNull = Cvec(0f)
private val gdxColorNull = Color(0)
private const val epsilon = 1f/1024f
@@ -990,12 +896,7 @@ object LightmapRenderer {
val color = if (solidMultMagic == null)
gdxColorNull
else
- Color(
- lightmap.getR(arrayX, arrayY) * solidMultMagic,
- lightmap.getG(arrayX, arrayY) * solidMultMagic,
- lightmap.getB(arrayX, arrayY) * solidMultMagic,
- lightmap.getA(arrayX, arrayY) * solidMultMagic
- ).normaliseToHDR()
+ lightmap.getVec(arrayX, arrayY).times(solidMultMagic).toGdxColor().normaliseToHDR()
lightBuffer.setColor(color)
@@ -1028,7 +929,8 @@ object LightmapRenderer {
lightmap.destroy()
}
- private const val lightScalingMagic = 8f
+ private val lightScalingMagic = Cvec(8f)
+ private val CVEC_ONE = Cvec(1f)
/**
* Subtract each channel's RGB value.
@@ -1050,30 +952,7 @@ object LightmapRenderer {
if (x !in 0 until LIGHTMAP_WIDTH || y !in 0 until LIGHTMAP_HEIGHT) return colourNull
- return Cvec(
- lightmap.getR(x, y) * (1f - darken.r * lightScalingMagic),
- lightmap.getG(x, y) * (1f - darken.g * lightScalingMagic),
- lightmap.getB(x, y) * (1f - darken.b * lightScalingMagic),
- lightmap.getA(x, y) * (1f - darken.a * lightScalingMagic)
- )
-
- }
-
- 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 */
- 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
- // that was because you forgot 'this.r/g/b/a = ' part, bitch. --Torvald, 2019-06-07
- this.r = if (this.r > other.r) this.r else other.r
- this.g = if (this.g > other.g) this.g else other.g
- this.b = if (this.b > other.b) this.b else other.b
- this.a = if (this.a > other.a) this.a else other.a
-
- return this
+ return lightmap.getVec(x, y) * (CVEC_ONE - darken * lightScalingMagic)
}
private fun Float.inv() = 1f / this
@@ -1142,11 +1021,6 @@ object LightmapRenderer {
hdr(this.a.coerceIn(0f, 1f))
)
- private fun Cvec.nonZero() = this.r.abs() > epsilon ||
- this.g.abs() > epsilon ||
- this.b.abs() > epsilon ||
- this.a.abs() > epsilon
-
val histogram: Histogram
get() {
val reds = IntArray(MUL) // reds[intensity] ← counts
@@ -1226,6 +1100,5 @@ 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()