mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
Light Calculation using JDK Incubator Vector
This commit is contained in:
3
.idea/compiler.xml
generated
3
.idea/compiler.xml
generated
@@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
|
<option name="BUILD_PROCESS_HEAP_SIZE" value="2048" />
|
||||||
|
<option name="BUILD_PROCESS_ADDITIONAL_VM_OPTIONS" value="--enable-preview" />
|
||||||
<annotationProcessing>
|
<annotationProcessing>
|
||||||
<profile default="true" name="Default" enabled="true" />
|
<profile default="true" name="Default" enabled="true" />
|
||||||
</annotationProcessing>
|
</annotationProcessing>
|
||||||
@@ -8,5 +10,6 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="JavacSettings">
|
<component name="JavacSettings">
|
||||||
<option name="PREFER_TARGET_JDK_COMPILER" value="false" />
|
<option name="PREFER_TARGET_JDK_COMPILER" value="false" />
|
||||||
|
<option name="ADDITIONAL_OPTIONS_STRING" value="--enable-preview" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
5
.idea/kotlinc.xml
generated
5
.idea/kotlinc.xml
generated
@@ -1,9 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="Kotlin2JsCompilerArguments">
|
|
||||||
<option name="sourceMapEmbedSources" />
|
|
||||||
</component>
|
|
||||||
<component name="Kotlin2JvmCompilerArguments">
|
<component name="Kotlin2JvmCompilerArguments">
|
||||||
<option name="jvmTarget" value="1.8" />
|
<option name="jvmTarget" value="17" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
2
.idea/runConfigurations/Terrarum.xml
generated
2
.idea/runConfigurations/Terrarum.xml
generated
@@ -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" />
|
<option name="VM_PARAMETERS" value="--enable-preview --add-modules=jdk.incubator.vector -ea" />
|
||||||
<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" />
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Terrarum (no DEV MODE)" type="JarApplication">
|
<configuration default="false" name="Terrarum (no DEV MODE)" 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="--enable-preview --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" />
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ module Terrarum {
|
|||||||
requires java.desktop;
|
requires java.desktop;
|
||||||
requires java.logging;
|
requires java.logging;
|
||||||
requires jdk.unsupported; // sun.misc.Unsafe
|
requires jdk.unsupported; // sun.misc.Unsafe
|
||||||
|
requires jdk.incubator.vector;
|
||||||
|
|
||||||
// kotlin
|
// kotlin
|
||||||
requires kotlin.stdlib;
|
requires kotlin.stdlib;
|
||||||
|
|||||||
@@ -18,12 +18,16 @@ package net.torvald.gdx.graphics
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.utils.NumberUtils
|
import com.badlogic.gdx.utils.NumberUtils
|
||||||
|
import jdk.incubator.vector.FloatVector
|
||||||
|
import jdk.incubator.vector.FloatVector.SPECIES_128
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Cvec is kind of a Vector4f made compatible with LibGdx's Color class, with the intention of actually utilising
|
* 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.
|
* the JEP 338 VectorInstrinsics later, when the damned thing finally releases.
|
||||||
*
|
*
|
||||||
* Before then, the code will be identical to LibGdx's.
|
* Before then, the code will be identical to LibGdx's.
|
||||||
|
*
|
||||||
|
* THIS CLASS MUST NOT BE SERIALISED
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** A color class, holding the r, g, b and alpha component as floats in the range [0,1]. All methods perform clamping on the
|
/** A color class, holding the r, g, b and alpha component as floats in the range [0,1]. All methods perform clamping on the
|
||||||
@@ -33,11 +37,13 @@ import com.badlogic.gdx.utils.NumberUtils
|
|||||||
*/
|
*/
|
||||||
class Cvec {
|
class Cvec {
|
||||||
|
|
||||||
|
var vec = FloatVector.broadcast(SPECIES_128, 0f); private set
|
||||||
|
|
||||||
/** the red, green, blue and alpha components */
|
/** the red, green, blue and alpha components */
|
||||||
var r: Float = 0f
|
val r: Float; get() = vec.lane(0)
|
||||||
var g: Float = 0f
|
val g: Float; get() = vec.lane(1)
|
||||||
var b: Float = 0f
|
val b: Float; get() = vec.lane(2)
|
||||||
var a: Float = 0f
|
val a: Float; get() = vec.lane(3)
|
||||||
|
|
||||||
/** Constructs a new Cvec with all components set to 0. */
|
/** Constructs a new Cvec with all components set to 0. */
|
||||||
constructor() {}
|
constructor() {}
|
||||||
@@ -48,11 +54,16 @@ class Cvec {
|
|||||||
rgba8888ToCvec(this, rgba8888)
|
rgba8888ToCvec(this, rgba8888)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(scalar: Float) {
|
||||||
|
vec = FloatVector.broadcast(SPECIES_128, scalar)
|
||||||
|
}
|
||||||
|
|
||||||
constructor(color: Color) {
|
constructor(color: Color) {
|
||||||
this.r = color.r
|
vec = FloatVector.fromArray(SPECIES_128, floatArrayOf(color.r, color.g, color.b, color.a), 0)
|
||||||
this.g = color.g
|
}
|
||||||
this.b = color.b
|
|
||||||
this.a = color.a
|
constructor(vec: FloatVector) {
|
||||||
|
this.vec = vec
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructor, sets the components of the color
|
/** Constructor, sets the components of the color
|
||||||
@@ -63,10 +74,7 @@ class Cvec {
|
|||||||
* @param a the alpha component
|
* @param a the alpha component
|
||||||
*/
|
*/
|
||||||
constructor(r: Float, g: Float, b: Float, a: Float) {
|
constructor(r: Float, g: Float, b: Float, a: Float) {
|
||||||
this.r = r
|
vec = FloatVector.fromArray(SPECIES_128, floatArrayOf(r, g, b, a), 0)
|
||||||
this.g = g
|
|
||||||
this.b = b
|
|
||||||
this.a = a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs a new color using the given color
|
/** Constructs a new color using the given color
|
||||||
@@ -77,10 +85,10 @@ class Cvec {
|
|||||||
set(color)
|
set(color)
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun component1() = r
|
// operator fun component1() = r
|
||||||
operator fun component2() = g
|
// operator fun component2() = g
|
||||||
operator fun component3() = b
|
// operator fun component3() = b
|
||||||
operator fun component4() = a
|
// operator fun component4() = a
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get RGBA Element using index, of which:
|
* Get RGBA Element using index, of which:
|
||||||
@@ -89,23 +97,24 @@ class Cvec {
|
|||||||
* - 2: B
|
* - 2: B
|
||||||
* - 3: A
|
* - 3: A
|
||||||
*/
|
*/
|
||||||
fun getElem(index: Int) = when(index) {
|
inline fun getElem(index: Int) = vec.lane(index)
|
||||||
0 -> r
|
|
||||||
1 -> g
|
|
||||||
2 -> b
|
|
||||||
3 -> a
|
|
||||||
else -> throw IndexOutOfBoundsException("Invalid index $index")
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets this color to the given color.
|
/** Sets this color to the given color.
|
||||||
*
|
*
|
||||||
* @param color the Cvec
|
* @param color the Cvec
|
||||||
*/
|
*/
|
||||||
fun set(color: Cvec): Cvec {
|
fun set(color: Cvec): Cvec {
|
||||||
this.r = color.r
|
this.vec = color.vec
|
||||||
this.g = color.g
|
return this
|
||||||
this.b = color.b
|
}
|
||||||
this.a = color.a
|
|
||||||
|
fun set(vec: FloatVector): Cvec {
|
||||||
|
this.vec = vec
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun set(scalar: Float): Cvec {
|
||||||
|
this.vec = FloatVector.broadcast(SPECIES_128, scalar)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,10 +124,7 @@ class Cvec {
|
|||||||
* @return this color.
|
* @return this color.
|
||||||
*/
|
*/
|
||||||
fun mul(color: Cvec): Cvec {
|
fun mul(color: Cvec): Cvec {
|
||||||
this.r *= color.r
|
this.vec = this.vec.mul(color.vec)
|
||||||
this.g *= color.g
|
|
||||||
this.b *= color.b
|
|
||||||
this.a *= color.a
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,10 +134,7 @@ class Cvec {
|
|||||||
* @return this color
|
* @return this color
|
||||||
*/
|
*/
|
||||||
fun mul(value: Float): Cvec {
|
fun mul(value: Float): Cvec {
|
||||||
this.r *= value
|
this.vec = this.vec.mul(value)
|
||||||
this.g *= value
|
|
||||||
this.b *= value
|
|
||||||
this.a *= value
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,10 +144,7 @@ class Cvec {
|
|||||||
* @return this color
|
* @return this color
|
||||||
*/
|
*/
|
||||||
fun add(color: Cvec): Cvec {
|
fun add(color: Cvec): Cvec {
|
||||||
this.r += color.r
|
this.vec = this.vec.add(color.vec)
|
||||||
this.g += color.g
|
|
||||||
this.b += color.b
|
|
||||||
this.a += color.a
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,10 +154,12 @@ class Cvec {
|
|||||||
* @return this color
|
* @return this color
|
||||||
*/
|
*/
|
||||||
fun sub(color: Cvec): Cvec {
|
fun sub(color: Cvec): Cvec {
|
||||||
this.r -= color.r
|
this.vec = this.vec.sub(color.vec)
|
||||||
this.g -= color.g
|
return this
|
||||||
this.b -= color.b
|
}
|
||||||
this.a -= color.a
|
|
||||||
|
fun max(color: Cvec): Cvec {
|
||||||
|
this.vec = this.vec.max(color.vec)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,10 +173,7 @@ class Cvec {
|
|||||||
* @return this Cvec for chaining
|
* @return this Cvec for chaining
|
||||||
*/
|
*/
|
||||||
operator fun set(r: Float, g: Float, b: Float, a: Float): Cvec {
|
operator fun set(r: Float, g: Float, b: Float, a: Float): Cvec {
|
||||||
this.r = r
|
vec = FloatVector.fromArray(SPECIES_128, floatArrayOf(r, g, b, a), 0)
|
||||||
this.g = g
|
|
||||||
this.b = b
|
|
||||||
this.a = a
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,96 +187,6 @@ class Cvec {
|
|||||||
return this
|
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(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other == null || javaClass != other.javaClass) return false
|
if (other == null || javaClass != other.javaClass) return false
|
||||||
@@ -317,102 +226,8 @@ class Cvec {
|
|||||||
value = "0$value"
|
value = "0$value"
|
||||||
return 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)
|
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
|
/** @return a copy of this color
|
||||||
*/
|
*/
|
||||||
fun cpy(): Cvec {
|
fun cpy(): Cvec {
|
||||||
@@ -474,10 +289,11 @@ class Cvec {
|
|||||||
* @param value An integer color value in RGBA8888 format.
|
* @param value An integer color value in RGBA8888 format.
|
||||||
*/
|
*/
|
||||||
fun rgba8888ToCvec(color: Cvec, value: Int) {
|
fun rgba8888ToCvec(color: Cvec, value: Int) {
|
||||||
color.r = (value and -0x1000000).ushr(24) / 255f
|
val r = (value and -0x1000000).ushr(24) / 255f
|
||||||
color.g = (value and 0x00ff0000).ushr(16) / 255f
|
val g = (value and 0x00ff0000).ushr(16) / 255f
|
||||||
color.b = (value and 0x0000ff00).ushr(8) / 255f
|
val b = (value and 0x0000ff00).ushr(8) / 255f
|
||||||
color.a = (value and 0x000000ff) / 255f
|
val a = (value and 0x000000ff) / 255f
|
||||||
|
color.vec = FloatVector.fromArray(SPECIES_128, floatArrayOf(r, g, b, a), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the Cvec components using the specified integer value in the format ARGB8888. This is the inverse to the argb8888(a,
|
/** Sets the Cvec components using the specified integer value in the format ARGB8888. This is the inverse to the argb8888(a,
|
||||||
@@ -487,10 +303,11 @@ class Cvec {
|
|||||||
* @param value An integer color value in ARGB8888 format.
|
* @param value An integer color value in ARGB8888 format.
|
||||||
*/
|
*/
|
||||||
fun argb8888ToCvec(color: Cvec, value: Int) {
|
fun argb8888ToCvec(color: Cvec, value: Int) {
|
||||||
color.a = (value and -0x1000000).ushr(24) / 255f
|
val a = (value and -0x1000000).ushr(24) / 255f
|
||||||
color.r = (value and 0x00ff0000).ushr(16) / 255f
|
val r = (value and 0x00ff0000).ushr(16) / 255f
|
||||||
color.g = (value and 0x0000ff00).ushr(8) / 255f
|
val g = (value and 0x0000ff00).ushr(8) / 255f
|
||||||
color.b = (value and 0x000000ff) / 255f
|
val b = (value and 0x000000ff) / 255f
|
||||||
|
color.vec = FloatVector.fromArray(SPECIES_128, floatArrayOf(r, g, b, a), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the Cvec components using the specified float value in the format ABGB8888.
|
/** Sets the Cvec components using the specified float value in the format ABGB8888.
|
||||||
@@ -498,10 +315,11 @@ class Cvec {
|
|||||||
*/
|
*/
|
||||||
fun abgr8888ToCvec(color: Cvec, value: Float) {
|
fun abgr8888ToCvec(color: Cvec, value: Float) {
|
||||||
val c = NumberUtils.floatToIntColor(value)
|
val c = NumberUtils.floatToIntColor(value)
|
||||||
color.a = (c and -0x1000000).ushr(24) / 255f
|
val a = (c and -0x1000000).ushr(24) / 255f
|
||||||
color.b = (c and 0x00ff0000).ushr(16) / 255f
|
val b = (c and 0x00ff0000).ushr(16) / 255f
|
||||||
color.g = (c and 0x0000ff00).ushr(8) / 255f
|
val g = (c and 0x0000ff00).ushr(8) / 255f
|
||||||
color.r = (c and 0x000000ff) / 255f
|
val r = (c and 0x000000ff) / 255f
|
||||||
|
color.vec = FloatVector.fromArray(SPECIES_128, floatArrayOf(r, g, b, a), 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package net.torvald.gdx.graphics
|
package net.torvald.gdx.graphics
|
||||||
|
|
||||||
|
import jdk.incubator.vector.FloatVector
|
||||||
import net.torvald.unsafe.UnsafeHelper
|
import net.torvald.unsafe.UnsafeHelper
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
import java.nio.ByteOrder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basically just a FloatArray. You may need to re-write the entire code to actually store the Vectors,
|
* Basically just a FloatArray. You may need to re-write the entire code to actually store the Vectors,
|
||||||
@@ -18,7 +21,9 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) {
|
|||||||
|
|
||||||
private inline fun toAddr(x: Int, y: Int) = 4L * (y * width + x)
|
private inline fun toAddr(x: Int, y: Int) = 4L * (y * width + x)
|
||||||
|
|
||||||
fun isDestroyed() = array.destroyed
|
// fun isDestroyed() = array.destroyed
|
||||||
|
|
||||||
|
private val byteOrder = ByteOrder.nativeOrder()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
zerofill()
|
zerofill()
|
||||||
@@ -29,152 +34,65 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) {
|
|||||||
fun getG(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 1)
|
fun getG(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 1)
|
||||||
fun getB(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 2)
|
fun getB(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 2)
|
||||||
fun getA(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 3)
|
fun getA(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 3)
|
||||||
inline fun getVec(x: Int, y: Int) = Cvec(
|
inline fun getVec(x: Int, y: Int) = Cvec(getFloatVector(x, y))
|
||||||
array.getFloat(toAddr(x, y)),
|
inline fun getFloatVector(x: Int, y: Int): FloatVector {
|
||||||
array.getFloat(toAddr(x, y) + 1),
|
val offset = toAddr(x, y)
|
||||||
array.getFloat(toAddr(x, y) + 2),
|
val array = floatArrayOf(
|
||||||
array.getFloat(toAddr(x, y) + 3)
|
array.getFloat(offset),
|
||||||
)
|
array.getFloat(offset + 1),
|
||||||
/**
|
array.getFloat(offset + 2),
|
||||||
* @param channel 0 for R, 1 for G, 2 for B, 3 for A
|
array.getFloat(offset + 3)
|
||||||
*/
|
)
|
||||||
fun channelGet(x: Int, y: Int, channel: Int) = array.getFloat(toAddr(x, y) + channel)
|
return FloatVector.fromArray(FloatVector.SPECIES_128, array, 0)
|
||||||
|
}
|
||||||
// setters
|
// setters
|
||||||
fun zerofill() = array.fillWith(0)
|
fun zerofill() {
|
||||||
fun setR(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y), value) }
|
array.fillWith(0)
|
||||||
fun setG(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 1, value) }
|
}
|
||||||
fun setB(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 2, value) }
|
// fun setR(x: Int, y: Int, value: Float) { array.putFloat(toAddr(x, y), value) }
|
||||||
fun setA(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 3, value) }
|
// fun setG(x: Int, y: Int, value: Float) { array.putFloat(toAddr(x, y) + 1, value) }
|
||||||
|
// fun setB(x: Int, y: Int, value: Float) { array.putFloat(toAddr(x, y) + 2, value) }
|
||||||
|
// fun setA(x: Int, y: Int, value: Float) { array.putFloat(toAddr(x, y) + 3, value) }
|
||||||
inline fun setVec(x: Int, y: Int, value: Cvec) {
|
inline fun setVec(x: Int, y: Int, value: Cvec) {
|
||||||
array.setFloat(toAddr(x, y), value.r)
|
setFromFloatVector(x, y, value.vec)
|
||||||
array.setFloat(toAddr(x, y) + 1, value.g)
|
|
||||||
array.setFloat(toAddr(x, y) + 2, value.b)
|
|
||||||
array.setFloat(toAddr(x, y) + 3, value.a)
|
|
||||||
}
|
}
|
||||||
inline fun setScalar(x: Int, y: Int, value: Float) {
|
|
||||||
array.setFloat(toAddr(x, y), value)
|
inline fun setFromFloatVector(x: Int, y: Int, value: FloatVector) {
|
||||||
array.setFloat(toAddr(x, y) + 1, value)
|
val offset = toAddr(x, y)
|
||||||
array.setFloat(toAddr(x, y) + 2, value)
|
value.toArray().forEachIndexed { index, fl ->
|
||||||
array.setFloat(toAddr(x, y) + 3, value)
|
array.setFloat(offset + index, fl)
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @param channel 0 for R, 1 for G, 2 for B, 3 for A
|
|
||||||
*/
|
|
||||||
fun channelSet(x: Int, y: Int, channel: Int, value: Float) {
|
|
||||||
array.setFloat(toAddr(x, y) + channel, value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// operators
|
// operators
|
||||||
inline fun max(x: Int, y: Int, other: Cvec) {
|
inline fun max(x: Int, y: Int, other: Cvec) {
|
||||||
setR(x, y, maxOf(getR(x, y), other.r))
|
setFromFloatVector(x, y, getFloatVector(x, y).max(other.vec))
|
||||||
setG(x, y, maxOf(getG(x, y), other.g))
|
|
||||||
setB(x, y, maxOf(getB(x, y), other.b))
|
|
||||||
setA(x, y, maxOf(getA(x, y), other.a))
|
|
||||||
}
|
}
|
||||||
inline fun mul(x: Int, y: Int, scalar: Float) {
|
inline fun mul(x: Int, y: Int, scalar: Float) {
|
||||||
setR(x, y, getR(x, y) * scalar)
|
setFromFloatVector(x, y, getFloatVector(x, y).mul(scalar))
|
||||||
setG(x, y, getG(x, y) * scalar)
|
|
||||||
setB(x, y, getB(x, y) * scalar)
|
|
||||||
setA(x, y, getA(x, y) * scalar)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mulAndAssign(x: Int, y: Int, scalar: Float) {
|
/*fun mulAndAssign(x: Int, y: Int, scalar: Float) {
|
||||||
val addr = toAddr(x, y)
|
val addr = toAddr(x, y)
|
||||||
for (k in 0..3) {
|
for (k in 0..3) {
|
||||||
array.setFloat(addr + k, (array.getFloat(addr + k) * scalar))
|
array.putFloat(addr + k, (array.getFloat(addr + k) * scalar))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun forAllMulAssign(scalar: Float) {
|
fun forAllMulAssign(scalar: Float) {
|
||||||
for (i in 0 until TOTAL_SIZE_IN_BYTES / 4) {
|
for (i in 0 until TOTAL_SIZE_IN_BYTES / 4) {
|
||||||
array.setFloat(i, array.getFloat(i) * scalar)
|
array.putFloat(i, array.getFloat(i) * scalar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun forAllMulAssign(vector: Cvec) {
|
fun forAllMulAssign(vector: Cvec) {
|
||||||
for (i in 0 until TOTAL_SIZE_IN_BYTES / 4 step 4) {
|
for (i in 0 until TOTAL_SIZE_IN_BYTES / 4 step 4) {
|
||||||
for (k in 0 until 4) {
|
for (k in 0 until 4) {
|
||||||
array.setFloat(i + 4*k, array.getFloat(i + k) * vector.getElem(k))
|
array.putFloat(i + 4*k, array.getFloat(i + k) * vector.getElem(k))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
fun destroy() = this.array.destroy()
|
fun destroy() = this.array.destroy()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Safe (and slower) version of UnsafeCvecArray utilised to tackle down the SEGFAULT
|
|
||||||
*/
|
|
||||||
internal class TestCvecArr(val width: Int, val height: Int) {
|
|
||||||
|
|
||||||
val TOTAL_SIZE_IN_BYTES = 4 * width * height
|
|
||||||
|
|
||||||
val array = FloatArray(TOTAL_SIZE_IN_BYTES)
|
|
||||||
|
|
||||||
private inline fun toAddr(x: Int, y: Int) = 4 * (y * width + x)
|
|
||||||
|
|
||||||
init {
|
|
||||||
zerofill()
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
fun getR(x: Int, y: Int) = array.get(toAddr(x, y))
|
|
||||||
fun getG(x: Int, y: Int) = array.get(toAddr(x, y) + 1)
|
|
||||||
fun getB(x: Int, y: Int) = array.get(toAddr(x, y) + 2)
|
|
||||||
fun getA(x: Int, y: Int) = array.get(toAddr(x, y) + 3)
|
|
||||||
inline fun getVec(x: Int, y: Int) = Cvec(
|
|
||||||
array.get(toAddr(x, y)),
|
|
||||||
array.get(toAddr(x, y) + 1),
|
|
||||||
array.get(toAddr(x, y) + 2),
|
|
||||||
array.get(toAddr(x, y) + 3)
|
|
||||||
)
|
|
||||||
/**
|
|
||||||
* @param channel 0 for R, 1 for G, 2 for B, 3 for A
|
|
||||||
*/
|
|
||||||
fun channelGet(x: Int, y: Int, channel: Int) = array.get(toAddr(x, y) + 1 * channel)
|
|
||||||
|
|
||||||
// setters
|
|
||||||
fun zerofill() = array.fill(0f)
|
|
||||||
fun setR(x: Int, y: Int, value: Float) { array.set(toAddr(x, y), value) }
|
|
||||||
fun setG(x: Int, y: Int, value: Float) { array.set(toAddr(x, y) + 1, value) }
|
|
||||||
fun setB(x: Int, y: Int, value: Float) { array.set(toAddr(x, y) + 2, value) }
|
|
||||||
fun setA(x: Int, y: Int, value: Float) { array.set(toAddr(x, y) + 3, value) }
|
|
||||||
inline fun setVec(x: Int, y: Int, value: Cvec) {
|
|
||||||
array.set(toAddr(x, y), value.r)
|
|
||||||
array.set(toAddr(x, y) + 1, value.g)
|
|
||||||
array.set(toAddr(x, y) + 2, value.b)
|
|
||||||
array.set(toAddr(x, y) + 3, value.a)
|
|
||||||
}
|
|
||||||
inline fun setScalar(x: Int, y: Int, value: Float) {
|
|
||||||
array.set(toAddr(x, y), value)
|
|
||||||
array.set(toAddr(x, y) + 1, value)
|
|
||||||
array.set(toAddr(x, y) + 2, value)
|
|
||||||
array.set(toAddr(x, y) + 3, value)
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param channel 0 for R, 1 for G, 2 for B, 3 for A
|
|
||||||
*/
|
|
||||||
fun channelSet(x: Int, y: Int, channel: Int, value: Float) {
|
|
||||||
array.set(toAddr(x, y) + 1 * channel, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// operators
|
|
||||||
inline fun max(x: Int, y: Int, other: Cvec) {
|
|
||||||
setR(x, y, maxOf(getR(x, y), other.r))
|
|
||||||
setG(x, y, maxOf(getG(x, y), other.g))
|
|
||||||
setB(x, y, maxOf(getB(x, y), other.b))
|
|
||||||
setA(x, y, maxOf(getA(x, y), other.a))
|
|
||||||
}
|
|
||||||
inline fun mul(x: Int, y: Int, scalar: Float) {
|
|
||||||
setR(x, y, getR(x, y) * scalar)
|
|
||||||
setG(x, y, getG(x, y) * scalar)
|
|
||||||
setB(x, y, getB(x, y) * scalar)
|
|
||||||
setA(x, y, getA(x, y) * scalar)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun destroy() = {}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -54,12 +54,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 val baseLumCol = Cvec(0f)
|
||||||
//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 val _lumCol = Cvec(0f)
|
||||||
// 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
|
||||||
|
|||||||
@@ -137,11 +137,6 @@ object BlockPropUtil {
|
|||||||
* @return processed colour
|
* @return processed colour
|
||||||
*/
|
*/
|
||||||
private fun alterBrightnessUniform(data: Cvec, brighten: Float): Cvec {
|
private fun alterBrightnessUniform(data: Cvec, brighten: Float): Cvec {
|
||||||
return Cvec(
|
return Cvec(data.vec.add(brighten))
|
||||||
data.r + brighten,
|
|
||||||
data.g + brighten,
|
|
||||||
data.b + brighten,
|
|
||||||
data.a + brighten
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
|
|
||||||
lateinit var mixedWeather: BaseModularWeather
|
lateinit var mixedWeather: BaseModularWeather
|
||||||
|
|
||||||
val globalLightNow = Cvec(0)
|
val globalLightNow = Cvec(0f)
|
||||||
|
|
||||||
// Weather indices
|
// Weather indices
|
||||||
const val WEATHER_GENERIC = "generic"
|
const val WEATHER_GENERIC = "generic"
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package net.torvald.terrarum.worlddrawer
|
|||||||
import com.badlogic.gdx.graphics.Color
|
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 jdk.incubator.vector.FloatVector
|
||||||
|
import jdk.incubator.vector.FloatVector.SPECIES_128
|
||||||
import net.torvald.gdx.graphics.Cvec
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.gdx.graphics.UnsafeCvecArray
|
import net.torvald.gdx.graphics.UnsafeCvecArray
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
@@ -365,10 +367,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)] ?: Cvec(0f) // 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -384,10 +386,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)] ?: Cvec(0f) // 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,20 +435,23 @@ object LightmapRenderer {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
// local variables that are made static
|
// local variables that are made static
|
||||||
private val sunLight = Cvec(0)
|
private val sunLight = Cvec(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 = Cvec(0f)
|
||||||
private val _reflectanceAccumulator = Cvec(0)
|
private var _reflectanceAccumulator = Cvec(0f)
|
||||||
private val _thisTileOpacity = Cvec(0)
|
private var _thisTileOpacity = Cvec(0f)
|
||||||
private val _thisTileOpacity2 = Cvec(0) // thisTileOpacity * sqrt(2)
|
private var _thisTileOpacity2 = Cvec(0f) // thisTileOpacity * sqrt(2)
|
||||||
private val _fluidAmountToCol = Cvec(0)
|
private var _fluidAmountToCol = Cvec(0f)
|
||||||
private val _thisTileLuminosity = Cvec(0)
|
private var _thisTileLuminosity = Cvec(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()
|
||||||
|
|
||||||
|
private val VECTOR_ZERO = Cvec(0f)
|
||||||
|
private val VECTOR_ONE = Cvec(1f)
|
||||||
|
|
||||||
private fun precalculate(rawx: Int, rawy: Int) {
|
private fun precalculate(rawx: Int, rawy: Int) {
|
||||||
val lx = rawx.convX(); val ly = rawy.convY()
|
val lx = rawx.convX(); val ly = rawy.convY()
|
||||||
val (worldX, worldY) = world.coerceXY(rawx, rawy)
|
val (worldX, worldY) = world.coerceXY(rawx, rawy)
|
||||||
@@ -491,9 +496,8 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
if (_thisFluid.type != Fluid.NULL) {
|
if (_thisFluid.type != Fluid.NULL) {
|
||||||
_fluidAmountToCol.set(_thisFluid.amount, _thisFluid.amount, _thisFluid.amount, _thisFluid.amount)
|
_fluidAmountToCol.set(_thisFluid.amount, _thisFluid.amount, _thisFluid.amount, _thisFluid.amount)
|
||||||
|
|
||||||
_thisTileLuminosity.set(_thisTerrainProp.getLumCol(worldX, worldY))
|
_thisTileLuminosity.set(_thisTerrainProp.getLumCol(worldX, worldY))
|
||||||
_thisTileLuminosity.maxAndAssign(_thisFluidProp.getLumCol(worldX, worldY).mul(_fluidAmountToCol))
|
_thisTileLuminosity.max(_thisFluidProp.getLumCol(worldX, worldY).cpy().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))
|
||||||
}
|
}
|
||||||
@@ -505,10 +509,11 @@ object LightmapRenderer {
|
|||||||
// 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)] ?: colourNull)
|
||||||
|
|
||||||
_mapThisTileOpacity2.setR(lx, ly, _mapThisTileOpacity.getR(lx, ly) * 1.41421356f)
|
// _mapThisTileOpacity2.setR(lx, ly, _mapThisTileOpacity.getR(lx, ly) * 1.41421356f)
|
||||||
_mapThisTileOpacity2.setG(lx, ly, _mapThisTileOpacity.getG(lx, ly) * 1.41421356f)
|
// _mapThisTileOpacity2.setG(lx, ly, _mapThisTileOpacity.getG(lx, ly) * 1.41421356f)
|
||||||
_mapThisTileOpacity2.setB(lx, ly, _mapThisTileOpacity.getB(lx, ly) * 1.41421356f)
|
// _mapThisTileOpacity2.setB(lx, ly, _mapThisTileOpacity.getB(lx, ly) * 1.41421356f)
|
||||||
_mapThisTileOpacity2.setA(lx, ly, _mapThisTileOpacity.getA(lx, ly) * 1.41421356f)
|
// _mapThisTileOpacity2.setA(lx, ly, _mapThisTileOpacity.getA(lx, ly) * 1.41421356f)
|
||||||
|
_mapThisTileOpacity2.setFromFloatVector(lx, ly, _mapThisTileOpacity.getFloatVector(lx, ly).mul(1.41421356f))
|
||||||
|
|
||||||
|
|
||||||
// open air || luminous tile backed by sunlight
|
// open air || luminous tile backed by sunlight
|
||||||
@@ -518,7 +523,7 @@ 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)] ?: colourNull
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -534,17 +539,16 @@ object LightmapRenderer {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// blend nearby 4 lights to get intensity
|
// blend nearby 4 lights to get intensity
|
||||||
_ambientAccumulator.set(0)
|
_ambientAccumulator.set(0f)
|
||||||
.maxAndAssign(lightmap.getVec(lx - 1, ly))
|
.max(lightmap.getVec(lx - 1, ly))
|
||||||
.maxAndAssign(lightmap.getVec(lx + 1, ly))
|
.max(lightmap.getVec(lx + 1, ly))
|
||||||
.maxAndAssign(lightmap.getVec(lx, ly - 1))
|
.max(lightmap.getVec(lx, ly - 1))
|
||||||
.maxAndAssign(lightmap.getVec(lx, ly + 1))
|
.max(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.set(App.tileMaker.terrainTileColourMap[_thisTerrainProp.id]!!)
|
||||||
_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)
|
||||||
@@ -557,26 +561,34 @@ object LightmapRenderer {
|
|||||||
private fun _swipeTask(x: Int, y: Int, x2: Int, y2: Int, lightmap: UnsafeCvecArray) {
|
private fun _swipeTask(x: Int, y: Int, x2: Int, y2: Int, lightmap: UnsafeCvecArray) {
|
||||||
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.r = _mapLightLevelThis.getR(x, y)
|
// _ambientAccumulator.r = _mapLightLevelThis.getR(x, y)
|
||||||
_ambientAccumulator.g = _mapLightLevelThis.getG(x, y)
|
// _ambientAccumulator.g = _mapLightLevelThis.getG(x, y)
|
||||||
_ambientAccumulator.b = _mapLightLevelThis.getB(x, y)
|
// _ambientAccumulator.b = _mapLightLevelThis.getB(x, y)
|
||||||
_ambientAccumulator.a = _mapLightLevelThis.getA(x, y)
|
// _ambientAccumulator.a = _mapLightLevelThis.getA(x, y)
|
||||||
|
|
||||||
|
_ambientAccumulator = _mapLightLevelThis.getVec(x, y)
|
||||||
|
|
||||||
if (!swipeDiag) {
|
if (!swipeDiag) {
|
||||||
_thisTileOpacity.r = _mapThisTileOpacity.getR(x, y)
|
// _thisTileOpacity.r = _mapThisTileOpacity.getR(x, y)
|
||||||
_thisTileOpacity.g = _mapThisTileOpacity.getG(x, y)
|
// _thisTileOpacity.g = _mapThisTileOpacity.getG(x, y)
|
||||||
_thisTileOpacity.b = _mapThisTileOpacity.getB(x, y)
|
// _thisTileOpacity.b = _mapThisTileOpacity.getB(x, y)
|
||||||
_thisTileOpacity.a = _mapThisTileOpacity.getA(x, y)
|
// _thisTileOpacity.a = _mapThisTileOpacity.getA(x, y)
|
||||||
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity, lightmap))
|
// _ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity, lightmap))
|
||||||
|
_thisTileOpacity = _mapThisTileOpacity.getVec(x, y)
|
||||||
|
_ambientAccumulator = _ambientAccumulator.max(darkenColoured(x2, y2, _thisTileOpacity, lightmap))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_thisTileOpacity2.r = _mapThisTileOpacity2.getR(x, y)
|
// _thisTileOpacity2.r = _mapThisTileOpacity2.getR(x, y)
|
||||||
_thisTileOpacity2.g = _mapThisTileOpacity2.getG(x, y)
|
// _thisTileOpacity2.g = _mapThisTileOpacity2.getG(x, y)
|
||||||
_thisTileOpacity2.b = _mapThisTileOpacity2.getB(x, y)
|
// _thisTileOpacity2.b = _mapThisTileOpacity2.getB(x, y)
|
||||||
_thisTileOpacity2.a = _mapThisTileOpacity2.getA(x, y)
|
// _thisTileOpacity2.a = _mapThisTileOpacity2.getA(x, y)
|
||||||
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity2, lightmap))
|
// _ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity2, lightmap))
|
||||||
|
_thisTileOpacity2 = _mapThisTileOpacity2.getVec(x, y)
|
||||||
|
_ambientAccumulator = _ambientAccumulator.max(darkenColoured(x2, y2, _thisTileOpacity2, lightmap))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _mapLightLevelThis.setVec(x, y, _ambientAccumulator)
|
||||||
|
// lightmap.setVec(x, y, _ambientAccumulator)
|
||||||
_mapLightLevelThis.setVec(x, y, _ambientAccumulator)
|
_mapLightLevelThis.setVec(x, y, _ambientAccumulator)
|
||||||
lightmap.setVec(x, y, _ambientAccumulator)
|
lightmap.setVec(x, y, _ambientAccumulator)
|
||||||
}
|
}
|
||||||
@@ -611,9 +623,9 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
var lightBuffer: Pixmap = Pixmap(64, 64, Pixmap.Format.RGBA8888) // must not be too small
|
var lightBuffer: Pixmap = Pixmap(64, 64, Pixmap.Format.RGBA8888) // must not be too small
|
||||||
|
|
||||||
private val colourNull = Cvec(0)
|
private val colourNull = Cvec(0f)
|
||||||
private val gdxColorNull = Color(0)
|
private val gdxColorNull = Color(0)
|
||||||
const val epsilon = 1f/1024f
|
val epsilon = FloatVector.broadcast(SPECIES_128, 1f / 1024f)
|
||||||
|
|
||||||
private var _lightBufferAsTex: Texture = Texture(64, 64, Pixmap.Format.RGBA8888) // must not be too small
|
private var _lightBufferAsTex: Texture = Texture(64, 64, Pixmap.Format.RGBA8888) // must not be too small
|
||||||
|
|
||||||
@@ -647,10 +659,10 @@ object LightmapRenderer {
|
|||||||
val arrayX = x.convX()
|
val arrayX = x.convX()
|
||||||
val arrayY = y.convY()
|
val arrayY = y.convY()
|
||||||
|
|
||||||
val red = lightmap.getR(arrayX, arrayY)
|
val red = lightmap.getR(arrayX, arrayY).let { if (it.isFinite()) it else 0f }
|
||||||
val grn = lightmap.getG(arrayX, arrayY)
|
val grn = lightmap.getG(arrayX, arrayY).let { if (it.isFinite()) it else 0f }
|
||||||
val blu = lightmap.getB(arrayX, arrayY)
|
val blu = lightmap.getB(arrayX, arrayY).let { if (it.isFinite()) it else 0f }
|
||||||
val uvl = lightmap.getA(arrayX, arrayY)
|
val uvl = lightmap.getA(arrayX, arrayY).let { if (it.isFinite()) it else 0f }
|
||||||
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)
|
||||||
@@ -666,13 +678,21 @@ object LightmapRenderer {
|
|||||||
0
|
0
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
lightBuffer.drawPixel(
|
/*lightBuffer.drawPixel(
|
||||||
x - this_x_start,
|
x - this_x_start,
|
||||||
lightBuffer.height - 1 - y + this_y_start, // flip Y
|
lightBuffer.height - 1 - y + this_y_start, // flip Y
|
||||||
(maxOf(red,grnw,bluw,uvlwr) * solidMultMagic).hdnorm().times(255f).roundToInt().shl(24) or
|
(maxOf(red,grnw,bluw,uvlwr) * solidMultMagic).hdnorm().times(255f).roundToInt().shl(24) or
|
||||||
(maxOf(redw,grn,bluw,uvlwg) * solidMultMagic).hdnorm().times(255f).roundToInt().shl(16) or
|
(maxOf(redw,grn,bluw,uvlwg) * solidMultMagic).hdnorm().times(255f).roundToInt().shl(16) or
|
||||||
(maxOf(redw,grnw,blu,uvlwb) * solidMultMagic).hdnorm().times(255f).roundToInt().shl(8) or
|
(maxOf(redw,grnw,blu,uvlwb) * solidMultMagic).hdnorm().times(255f).roundToInt().shl(8) or
|
||||||
(maxOf(bluwv,uvl) * solidMultMagic).hdnorm().times(255f).roundToInt()
|
(maxOf(bluwv,uvl) * solidMultMagic).hdnorm().times(255f).roundToInt()
|
||||||
|
)*/
|
||||||
|
lightBuffer.drawPixel(
|
||||||
|
x - this_x_start,
|
||||||
|
lightBuffer.height - 1 - y + this_y_start, // flip Y
|
||||||
|
(red * solidMultMagic).hdnorm().times(255f).roundToInt().shl(24) or
|
||||||
|
(grn * solidMultMagic).hdnorm().times(255f).roundToInt().shl(16) or
|
||||||
|
(blu * solidMultMagic).hdnorm().times(255f).roundToInt().shl(8) or
|
||||||
|
(uvl * solidMultMagic).hdnorm().times(255f).roundToInt()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -720,25 +740,15 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
if (x !in 0 until LIGHTMAP_WIDTH || y !in 0 until LIGHTMAP_HEIGHT) return colourNull
|
if (x !in 0 until LIGHTMAP_WIDTH || y !in 0 until LIGHTMAP_HEIGHT) return colourNull
|
||||||
|
|
||||||
return Cvec(
|
/*return Cvec(
|
||||||
lightmap.getR(x, y) * (1f - darken.r * lightScalingMagic),
|
lightmap.getR(x, y) * (1f - darken.r * lightScalingMagic),
|
||||||
lightmap.getG(x, y) * (1f - darken.g * lightScalingMagic),
|
lightmap.getG(x, y) * (1f - darken.g * lightScalingMagic),
|
||||||
lightmap.getB(x, y) * (1f - darken.b * lightScalingMagic),
|
lightmap.getB(x, y) * (1f - darken.b * lightScalingMagic),
|
||||||
lightmap.getA(x, y) * (1f - darken.a * lightScalingMagic)
|
lightmap.getA(x, y) * (1f - darken.a * lightScalingMagic)
|
||||||
)
|
)*/
|
||||||
|
return Cvec(lightmap.getFloatVector(x, y).mul(
|
||||||
}
|
VECTOR_ONE.vec.sub(darken.vec.mul(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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Float.inv() = 1f / this
|
private fun Float.inv() = 1f / this
|
||||||
@@ -811,10 +821,7 @@ 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 Cvec.nonZero() = epsilon.lt(this.vec.abs()).anyTrue()
|
||||||
this.g.abs() > epsilon ||
|
|
||||||
this.b.abs() > epsilon ||
|
|
||||||
this.a.abs() > epsilon
|
|
||||||
|
|
||||||
val histogram: Histogram
|
val histogram: Histogram
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
Reference in New Issue
Block a user