[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)) @Redirect(method = getBakedModel, at = @At(value = "INVOKE", target = bakeModel))
IBakedModel onStoreBakedModel( IBakedModel onBakeModel(
IUnbakedModel unbaked, IUnbakedModel unbaked,
ModelBakery bakery, ModelBakery bakery,
Function<Material, TextureAtlasSprite> spriteGetter, Function<Material, TextureAtlasSprite> spriteGetter,

View File

@@ -1,5 +1,100 @@
package mods.betterfoliage 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 { init {
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, Config.build()) 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) 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.chunk.ChunkOverlayManager
import mods.betterfoliage.config.Config 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.block.vanilla.RoundLogKey
import mods.betterfoliage.render.particle.FallingLeafParticle import mods.betterfoliage.render.particle.FallingLeafParticle
import mods.betterfoliage.render.particle.LeafBlockModel import mods.betterfoliage.render.particle.LeafBlockModel
import mods.betterfoliage.render.particle.RisingSoulParticle import mods.betterfoliage.render.particle.RisingSoulParticle
import mods.betterfoliage.util.plus
import net.minecraft.block.Block import net.minecraft.block.Block
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.block.Blocks 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.VoxelShape
import net.minecraft.util.math.shapes.VoxelShapes import net.minecraft.util.math.shapes.VoxelShapes
import net.minecraft.world.IBlockReader import net.minecraft.world.IBlockReader
import net.minecraft.world.ILightReader
import net.minecraft.world.World import net.minecraft.world.World
import java.util.Random import java.util.Random
fun getAmbientOcclusionLightValueOverride(original: Float, state: BlockState): Float { 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 Config.roundLogs.dimming.toFloat()
return original 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 { 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 VoxelShapes.empty()
return state.getFaceOcclusionShape(reader, pos, dir) return state.getFaceOcclusionShape(reader, pos, dir)
} }
fun shouldForceSideRenderOF(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction) = 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 val baked: BakedQuad
) )
/**
*
*/
open class HalfBakedSimpleModelWrapper(baseModel: SimpleBakedModel): IBakedModel by baseModel, SpecialRenderModel { open class HalfBakedSimpleModelWrapper(baseModel: SimpleBakedModel): IBakedModel by baseModel, SpecialRenderModel {
val baseQuads = baseModel.unbakeQuads() val baseQuads = baseModel.unbakeQuads()

View File

@@ -2,8 +2,6 @@ package mods.betterfoliage.model
import mods.betterfoliage.render.pipeline.RenderCtxBase import mods.betterfoliage.render.pipeline.RenderCtxBase
import mods.betterfoliage.util.HasLogger 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.IBakedModel
import net.minecraft.client.renderer.model.Material import net.minecraft.client.renderer.model.Material
import net.minecraft.client.renderer.model.ModelBakery 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.client.renderer.texture.TextureAtlasSprite
import net.minecraft.util.ResourceLocation import net.minecraft.util.ResourceLocation
import net.minecraft.util.WeightedRandom import net.minecraft.util.WeightedRandom
import net.minecraft.util.math.BlockPos
import net.minecraft.world.ILightReader
import org.apache.logging.log4j.Level.WARN import org.apache.logging.log4j.Level.WARN
import java.util.Random import java.util.Random
import java.util.function.Function import java.util.function.Function
@@ -24,7 +20,7 @@ interface SpecialRenderModel : IBakedModel {
fun render(ctx: RenderCtxBase, noDecorations: Boolean = false) fun render(ctx: RenderCtxBase, noDecorations: Boolean = false)
} }
class SpecialRenderVariantList( class WeightedModelWrapper(
val models: List<WeightedModel>, baseModel: SpecialRenderModel val models: List<WeightedModel>, baseModel: SpecialRenderModel
): IBakedModel by baseModel, SpecialRenderModel { ): IBakedModel by baseModel, SpecialRenderModel {
class WeightedModel(val model: SpecialRenderModel, weight: Int) : WeightedRandom.Item(weight) class WeightedModel(val model: SpecialRenderModel, weight: Int) : WeightedRandom.Item(weight)
@@ -35,43 +31,4 @@ class SpecialRenderVariantList(
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) { override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
getModel(ctx.random).model.render(ctx, noDecorations) 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 package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.Config import mods.betterfoliage.config.Config
import mods.betterfoliage.model.HalfBakedSpecialWrapper import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey import mods.betterfoliage.model.HalfBakedWrapperKey
import mods.betterfoliage.model.SpecialRenderModel import mods.betterfoliage.model.SpecialRenderModel
import mods.betterfoliage.model.SpriteDelegate
import mods.betterfoliage.model.SpriteSetDelegate import mods.betterfoliage.model.SpriteSetDelegate
import mods.betterfoliage.model.buildTufts import mods.betterfoliage.model.buildTufts
import mods.betterfoliage.model.crossModelsRaw import mods.betterfoliage.model.crossModelsRaw
@@ -39,8 +38,9 @@ object StandardCactusDiscovery : AbstractModelDiscovery() {
override fun processModel(ctx: ModelDiscoveryContext) { override fun processModel(ctx: ModelDiscoveryContext) {
val model = ctx.getUnbaked() val model = ctx.getUnbaked()
if (model is BlockModel && ctx.blockState.block in CACTUS_BLOCKS) { 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.addReplacement(StandardCactusKey)
ctx.sprites.add(StandardCactusModel.cactusCrossSprite)
} }
super.processModel(ctx) super.processModel(ctx)
} }
@@ -69,9 +69,7 @@ class StandardCactusModel(
} }
companion object { companion object {
val cactusCrossSprite by SpriteDelegate(Atlas.BLOCKS) { val cactusCrossSprite = ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_cactus")
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_cactus")
}
val cactusArmSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx -> val cactusArmSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx ->
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_cactus_arm_$idx") ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_cactus_arm_$idx")
} }
@@ -87,7 +85,7 @@ class StandardCactusModel(
crossModelsRaw(64, config.size, 0.0, 0.0) crossModelsRaw(64, config.size, 0.0, 0.0)
.transform { rotateZ(randomD(-config.sizeVariation, config.sizeVariation)) } .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 package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.Config import mods.betterfoliage.config.Config
import mods.betterfoliage.model.HalfBakedSpecialWrapper import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey import mods.betterfoliage.model.HalfBakedWrapperKey
@@ -44,7 +44,7 @@ object StandardDirtDiscovery : AbstractModelDiscovery() {
override fun processModel(ctx: ModelDiscoveryContext) { override fun processModel(ctx: ModelDiscoveryContext) {
if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in DIRT_BLOCKS) { 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) ctx.addReplacement(StandardDirtKey)
RenderTypeLookup.setRenderLayer(ctx.blockState.block, ::canRenderInLayer) RenderTypeLookup.setRenderLayer(ctx.blockState.block, ::canRenderInLayer)
} }
@@ -65,7 +65,7 @@ class StandardDirtModel(
if (!Config.enabled || noDecorations) return super.render(ctx, noDecorations) if (!Config.enabled || noDecorations) return super.render(ctx, noDecorations)
val stateUp = ctx.offset(UP).state 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) { if (isConnectedGrass) {
(ctx.blockModelShapes.getModel(stateUp) as? SpecialRenderModel)?.let { grassModel -> (ctx.blockModelShapes.getModel(stateUp) as? SpecialRenderModel)?.let { grassModel ->
ctx.renderMasquerade(UP.offset) { ctx.renderMasquerade(UP.offset) {
@@ -101,7 +101,7 @@ class StandardDirtModel(
val reedSprites by SpriteSetDelegate( val reedSprites by SpriteSetDelegate(
Atlas.BLOCKS, Atlas.BLOCKS,
idFunc = { idx -> ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_reed_$idx") }, 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 algaeModels by LazyInvalidatable(BakeWrapperManager) {
val shapes = Config.algae.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) } 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 package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.BlockConfig import mods.betterfoliage.config.BlockConfig
import mods.betterfoliage.config.Config import mods.betterfoliage.config.Config
import mods.betterfoliage.integration.ShadersModIntegration import mods.betterfoliage.integration.ShadersModIntegration
@@ -26,8 +26,10 @@ import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.LazyInvalidatable import mods.betterfoliage.util.LazyInvalidatable
import mods.betterfoliage.util.LazyMapInvalidatable import mods.betterfoliage.util.LazyMapInvalidatable
import mods.betterfoliage.util.averageColor import mods.betterfoliage.util.averageColor
import mods.betterfoliage.util.colorOverride
import mods.betterfoliage.util.get import mods.betterfoliage.util.get
import mods.betterfoliage.util.isSnow import mods.betterfoliage.util.isSnow
import mods.betterfoliage.util.logColorOverride
import mods.betterfoliage.util.randomI import mods.betterfoliage.util.randomI
import net.minecraft.util.Direction.DOWN import net.minecraft.util.Direction.DOWN
import net.minecraft.util.Direction.UP import net.minecraft.util.Direction.UP
@@ -39,7 +41,7 @@ object StandardGrassDiscovery : ConfigurableModelDiscovery() {
override fun processModel(ctx: ModelDiscoveryContext, textureMatch: List<ResourceLocation>) { override fun processModel(ctx: ModelDiscoveryContext, textureMatch: List<ResourceLocation>) {
ctx.addReplacement(StandardGrassKey(textureMatch[0], null)) 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 isSnowed = stateAbove.isSnow
val connected = Config.connectedGrass.enabled && val connected = Config.connectedGrass.enabled &&
(!isSnowed || Config.connectedGrass.snowEnabled) && (!isSnowed || Config.connectedGrass.snowEnabled) &&
Client.blockTypes.run { stateBelow in grass || stateBelow in dirt } BetterFoliage.blockTypes.run { stateBelow in grass || stateBelow in dirt }
if (connected) { if (connected) {
ctx.renderQuads(if (isSnowed) snowFullBlockMeshes[ctx.random] else fullBlock[ctx.random]) ctx.renderQuads(if (isSnowed) snowFullBlockMeshes[ctx.random] else fullBlock[ctx.random])

View File

@@ -1,11 +1,10 @@
package mods.betterfoliage.render.block.vanilla package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.BlockConfig import mods.betterfoliage.config.BlockConfig
import mods.betterfoliage.config.Config import mods.betterfoliage.config.Config
import mods.betterfoliage.model.Color import mods.betterfoliage.model.Color
import mods.betterfoliage.model.HSB
import mods.betterfoliage.model.HalfBakedSpecialWrapper import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey import mods.betterfoliage.model.HalfBakedWrapperKey
import mods.betterfoliage.model.SpecialRenderModel 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.ModelBakingContext
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
import mods.betterfoliage.resource.discovery.ModelTextureList 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.Atlas
import mods.betterfoliage.util.LazyMapInvalidatable import mods.betterfoliage.util.LazyMapInvalidatable
import mods.betterfoliage.util.averageColor import mods.betterfoliage.util.averageColor
import mods.betterfoliage.util.colorOverride
import mods.betterfoliage.util.isSnow import mods.betterfoliage.util.isSnow
import mods.betterfoliage.util.logColorOverride
import net.minecraft.util.Direction.UP import net.minecraft.util.Direction.UP
import net.minecraft.util.ResourceLocation import net.minecraft.util.ResourceLocation
import org.apache.logging.log4j.Level.DEBUG
import org.apache.logging.log4j.Level.INFO import org.apache.logging.log4j.Level.INFO
import org.apache.logging.log4j.Logger
object StandardLeafDiscovery : ConfigurableModelDiscovery() { object StandardLeafDiscovery : ConfigurableModelDiscovery() {
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.leafBlocks override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.leafBlocks
override val modelTextures: List<ModelTextureList> get() = BlockConfig.leafModels.modelList override val modelTextures: List<ModelTextureList> get() = BlockConfig.leafModels.modelList
override fun processModel(ctx: ModelDiscoveryContext, textureMatch: List<ResourceLocation>) { override fun processModel(ctx: ModelDiscoveryContext, textureMatch: List<ResourceLocation>) {
val leafType = LeafParticleRegistry.typeMappings.getType(textureMatch[0]) ?: "default" val leafType = LeafParticleRegistry.typeMappings.getType(textureMatch[0]) ?: "default"
val generated = GeneratedLeaf(textureMatch[0], leafType) val generated = GeneratedLeafSprite(textureMatch[0], leafType)
.register(Client.generatedPack) .register(BetterFoliage.generatedPack)
.apply { ctx.sprites.add(this) } .apply { ctx.sprites.add(this) }
detailLogger.log(INFO, " particle $leafType") 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( data class StandardLeafKey(
val roundLeafTexture: ResourceLocation, val roundLeafTexture: ResourceLocation,
override val leafType: String, override val leafType: String,
@@ -74,7 +60,6 @@ data class StandardLeafKey(
logColorOverride(BetterFoliageMod.detailLogger(this), Config.leaves.saturationThreshold, hsb) logColorOverride(BetterFoliageMod.detailLogger(this), Config.leaves.saturationThreshold, hsb)
hsb.colorOverride(Config.leaves.saturationThreshold) hsb.colorOverride(Config.leaves.saturationThreshold)
} }
detailLogger.log(DEBUG, "roundLeaf=$roundLeafTexture overrideColor=$leafSpriteColor")
return StandardLeafModel(wrapped, this.copy(overrideColor = leafSpriteColor)) return StandardLeafModel(wrapped, this.copy(overrideColor = leafSpriteColor))
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,5 +9,6 @@ class BlockTypeCache {
val stateKeys = mutableMapOf<BlockState, ModelBakingKey>() 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 package mods.betterfoliage.resource.discovery
import mods.betterfoliage.BetterFoliageMod import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.util.HasLogger
import mods.betterfoliage.util.getJavaClass import mods.betterfoliage.util.getJavaClass
import mods.betterfoliage.util.getLines import mods.betterfoliage.util.getLines
import mods.betterfoliage.util.resourceManager import mods.betterfoliage.util.resourceManager
@@ -23,9 +24,7 @@ class SimpleBlockMatcher(vararg val classes: Class<*>) : IBlockMatcher {
} }
} }
class ConfigurableBlockMatcher(val location: ResourceLocation) : IBlockMatcher { class ConfigurableBlockMatcher(val location: ResourceLocation) : HasLogger(), IBlockMatcher {
val logger = BetterFoliageMod.detailLogger(this)
val blackList = mutableListOf<Class<*>>() val blackList = mutableListOf<Class<*>>()
val whiteList = mutableListOf<Class<*>>() val whiteList = mutableListOf<Class<*>>()
@@ -47,7 +46,7 @@ class ConfigurableBlockMatcher(val location: ResourceLocation) : IBlockMatcher {
blackList.clear() blackList.clear()
whiteList.clear() whiteList.clear()
resourceManager.getAllResources(location).forEach { resource -> 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 -> resource.getLines().map{ it.trim() }.filter { !it.startsWith("//") && it.isNotEmpty() }.forEach { line ->
if (line.startsWith("-")) getJavaClass(line.substring(1))?.let { blackList.add(it) } if (line.startsWith("-")) getJavaClass(line.substring(1))?.let { blackList.add(it) }
else getJavaClass(line)?.let { whiteList.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)) constructor(vararg args: String) : this(ResourceLocation(args[0]), listOf(*args).drop(1))
} }
class ModelTextureListConfiguration(val location: ResourceLocation) { class ModelTextureListConfiguration(val location: ResourceLocation) : HasLogger() {
val logger = BetterFoliageMod.detailLogger(this)
val modelList = mutableListOf<ModelTextureList>() val modelList = mutableListOf<ModelTextureList>()
fun readDefaults() { fun readDefaults() {
resourceManager.getAllResources(location).forEach { resource -> 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 -> resource.getLines().map{ it.trim() }.filter { !it.startsWith("//") && it.isNotEmpty() }.forEach { line ->
val elements = line.split(",") val elements = line.split(",")
modelList.add(ModelTextureList(ResourceLocation(elements.first()), elements.drop(1))) 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)) processModel(ctx.copy(modelLocation = variant.modelLocation, replacements = scopedReplacements))
} }
if (scopedReplacements.isNotEmpty()) { 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.HalfBakedSimpleModelWrapper
import mods.betterfoliage.model.SpecialRenderModel 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.IBakedModel
import net.minecraft.client.renderer.model.SimpleBakedModel import net.minecraft.client.renderer.model.SimpleBakedModel
import net.minecraft.client.renderer.model.VariantList import net.minecraft.client.renderer.model.VariantList
import net.minecraft.util.ResourceLocation import net.minecraft.util.ResourceLocation
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Level.INFO import org.apache.logging.log4j.Level.INFO
import org.apache.logging.log4j.Level.WARN import org.apache.logging.log4j.Level.WARN
class SpecialRenderVariantList( class WeightedUnbakedKey(
val replacements: Map<ResourceLocation, ModelBakingKey> val replacements: Map<ResourceLocation, ModelBakingKey>
) : ModelBakingKey { ) : ModelBakingKey {
@@ -29,6 +29,8 @@ class SpecialRenderVariantList(
} ?: variantCtx.getBaked() } ?: variantCtx.getBaked()
when(baked) { when(baked) {
is SpecialRenderModel -> it to 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) is SimpleBakedModel -> it to HalfBakedSimpleModelWrapper(baked)
else -> null else -> null
} }
@@ -39,16 +41,18 @@ class SpecialRenderVariantList(
if (bakedModels.isEmpty()) return super.bake(ctx) if (bakedModels.isEmpty()) return super.bake(ctx)
if (bakedModels.size < unbaked.variantList.size) { if (bakedModels.size < unbaked.variantList.size) {
SpecialRenderVariantList.detailLogger.log( detailLogger.log(
WARN, WARN,
"Dropped ${unbaked.variantList.size - bakedModels.size} variants from model ${ctx.location}" "Dropped ${unbaked.variantList.size - bakedModels.size} variants from model ${ctx.location}"
) )
} }
val weightedSpecials = bakedModels.map { (variant, model) -> 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]" 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 * @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) 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. * @param[maxSize] Preferred mask size.
*/ */
fun getLeafMask(type: String, maxSize: Int) = getMultisizeTexture(maxSize) { 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.BetterFoliageMod
import mods.betterfoliage.util.Atlas import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.HasLogger
import net.minecraft.client.Minecraft import net.minecraft.client.Minecraft
import net.minecraft.client.resources.ClientResourcePackInfo import net.minecraft.client.resources.ClientResourcePackInfo
import net.minecraft.resources.* import net.minecraft.resources.*
@@ -22,10 +23,7 @@ import java.util.function.Supplier
*/ */
class GeneratedTexturePack( class GeneratedTexturePack(
val nameSpace: String, val packName: String val nameSpace: String, val packName: String
) : IResourcePack { ) : HasLogger(), IResourcePack {
val logger = BetterFoliageMod.detailLogger(this)
override fun getName() = packName override fun getName() = packName
override fun getResourceNamespaces(type: ResourcePackType) = setOf(nameSpace) override fun getResourceNamespaces(type: ResourcePackType) = setOf(nameSpace)
override fun <T : Any?> getMetadata(deserializer: IMetadataSectionSerializer<T>) = null override fun <T : Any?> getMetadata(deserializer: IMetadataSectionSerializer<T>) = null
@@ -47,7 +45,7 @@ class GeneratedTexturePack(
identifiers[key] = id identifiers[key] = id
resources[fileName] = resource resources[fileName] = resource
logger.log(INFO, "generated resource $key -> $fileName") detailLogger.log(INFO, "generated resource $key -> $fileName")
return id 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)) return 1 shl (if (x == 0) 0 else 32 - Integer.numberOfLeadingZeros(x - 1))
} }
@Suppress("LeakingThis")
abstract class HasLogger { abstract class HasLogger {
val logger = BetterFoliageMod.logger(this) val logger = BetterFoliageMod.logger(this)
val detailLogger = BetterFoliageMod.detailLogger(this) val detailLogger = BetterFoliageMod.detailLogger(this)

View File

@@ -1,5 +1,6 @@
package mods.betterfoliage.util package mods.betterfoliage.util
import mods.betterfoliage.model.Color
import mods.betterfoliage.model.HSB import mods.betterfoliage.model.HSB
import net.minecraft.client.Minecraft import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.model.Material 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.IResource
import net.minecraft.resources.IResourceManager import net.minecraft.resources.IResourceManager
import net.minecraft.util.ResourceLocation import net.minecraft.util.ResourceLocation
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger
import java.awt.image.BufferedImage import java.awt.image.BufferedImage
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.IOException import java.io.IOException
@@ -55,8 +58,7 @@ 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), * 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. * and the result transformed back to the RGB color space.
*/ */
val TextureAtlasSprite.averageColor: HSB val TextureAtlasSprite.averageColor: HSB get() {
get() {
var numOpaque = 0 var numOpaque = 0
var sumHueX = 0.0 var sumHueX = 0.0
var sumHueY = 0.0 var sumHueY = 0.0
@@ -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) val result = ((a shl 24) or (r shl 16) or (g shl 8) or b)
return result 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