[WIP] finishing touches

+bunch of renames to bring the 2 version closer
This commit is contained in:
octarine-noise
2021-05-13 21:11:47 +02:00
parent 9899816029
commit 4174301ff7
25 changed files with 235 additions and 281 deletions

View File

@@ -31,7 +31,7 @@ abstract public class MixinModelBakery {
}
@Redirect(method = getBakedModel, at = @At(value = "INVOKE", target = bakeModel))
IBakedModel onStoreBakedModel(
IBakedModel onBakeModel(
IUnbakedModel unbaked,
ModelBakery bakery,
Function<Material, TextureAtlasSprite> spriteGetter,

View File

@@ -1,5 +1,100 @@
package mods.betterfoliage
object BetterFoliage {
import mods.betterfoliage.chunk.ChunkOverlayManager
import mods.betterfoliage.config.BlockConfig
import mods.betterfoliage.integration.OptifineCustomColors
import mods.betterfoliage.integration.ShadersModIntegration
import mods.betterfoliage.render.block.vanilla.RoundLogOverlayLayer
import mods.betterfoliage.render.block.vanilla.StandardCactusDiscovery
import mods.betterfoliage.render.block.vanilla.StandardCactusModel
import mods.betterfoliage.render.block.vanilla.StandardDirtDiscovery
import mods.betterfoliage.render.block.vanilla.StandardDirtModel
import mods.betterfoliage.render.block.vanilla.StandardGrassDiscovery
import mods.betterfoliage.render.block.vanilla.StandardGrassModel
import mods.betterfoliage.render.block.vanilla.StandardLeafDiscovery
import mods.betterfoliage.render.block.vanilla.StandardLeafModel
import mods.betterfoliage.render.block.vanilla.StandardLilypadDiscovery
import mods.betterfoliage.render.block.vanilla.StandardLilypadModel
import mods.betterfoliage.render.block.vanilla.StandardRoundLogDiscovery
import mods.betterfoliage.render.block.vanilla.StandardMyceliumDiscovery
import mods.betterfoliage.render.block.vanilla.StandardMyceliumModel
import mods.betterfoliage.render.block.vanilla.StandardNetherrackDiscovery
import mods.betterfoliage.render.block.vanilla.StandardNetherrackModel
import mods.betterfoliage.render.block.vanilla.StandardRoundLogModel
import mods.betterfoliage.render.block.vanilla.StandardSandDiscovery
import mods.betterfoliage.render.block.vanilla.StandardSandModel
import mods.betterfoliage.render.lighting.AoSideHelper
import mods.betterfoliage.render.particle.LeafWindTracker
import mods.betterfoliage.resource.discovery.BakeWrapperManager
import mods.betterfoliage.resource.discovery.BlockTypeCache
import mods.betterfoliage.resource.discovery.ModelDefinitionsLoadedEvent
import mods.betterfoliage.resource.generated.GeneratedTexturePack
import mods.betterfoliage.render.particle.LeafParticleRegistry
import mods.betterfoliage.render.particle.RisingSoulParticle
import net.minecraft.block.BlockState
import net.minecraft.client.Minecraft
import net.minecraft.resources.IReloadableResourceManager
import net.minecraftforge.eventbus.api.SubscribeEvent
/**
* Object responsible for initializing (and holding a reference to) all the infrastructure of the mod
* except for the call hooks.
*/
object BetterFoliage {
/** Resource pack holding generated assets */
val generatedPack = GeneratedTexturePack("bf_gen", "Better Foliage generated assets")
/** List of recognized [BlockState]s */
var blockTypes = BlockTypeCache()
fun init() {
// discoverers
BetterFoliageMod.bus.register(BakeWrapperManager)
BetterFoliageMod.bus.register(LeafParticleRegistry)
(Minecraft.getInstance().resourceManager as IReloadableResourceManager).addReloadListener(LeafParticleRegistry)
ChunkOverlayManager.layers.add(RoundLogOverlayLayer)
listOf(
StandardLeafDiscovery,
StandardGrassDiscovery,
StandardDirtDiscovery,
StandardMyceliumDiscovery,
StandardSandDiscovery,
StandardLilypadDiscovery,
StandardCactusDiscovery,
StandardNetherrackDiscovery,
StandardRoundLogDiscovery
).forEach {
BakeWrapperManager.discoverers.add(it)
}
// init singletons
val singletons = listOf(
AoSideHelper,
BlockConfig,
ChunkOverlayManager,
LeafWindTracker
)
val modelSingletons = listOf(
StandardLeafModel.Companion,
StandardGrassModel.Companion,
StandardDirtModel.Companion,
StandardMyceliumModel.Companion,
StandardSandModel.Companion,
StandardLilypadModel.Companion,
StandardCactusModel.Companion,
StandardNetherrackModel.Companion,
StandardRoundLogModel.Companion,
RisingSoulParticle.Companion
)
// init mod integrations
val integrations = listOf(
ShadersModIntegration,
OptifineCustomColors
)
}
}
}

View File

@@ -33,8 +33,8 @@ object BetterFoliageMod {
init {
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, Config.build())
Minecraft.getInstance().resourcePackList.addPackFinder(Client.generatedPack.finder)
Minecraft.getInstance().resourcePackList.addPackFinder(BetterFoliage.generatedPack.finder)
bus.register(BlockConfig)
Client.init()
BetterFoliage.init()
}
}

View File

@@ -1,107 +0,0 @@
package mods.betterfoliage
import mods.betterfoliage.chunk.ChunkOverlayManager
import mods.betterfoliage.config.BlockConfig
import mods.betterfoliage.integration.OptifineCustomColors
import mods.betterfoliage.integration.ShadersModIntegration
import mods.betterfoliage.render.block.vanilla.RoundLogOverlayLayer
import mods.betterfoliage.render.block.vanilla.StandardCactusDiscovery
import mods.betterfoliage.render.block.vanilla.StandardCactusModel
import mods.betterfoliage.render.block.vanilla.StandardDirtDiscovery
import mods.betterfoliage.render.block.vanilla.StandardDirtModel
import mods.betterfoliage.render.block.vanilla.StandardGrassDiscovery
import mods.betterfoliage.render.block.vanilla.StandardGrassModel
import mods.betterfoliage.render.block.vanilla.StandardLeafDiscovery
import mods.betterfoliage.render.block.vanilla.StandardLeafModel
import mods.betterfoliage.render.block.vanilla.StandardLilypadDiscovery
import mods.betterfoliage.render.block.vanilla.StandardLilypadModel
import mods.betterfoliage.render.block.vanilla.StandardLogDiscovery
import mods.betterfoliage.render.block.vanilla.StandardMyceliumDiscovery
import mods.betterfoliage.render.block.vanilla.StandardMyceliumModel
import mods.betterfoliage.render.block.vanilla.StandardNetherrackDiscovery
import mods.betterfoliage.render.block.vanilla.StandardNetherrackModel
import mods.betterfoliage.render.block.vanilla.StandardRoundLogModel
import mods.betterfoliage.render.block.vanilla.StandardSandDiscovery
import mods.betterfoliage.render.block.vanilla.StandardSandModel
import mods.betterfoliage.render.lighting.AoSideHelper
import mods.betterfoliage.render.particle.LeafWindTracker
import mods.betterfoliage.resource.discovery.BakeWrapperManager
import mods.betterfoliage.resource.discovery.BlockTypeCache
import mods.betterfoliage.resource.discovery.ModelDefinitionsLoadedEvent
import mods.betterfoliage.resource.generated.GeneratedTexturePack
import mods.betterfoliage.render.particle.LeafParticleRegistry
import mods.betterfoliage.render.particle.RisingSoulParticle
import net.minecraft.block.BlockState
import net.minecraft.client.Minecraft
import net.minecraft.resources.IReloadableResourceManager
import net.minecraftforge.eventbus.api.SubscribeEvent
/**
* Object responsible for initializing (and holding a reference to) all the infrastructure of the mod
* except for the call hooks.
*/
object Client {
/** Resource pack holding generated assets */
val generatedPack = GeneratedTexturePack("bf_gen", "Better Foliage generated assets")
/** List of recognized [BlockState]s */
var blockTypes = BlockTypeCache()
fun init() {
// discoverers
BetterFoliageMod.bus.register(BakeWrapperManager)
BetterFoliageMod.bus.register(LeafParticleRegistry)
BetterFoliageMod.bus.register(this)
(Minecraft.getInstance().resourceManager as IReloadableResourceManager).addReloadListener(LeafParticleRegistry)
ChunkOverlayManager.layers.add(RoundLogOverlayLayer)
listOf(
StandardLeafDiscovery,
StandardGrassDiscovery,
StandardDirtDiscovery,
StandardMyceliumDiscovery,
StandardSandDiscovery,
StandardLilypadDiscovery,
StandardCactusDiscovery,
StandardNetherrackDiscovery,
StandardLogDiscovery
).forEach {
BakeWrapperManager.discoverers.add(it)
}
// init singletons
val singletons = listOf(
AoSideHelper,
BlockConfig,
ChunkOverlayManager,
LeafWindTracker
)
val modelSingletons = listOf(
StandardLeafModel.Companion,
StandardGrassModel.Companion,
StandardDirtModel.Companion,
StandardMyceliumModel.Companion,
StandardSandModel.Companion,
StandardLilypadModel.Companion,
StandardCactusModel.Companion,
StandardNetherrackModel.Companion,
StandardRoundLogModel.Companion,
RisingSoulParticle.Companion
)
// init mod integrations
val integrations = listOf(
ShadersModIntegration,
OptifineCustomColors
)
}
@SubscribeEvent
fun handleModelLoad(event: ModelDefinitionsLoadedEvent) {
blockTypes = BlockTypeCache()
}
}

View File

@@ -3,12 +3,12 @@ package mods.betterfoliage
import mods.betterfoliage.chunk.ChunkOverlayManager
import mods.betterfoliage.config.Config
import mods.betterfoliage.model.getActualRenderModel
import mods.betterfoliage.model.SpecialRenderModel
import mods.betterfoliage.model.WeightedModelWrapper
import mods.betterfoliage.render.block.vanilla.RoundLogKey
import mods.betterfoliage.render.particle.FallingLeafParticle
import mods.betterfoliage.render.particle.LeafBlockModel
import mods.betterfoliage.render.particle.RisingSoulParticle
import mods.betterfoliage.util.plus
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.Blocks
@@ -21,11 +21,12 @@ import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.shapes.VoxelShape
import net.minecraft.util.math.shapes.VoxelShapes
import net.minecraft.world.IBlockReader
import net.minecraft.world.ILightReader
import net.minecraft.world.World
import java.util.Random
fun getAmbientOcclusionLightValueOverride(original: Float, state: BlockState): Float {
if (Config.enabled && Config.roundLogs.enabled && Client.blockTypes.stateKeys[state] is RoundLogKey)
if (Config.enabled && Config.roundLogs.enabled && BetterFoliage.blockTypes.hasTyped<RoundLogKey>(state))
return Config.roundLogs.dimming.toFloat()
return original
}
@@ -56,10 +57,20 @@ fun onRandomDisplayTick(block: Block, state: BlockState, world: World, pos: Bloc
}
fun getVoxelShapeOverride(state: BlockState, reader: IBlockReader, pos: BlockPos, dir: Direction): VoxelShape {
if (Config.enabled && Config.roundLogs.enabled && Client.blockTypes.stateKeys[state] is RoundLogKey)
if (Config.enabled && Config.roundLogs.enabled && BetterFoliage.blockTypes.hasTyped<RoundLogKey>(state))
return VoxelShapes.empty()
return state.getFaceOcclusionShape(reader, pos, dir)
}
fun shouldForceSideRenderOF(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction) =
world.getBlockState(pos.offset(face)).let { neighbor -> Client.blockTypes.stateKeys[neighbor] is RoundLogKey }
world.getBlockState(pos.offset(face)).let { neighbor -> BetterFoliage.blockTypes.hasTyped<RoundLogKey>(neighbor) }
fun getActualRenderModel(world: ILightReader, pos: BlockPos, state: BlockState, random: Random): SpecialRenderModel? {
val model = Minecraft.getInstance().blockRendererDispatcher.blockModelShapes.getModel(state) as? SpecialRenderModel
?: return null
if (model is WeightedModelWrapper) {
random.setSeed(state.getPositionRandom(pos))
return model.getModel(random).model
}
return model
}

View File

@@ -24,9 +24,6 @@ data class HalfBakedQuad(
val baked: BakedQuad
)
/**
*
*/
open class HalfBakedSimpleModelWrapper(baseModel: SimpleBakedModel): IBakedModel by baseModel, SpecialRenderModel {
val baseQuads = baseModel.unbakeQuads()

View File

@@ -2,8 +2,6 @@ package mods.betterfoliage.model
import mods.betterfoliage.render.pipeline.RenderCtxBase
import mods.betterfoliage.util.HasLogger
import net.minecraft.block.BlockState
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.model.IBakedModel
import net.minecraft.client.renderer.model.Material
import net.minecraft.client.renderer.model.ModelBakery
@@ -11,8 +9,6 @@ import net.minecraft.client.renderer.model.VariantList
import net.minecraft.client.renderer.texture.TextureAtlasSprite
import net.minecraft.util.ResourceLocation
import net.minecraft.util.WeightedRandom
import net.minecraft.util.math.BlockPos
import net.minecraft.world.ILightReader
import org.apache.logging.log4j.Level.WARN
import java.util.Random
import java.util.function.Function
@@ -24,7 +20,7 @@ interface SpecialRenderModel : IBakedModel {
fun render(ctx: RenderCtxBase, noDecorations: Boolean = false)
}
class SpecialRenderVariantList(
class WeightedModelWrapper(
val models: List<WeightedModel>, baseModel: SpecialRenderModel
): IBakedModel by baseModel, SpecialRenderModel {
class WeightedModel(val model: SpecialRenderModel, weight: Int) : WeightedRandom.Item(weight)
@@ -35,43 +31,4 @@ class SpecialRenderVariantList(
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
getModel(ctx.random).model.render(ctx, noDecorations)
}
companion object : HasLogger() {
/**
* If any of the variants in this [VariantList] bake to [SpecialRenderModel], give back a
* [SpecialRenderVariantList] so that variants can take advantage of extra features.
* Otherwise, give back null.
*/
fun bakeIfSpecial(
location: ResourceLocation,
variantModel: VariantList,
bakery: ModelBakery,
spriteGetter: Function<Material, TextureAtlasSprite>
): SpecialRenderVariantList? {
val bakedModels = variantModel.variantList.map {
it to bakery.getBakedModel(it.modelLocation, it, spriteGetter)
}.filter { it.second != null }
if (bakedModels.all { it.second !is SpecialRenderModel }) return null
val weightedSpecials = bakedModels.mapNotNull { (variant, model) ->
when (model) {
is SpecialRenderModel -> WeightedModel(model, variant.weight)
else -> null
}
}
if (bakedModels.size > weightedSpecials.size) {
detailLogger.log(WARN, "Dropped ${bakedModels.size - weightedSpecials.size} variants from model $location")
}
return SpecialRenderVariantList(weightedSpecials, weightedSpecials[0].model)
}
}
}
fun getActualRenderModel(world: ILightReader, pos: BlockPos, state: BlockState, random: Random): SpecialRenderModel? {
val model = Minecraft.getInstance().blockRendererDispatcher.blockModelShapes.getModel(state) as? SpecialRenderModel ?: return null
if (model is SpecialRenderVariantList) {
random.setSeed(state.getPositionRandom(pos))
return model.getModel(random).model
}
return model
}

View File

@@ -1,12 +1,11 @@
package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client
import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.Config
import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey
import mods.betterfoliage.model.SpecialRenderModel
import mods.betterfoliage.model.SpriteDelegate
import mods.betterfoliage.model.SpriteSetDelegate
import mods.betterfoliage.model.buildTufts
import mods.betterfoliage.model.crossModelsRaw
@@ -39,8 +38,9 @@ object StandardCactusDiscovery : AbstractModelDiscovery() {
override fun processModel(ctx: ModelDiscoveryContext) {
val model = ctx.getUnbaked()
if (model is BlockModel && ctx.blockState.block in CACTUS_BLOCKS) {
Client.blockTypes.dirt.add(ctx.blockState)
BetterFoliage.blockTypes.dirt.add(ctx.blockState)
ctx.addReplacement(StandardCactusKey)
ctx.sprites.add(StandardCactusModel.cactusCrossSprite)
}
super.processModel(ctx)
}
@@ -69,9 +69,7 @@ class StandardCactusModel(
}
companion object {
val cactusCrossSprite by SpriteDelegate(Atlas.BLOCKS) {
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_cactus")
}
val cactusCrossSprite = ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_cactus")
val cactusArmSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx ->
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_cactus_arm_$idx")
}
@@ -87,7 +85,7 @@ class StandardCactusModel(
crossModelsRaw(64, config.size, 0.0, 0.0)
.transform { rotateZ(randomD(-config.sizeVariation, config.sizeVariation)) }
}
crossModelsTextured(models, -1, true) { cactusCrossSprite.name }
crossModelsTextured(models, -1, true) { cactusCrossSprite }
}
}
}

View File

@@ -1,7 +1,7 @@
package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client
import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.Config
import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey
@@ -44,7 +44,7 @@ object StandardDirtDiscovery : AbstractModelDiscovery() {
override fun processModel(ctx: ModelDiscoveryContext) {
if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in DIRT_BLOCKS) {
Client.blockTypes.dirt.add(ctx.blockState)
BetterFoliage.blockTypes.dirt.add(ctx.blockState)
ctx.addReplacement(StandardDirtKey)
RenderTypeLookup.setRenderLayer(ctx.blockState.block, ::canRenderInLayer)
}
@@ -65,7 +65,7 @@ class StandardDirtModel(
if (!Config.enabled || noDecorations) return super.render(ctx, noDecorations)
val stateUp = ctx.offset(UP).state
val isConnectedGrass = Config.connectedGrass.enabled && stateUp in Client.blockTypes.grass
val isConnectedGrass = Config.connectedGrass.enabled && stateUp in BetterFoliage.blockTypes.grass
if (isConnectedGrass) {
(ctx.blockModelShapes.getModel(stateUp) as? SpecialRenderModel)?.let { grassModel ->
ctx.renderMasquerade(UP.offset) {
@@ -101,7 +101,7 @@ class StandardDirtModel(
val reedSprites by SpriteSetDelegate(
Atlas.BLOCKS,
idFunc = { idx -> ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_reed_$idx") },
idRegister = { id -> CenteredSprite(id, aspectHeight = 2).register(Client.generatedPack) }
idRegister = { id -> CenteredSprite(id, aspectHeight = 2).register(BetterFoliage.generatedPack) }
)
val algaeModels by LazyInvalidatable(BakeWrapperManager) {
val shapes = Config.algae.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) }

View File

@@ -1,7 +1,7 @@
package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client
import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.BlockConfig
import mods.betterfoliage.config.Config
import mods.betterfoliage.integration.ShadersModIntegration
@@ -26,8 +26,10 @@ import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.LazyInvalidatable
import mods.betterfoliage.util.LazyMapInvalidatable
import mods.betterfoliage.util.averageColor
import mods.betterfoliage.util.colorOverride
import mods.betterfoliage.util.get
import mods.betterfoliage.util.isSnow
import mods.betterfoliage.util.logColorOverride
import mods.betterfoliage.util.randomI
import net.minecraft.util.Direction.DOWN
import net.minecraft.util.Direction.UP
@@ -39,7 +41,7 @@ object StandardGrassDiscovery : ConfigurableModelDiscovery() {
override fun processModel(ctx: ModelDiscoveryContext, textureMatch: List<ResourceLocation>) {
ctx.addReplacement(StandardGrassKey(textureMatch[0], null))
Client.blockTypes.grass.add(ctx.blockState)
BetterFoliage.blockTypes.grass.add(ctx.blockState)
}
}
@@ -77,7 +79,7 @@ class StandardGrassModel(
val isSnowed = stateAbove.isSnow
val connected = Config.connectedGrass.enabled &&
(!isSnowed || Config.connectedGrass.snowEnabled) &&
Client.blockTypes.run { stateBelow in grass || stateBelow in dirt }
BetterFoliage.blockTypes.run { stateBelow in grass || stateBelow in dirt }
if (connected) {
ctx.renderQuads(if (isSnowed) snowFullBlockMeshes[ctx.random] else fullBlock[ctx.random])

View File

@@ -1,11 +1,10 @@
package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client
import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.BlockConfig
import mods.betterfoliage.config.Config
import mods.betterfoliage.model.Color
import mods.betterfoliage.model.HSB
import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey
import mods.betterfoliage.model.SpecialRenderModel
@@ -23,26 +22,25 @@ import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
import mods.betterfoliage.resource.discovery.ModelBakingContext
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
import mods.betterfoliage.resource.discovery.ModelTextureList
import mods.betterfoliage.resource.generated.GeneratedLeaf
import mods.betterfoliage.resource.generated.GeneratedLeafSprite
import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.LazyMapInvalidatable
import mods.betterfoliage.util.averageColor
import mods.betterfoliage.util.colorOverride
import mods.betterfoliage.util.isSnow
import mods.betterfoliage.util.logColorOverride
import net.minecraft.util.Direction.UP
import net.minecraft.util.ResourceLocation
import org.apache.logging.log4j.Level.DEBUG
import org.apache.logging.log4j.Level.INFO
import org.apache.logging.log4j.Logger
object StandardLeafDiscovery : ConfigurableModelDiscovery() {
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.leafBlocks
override val modelTextures: List<ModelTextureList> get() = BlockConfig.leafModels.modelList
override fun processModel(ctx: ModelDiscoveryContext, textureMatch: List<ResourceLocation>) {
val leafType = LeafParticleRegistry.typeMappings.getType(textureMatch[0]) ?: "default"
val generated = GeneratedLeaf(textureMatch[0], leafType)
.register(Client.generatedPack)
val generated = GeneratedLeafSprite(textureMatch[0], leafType)
.register(BetterFoliage.generatedPack)
.apply { ctx.sprites.add(this) }
detailLogger.log(INFO, " particle $leafType")
@@ -50,18 +48,6 @@ object StandardLeafDiscovery : ConfigurableModelDiscovery() {
}
}
fun logColorOverride(logger: Logger, threshold: Double, hsb: HSB) {
return if (hsb.saturation >= threshold) {
logger.log(INFO, " brightness ${hsb.brightness}")
logger.log(INFO, " saturation ${hsb.saturation} >= ${threshold}, will use texture color")
} else {
logger.log(INFO, " saturation ${hsb.saturation} < ${threshold}, will use block color")
}
}
fun HSB.colorOverride(threshold: Double) =
if (saturation < threshold) null else copy(brightness = (brightness * 2.0f).coerceAtMost(0.9f)).asColor.let { Color(it) }
data class StandardLeafKey(
val roundLeafTexture: ResourceLocation,
override val leafType: String,
@@ -74,7 +60,6 @@ data class StandardLeafKey(
logColorOverride(BetterFoliageMod.detailLogger(this), Config.leaves.saturationThreshold, hsb)
hsb.colorOverride(Config.leaves.saturationThreshold)
}
detailLogger.log(DEBUG, "roundLeaf=$roundLeafTexture overrideColor=$leafSpriteColor")
return StandardLeafModel(wrapped, this.copy(overrideColor = leafSpriteColor))
}
}

View File

@@ -1,7 +1,7 @@
package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client
import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.Config
import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey
@@ -40,7 +40,7 @@ object StandardNetherrackDiscovery : AbstractModelDiscovery() {
override fun processModel(ctx: ModelDiscoveryContext) {
if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in NETHERRACK_BLOCKS) {
Client.blockTypes.dirt.add(ctx.blockState)
BetterFoliage.blockTypes.dirt.add(ctx.blockState)
ctx.addReplacement(StandardNetherrackKey)
RenderTypeLookup.setRenderLayer(ctx.blockState.block, ::canRenderInLayer)
}

View File

@@ -1,6 +1,6 @@
package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.Client
import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.BlockConfig
import mods.betterfoliage.config.Config
import mods.betterfoliage.resource.discovery.ModelTextureList
@@ -31,23 +31,20 @@ interface RoundLogKey : ColumnBlockKey, ModelBakingKey {
}
object RoundLogOverlayLayer : ColumnRenderLayer() {
override fun getColumnKey(state: BlockState) = Client.blockTypes.getTyped<ColumnBlockKey>(state)
override fun getColumnKey(state: BlockState) = BetterFoliage.blockTypes.getTypedOrNull<ColumnBlockKey>(state)
override val connectSolids: Boolean get() = Config.roundLogs.connectSolids
override val lenientConnect: Boolean get() = Config.roundLogs.lenientConnect
override val defaultToY: Boolean get() = Config.roundLogs.defaultY
}
object StandardLogDiscovery : ConfigurableModelDiscovery() {
object StandardRoundLogDiscovery : ConfigurableModelDiscovery() {
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.logBlocks
override val modelTextures: List<ModelTextureList> get() = BlockConfig.logModels.modelList
override fun processModel(ctx: ModelDiscoveryContext, textureMatch: List<ResourceLocation>) {
val axis = getAxis(ctx.blockState)
detailLogger.log(INFO, " axis $axis")
StandardRoundLogKey(axis, textureMatch[0], textureMatch[1]).let { key ->
ctx.addReplacement(key)
Client.blockTypes.stateKeys[ctx.blockState] = key
}
ctx.addReplacement(StandardRoundLogKey(axis, textureMatch[0], textureMatch[1]))
}
fun getAxis(state: BlockState): Axis? {

View File

@@ -1,7 +1,7 @@
package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client
import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.Config
import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey
@@ -43,7 +43,7 @@ object StandardSandDiscovery : AbstractModelDiscovery() {
override fun processModel(ctx: ModelDiscoveryContext) {
if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in SAND_BLOCKS) {
Client.blockTypes.dirt.add(ctx.blockState)
BetterFoliage.blockTypes.dirt.add(ctx.blockState)
ctx.addReplacement(StandardSandKey)
RenderTypeLookup.setRenderLayer(ctx.blockState.block, RenderType.getCutoutMipped())
}

View File

@@ -25,8 +25,9 @@ abstract class ColumnModelBase(
abstract fun getMeshSet(axis: Axis, quadrant: Int): ColumnMeshSet
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
if (!enabled) return super.render(ctx, noDecorations)
val roundLog = ChunkOverlayManager.get(overlayLayer, ctx)
when(roundLog) {
ColumnLayerData.SkipRender -> return
NormalRender -> return super.render(ctx, noDecorations)

View File

@@ -1,17 +1,15 @@
package mods.betterfoliage.resource.discovery
import mods.betterfoliage.model.SpecialRenderVariantList
import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.HasLogger
import mods.betterfoliage.util.Invalidator
import mods.betterfoliage.util.SimpleInvalidator
import net.minecraft.block.BlockState
import net.minecraft.client.renderer.model.IBakedModel
import net.minecraft.client.renderer.model.IModelTransform
import net.minecraft.client.renderer.model.IUnbakedModel
import net.minecraft.client.renderer.model.Material
import net.minecraft.client.renderer.model.ModelBakery
import net.minecraft.client.renderer.model.VariantList
import net.minecraft.client.renderer.texture.TextureAtlasSprite
import net.minecraft.util.ResourceLocation
import net.minecraftforge.client.event.ModelBakeEvent
@@ -20,8 +18,8 @@ import net.minecraftforge.eventbus.api.Event
import net.minecraftforge.eventbus.api.EventPriority
import net.minecraftforge.eventbus.api.SubscribeEvent
import net.minecraftforge.fml.loading.progress.StartupMessageManager
import org.apache.logging.log4j.Level.DEBUG
import org.apache.logging.log4j.Level.INFO
import org.apache.logging.log4j.Level.WARN
import org.apache.logging.log4j.Logger
import java.lang.ref.WeakReference
import java.util.function.Function
@@ -30,6 +28,19 @@ data class ModelDefinitionsLoadedEvent(
val bakery: ModelBakery
) : Event()
interface ModelBakingKey {
fun bake(ctx: ModelBakingContext): IBakedModel? =
ctx.getUnbaked().bakeModel(ctx.bakery, ctx.spriteGetter, ctx.transform, ctx.location)
}
interface ModelDiscovery {
fun onModelsLoaded(
bakery: ModelBakery,
sprites: MutableSet<ResourceLocation>,
replacements: MutableMap<ResourceLocation, ModelBakingKey>
)
}
data class ModelDiscoveryContext(
val bakery: ModelBakery,
val blockState: BlockState,
@@ -39,20 +50,13 @@ data class ModelDiscoveryContext(
val logger: Logger
) {
fun getUnbaked(location: ResourceLocation = modelLocation) = bakery.getUnbakedModel(location)
fun addReplacement(key: ModelBakingKey) {
fun addReplacement(key: ModelBakingKey, addToStateKeys: Boolean = true) {
replacements[modelLocation] = key
if (addToStateKeys) BetterFoliage.blockTypes.stateKeys[blockState] = key
logger.log(INFO, "Adding model replacement $modelLocation -> $key")
}
}
interface ModelDiscovery {
fun onModelsLoaded(
bakery: ModelBakery,
sprites: MutableSet<ResourceLocation>,
replacements: MutableMap<ResourceLocation, ModelBakingKey>
)
}
data class ModelBakingContext(
val bakery: ModelBakery,
val spriteGetter: Function<Material, TextureAtlasSprite>,
@@ -64,31 +68,26 @@ data class ModelBakingContext(
fun getBaked() = bakery.getBakedModel(location, transform, spriteGetter)
}
interface ModelBakingKey {
fun bake(ctx: ModelBakingContext): IBakedModel? =
ctx.getUnbaked().bakeModel(ctx.bakery, ctx.spriteGetter, ctx.transform, ctx.location)
}
object BakeWrapperManager : Invalidator, HasLogger() {
val discoverers = mutableListOf<ModelDiscovery>()
override val callbacks = mutableListOf<WeakReference<()->Unit>>()
val modelsValid = SimpleInvalidator()
val spritesValid = SimpleInvalidator()
private val replacements = mutableMapOf<ResourceLocation, ModelBakingKey>()
private val sprites = mutableSetOf<ResourceLocation>()
@SubscribeEvent(priority = EventPriority.LOWEST)
fun handleModelLoad(event: ModelDefinitionsLoadedEvent) {
val startTime = System.currentTimeMillis()
modelsValid.invalidate()
invalidate()
BetterFoliage.blockTypes = BlockTypeCache()
StartupMessageManager.addModMessage("BetterFoliage: discovering models")
logger.log(INFO, "starting model discovery (${discoverers.size} listeners)")
discoverers.forEach { listener ->
val replacementsLocal = mutableMapOf<ResourceLocation, ModelBakingKey>()
listener.onModelsLoaded(event.bakery, sprites, replacements)
}
val elapsed = System.currentTimeMillis() - startTime
logger.log(INFO, "finished model discovery in $elapsed ms, ${replacements.size} top-level replacements")
}
@@ -97,7 +96,6 @@ object BakeWrapperManager : Invalidator, HasLogger() {
fun handleStitch(event: TextureStitchEvent.Pre) {
if (event.map.textureLocation == Atlas.BLOCKS.resourceId) {
logger.log(INFO, "Adding ${sprites.size} sprites to block atlas")
spritesValid.invalidate()
sprites.forEach { event.addSprite(it) }
sprites.clear()
}
@@ -119,7 +117,12 @@ object BakeWrapperManager : Invalidator, HasLogger() {
// bake replacement if available
replacements[location]?.let { replacement ->
detailLogger.log(INFO, "Baking replacement for [${unbaked::class.java.simpleName}] $location -> $replacement")
return replacement.bake(ctx)
try {
return replacement.bake(ctx)
} catch (e: Exception) {
detailLogger.log(WARN, "Error while baking $replacement", e)
logger.log(WARN, "Error while baking $replacement", e)
}
}
return unbaked.bakeModel(bakery, spriteGetter, transform, location)
}

View File

@@ -9,5 +9,6 @@ class BlockTypeCache {
val stateKeys = mutableMapOf<BlockState, ModelBakingKey>()
inline fun <reified T> getTyped(state: BlockState) = stateKeys[state] as? T
inline fun <reified T> getTypedOrNull(state: BlockState) = stateKeys[state] as? T
inline fun <reified T> hasTyped(state: BlockState) = stateKeys[state] is T
}

View File

@@ -1,6 +1,7 @@
package mods.betterfoliage.resource.discovery
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.util.HasLogger
import mods.betterfoliage.util.getJavaClass
import mods.betterfoliage.util.getLines
import mods.betterfoliage.util.resourceManager
@@ -23,9 +24,7 @@ class SimpleBlockMatcher(vararg val classes: Class<*>) : IBlockMatcher {
}
}
class ConfigurableBlockMatcher(val location: ResourceLocation) : IBlockMatcher {
val logger = BetterFoliageMod.detailLogger(this)
class ConfigurableBlockMatcher(val location: ResourceLocation) : HasLogger(), IBlockMatcher {
val blackList = mutableListOf<Class<*>>()
val whiteList = mutableListOf<Class<*>>()
@@ -47,7 +46,7 @@ class ConfigurableBlockMatcher(val location: ResourceLocation) : IBlockMatcher {
blackList.clear()
whiteList.clear()
resourceManager.getAllResources(location).forEach { resource ->
logger.log(INFO, "Reading block class configuration $location from pack ${resource.packName}")
detailLogger.log(INFO, "Reading block class configuration $location from pack ${resource.packName}")
resource.getLines().map{ it.trim() }.filter { !it.startsWith("//") && it.isNotEmpty() }.forEach { line ->
if (line.startsWith("-")) getJavaClass(line.substring(1))?.let { blackList.add(it) }
else getJavaClass(line)?.let { whiteList.add(it) }
@@ -61,13 +60,11 @@ data class ModelTextureList(val modelLocation: ResourceLocation, val textureName
constructor(vararg args: String) : this(ResourceLocation(args[0]), listOf(*args).drop(1))
}
class ModelTextureListConfiguration(val location: ResourceLocation) {
val logger = BetterFoliageMod.detailLogger(this)
class ModelTextureListConfiguration(val location: ResourceLocation) : HasLogger() {
val modelList = mutableListOf<ModelTextureList>()
fun readDefaults() {
resourceManager.getAllResources(location).forEach { resource ->
logger.log(INFO, "Reading model/texture configuration $location from pack ${resource.packName}")
detailLogger.log(INFO, "Reading model/texture configuration $location from pack ${resource.packName}")
resource.getLines().map{ it.trim() }.filter { !it.startsWith("//") && it.isNotEmpty() }.forEach { line ->
val elements = line.split(",")
modelList.add(ModelTextureList(ResourceLocation(elements.first()), elements.drop(1)))

View File

@@ -42,7 +42,7 @@ abstract class AbstractModelDiscovery : HasLogger(), ModelDiscovery {
processModel(ctx.copy(modelLocation = variant.modelLocation, replacements = scopedReplacements))
}
if (scopedReplacements.isNotEmpty()) {
ctx.addReplacement(SpecialRenderVariantList(scopedReplacements))
ctx.addReplacement(WeightedUnbakedKey(scopedReplacements), addToStateKeys = false)
}
}
}

View File

@@ -2,16 +2,16 @@ package mods.betterfoliage.resource.discovery
import mods.betterfoliage.model.HalfBakedSimpleModelWrapper
import mods.betterfoliage.model.SpecialRenderModel
import mods.betterfoliage.model.SpecialRenderVariantList
import mods.betterfoliage.model.WeightedModelWrapper
import mods.betterfoliage.util.HasLogger
import net.minecraft.client.renderer.model.IBakedModel
import net.minecraft.client.renderer.model.SimpleBakedModel
import net.minecraft.client.renderer.model.VariantList
import net.minecraft.util.ResourceLocation
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Level.INFO
import org.apache.logging.log4j.Level.WARN
class SpecialRenderVariantList(
class WeightedUnbakedKey(
val replacements: Map<ResourceLocation, ModelBakingKey>
) : ModelBakingKey {
@@ -29,6 +29,8 @@ class SpecialRenderVariantList(
} ?: variantCtx.getBaked()
when(baked) {
is SpecialRenderModel -> it to baked
// just in case we replaced some variants in the list, but not others
// this should not realistically happen, this is just a best-effort fallback
is SimpleBakedModel -> it to HalfBakedSimpleModelWrapper(baked)
else -> null
}
@@ -39,16 +41,18 @@ class SpecialRenderVariantList(
if (bakedModels.isEmpty()) return super.bake(ctx)
if (bakedModels.size < unbaked.variantList.size) {
SpecialRenderVariantList.detailLogger.log(
detailLogger.log(
WARN,
"Dropped ${unbaked.variantList.size - bakedModels.size} variants from model ${ctx.location}"
)
}
val weightedSpecials = bakedModels.map { (variant, model) ->
SpecialRenderVariantList.WeightedModel(model, variant.weight)
WeightedModelWrapper.WeightedModel(model, variant.weight)
}
return SpecialRenderVariantList(weightedSpecials, weightedSpecials[0].model)
return WeightedModelWrapper(weightedSpecials, weightedSpecials[0].model)
}
override fun toString() = "[SpecialRenderVariantList, ${replacements.size} replacements]"
companion object : HasLogger()
}

View File

@@ -21,7 +21,7 @@ import java.awt.image.BufferedImage
*
* @param[domain] Resource domain of generator
*/
data class GeneratedLeaf(val baseSprite: ResourceLocation, val leafType: String, val atlas: Atlas = Atlas.BLOCKS) {
data class GeneratedLeafSprite(val baseSprite: ResourceLocation, val leafType: String, val atlas: Atlas = Atlas.BLOCKS) {
fun register(pack: GeneratedTexturePack) = pack.register(atlas, this, this::draw)
@@ -73,7 +73,7 @@ data class GeneratedLeaf(val baseSprite: ResourceLocation, val leafType: String,
* @param[maxSize] Preferred mask size.
*/
fun getLeafMask(type: String, maxSize: Int) = getMultisizeTexture(maxSize) { size ->
ResourceLocation(BetterFoliageMod.MOD_ID, "textures/blocks/leafmask_${size}_${type}.png")
Atlas.BLOCKS.file(ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/leafmask_${size}_${type}"))
}
/**

View File

@@ -2,6 +2,7 @@ package mods.betterfoliage.resource.generated
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.HasLogger
import net.minecraft.client.Minecraft
import net.minecraft.client.resources.ClientResourcePackInfo
import net.minecraft.resources.*
@@ -22,10 +23,7 @@ import java.util.function.Supplier
*/
class GeneratedTexturePack(
val nameSpace: String, val packName: String
) : IResourcePack {
val logger = BetterFoliageMod.detailLogger(this)
) : HasLogger(), IResourcePack {
override fun getName() = packName
override fun getResourceNamespaces(type: ResourcePackType) = setOf(nameSpace)
override fun <T : Any?> getMetadata(deserializer: IMetadataSectionSerializer<T>) = null
@@ -47,7 +45,7 @@ class GeneratedTexturePack(
identifiers[key] = id
resources[fileName] = resource
logger.log(INFO, "generated resource $key -> $fileName")
detailLogger.log(INFO, "generated resource $key -> $fileName")
return id
}

View File

@@ -50,6 +50,7 @@ fun nextPowerOf2(x: Int): Int {
return 1 shl (if (x == 0) 0 else 32 - Integer.numberOfLeadingZeros(x - 1))
}
@Suppress("LeakingThis")
abstract class HasLogger {
val logger = BetterFoliageMod.logger(this)
val detailLogger = BetterFoliageMod.detailLogger(this)

View File

@@ -1,5 +1,6 @@
package mods.betterfoliage.util
import mods.betterfoliage.model.Color
import mods.betterfoliage.model.HSB
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.model.Material
@@ -8,6 +9,8 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite
import net.minecraft.resources.IResource
import net.minecraft.resources.IResourceManager
import net.minecraft.util.ResourceLocation
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger
import java.awt.image.BufferedImage
import java.io.ByteArrayOutputStream
import java.io.IOException
@@ -55,31 +58,30 @@ val BufferedImage.bytes: ByteArray get() =
* 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.
*/
val TextureAtlasSprite.averageColor: HSB
get() {
var numOpaque = 0
var sumHueX = 0.0
var sumHueY = 0.0
var sumSaturation = 0.0f
var sumBrightness = 0.0f
for (x in 0 until width)
for (y in 0 until height) {
val pixel = getPixelRGBA(0, x, y)
val alpha = (pixel shr 24) and 255
val hsb = HSB.fromColorRGBA(pixel)
if (alpha == 255) {
numOpaque++
sumHueX += cos((hsb.hue.toDouble() - 0.5) * PI2)
sumHueY += sin((hsb.hue.toDouble() - 0.5) * PI2)
sumSaturation += hsb.saturation
sumBrightness += hsb.brightness
}
val TextureAtlasSprite.averageColor: HSB get() {
var numOpaque = 0
var sumHueX = 0.0
var sumHueY = 0.0
var sumSaturation = 0.0f
var sumBrightness = 0.0f
for (x in 0 until width)
for (y in 0 until height) {
val pixel = getPixelRGBA(0, x, y)
val alpha = (pixel shr 24) and 255
val hsb = HSB.fromColorRGBA(pixel)
if (alpha == 255) {
numOpaque++
sumHueX += cos((hsb.hue.toDouble() - 0.5) * PI2)
sumHueY += 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()
return HSB(avgHue, sumSaturation / numOpaque.toFloat(), sumBrightness / numOpaque.toFloat())
}
// circular average - transform sum vector to polar angle
val avgHue = (atan2(sumHueY, sumHueX) / PI2 + 0.5).toFloat()
return 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 {
@@ -90,3 +92,15 @@ fun blendRGB(rgb1: Int, rgb2: Int, weight1: Int, weight2: Int): Int {
val result = ((a shl 24) or (r shl 16) or (g shl 8) or b)
return result
}
fun logColorOverride(logger: Logger, threshold: Double, hsb: HSB) {
return if (hsb.saturation >= threshold) {
logger.log(Level.INFO, " brightness ${hsb.brightness}")
logger.log(Level.INFO, " saturation ${hsb.saturation} >= ${threshold}, will use texture color")
} else {
logger.log(Level.INFO, " saturation ${hsb.saturation} < ${threshold}, will use block color")
}
}
fun HSB.colorOverride(threshold: Double) =
if (saturation < threshold) null else copy(brightness = (brightness * 2.0f).coerceAtMost(0.9f)).asColor.let { Color(it) }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 B