[WIP] Falling leaves working

+ more cleanup
+ fix double-tinted leaves
This commit is contained in:
octarine-noise
2021-05-11 15:08:28 +02:00
parent 7168caded1
commit 835bf45f13
18 changed files with 417 additions and 214 deletions
@@ -1,13 +1,25 @@
package mods.betterfoliage.render
import com.mojang.blaze3d.vertex.IVertexBuilder
import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.Config
import mods.betterfoliage.render.old.AbstractEntityFX
import mods.betterfoliage.model.HSB
import mods.betterfoliage.model.getActualRenderModel
import mods.betterfoliage.render.particle.AbstractParticle
import mods.betterfoliage.texture.LeafParticleKey
import mods.betterfoliage.texture.LeafParticleRegistry
import mods.betterfoliage.util.Double3
import mods.betterfoliage.util.PI2
import mods.betterfoliage.util.get
import mods.betterfoliage.util.minmax
import mods.betterfoliage.util.randomB
import mods.betterfoliage.util.randomD
import mods.betterfoliage.util.randomF
import mods.betterfoliage.util.randomI
import net.minecraft.client.Minecraft
import net.minecraft.client.particle.IParticleRenderType
import net.minecraft.client.renderer.ActiveRenderInfo
import net.minecraft.client.renderer.BufferBuilder
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.MathHelper
@@ -23,116 +35,3 @@ import kotlin.math.sin
const val rotationFactor = PI2.toFloat() / 64.0f
class EntityFallingLeavesFX(
world: World, pos: BlockPos
) : AbstractEntityFX(
world, pos.x.toDouble() + 0.5, pos.y.toDouble(), pos.z.toDouble() + 0.5
) {
companion object {
@JvmStatic val biomeBrightnessMultiplier = 0.5f
}
var particleRot = rand.nextInt(64)
var rotPositive = true
val isMirrored = (rand.nextInt() and 1) == 1
var wasCollided = false
init {
maxAge = MathHelper.floor(randomD(0.6, 1.0) * Config.fallingLeaves.lifetime * 20.0)
motionY = -Config.fallingLeaves.speed
particleScale = Config.fallingLeaves.size.toFloat() * 0.1f
val state = world.getBlockState(pos)
// val leafInfo = LeafRegistry[state, world, pos]
val blockColor = Minecraft.getInstance().blockColors.getColor(state, world, pos, 0)
// if (leafInfo != null) {
// sprite = leafInfo.particleTextures[rand.nextInt(1024)]
// calculateParticleColor(leafInfo.averageColor, blockColor)
// } else {
// sprite = LeafParticleRegistry["default"][rand.nextInt(1024)]
// setColor(blockColor)
// }
}
override val isValid: Boolean get() = (sprite != null)
override fun update() {
if (rand.nextFloat() > 0.95f) rotPositive = !rotPositive
if (age > maxAge - 20) particleAlpha = 0.05f * (maxAge - age)
if (onGround || wasCollided) {
velocity.setTo(0.0, 0.0, 0.0)
if (!wasCollided) {
age = age.coerceAtLeast(maxAge - 20)
wasCollided = true
}
} else {
velocity.setTo(cos[particleRot], 0.0, sin[particleRot]).mul(Config.fallingLeaves.perturb)
.add(LeafWindTracker.current).add(0.0, -1.0, 0.0).mul(Config.fallingLeaves.speed)
particleRot = (particleRot + (if (rotPositive) 1 else -1)) and 63
particleAngle = rotationFactor * particleRot.toFloat()
}
}
override fun render(worldRenderer: BufferBuilder, partialTickTime: Float) {
// if (Config.fallingLeaves.opacityHack) GL11.glDepthMask(true)
// renderParticleQuad(worldRenderer, partialTickTime, rotation = particleRot, isMirrored = isMirrored)
}
fun calculateParticleColor(textureAvgColor: Int, blockColor: Int) {
val texture = HSB.fromColor(textureAvgColor)
val block = HSB.fromColor(blockColor)
val weightTex = texture.saturation / (texture.saturation + block.saturation)
val weightBlock = 1.0f - weightTex
// avoid circular average for hue for performance reasons
// one of the color components should dominate anyway
val particle = HSB(
weightTex * texture.hue + weightBlock * block.hue,
weightTex * texture.saturation + weightBlock * block.saturation,
weightTex * texture.brightness + weightBlock * block.brightness * biomeBrightnessMultiplier
)
setColor(particle.asColor)
}
}
object LeafWindTracker {
var random = Random()
val target = Double3.zero
val current = Double3.zero
var nextChange: Long = 0
init {
MinecraftForge.EVENT_BUS.register(this)
}
fun changeWind(world: World) {
nextChange = world.worldInfo.gameTime + 120 + random.nextInt(80)
val direction = PI2 * random.nextDouble()
val speed = abs(random.nextGaussian()) * Config.fallingLeaves.windStrength +
(if (!world.isRaining) 0.0 else abs(random.nextGaussian()) * Config.fallingLeaves.stormStrength)
target.setTo(cos(direction) * speed, 0.0, sin(direction) * speed)
}
@SubscribeEvent
fun handleWorldTick(event: TickEvent.ClientTickEvent) {
if (event.phase == TickEvent.Phase.START) Minecraft.getInstance().world?.let { world ->
// change target wind speed
if (world.worldInfo.dayTime >= nextChange) changeWind(world)
// change current wind speed
val changeRate = if (world.isRaining) 0.015 else 0.005
current.add(
(target.x - current.x).minmax(-changeRate, changeRate),
0.0,
(target.z - current.z).minmax(-changeRate, changeRate)
)
}
}
@SubscribeEvent
fun handleWorldLoad(event: WorldEvent.Load) { if (event.world.isRemote) changeWind(event.world.world) }
}