mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 02:54:04 +09:00
colorutil update, some code cleanup
Former-commit-id: 47b13e7e899dc9151f7a1ae71977ed8d4b403345 Former-commit-id: 136f9c787b76aec75d76535891cf264170bd3b04
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
package net.torvald.colourutil
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.colourutil.CIELChUtil.toLCh
|
||||
import net.torvald.colourutil.CIELChUtil.toLab
|
||||
import net.torvald.colourutil.CIELChabUtil.toLCh
|
||||
import net.torvald.colourutil.CIELChabUtil.toLab
|
||||
import net.torvald.colourutil.CIELabUtil.toLab
|
||||
import net.torvald.colourutil.CIELabUtil.toRGB
|
||||
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
||||
import net.torvald.colourutil.CIEXYZUtil.toColor
|
||||
import net.torvald.colourutil.CIELabUtil.toXYZ
|
||||
import org.newdawn.slick.Color
|
||||
|
||||
@@ -16,7 +17,7 @@ import org.newdawn.slick.Color
|
||||
* Created by minjaesong on 16-09-01.
|
||||
*/
|
||||
|
||||
object CIELChUtil {
|
||||
object CIELChabUtil {
|
||||
|
||||
/** Sweet LCh_ab linear gradient */
|
||||
fun getGradient(scale: Float, fromCol: Color, toCol: Color): Color {
|
||||
@@ -34,7 +35,7 @@ object CIELChUtil {
|
||||
else
|
||||
newH = FastMath.interpolateLinear(scale, from.h, to.h)
|
||||
|
||||
return CIELCh(newL, newC, newH, newAlpha).toRGB()
|
||||
return CIELCh(newL, newC, newH, newAlpha).toColor()
|
||||
}
|
||||
|
||||
fun CIELab.toLCh(): CIELCh {
|
||||
@@ -58,7 +59,7 @@ object CIELChUtil {
|
||||
}
|
||||
|
||||
fun Color.toLCh() = this.toXYZ().toLab().toLCh()
|
||||
fun CIELCh.toRGB() = this.toLab().toXYZ().toRGB()
|
||||
fun CIELCh.toColor() = this.toLab().toXYZ().toColor()
|
||||
|
||||
/**
|
||||
* @param L : Luminosity in 0.0 - 1.0
|
||||
|
||||
@@ -2,8 +2,9 @@ package net.torvald.colourutil
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.colourutil.CIELabUtil.toLab
|
||||
import net.torvald.colourutil.CIELabUtil.toRGB
|
||||
import net.torvald.colourutil.CIELabUtil.toRawRGB
|
||||
import net.torvald.colourutil.CIEXYZUtil.toColor
|
||||
import net.torvald.colourutil.CIEXYZUtil.toRGB
|
||||
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
||||
import net.torvald.colourutil.CIELabUtil.toXYZ
|
||||
import org.newdawn.slick.Color
|
||||
|
||||
@@ -28,7 +29,7 @@ object CIELabUtil {
|
||||
|
||||
val lab = this.toLab()
|
||||
lab.L *= brighten
|
||||
return lab.toRGB()
|
||||
return lab.toColor()
|
||||
}
|
||||
|
||||
fun Color.darkerLab(scale: Float): Color {
|
||||
@@ -36,7 +37,7 @@ object CIELabUtil {
|
||||
|
||||
val lab = this.toLab()
|
||||
lab.L *= darken
|
||||
return lab.toRGB()
|
||||
return lab.toColor()
|
||||
}
|
||||
|
||||
/** Sweet Lab linear gradient */
|
||||
@@ -48,53 +49,7 @@ object CIELabUtil {
|
||||
val newB = FastMath.interpolateLinear(scale, from.b, to.b)
|
||||
val newAlpha = FastMath.interpolateLinear(scale, from.alpha, to.alpha)
|
||||
|
||||
return CIELab(newL, newA, newB, newAlpha).toRGB()
|
||||
}
|
||||
|
||||
fun RGB.toXYZ(): CIEXYZ {
|
||||
val newR = if (r > 0.04045f)
|
||||
((r + 0.055f) / 1.055f).powerOf(2.4f)
|
||||
else r / 12.92f
|
||||
val newG = if (g > 0.04045f)
|
||||
((g + 0.055f) / 1.055f).powerOf(2.4f)
|
||||
else g / 12.92f
|
||||
val newB = if (b > 0.04045f)
|
||||
((b + 0.055f) / 1.055f).powerOf(2.4f)
|
||||
else b / 12.92f
|
||||
|
||||
val x = 0.4124564f * newR + 0.3575761f * newG + 0.1804375f * newB
|
||||
val y = 0.2126729f * newR + 0.7151522f * newG + 0.0721750f * newB
|
||||
val z = 0.0193339f * newR + 0.1191920f * newG + 0.9503041f * newB
|
||||
|
||||
return CIEXYZ(x, y, z, alpha)
|
||||
}
|
||||
|
||||
fun Color.toXYZ(): CIEXYZ = RGB(this).toXYZ()
|
||||
|
||||
fun CIEXYZ.toRawRGB(): RGB {
|
||||
var r = 3.2404542f * X - 1.5371385f * Y - 0.4985314f * Z
|
||||
var g = -0.9692660f * X + 1.8760108f * Y + 0.0415560f * Z
|
||||
var b = 0.0556434f * X - 0.2040259f * Y + 1.0572252f * Z
|
||||
|
||||
if (r > 0.0031308f)
|
||||
r = 1.055f * r.powerOf(1f / 2.4f) - 0.055f
|
||||
else
|
||||
r *= 12.92f
|
||||
if (g > 0.0031308f)
|
||||
g = 1.055f * g.powerOf(1f / 2.4f) - 0.055f
|
||||
else
|
||||
g *= 12.92f
|
||||
if (b > 0.0031308f)
|
||||
b = 1.055f * b.powerOf(1f / 2.4f) - 0.055f
|
||||
else
|
||||
b *= 12.92f
|
||||
|
||||
return RGB(r, g, b, alpha)
|
||||
}
|
||||
|
||||
fun CIEXYZ.toRGB(): Color {
|
||||
val rgb = this.toRawRGB()
|
||||
return Color(rgb.r, rgb.g, rgb.b, rgb.alpha)
|
||||
return CIELab(newL, newA, newB, newAlpha).toColor()
|
||||
}
|
||||
|
||||
fun CIEXYZ.toLab(): CIELab {
|
||||
@@ -134,20 +89,13 @@ object CIELabUtil {
|
||||
|
||||
fun Color.toLab() = this.toXYZ().toLab()
|
||||
fun RGB.toLab() = this.toXYZ().toLab()
|
||||
fun CIELab.toColor() = this.toXYZ().toColor()
|
||||
fun CIELab.toRGB() = this.toXYZ().toRGB()
|
||||
fun CIELab.toRawRGB() = this.toXYZ().toRawRGB()
|
||||
|
||||
internal val D65 = CIEXYZ(0.95047f, 1.00f, 1.08883f)
|
||||
internal val D65 = CIEXYZ(0.95047f, 1f, 1.08883f)
|
||||
val epsilon = 216f/24389f
|
||||
val kappa = 24389f/27f
|
||||
|
||||
/** Range: X, Y, Z: 0 - 1.0+ (One-based-plus) */
|
||||
data class CIEXYZ(var X: Float = 0f, var Y: Float = 0f, var Z: Float = 0f, val alpha: Float = 1f) {
|
||||
init {
|
||||
if (X > 2f || Y > 2f || Z > 2f)
|
||||
throw IllegalArgumentException("Value range error - CIEXYZ is one-based (0.0 - 1.0+): ($X, $Y, $Z)")
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Range:
|
||||
* L: 0-100.0
|
||||
@@ -155,9 +103,4 @@ data class CIEXYZ(var X: Float = 0f, var Y: Float = 0f, var Z: Float = 0f, val a
|
||||
* (Hundred-based-plus)
|
||||
*/
|
||||
data class CIELab(var L: Float = 0f, var a: Float = 0f, var b: Float = 0f, val alpha: Float = 1f)
|
||||
/** Range: r, g, b: 0 - 1.0 (One-based) */
|
||||
data class RGB(var r: Float = 0f, var g: Float = 0f, var b: Float = 0f, val alpha: Float = 1f) {
|
||||
constructor(color: Color) : this() {
|
||||
r = color.r; g = color.g; b = color.b
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,9 @@ package net.torvald.colourutil
|
||||
import com.jme3.math.FastMath
|
||||
import org.newdawn.slick.Color
|
||||
import net.torvald.colourutil.CIELabUtil.toXYZ
|
||||
import net.torvald.colourutil.CIELabUtil.toRawRGB
|
||||
import net.torvald.colourutil.CIELabUtil.toRGB
|
||||
import net.torvald.colourutil.CIEXYZUtil.toColor
|
||||
import net.torvald.colourutil.CIEXYZUtil.toRGB
|
||||
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
||||
import net.torvald.colourutil.CIELuvUtil.toLuv
|
||||
import net.torvald.colourutil.CIELuvUtil.toXYZ
|
||||
|
||||
@@ -25,7 +26,7 @@ object CIELuvUtil {
|
||||
|
||||
val luv = this.toLuv()
|
||||
luv.L *= brighten
|
||||
return luv.toRGB()
|
||||
return luv.toColor()
|
||||
}
|
||||
|
||||
fun Color.darkerLuv(scale: Float): Color {
|
||||
@@ -33,7 +34,7 @@ object CIELuvUtil {
|
||||
|
||||
val luv = this.toLuv()
|
||||
luv.L *= darken
|
||||
return luv.toRGB()
|
||||
return luv.toColor()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +56,7 @@ object CIELuvUtil {
|
||||
val newU = thisLuv.u.times(otherLuv.L / newL) + otherLuv.u.times(otherLuv.L).times(1f - thisLuv.L).div(newL)
|
||||
val newV = thisLuv.v.times(otherLuv.L / newL) + otherLuv.v.times(otherLuv.L).times(1f - thisLuv.L).div(newL)
|
||||
|
||||
return CIELuv(newL, newU, newV).toRawRGB()
|
||||
return CIELuv(newL, newU, newV).toRGB()
|
||||
}
|
||||
|
||||
fun CIEXYZ.toLuv(): CIELuv {
|
||||
@@ -98,8 +99,8 @@ object CIELuvUtil {
|
||||
}
|
||||
|
||||
fun Color.toLuv() = this.toXYZ().toLuv()
|
||||
fun CIELuv.toRawRGB() = this.toXYZ().toRawRGB()
|
||||
fun CIELuv.toRGB() = this.toXYZ().toRGB()
|
||||
fun CIELuv.toColor() = this.toXYZ().toColor()
|
||||
|
||||
/**
|
||||
* Range:
|
||||
|
||||
@@ -1,5 +1,111 @@
|
||||
package net.torvald.colourutil
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import org.newdawn.slick.Color
|
||||
|
||||
/**
|
||||
* Created by SKYHi14 on 2017-01-12.
|
||||
*/
|
||||
object CIEXYZUtil {
|
||||
fun Color.brighterXYZ(scale: Float): Color {
|
||||
val xyz = this.toXYZ()
|
||||
xyz.X = xyz.X.times(1f + scale).clampOne()
|
||||
xyz.Y = xyz.Y.times(1f + scale).clampOne()
|
||||
xyz.Z = xyz.Z.times(1f + scale).clampOne()
|
||||
return xyz.toColor()
|
||||
}
|
||||
|
||||
fun Color.darkerXYZ(scale: Float): Color {
|
||||
val xyz = this.toXYZ()
|
||||
xyz.X = xyz.X.times(1f - scale).clampOne()
|
||||
xyz.Y = xyz.Y.times(1f - scale).clampOne()
|
||||
xyz.Z = xyz.Z.times(1f - scale).clampOne()
|
||||
return xyz.toColor()
|
||||
}
|
||||
|
||||
fun getGradient(scale: Float, fromCol: Color, toCol: Color): Color {
|
||||
val from = fromCol.toXYZ()
|
||||
val to = toCol.toXYZ()
|
||||
val newX = FastMath.interpolateLinear(scale, from.X, to.X)
|
||||
val newY = FastMath.interpolateLinear(scale, from.Y, to.Y)
|
||||
val newZ = FastMath.interpolateLinear(scale, from.Z, to.Z)
|
||||
val newAlpha = FastMath.interpolateLinear(scale, from.alpha, to.alpha)
|
||||
|
||||
return CIEXYZ(newX, newY, newZ, newAlpha).toColor()
|
||||
}
|
||||
|
||||
fun Color.toXYZ(): CIEXYZ = RGB(this).toXYZ()
|
||||
|
||||
fun RGB.toXYZ(): CIEXYZ {
|
||||
val newR = if (r > 0.04045f)
|
||||
((r + 0.055f) / 1.055f).powerOf(2.4f)
|
||||
else r / 12.92f
|
||||
val newG = if (g > 0.04045f)
|
||||
((g + 0.055f) / 1.055f).powerOf(2.4f)
|
||||
else g / 12.92f
|
||||
val newB = if (b > 0.04045f)
|
||||
((b + 0.055f) / 1.055f).powerOf(2.4f)
|
||||
else b / 12.92f
|
||||
|
||||
val x = 0.4124564f * newR + 0.3575761f * newG + 0.1804375f * newB
|
||||
val y = 0.2126729f * newR + 0.7151522f * newG + 0.0721750f * newB
|
||||
val z = 0.0193339f * newR + 0.1191920f * newG + 0.9503041f * newB
|
||||
|
||||
return CIEXYZ(x, y, z, alpha)
|
||||
}
|
||||
|
||||
fun CIEXYZ.toRGB(): RGB {
|
||||
var r = 3.2404542f * X - 1.5371385f * Y - 0.4985314f * Z
|
||||
var g = -0.9692660f * X + 1.8760108f * Y + 0.0415560f * Z
|
||||
var b = 0.0556434f * X - 0.2040259f * Y + 1.0572252f * Z
|
||||
|
||||
if (r > 0.0031308f)
|
||||
r = 1.055f * r.powerOf(1f / 2.4f) - 0.055f
|
||||
else
|
||||
r *= 12.92f
|
||||
if (g > 0.0031308f)
|
||||
g = 1.055f * g.powerOf(1f / 2.4f) - 0.055f
|
||||
else
|
||||
g *= 12.92f
|
||||
if (b > 0.0031308f)
|
||||
b = 1.055f * b.powerOf(1f / 2.4f) - 0.055f
|
||||
else
|
||||
b *= 12.92f
|
||||
|
||||
return RGB(r, g, b, alpha)
|
||||
}
|
||||
|
||||
fun CIEXYZ.toColor(): Color {
|
||||
val rgb = this.toRGB()
|
||||
return Color(rgb.r, rgb.g, rgb.b, rgb.alpha)
|
||||
}
|
||||
|
||||
fun colourTempToXYZ(temp: Float, Y: Float): CIEXYZ {
|
||||
val x = if (temp < 7000)
|
||||
-4607000000f / FastMath.pow(temp, 3f) + 2967800f / FastMath.pow(temp, 2f) + 99.11f / temp + 0.244063f
|
||||
else
|
||||
-2006400000f / FastMath.pow(temp, 3f) + 1901800f / FastMath.pow(temp, 2f) + 247.48f / temp + 0.237040f
|
||||
|
||||
val y = -3f * FastMath.pow(x, 2f) + 2.870f * x - 0.275f
|
||||
|
||||
return CIEXYZ(x * Y / y, Y, (1 - x - y) * Y / y)
|
||||
}
|
||||
|
||||
private fun Float.powerOf(exp: Float) = FastMath.pow(this, exp)
|
||||
private fun Float.clampOne() = if (this > 1f) 1f else if (this < 0f) 0f else this
|
||||
}
|
||||
|
||||
/** Range: X, Y, Z: 0 - 1.0+ (One-based-plus) */
|
||||
data class CIEXYZ(var X: Float = 0f, var Y: Float = 0f, var Z: Float = 0f, val alpha: Float = 1f) {
|
||||
init {
|
||||
if (X > 2f || Y > 2f || Z > 2f)
|
||||
throw IllegalArgumentException("Value range error - CIEXYZ is one-based (0.0 - 1.0+): ($X, $Y, $Z)")
|
||||
}
|
||||
}
|
||||
|
||||
/** Range: r, g, b: 0 - 1.0 (One-based) */
|
||||
data class RGB(var r: Float = 0f, var g: Float = 0f, var b: Float = 0f, val alpha: Float = 1f) {
|
||||
constructor(color: Color) : this() {
|
||||
r = color.r; g = color.g; b = color.b
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
package net.torvald.colourutil
|
||||
|
||||
import net.torvald.terrarum.getPixel
|
||||
import net.torvald.terrarum.weather.toColor
|
||||
import org.newdawn.slick.Color
|
||||
import org.newdawn.slick.Image
|
||||
import net.torvald.colourutil.CIEXYZUtil.toColor
|
||||
|
||||
/**
|
||||
* RGB-modeled CCT calculator
|
||||
* Created by minjaesong on 16-07-26.
|
||||
*/
|
||||
object ColourTemp {
|
||||
@@ -14,5 +18,12 @@ object ColourTemp {
|
||||
return (K - 1000) / 10
|
||||
}
|
||||
|
||||
operator fun invoke(temp: Int): Color = envOverlayColourmap.getColor(colTempToImagePos(temp), 0)
|
||||
/** returns sRGB-normalised colour */
|
||||
operator fun invoke(temp: Int): Color =
|
||||
envOverlayColourmap.getPixel(colTempToImagePos(temp), 0).toColor()
|
||||
|
||||
/** returns CIExyY-based colour converted to slick.color
|
||||
* @param CIE_Y 0.0 - 1.0+ */
|
||||
operator fun invoke(temp: Float, CIE_Y: Float): Color =
|
||||
CIEXYZUtil.colourTempToXYZ(temp, CIE_Y).toColor()
|
||||
}
|
||||
Reference in New Issue
Block a user