-
-
Save nilium/b9f0088d525da4848d5c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.spifftastic.ascension2.backend | |
import net.spifftastic.spastic.graphics.ColorSpace | |
abstract class ColorGenerator { | |
trait TouchColorGenerator { | |
/** | |
* Modifies the given HSV color in hsvInOut depending on the bar state and | |
* alpha. This color stage is applied before color shimmer is applied. | |
* @param state The bar state to use for the color. | |
* @param alpha How much blending to apply between a color's off/on or | |
* touched/untouched state. | |
* @param hsvInOut An HSV color. The resulting HSV color must be placed in | |
* this array. Hue, saturation, and value are always at indices 0, 1, | |
* and 2 respectively. Other indices are undefined. | |
*/ | |
def pre(state: BarState, alpha: Float, hsvInOut: Array[Float]): Unit | |
/** | |
* Modifies the given RGB color in rgbInOut depending on the bar state and | |
* alpha. This color stage is applied after color shimmer is applied. | |
* @param state The bar state to use for the color. | |
* @param alpha How much blending to apply between a color's off/on or | |
* touched/untouched state. | |
* @param rgbInOut An RGB color. The resulting RGB color must be placed in | |
* this array. Red, green, and blue components are always at indices 0, | |
* 1, and 2 respectively. Other indices are undefined. | |
*/ | |
def post(state: BarState, alpha: Float, rgbInOut: Array[Float]): Unit | |
} | |
/** | |
* Returns a touch color generator that makes use of custom touch colors. This may be called | |
* during each call to prepare, so it's worth caching the result if it doesn't change. | |
* @return a TouchColorGenerator. | |
*/ | |
def specificTouchColorGenerator: TouchColorGenerator | |
/** | |
* Returns a touch color generator that doesn't make use of custom touch colors. This may be | |
* called during each call to prepare, so it's worth caching the result if it doesn't change. | |
* @return a TouchColorGenerator. | |
*/ | |
def baseTouchColorGenerator: TouchColorGenerator | |
/** The current touch color generator as acquired by prepare(BarState). */ | |
private[this] var touchGen: TouchColorGenerator = null | |
private[this] val shimmerTemp = new Array[Float](3) | |
/** | |
* Given the BarState, do any preparation necessary for computing bar colors. This is called once | |
* per frame. By default, it simply caches the TouchColorGenerator based on the current config. | |
* @param state The bar state to prepare with. | |
*/ | |
def prepare(state: BarState): Unit = { | |
if (state.config.useTouchColor) touchGen = specificTouchColorGenerator | |
else touchGen = baseTouchColorGenerator | |
} | |
@inline | |
final def applyShimmer(state: BarState, barIndex: Int, output: Array[Float]): Unit = { | |
state.shimmerForBar(barIndex, shimmerTemp) | |
val hue = output(0) + shimmerTemp(0) | |
if (hue < 0f) output(0) = hue + 1f | |
else if (hue > 1f) output(0) = hue - 1f | |
else output(0) = hue | |
output(1) += shimmerTemp(1) | |
output(2) += shimmerTemp(2) | |
} | |
@inline | |
final def initColorForBar(state: BarState, barIndex: Int, output: Array[Float]): Unit = { | |
state.baseColorForBar(barIndex, output) | |
} | |
@inline | |
final def applyPreTouchColor(state: BarState, barIndex: Int, transition: Float, output: Array[Float]): Unit = { | |
touchGen.pre(state, transition, output) | |
} | |
@inline | |
final def applyPostTouchColor(state: BarState, barIndex: Int, transition: Float, output: Array[Float]): Unit = { | |
touchGen.post(state, transition, output) | |
} | |
/** | |
* Gets the RGB color of a bar given the touch state provided. The default implementation | |
* simply calls initColorForBar, applyPreTouchColor, applyShimmer, converts from HSV to RGB, | |
* and calls then applyPostTouchColor in order. Subclasses should implement this without | |
* calling into the super method, as the super method overwrites any current output. @param | |
* state The bar state to use when generating the color. | |
* | |
* @param state The BarState to compute with. | |
* @param barIndex The bar index to get the color of. | |
* @param output An array of at least length 3 to write the HSV components to. RGB components are | |
* always written to indices 0, 1, and 2 respectively. | |
*/ | |
def colorForBar(state: BarState, barIndex: Int, output: Array[Float]): Unit = { | |
initColorForBar(state, barIndex, output) | |
applyPreTouchColor(state, barIndex, state.transitionForBar(barIndex), output) | |
applyShimmer(state, barIndex, output) | |
ColorSpace.RGB.coerce(ColorSpace.HSV, output, 0) | |
applyPostTouchColor(state, barIndex, state.transitionForBar(barIndex), output) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.spifftastic.ascension2.backend | |
class GelColorGenerator extends ColorGenerator { | |
object BaseTouchColorGenerator extends TouchColorGenerator { | |
def pre(state: BarState, alpha: Float, hsvInOut: Array[Float]): Unit = { | |
hsvInOut(2) *= 0.4f + (1f - alpha) * 0.6f | |
} | |
def post(state: BarState, alpha: Float, rgbInOut: Array[Float]): Unit = () | |
} | |
object SpecificTouchColorGenerator extends TouchColorGenerator { | |
def pre(state: BarState, alpha: Float, hsvInOut: Array[Float]): Unit = () | |
def post(state: BarState, alpha: Float, rgbInOut: Array[Float]): Unit = { | |
val color = state.config.touchColor | |
val beta = 1f - alpha | |
rgbInOut(0) = rgbInOut(0) * beta + color.red * alpha | |
rgbInOut(1) = rgbInOut(1) * beta + color.green * alpha | |
rgbInOut(2) = rgbInOut(2) * beta + color.blue * alpha | |
} | |
} | |
/** | |
* Returns a touch color generator that makes use of custom touch colors. This may be called | |
* during each call to prepare, so it's worth caching the result if it doesn't change. | |
* @return a TouchColorGenerator. | |
*/ | |
def specificTouchColorGenerator = SpecificTouchColorGenerator | |
/** | |
* Returns a touch color generator that doesn't make use of custom touch colors. This may be | |
* called during each call to prepare, so it's worth caching the result if it doesn't change. | |
* @return a TouchColorGenerator. | |
*/ | |
def baseTouchColorGenerator = BaseTouchColorGenerator | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment