micro improvements to VeronoiBiomeAccessor

This commit is contained in:
Moritz Zwerger 2023-12-07 19:45:30 +01:00
parent 255e14cd82
commit 488c36f9da
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
2 changed files with 36 additions and 24 deletions

View File

@ -94,6 +94,17 @@ class VoronoiBiomeAccessorTest {
assertEquals(calculate(8, 15, 4, -987654321987654319L), Vec3i(1, 4, 0)) assertEquals(calculate(8, 15, 4, -987654321987654319L), Vec3i(1, 4, 0))
} }
// fun `benchmark 1`() {
// val accessor = VoronoiBiomeAccessor::class.java.allocate()
// val time = measureNanoTime {
// for (i in 0 until 20000000) {
// val index = accessor.getBiomeOffset(-987654321987654319L, 8, 15, 4) as Int
// assertEquals(index, 0x1FF46D8)
// }
// }
// println(time.formatNanos())
// }
private fun calculate(x: Int, y: Int, z: Int, seed: Long): Vec3i { private fun calculate(x: Int, y: Int, z: Int, seed: Long): Vec3i {
val accessor = VoronoiBiomeAccessor::class.java.allocate() val accessor = VoronoiBiomeAccessor::class.java.allocate()
val index = getBiomeOffset.invoke(accessor, seed, x, y, z) as Int val index = getBiomeOffset.invoke(accessor, seed, x, y, z) as Int

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.data.world.biome.accessor.noise package de.bixilon.minosoft.data.world.biome.accessor.noise
import de.bixilon.kutil.math.simple.DoubleMath.square import de.bixilon.kutil.math.simple.FloatMath.square
import de.bixilon.minosoft.data.registries.biomes.Biome import de.bixilon.minosoft.data.registries.biomes.Biome
import de.bixilon.minosoft.data.world.World import de.bixilon.minosoft.data.world.World
import de.bixilon.minosoft.data.world.biome.source.SpatialBiomeArray import de.bixilon.minosoft.data.world.biome.source.SpatialBiomeArray
@ -41,7 +41,7 @@ class VoronoiBiomeAccessor(
return biomeChunk?.biomeSource?.get(biomeX and 0x0F, biomeY, biomeZ and 0x0F) return biomeChunk?.biomeSource?.get(biomeX and 0x0F, biomeY, biomeZ and 0x0F)
} }
private fun getBiomeOffset(seed: Long, x: Int, y: Int, z: Int): Int { fun getBiomeOffset(seed: Long, x: Int, y: Int, z: Int): Int {
// all xyz coordinates are from 0..15 // all xyz coordinates are from 0..15
// target biome can also be on the negative side, offset by -2 // target biome can also be on the negative side, offset by -2
@ -55,33 +55,33 @@ class VoronoiBiomeAccessor(
val sZ = cZ shr 2 val sZ = cZ shr 2
// in array // in array
val iX = (cX and 0x03) / 4.0 val iX = (cX and 0x03) / 4.0f
val iY = (cY and 0x03) / 4.0 val iY = (cY and 0x03) / 4.0f
val iZ = (cZ and 0x03) / 4.0 val iZ = (cZ and 0x03) / 4.0f
var minXYZ = 0 var minXYZ = 0
var minDistance = Double.POSITIVE_INFINITY var minDistance = Float.POSITIVE_INFINITY
for (xyz in 0 until 2 * 2 * 2) { for (xyz in 0 until 2 * 2 * 2) {
var uX = sX var uX = sX
var offsetX = iX var offsetX = iX
if (xyz and 0x04 != 0) { if (xyz and 0x04 != 0) {
uX++ uX++
offsetX -= 1.0 offsetX -= 1.0f
} }
var uY = sY var uY = sY
var offsetY = iY var offsetY = iY
if (xyz and 0x02 != 0) { if (xyz and 0x02 != 0) {
uY++ uY++
offsetY -= 1.0 offsetY -= 1.0f
} }
var uZ = sZ var uZ = sZ
var offsetZ = iZ var offsetZ = iZ
if (xyz and 0x01 != 0) { if (xyz and 0x01 != 0) {
uZ++ uZ++
offsetZ -= 1.0 offsetZ -= 1.0f
} }
@ -108,7 +108,7 @@ class VoronoiBiomeAccessor(
} }
private fun noiseDistance(seed: Long, x: Int, y: Int, z: Int, offsetX: Double, offsetY: Double, offsetZ: Double): Double { private fun noiseDistance(seed: Long, x: Int, y: Int, z: Int, offsetX: Float, offsetY: Float, offsetZ: Float): Float {
var ret = mix(seed, x, y, z) var ret = mix(seed, x, y, z)
val noiseX = nextNoiseOffset(ret); ret = next(ret, seed) val noiseX = nextNoiseOffset(ret); ret = next(ret, seed)
@ -120,20 +120,25 @@ class VoronoiBiomeAccessor(
private fun mix(seed: Long, x: Int, y: Int, z: Int): Long { private fun mix(seed: Long, x: Int, y: Int, z: Int): Long {
var mixed = seed var mixed = seed
mixed = next(mixed, x)
mixed = next(mixed, y) val xL = x.toLong()
mixed = next(mixed, z) val yL = y.toLong()
mixed = next(mixed, x) val zL = z.toLong()
mixed = next(mixed, y)
mixed = next(mixed, z) mixed = next(mixed, xL)
mixed = next(mixed, yL)
mixed = next(mixed, zL)
mixed = next(mixed, xL)
mixed = next(mixed, yL)
mixed = next(mixed, zL)
return mixed return mixed
} }
private fun nextNoiseOffset(seed: Long): Double { private fun nextNoiseOffset(seed: Long): Float {
val floor = Math.floorMod(seed shr 24, SpatialBiomeArray.SIZE.toLong()).toInt() val floor = Math.floorMod((seed shr 24), SpatialBiomeArray.SIZE.toLong()).toInt()
val double = (floor - (SpatialBiomeArray.SIZE / 2)) / SpatialBiomeArray.SIZE.toDouble()
return double * 0.9 // return ((floor - (SpatialBiomeArray.SIZE / 2)) / SpatialBiomeArray.SIZE.toDouble()) * 0.9
return (1.0f / 1137.0f) * floor + (-0.45f) // roughly equivalent and minimal faster
} }
// https://en.wikipedia.org/wiki/Linear_congruential_generator // https://en.wikipedia.org/wiki/Linear_congruential_generator
@ -141,10 +146,6 @@ class VoronoiBiomeAccessor(
return seed * (seed * 6364136223846793005L + 1442695040888963407L) return seed * (seed * 6364136223846793005L + 1442695040888963407L)
} }
private fun next(seed: Long, salt: Int): Long {
return next(seed) + salt
}
private fun next(seed: Long, salt: Long): Long { private fun next(seed: Long, salt: Long): Long {
return next(seed) + salt return next(seed) + salt
} }