From 1686a6695d58a95d402c8834de332bfce6131a8c Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Fri, 8 Dec 2023 18:18:18 +0100 Subject: [PATCH] tint optimisations, refactor and abstract color maps --- .../versions/registries/pixlyzer/1_20_4.kt} | 16 ++--- .../texture/data/buffer/RGB8BufferTest.kt | 7 ++ .../texture/data/buffer/RGBA8BufferTest.kt | 6 ++ .../rendering/tint/tints/ColorMapTintTest.kt | 37 +++++++++++ .../tints/grass/GrassTintCalculatorTest.kt | 35 ++++++++++ .../resources/tint/foliage.png | Bin 0 -> 14154 bytes src/integration-test/resources/tint/grass.png | Bin 0 -> 5984 bytes .../assets/minecraft/JarAssetsManager.kt | 4 +- .../minosoft/assets/util/InputStreamUtil.kt | 27 +------- .../minosoft/data/registries/biomes/Biome.kt | 21 ++---- .../minosoft/gui/rendering/RenderConstants.kt | 3 - .../chunk/queue/meshing/ChunkMeshingQueue.kt | 2 +- .../base/texture/array/StaticTextureArray.kt | 7 +- .../base/texture/data/buffer/RGB8Buffer.kt | 6 ++ .../base/texture/data/buffer/RGBA8Buffer.kt | 9 ++- .../base/texture/data/buffer/TextureBuffer.kt | 2 + .../textures/properties/ImageProperties.kt | 4 +- .../gui/rendering/tint/tints/ColorMapTint.kt | 62 ++++++++++++++++++ .../tint/tints/grass/GrassTintCalculator.kt | 48 ++++++-------- .../tints/plants/FoliageTintCalculator.kt | 37 ++++++----- .../protocol/protocol/ProtocolDefinition.java | 3 - .../de/bixilon/minosoft/util/json/Jackson.kt | 1 + 22 files changed, 224 insertions(+), 113 deletions(-) rename src/{test/java/de/bixilon/minosoft/data/registries/biomes/BiomeTest.kt => integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/pixlyzer/1_20_4.kt} (65%) create mode 100644 src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/tint/tints/ColorMapTintTest.kt create mode 100644 src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTintCalculatorTest.kt create mode 100644 src/integration-test/resources/tint/foliage.png create mode 100644 src/integration-test/resources/tint/grass.png create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/ColorMapTint.kt diff --git a/src/test/java/de/bixilon/minosoft/data/registries/biomes/BiomeTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/pixlyzer/1_20_4.kt similarity index 65% rename from src/test/java/de/bixilon/minosoft/data/registries/biomes/BiomeTest.kt rename to src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/pixlyzer/1_20_4.kt index 58560be4b..8cdd0a8d1 100644 --- a/src/test/java/de/bixilon/minosoft/data/registries/biomes/BiomeTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/pixlyzer/1_20_4.kt @@ -11,17 +11,9 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.data.registries.biomes +package de.bixilon.minosoft.data.registries.versions.registries.pixlyzer -import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test +import org.testng.annotations.Test -class BiomeTest { - - @Test - fun `color map index`() { - val biome = Biome(minecraft("plains"), temperature = 0.8f, downfall = 0.4f) - assertEquals(biome.colorMapPixelIndex, 44338) - } -} +@Test(groups = ["pixlyzer"], dependsOnGroups = ["version"], priority = Int.MAX_VALUE, timeOut = 15000L) +class `1_20_4` : PixLyzerLoadingTest("1.20.4") diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGB8BufferTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGB8BufferTest.kt index 35997f670..ce2fbdd64 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGB8BufferTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGB8BufferTest.kt @@ -67,6 +67,13 @@ class RGB8BufferTest { assertEquals(source.getA(3, 3), 0xFF) } + fun `get rgb at 3,3`() { + val source = RGB8Buffer(Vec2i(12, 13)) + source.data.put(117 + 0, 0x11).put(117 + 1, 0x22).put(117 + 2, 0x33) + val rgba = source.getRGB(3, 3) + assertEquals(rgba, 0x112233) + } + fun `put complete texture`() { val source = RGB8Buffer(Vec2i(12, 13)) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGBA8BufferTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGBA8BufferTest.kt index 856e7c8ca..2352b1da7 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGBA8BufferTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGBA8BufferTest.kt @@ -69,6 +69,12 @@ class RGBA8BufferTest { assertEquals(source.getB(3, 3), 0x33) assertEquals(source.getA(3, 3), 0x44) } + fun `get rgb at 3,3`() { + val source = RGBA8Buffer(Vec2i(12, 13)) + source.data.put(156 + 0, 0x11).put(156 + 1, 0x22).put(156 + 2, 0x33).put(156 + 3, 0x44) + val rgba = source.getRGB(3, 3) + assertEquals(rgba, 0x112233) + } fun `put complete texture`() { diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/tint/tints/ColorMapTintTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/tint/tints/ColorMapTintTest.kt new file mode 100644 index 000000000..2360c7f63 --- /dev/null +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/tint/tints/ColorMapTintTest.kt @@ -0,0 +1,37 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.tint.tints + +import de.bixilon.minosoft.data.registries.biomes.Biome +import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft +import org.testng.Assert.assertEquals +import org.testng.annotations.Test + +@Test(groups = ["biome"]) +class ColorMapTintTest { + + @Test + fun `plains color map index`() { + val biome = Biome(minecraft("plains"), temperature = 0.8f, downfall = 0.4f) + assertEquals(biome.temperatureIndex, 50) + assertEquals(biome.downfallIndex, 173) + } + + @Test + fun `dessert color map index`() { + val biome = Biome(minecraft("dessert"), temperature = 2.0f, downfall = 0.0f) + assertEquals(biome.temperatureIndex, 0) + assertEquals(biome.downfallIndex, 255) + } +} diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTintCalculatorTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTintCalculatorTest.kt new file mode 100644 index 000000000..16bfb1f7b --- /dev/null +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTintCalculatorTest.kt @@ -0,0 +1,35 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.tint.tints.grass + +import de.bixilon.minosoft.assets.MemoryAssetsManager +import org.testng.Assert.assertEquals +import org.testng.annotations.Test + +@Test(groups = ["tint"]) +class GrassTintCalculatorTest { + private val map by lazy { + val map = GrassTintCalculator() + val assets = MemoryAssetsManager() + assets.push(GrassTintCalculator.FILE, GrassTintCalculatorTest::class.java.getResourceAsStream("/tint/grass.png")!!.readAllBytes()) + map.init(assets) + + return@lazy map + } + + + fun `color of dessert`() { + assertEquals(map.getColor(255, 0), 0xBFB755) + } +} diff --git a/src/integration-test/resources/tint/foliage.png b/src/integration-test/resources/tint/foliage.png new file mode 100644 index 0000000000000000000000000000000000000000..d58fce229108e9e6e188ed13baa75bc432ead19a GIT binary patch literal 14154 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 Ut;h_7$p8QV07*qoM6N<$f=RGsc>n+a literal 0 HcmV?d00001 diff --git a/src/integration-test/resources/tint/grass.png b/src/integration-test/resources/tint/grass.png new file mode 100644 index 0000000000000000000000000000000000000000..5b946547e675348ee9a864af7000e9de013f8dfa GIT binary patch literal 5984 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 InputStream.readJson(close: Boolean = true): T { @@ -89,7 +81,7 @@ object InputStreamUtil { } } - fun InputStream.readArchive(): Map { + fun InputStream.readTarArchive(): Map { val content: MutableMap = mutableMapOf() val stream = TarInputStream(this) while (true) { @@ -111,21 +103,6 @@ object InputStreamUtil { return content } - fun InputStream.readRGBArray(): IntArray { - val decoder = PNGDecoder(this) - - val buffer = BufferUtils.createByteBuffer(decoder.width * decoder.height * PNGDecoder.Format.RGB.numComponents) - decoder.decode(buffer, decoder.width * PNGDecoder.Format.RGB.numComponents, PNGDecoder.Format.RGB) - buffer.flip() - val colors = IntArray(decoder.width * decoder.height) - - for (i in colors.indices) { - colors[i] = ((buffer.get().toInt() and 0xFF) shl 16) or ((buffer.get().toInt() and 0xFF) shl 8) or (buffer.get().toInt() and 0xFF) - } - - return colors - } - fun InputStream.readMBFMap(): Map { return MBFBinaryReader(this).readMBF().data.unsafeCast() } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/biomes/Biome.kt b/src/main/java/de/bixilon/minosoft/data/registries/biomes/Biome.kt index c700a3898..3b46cf765 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/biomes/Biome.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/biomes/Biome.kt @@ -12,7 +12,6 @@ */ package de.bixilon.minosoft.data.registries.biomes -import de.bixilon.kotlinglm.func.common.clamp import de.bixilon.kutil.json.JsonUtil.toJsonObject import de.bixilon.kutil.primitive.FloatUtil.toFloat import de.bixilon.minosoft.data.registries.identified.ResourceLocation @@ -20,9 +19,8 @@ import de.bixilon.minosoft.data.registries.registries.Registries import de.bixilon.minosoft.data.registries.registries.registry.RegistryItem import de.bixilon.minosoft.data.registries.registries.registry.codec.IdentifierCodec import de.bixilon.minosoft.data.text.formatting.color.RGBColor -import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.tint.TintManager.Companion.jsonTint -import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition +import de.bixilon.minosoft.gui.rendering.tint.tints.ColorMapTint data class Biome( override val identifier: ResourceLocation, @@ -34,26 +32,15 @@ data class Biome( val waterFogColor: RGBColor? = null, val precipitation: BiomePrecipitation? = null, ) : RegistryItem() { - val grassColorModifier = GrassColorModifiers.BIOME_MAP[identifier] - val temperatureColorMapCoordinate = getColorMapCoordinate(temperature) - val downfallColorMapCoordinate = getColorMapCoordinate(downfall * temperature) - val colorMapPixelIndex = downfallColorMapCoordinate shl 8 or temperatureColorMapCoordinate + val grassModifier = GrassColorModifiers.BIOME_MAP[identifier] - fun getClampedTemperature(height: Int): Int { - return getColorMapCoordinate((temperature + ((height - ProtocolDefinition.SEA_LEVEL_HEIGHT).clamp(1, Int.MAX_VALUE) * ProtocolDefinition.HEIGHT_SEA_LEVEL_MODIFIER)).clamp(0.0f, 1.0f)) - } + val temperatureIndex = ColorMapTint.getIndex(temperature) + val downfallIndex = ColorMapTint.getIndex(downfall * temperature) - override fun toString(): String { - return identifier.toString() - } companion object : IdentifierCodec { - private fun getColorMapCoordinate(value: Float): Int { - return ((1.0 - value.clamp(0.0f, 1.0f)) * RenderConstants.COLORMAP_SIZE).toInt() - } - override fun deserialize(registries: Registries?, identifier: ResourceLocation, data: Map): Biome { val effects = data["effects"].toJsonObject() // nbt data val skyColor = (data["sky_color"] ?: effects?.get("sky_color"))?.jsonTint() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt index 9fa27f365..252f3054b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt @@ -18,9 +18,6 @@ import de.bixilon.minosoft.data.text.formatting.color.RGBColor import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture object RenderConstants { - const val COLORMAP_SIZE = 255 - - val TEXT_BACKGROUND_COLOR = RGBColor(0, 0, 0, 80) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/queue/meshing/ChunkMeshingQueue.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/queue/meshing/ChunkMeshingQueue.kt index d29cc6c27..3c4a70bae 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/queue/meshing/ChunkMeshingQueue.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/queue/meshing/ChunkMeshingQueue.kt @@ -34,7 +34,7 @@ class ChunkMeshingQueue( @Volatile private var working = false - private val queue: MutableList = mutableListOf() + private val queue: MutableList = ArrayList() private val set: MutableSet = HashSet() private val lock = SimpleLock() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/array/StaticTextureArray.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/array/StaticTextureArray.kt index c4dba69e4..c51354837 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/array/StaticTextureArray.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/array/StaticTextureArray.kt @@ -21,7 +21,7 @@ import de.bixilon.kutil.concurrent.pool.runnable.ForcePooledRunnable import de.bixilon.kutil.concurrent.pool.runnable.SimplePoolRunnable import de.bixilon.kutil.latch.AbstractLatch import de.bixilon.kutil.latch.AbstractLatch.Companion.child -import de.bixilon.minosoft.assets.util.InputStreamUtil.readAsString +import de.bixilon.minosoft.assets.util.InputStreamUtil.readJson import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureStates @@ -31,7 +31,6 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.file.PNGTexture import de.bixilon.minosoft.gui.rendering.textures.properties.ImageProperties import de.bixilon.minosoft.util.KUtil.toResourceLocation -import de.bixilon.minosoft.util.json.Jackson import java.util.concurrent.atomic.AtomicInteger abstract class StaticTextureArray( @@ -88,8 +87,8 @@ abstract class StaticTextureArray( private fun readImageProperties(texture: ResourceLocation): ImageProperties? { try { - val data = context.connection.assetsManager.getOrNull("$texture.mcmeta".toResourceLocation())?.readAsString() ?: return null - return Jackson.MAPPER.readValue(data, ImageProperties::class.java) + val stream = context.connection.assetsManager.getOrNull("$texture.mcmeta".toResourceLocation()) ?: return null + return stream.readJson(reader = ImageProperties.READER) } catch (error: Throwable) { error.printStackTrace() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGB8Buffer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGB8Buffer.kt index 88e4e041f..dcc34d1e4 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGB8Buffer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGB8Buffer.kt @@ -62,6 +62,11 @@ class RGB8Buffer( return (this[stride + 0] shl 24) or (this[stride + 1] shl 16) or (this[stride + 2] shl 8) or 0xFF } + override fun getRGB(x: Int, y: Int): Int { + val stride = stride(x, y) + return (this[stride + 0] shl 16) or (this[stride + 1] shl 8) or this[stride + 2] + } + override fun getR(x: Int, y: Int) = this[stride(x, y) + 0] override fun getG(x: Int, y: Int) = this[stride(x, y) + 1] @@ -70,6 +75,7 @@ class RGB8Buffer( private fun stride(x: Int, y: Int): Int { + if (x >= size.x || y >= size.y) throw IllegalArgumentException("Can not access pixel at ($x,$y), exceeds size: $size") return ((size.x * y) + x) * bytes } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGBA8Buffer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGBA8Buffer.kt index 98f861503..19962ce6f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGBA8Buffer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/RGBA8Buffer.kt @@ -58,18 +58,21 @@ class RGBA8Buffer( override fun getRGBA(x: Int, y: Int): Int { val stride = stride(x, y) - if (stride > data.capacity()) { - throw IllegalArgumentException("Can not access pixel at ($x,$y), exceeds size: $size") - } return (this[stride + 0] shl 24) or (this[stride + 1] shl 16) or (this[stride + 2] shl 8) or (this[stride + 3] shl 0) } + override fun getRGB(x: Int, y: Int): Int { + val stride = stride(x, y) + return (this[stride + 0] shl 16) or (this[stride + 1] shl 8) or this[stride + 2] + } + override fun getR(x: Int, y: Int) = this[stride(x, y) + 0] override fun getG(x: Int, y: Int) = this[stride(x, y) + 1] override fun getB(x: Int, y: Int) = this[stride(x, y) + 2] override fun getA(x: Int, y: Int) = this[stride(x, y) + 3] private fun stride(x: Int, y: Int): Int { + if (x >= size.x || y >= size.y) throw IllegalArgumentException("Can not access pixel at ($x,$y), exceeds size: $size") return ((size.x * y) + x) * bytes } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/TextureBuffer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/TextureBuffer.kt index 5dc525c47..305020bbd 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/TextureBuffer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/buffer/TextureBuffer.kt @@ -55,6 +55,8 @@ interface TextureBuffer { fun getB(x: Int, y: Int): Int fun getA(x: Int, y: Int): Int + fun getRGB(x: Int, y: Int): Int + fun getRGBA(x: Int, y: Int): Int fun setRGBA(x: Int, y: Int, value: Int) fun setRGBA(x: Int, y: Int, red: Int, green: Int, blue: Int, alpha: Int) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/properties/ImageProperties.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/properties/ImageProperties.kt index 0849b796b..f9ecbb2cb 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/properties/ImageProperties.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/properties/ImageProperties.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -14,6 +14,7 @@ package de.bixilon.minosoft.gui.rendering.textures.properties import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture +import de.bixilon.minosoft.util.json.Jackson data class ImageProperties( val texture: TextureProperties = TextureProperties(), @@ -27,5 +28,6 @@ data class ImageProperties( companion object { val DEFAULT = ImageProperties() + val READER = Jackson.MAPPER.readerFor(ImageProperties::class.java) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/ColorMapTint.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/ColorMapTint.kt new file mode 100644 index 000000000..b428506ea --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/ColorMapTint.kt @@ -0,0 +1,62 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.tint.tints + +import de.bixilon.kutil.exception.ExceptionUtil.ignoreAll +import de.bixilon.minosoft.assets.AssetsManager +import de.bixilon.minosoft.data.registries.identified.ResourceLocation +import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.TextureBuffer +import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.readTexture +import de.bixilon.minosoft.gui.rendering.tint.TintProvider +import de.bixilon.minosoft.util.logging.Log +import de.bixilon.minosoft.util.logging.LogLevels +import de.bixilon.minosoft.util.logging.LogMessageType + +abstract class ColorMapTint( + private val file: ResourceLocation, +) : TintProvider { + protected var map: IntArray? = null + + fun init(assets: AssetsManager) { + val map = ignoreAll { assets[file].readTexture() } ?: return + if (map.size.x != SIZE || map.size.y != SIZE) { + Log.log(LogMessageType.LOADING, LogLevels.WARN) { "Color map ($file) has invalid size: ${map.size}" } + return + } + this.map = map.toColorMap() + } + + private fun TextureBuffer.toColorMap(): IntArray { + val array = IntArray(size.x * size.y) + var index = 0 + for (y in 0 until size.y) { + for (x in 0 until size.x) { + array[index++] = getRGB(x, y) + } + } + return array + } + + companion object { + const val SIZE = 256 + + fun getIndex(value: Float): Int { + if (value <= 0.0f) return SIZE - 1 + if (value >= 1.0f) return 0 + + val delta = 1.0f - value + return (delta * (SIZE - 1)).toInt() + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTintCalculator.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTintCalculator.kt index 2bdf32e62..1a15d6b8f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTintCalculator.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTintCalculator.kt @@ -13,48 +13,33 @@ package de.bixilon.minosoft.gui.rendering.tint.tints.grass -import de.bixilon.kutil.exception.ExceptionUtil.ignoreAll -import de.bixilon.minosoft.assets.AssetsManager -import de.bixilon.minosoft.assets.util.InputStreamUtil.readRGBArray +import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.data.registries.biomes.Biome import de.bixilon.minosoft.data.registries.biomes.GrassColorModifiers import de.bixilon.minosoft.data.registries.blocks.state.BlockState import de.bixilon.minosoft.data.registries.blocks.types.building.dirt.GrassBlock +import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.data.text.formatting.color.Colors import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture -import de.bixilon.minosoft.gui.rendering.tint.TintProvider -import de.bixilon.minosoft.util.KUtil.toResourceLocation +import de.bixilon.minosoft.gui.rendering.tint.tints.ColorMapTint -class GrassTintCalculator : TintProvider { - private lateinit var colorMap: IntArray +class GrassTintCalculator : ColorMapTint(FILE) { - fun init(assetsManager: AssetsManager) { - colorMap = ignoreAll { assetsManager["minecraft:colormap/grass".toResourceLocation().texture()].readRGBArray() } ?: IntArray(256) - } + fun getColor(downfallIndex: Int, temperatureIndex: Int): Int { + val map = map ?: return FALLBACK - inline fun getColor(downfall: Int, temperature: Int): Int { - return getColor(downfall shl 8 or temperature) - } - - fun getColor(colorMapPixelIndex: Int): Int { - if (colorMapPixelIndex > colorMap.size) { - return 0xFF00FF // ToDo: Is this correct? Was used in my old implementation - } - val color = colorMap[colorMapPixelIndex] - if (color == 0xFFFFFF) { - return 0x48B518 - } + val color = map[downfallIndex shl 8 or temperatureIndex] + if (color == 0xFFFFFF) return 0x48B518 return color } fun getBlockColor(biome: Biome?): Int { - if (biome == null) { - return getColor(127, 255) - } - val color = getColor(biome.colorMapPixelIndex) + if (biome == null) return getColor(127, 255) - return when (biome.grassColorModifier) { + val color = getColor(biome.downfallIndex, biome.temperatureIndex) + + return when (biome.grassModifier) { null -> color GrassColorModifiers.SWAMP -> 0x6A7039 // ToDo: Biome noise is applied here GrassColorModifiers.DARK_FOREST -> (color and 0xFEFEFE) + 0x28340A shr 1 @@ -71,4 +56,13 @@ class GrassTintCalculator : TintProvider { } return getBlockColor(biome) } + + override fun getItemColor(stack: ItemStack, tintIndex: Int): Int { + return getColor(127, 255) // TODO: verify + } + + companion object { + val FILE = minecraft("colormap/grass").texture() + private const val FALLBACK = 0xFF00FF // ToDo: Is this correct? Was used in my old implementation + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/plants/FoliageTintCalculator.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/plants/FoliageTintCalculator.kt index 8bd75ebf0..011a03008 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/plants/FoliageTintCalculator.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/plants/FoliageTintCalculator.kt @@ -13,29 +13,23 @@ package de.bixilon.minosoft.gui.rendering.tint.tints.plants -import de.bixilon.kutil.exception.ExceptionUtil.ignoreAll -import de.bixilon.minosoft.assets.AssetsManager -import de.bixilon.minosoft.assets.util.InputStreamUtil.readRGBArray +import de.bixilon.kotlinglm.func.common.clamp import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.data.registries.biomes.Biome import de.bixilon.minosoft.data.registries.blocks.state.BlockState +import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture -import de.bixilon.minosoft.gui.rendering.tint.TintProvider -import de.bixilon.minosoft.util.KUtil.toResourceLocation +import de.bixilon.minosoft.gui.rendering.tint.tints.ColorMapTint -class FoliageTintCalculator : TintProvider { - private lateinit var colorMap: IntArray - - fun init(assetsManager: AssetsManager) { - colorMap = ignoreAll { assetsManager["minecraft:colormap/foliage".toResourceLocation().texture()].readRGBArray() } ?: IntArray(256) - } +class FoliageTintCalculator : ColorMapTint(FILE) { fun getBlockColor(biome: Biome?, y: Int): Int { - if (biome == null) { - return FALLBACK_COLOR - } + if (biome == null) return FALLBACK_COLOR + val map = this.map ?: return FALLBACK_COLOR + // ToDo: Override - return colorMap[biome.downfallColorMapCoordinate shl 8 or biome.getClampedTemperature(y)] + val temperature = modifyTemperature(biome.temperature, y) + return map[biome.downfallIndex shl 8 or temperature] } override fun getBlockColor(blockState: BlockState, biome: Biome?, x: Int, y: Int, z: Int, tintIndex: Int): Int { @@ -51,6 +45,19 @@ class FoliageTintCalculator : TintProvider { } companion object { + private val FILE = minecraft("colormap/foliage").texture() private const val FALLBACK_COLOR = 0x48B518 + + // not sure if that is accurate or relevant + private const val SEA_LEVEL = 62 + private const val SEA_LEVEL_MODIFIER = 0.00166667f + + + fun modifyTemperature(temperature: Float, height: Int): Int { + val modifier = maxOf(1, height - SEA_LEVEL) * SEA_LEVEL_MODIFIER + val modified = (temperature + modifier).clamp(0.0f, 1.0f) + + return getIndex(modified) + } } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java index c70587109..64836a20f 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java @@ -68,9 +68,6 @@ public final class ProtocolDefinition { public static final float VELOCITY_NETWORK_DIVIDER = 8000.0f; - public static final int SEA_LEVEL_HEIGHT = 62; - - public static final float HEIGHT_SEA_LEVEL_MODIFIER = 0.00166667f; public static final RGBColor DEFAULT_COLOR = ChatColors.WHITE; diff --git a/src/main/java/de/bixilon/minosoft/util/json/Jackson.kt b/src/main/java/de/bixilon/minosoft/util/json/Jackson.kt index 1e97343ac..e5792c6f7 100644 --- a/src/main/java/de/bixilon/minosoft/util/json/Jackson.kt +++ b/src/main/java/de/bixilon/minosoft/util/json/Jackson.kt @@ -64,6 +64,7 @@ object Jackson { val JSON_MAP_TYPE: MapType = MAPPER.typeFactory.constructMapType(HashMap::class.java, Any::class.java, Any::class.java) + val MAP_READER = MAPPER.readerFor(JSON_MAP_TYPE) fun init() = Unit }