mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-12 00:47:26 -04:00
tint optimisations, refactor and abstract color maps
This commit is contained in:
parent
272df21f9e
commit
1686a6695d
@ -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")
|
@ -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))
|
||||
|
@ -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`() {
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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)
|
||||
}
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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)
|
||||
}
|
||||
}
|
BIN
src/integration-test/resources/tint/foliage.png
Normal file
BIN
src/integration-test/resources/tint/foliage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
src/integration-test/resources/tint/grass.png
Normal file
BIN
src/integration-test/resources/tint/grass.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
@ -25,7 +25,7 @@ import de.bixilon.minosoft.assets.properties.manager.pack.PackProperties
|
||||
import de.bixilon.minosoft.assets.util.FileAssetsTypes
|
||||
import de.bixilon.minosoft.assets.util.FileAssetsUtil
|
||||
import de.bixilon.minosoft.assets.util.HashTypes
|
||||
import de.bixilon.minosoft.assets.util.InputStreamUtil.readArchive
|
||||
import de.bixilon.minosoft.assets.util.InputStreamUtil.readTarArchive
|
||||
import de.bixilon.minosoft.assets.util.InputStreamUtil.readZipArchive
|
||||
import de.bixilon.minosoft.assets.util.PathUtil
|
||||
import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfile
|
||||
@ -66,7 +66,7 @@ class JarAssetsManager(
|
||||
|
||||
|
||||
private fun tryLoadAssets(): Boolean {
|
||||
val assets = FileAssetsUtil.readOrNull(jarAssetsHash, FileAssetsTypes.GAME, verify = profile.verify)?.let { ByteArrayInputStream(it).readArchive() } ?: return false
|
||||
val assets = FileAssetsUtil.readOrNull(jarAssetsHash, FileAssetsTypes.GAME, verify = profile.verify)?.let { ByteArrayInputStream(it).readTarArchive() } ?: return false
|
||||
|
||||
for ((path, data) in assets) {
|
||||
this.assets[path.removePrefix("assets/" + Namespaces.MINECRAFT + "/")] = data
|
||||
|
@ -21,9 +21,7 @@ import de.bixilon.kutil.cast.CastUtil.unsafeCast
|
||||
import de.bixilon.kutil.json.JsonObject
|
||||
import de.bixilon.mbf.MBFBinaryReader
|
||||
import de.bixilon.minosoft.util.json.Jackson
|
||||
import de.matthiasmann.twl.utils.PNGDecoder
|
||||
import org.kamranzafar.jtar.TarInputStream
|
||||
import org.lwjgl.BufferUtils
|
||||
import java.io.InputStream
|
||||
import java.util.zip.ZipInputStream
|
||||
|
||||
@ -50,13 +48,7 @@ object InputStreamUtil {
|
||||
}
|
||||
|
||||
fun InputStream.readJsonObject(close: Boolean = true): JsonObject {
|
||||
try {
|
||||
return Jackson.MAPPER.readValue(this, Jackson.JSON_MAP_TYPE)
|
||||
} finally {
|
||||
if (close) {
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
return readJson(close = close, reader = Jackson.MAP_READER)
|
||||
}
|
||||
|
||||
inline fun <reified T> InputStream.readJson(close: Boolean = true): T {
|
||||
@ -89,7 +81,7 @@ object InputStreamUtil {
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream.readArchive(): Map<String, ByteArray> {
|
||||
fun InputStream.readTarArchive(): Map<String, ByteArray> {
|
||||
val content: MutableMap<String, ByteArray> = 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<Any, Any> {
|
||||
return MBFBinaryReader(this).readMBF().data.unsafeCast()
|
||||
}
|
||||
|
@ -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<Biome> {
|
||||
|
||||
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<String, Any>): Biome {
|
||||
val effects = data["effects"].toJsonObject() // nbt data
|
||||
val skyColor = (data["sky_color"] ?: effects?.get("sky_color"))?.jsonTint()
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ class ChunkMeshingQueue(
|
||||
|
||||
@Volatile
|
||||
private var working = false
|
||||
private val queue: MutableList<WorldQueueItem> = mutableListOf()
|
||||
private val queue: MutableList<WorldQueueItem> = ArrayList()
|
||||
private val set: MutableSet<WorldQueueItem> = HashSet()
|
||||
|
||||
private val lock = SimpleLock()
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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()
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user