[WIP] initial Fabric port

major package refactoring
This commit is contained in:
octarine-noise
2020-02-05 13:42:48 +01:00
parent 2252fb3b42
commit df50f61b0d
151 changed files with 5181 additions and 5663 deletions

View File

@@ -0,0 +1,84 @@
package mods.betterfoliage.util
import mods.betterfoliage.resource.model.HSB
import net.minecraft.client.MinecraftClient
import net.minecraft.client.texture.Sprite
import net.minecraft.client.texture.SpriteAtlasTexture
import net.minecraft.resource.Resource
import net.minecraft.resource.ResourceManager
import net.minecraft.util.Identifier
import java.awt.image.BufferedImage
import java.io.ByteArrayOutputStream
import java.io.IOException
import javax.imageio.ImageIO
import kotlin.math.atan2
enum class Atlas(val basePath: String, val resourceId: Identifier) {
BLOCKS("textures", SpriteAtlasTexture.BLOCK_ATLAS_TEX),
PARTICLES("textures/particle", SpriteAtlasTexture.PARTICLE_ATLAS_TEX);
/** Get the fully-qualified resource name for sprites belonging to this atlas*/
fun wrap(resource: Identifier) = Identifier(resource.namespace, "$basePath/${resource.path}.png")
/** Get the short resource name for sprites belonging to this atlas*/
fun unwrap(resource: Identifier) = resource.stripStart("$basePath/").stripEnd(".png")
/** Reference to the atlas itself */
val atlas: SpriteAtlasTexture get() = MinecraftClient.getInstance().textureManager.getTexture(resourceId) as SpriteAtlasTexture
}
operator fun SpriteAtlasTexture.get(res: Identifier): Sprite? = getSprite(res)
operator fun SpriteAtlasTexture.get(name: String): Sprite? = getSprite(Identifier(name))
fun ResourceManager.loadSprite(id: Identifier) = this.get(id)?.loadImage() ?: throw IOException("Cannot load resource $id")
fun Resource.loadImage(): BufferedImage? = ImageIO.read(this.inputStream)
/** Index operator to get the RGB value of a pixel. */
operator fun BufferedImage.get(x: Int, y: Int) = this.getRGB(x, y)
/** Index operator to set the RGB value of a pixel. */
operator fun BufferedImage.set(x: Int, y: Int, value: Int) = this.setRGB(x, y, value)
val BufferedImage.bytes: ByteArray get() =
ByteArrayOutputStream().let { ImageIO.write(this, "PNG", it); it.toByteArray() }
/**
* Calculate the average color of an image.
*
* Only non-transparent pixels are considered. Averages are taken in the HSB color space (note: Hue is a circular average),
* and the result transformed back to the RGB color space.
*/
fun ResourceManager.averageImageColorHSB(id: Identifier, atlas: Atlas) = loadSprite(atlas.wrap(id)).let { image ->
var numOpaque = 0
var sumHueX = 0.0
var sumHueY = 0.0
var sumSaturation = 0.0f
var sumBrightness = 0.0f
for (x in 0 until image.width)
for (y in 0 until image.height) {
val pixel = image.get(x, y)
val alpha = (pixel shr 24) and 255
val hsb = HSB.fromColor(pixel)
if (alpha == 255) {
numOpaque++
sumHueX += Math.cos((hsb.hue.toDouble() - 0.5) * PI2)
sumHueY += Math.sin((hsb.hue.toDouble() - 0.5) * PI2)
sumSaturation += hsb.saturation
sumBrightness += hsb.brightness
}
}
// circular average - transform sum vector to polar angle
val avgHue = (atan2(sumHueY, sumHueX) / PI2 + 0.5).toFloat()
HSB(avgHue, sumSaturation / numOpaque.toFloat(), sumBrightness / numOpaque.toFloat())
}
/** Weighted blend of 2 packed RGB colors */
fun blendRGB(rgb1: Int, rgb2: Int, weight1: Int, weight2: Int): Int {
val r = (((rgb1 shr 16) and 255) * weight1 + ((rgb2 shr 16) and 255) * weight2) / (weight1 + weight2)
val g = (((rgb1 shr 8) and 255) * weight1 + ((rgb2 shr 8) and 255) * weight2) / (weight1 + weight2)
val b = ((rgb1 and 255) * weight1 + (rgb2 and 255) * weight2) / (weight1 + weight2)
val a = (rgb1 shr 24) and 255
val result = ((a shl 24) or (r shl 16) or (g shl 8) or b)
return result
}