[WIP] algae, reeds, mycelium, coral working
+ lots of cleanup, reorganizing
This commit is contained in:
@@ -2,7 +2,7 @@ package mods.betterfoliage.mixin;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import mods.betterfoliage.render.ISpecialRenderModel;
|
||||
import mods.betterfoliage.model.SpecialRenderModel;
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxVanilla;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
@@ -25,16 +25,16 @@ public class MixinBlockModelRenderer {
|
||||
|
||||
@Redirect(method = renderModel, at = @At(value = "INVOKE", target = renderModelSmooth), remap = false)
|
||||
public boolean onRenderModelSmooth(BlockModelRenderer renderer, ILightReader world, IBakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, IVertexBuilder buffer, boolean checkSides, Random random, long rand, int combinedOverlay, IModelData modelData) {
|
||||
if (model instanceof ISpecialRenderModel)
|
||||
return RenderCtxVanilla.render(renderer, world, (ISpecialRenderModel) model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData, true);
|
||||
if (model instanceof SpecialRenderModel)
|
||||
return RenderCtxVanilla.render(renderer, world, (SpecialRenderModel) model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData, true);
|
||||
else
|
||||
return renderer.renderModelSmooth(world, model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData);
|
||||
}
|
||||
|
||||
@Redirect(method = renderModel, at = @At(value = "INVOKE", target = renderModelFlat), remap = false)
|
||||
public boolean onRenderModelFlat(BlockModelRenderer renderer, ILightReader world, IBakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, IVertexBuilder buffer, boolean checkSides, Random random, long rand, int combinedOverlay, IModelData modelData) {
|
||||
if (model instanceof ISpecialRenderModel)
|
||||
return RenderCtxVanilla.render(renderer, world, (ISpecialRenderModel) model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData, false);
|
||||
if (model instanceof SpecialRenderModel)
|
||||
return RenderCtxVanilla.render(renderer, world, (SpecialRenderModel) model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData, false);
|
||||
else
|
||||
return renderer.renderModelSmooth(world, model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package mods.betterfoliage.mixin;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxForge;
|
||||
import mods.betterfoliage.render.ISpecialRenderModel;
|
||||
import mods.betterfoliage.model.SpecialRenderModel;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -36,8 +36,8 @@ public class MixinForgeBlockModelRenderer {
|
||||
long seed,
|
||||
IModelData modelData
|
||||
) {
|
||||
if (model instanceof ISpecialRenderModel)
|
||||
return RenderCtxForge.render(lighter, world, (ISpecialRenderModel) model, state, pos, matrixStack, checkSides, rand, seed, modelData);
|
||||
if (model instanceof SpecialRenderModel)
|
||||
return RenderCtxForge.render(lighter, world, (SpecialRenderModel) model, state, pos, matrixStack, checkSides, rand, seed, modelData);
|
||||
else
|
||||
return ForgeBlockModelRenderer.render(lighter, world, model, state, pos, matrixStack, checkSides, rand, seed, modelData);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@ abstract public class MixinForgeCustomVertexLighting implements ForgeVertexLight
|
||||
|
||||
@Inject(method = resetBlockInfo, at = @At("RETURN"), remap = false)
|
||||
void onReset(CallbackInfo ci) {
|
||||
// just in case
|
||||
vertexLighter = this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ object BetterFoliageMod {
|
||||
|
||||
init {
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, Config.build())
|
||||
Minecraft.getInstance().resourcePackList.addPackFinder(Client.asyncPack.finder)
|
||||
Minecraft.getInstance().resourcePackList.addPackFinder(Client.generatedPack.finder)
|
||||
bus.register(BlockConfig)
|
||||
Client.init()
|
||||
}
|
||||
|
||||
@@ -7,10 +7,15 @@ import mods.betterfoliage.integration.ShadersModIntegration
|
||||
import mods.betterfoliage.render.LeafWindTracker
|
||||
import mods.betterfoliage.render.block.vanilla.StandardDirtDiscovery
|
||||
import mods.betterfoliage.render.block.vanilla.StandardDirtKey
|
||||
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.StandardMyceliumDiscovery
|
||||
import mods.betterfoliage.render.block.vanilla.StandardMyceliumModel
|
||||
import mods.betterfoliage.render.block.vanilla.StandardSandDiscovery
|
||||
import mods.betterfoliage.render.block.vanilla.StandardSandModel
|
||||
import mods.betterfoliage.render.lighting.AoSideHelper
|
||||
import mods.betterfoliage.resource.discovery.BakeWrapperManager
|
||||
import mods.betterfoliage.resource.discovery.BlockTypeCache
|
||||
@@ -26,7 +31,7 @@ import net.minecraftforge.common.ForgeConfig
|
||||
* except for the call hooks.
|
||||
*/
|
||||
object Client {
|
||||
val asyncPack = GeneratedTexturePack("bf_gen", "Better Foliage generated assets")
|
||||
val generatedPack = GeneratedTexturePack("bf_gen", "Better Foliage generated assets")
|
||||
var blockTypes = BlockTypeCache()
|
||||
|
||||
val suppressRenderErrors = mutableSetOf<BlockState>()
|
||||
@@ -37,7 +42,9 @@ object Client {
|
||||
listOf(
|
||||
StandardLeafDiscovery,
|
||||
StandardGrassDiscovery,
|
||||
StandardDirtDiscovery
|
||||
StandardDirtDiscovery,
|
||||
StandardMyceliumDiscovery,
|
||||
StandardSandDiscovery
|
||||
).forEach {
|
||||
BakeWrapperManager.discoverers.add(it)
|
||||
}
|
||||
@@ -52,7 +59,10 @@ object Client {
|
||||
|
||||
val modelSingletons = listOf(
|
||||
StandardLeafModel.Companion,
|
||||
StandardGrassModel.Companion
|
||||
StandardGrassModel.Companion,
|
||||
StandardDirtModel.Companion,
|
||||
StandardMyceliumModel.Companion,
|
||||
StandardSandModel.Companion
|
||||
)
|
||||
|
||||
// init mod integrations
|
||||
|
||||
@@ -7,6 +7,7 @@ import mods.betterfoliage.util.plus
|
||||
import mods.betterfoliage.util.semiRandom
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
@@ -29,7 +30,9 @@ interface BlockCtx {
|
||||
fun state(dir: Direction) = world.getBlockState(pos + dir.offset)
|
||||
fun state(offset: Int3) = world.getBlockState(pos + offset)
|
||||
|
||||
val biome: Biome? get() = (world as? IWorldReader)?.getBiome(pos)
|
||||
val biome: Biome? get() =
|
||||
(world as? IWorldReader)?.getBiome(pos) ?:
|
||||
(world as? ChunkRenderCache)?.world?.getBiome(pos)
|
||||
|
||||
val isNormalCube: Boolean get() = state.isNormalCube(world, pos)
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package mods.betterfoliage.render.old
|
||||
package mods.betterfoliage.model
|
||||
|
||||
import mods.betterfoliage.render.ISpecialRenderModel
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import mods.betterfoliage.resource.discovery.ModelBakeKey
|
||||
import mods.betterfoliage.resource.discovery.ModelBakingKey
|
||||
import mods.betterfoliage.util.Double3
|
||||
import mods.betterfoliage.util.HasLogger
|
||||
import mods.betterfoliage.util.directionsAndNull
|
||||
@@ -21,13 +20,19 @@ import net.minecraftforge.client.model.pipeline.BakedQuadBuilder
|
||||
import java.util.Random
|
||||
import java.util.function.Function
|
||||
|
||||
|
||||
/**
|
||||
* Hybrid baked quad implementation, carrying both baked and unbaked information.
|
||||
* Used to do advanced vertex lighting without unbaking vertex data at lighting time.
|
||||
*/
|
||||
data class HalfBakedQuad(
|
||||
val raw: Quad,
|
||||
val baked: BakedQuad
|
||||
)
|
||||
|
||||
open class HalfBakedSimpleModelWrapper(baseModel: SimpleBakedModel): IBakedModel by baseModel, ISpecialRenderModel {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
open class HalfBakedSimpleModelWrapper(baseModel: SimpleBakedModel): IBakedModel by baseModel, SpecialRenderModel {
|
||||
val baseQuads = baseModel.unbakeQuads()
|
||||
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
@@ -35,21 +40,21 @@ open class HalfBakedSimpleModelWrapper(baseModel: SimpleBakedModel): IBakedModel
|
||||
}
|
||||
}
|
||||
|
||||
open class HalfBakedSpecialWrapper(val baseModel: ISpecialRenderModel): IBakedModel by baseModel, ISpecialRenderModel {
|
||||
open class HalfBakedSpecialWrapper(val baseModel: SpecialRenderModel): IBakedModel by baseModel, SpecialRenderModel {
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
baseModel.render(ctx, noDecorations)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class HalfBakedWrapKey : ModelBakeKey, HasLogger() {
|
||||
override fun replace(
|
||||
abstract class HalfBakedWrapperKey : ModelBakingKey, HasLogger() {
|
||||
override fun bake(
|
||||
location: ResourceLocation,
|
||||
unbaked: IUnbakedModel,
|
||||
transform: IModelTransform,
|
||||
bakery: ModelBakery,
|
||||
spriteGetter: Function<Material, TextureAtlasSprite>
|
||||
): IBakedModel? {
|
||||
val baseModel = super.replace(location, unbaked, transform, bakery, spriteGetter)
|
||||
val baseModel = super.bake(location, unbaked, transform, bakery, spriteGetter)
|
||||
val halfBaked = when(baseModel) {
|
||||
is SimpleBakedModel -> HalfBakedSimpleModelWrapper(baseModel)
|
||||
else -> null
|
||||
@@ -57,7 +62,8 @@ abstract class HalfBakedWrapKey : ModelBakeKey, HasLogger() {
|
||||
return if (halfBaked == null) baseModel else replace(halfBaked)
|
||||
}
|
||||
|
||||
abstract fun replace(wrapped: ISpecialRenderModel): ISpecialRenderModel
|
||||
|
||||
abstract fun replace(wrapped: SpecialRenderModel): SpecialRenderModel
|
||||
}
|
||||
|
||||
fun List<Quad>.bake(applyDiffuseLighting: Boolean) = map { quad ->
|
||||
@@ -1,26 +1,16 @@
|
||||
package mods.betterfoliage.render.old
|
||||
package mods.betterfoliage.model
|
||||
|
||||
import mods.betterfoliage.util.Double3
|
||||
import mods.betterfoliage.util.Rotation
|
||||
import mods.betterfoliage.util.allDirections
|
||||
import mods.betterfoliage.util.boxFaces
|
||||
import mods.betterfoliage.util.get
|
||||
import mods.betterfoliage.util.minmax
|
||||
import mods.betterfoliage.util.nearestAngle
|
||||
import mods.betterfoliage.util.replace
|
||||
import mods.betterfoliage.util.rotate
|
||||
import mods.betterfoliage.util.times
|
||||
import mods.betterfoliage.util.toImmutableList
|
||||
import mods.betterfoliage.util.vec
|
||||
import net.minecraft.client.renderer.model.BakedQuad
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement.Type
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement.Usage
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder
|
||||
import java.lang.Math.max
|
||||
import java.lang.Math.min
|
||||
import java.util.Random
|
||||
@@ -0,0 +1,64 @@
|
||||
package mods.betterfoliage.model
|
||||
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import mods.betterfoliage.util.HasLogger
|
||||
import net.minecraft.client.renderer.model.IBakedModel
|
||||
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.minecraft.util.WeightedRandom
|
||||
import org.apache.logging.log4j.Level.WARN
|
||||
import java.util.Random
|
||||
import java.util.function.Function
|
||||
|
||||
/**
|
||||
* Model that makes use of advanced rendering features.
|
||||
*/
|
||||
interface SpecialRenderModel : IBakedModel {
|
||||
fun render(ctx: RenderCtxBase, noDecorations: Boolean = false)
|
||||
}
|
||||
|
||||
class SpecialRenderVariantList(
|
||||
val models: List<WeightedModel>, baseModel: SpecialRenderModel
|
||||
): IBakedModel by baseModel, SpecialRenderModel {
|
||||
class WeightedModel(val model: SpecialRenderModel, weight: Int) : WeightedRandom.Item(weight)
|
||||
val totalWeight = models.sumBy { it.itemWeight }
|
||||
|
||||
fun getModel(random: Random) = WeightedRandom.getRandomItem(models, random.nextInt(totalWeight))
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package mods.betterfoliage.resource.model
|
||||
package mods.betterfoliage.model
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.util.Atlas
|
||||
@@ -1,22 +1,16 @@
|
||||
package mods.betterfoliage.resource.model
|
||||
package mods.betterfoliage.model
|
||||
|
||||
import mods.betterfoliage.render.block.vanilla.getColorOverride
|
||||
import mods.betterfoliage.render.old.Color
|
||||
import mods.betterfoliage.render.old.HalfBakedQuad
|
||||
import mods.betterfoliage.render.old.Quad
|
||||
import mods.betterfoliage.render.old.bake
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.util.Double3
|
||||
import mods.betterfoliage.util.PI2
|
||||
import mods.betterfoliage.util.allDirections
|
||||
import mods.betterfoliage.util.averageColor
|
||||
import mods.betterfoliage.util.random
|
||||
import mods.betterfoliage.util.randomB
|
||||
import mods.betterfoliage.util.randomD
|
||||
import mods.betterfoliage.util.randomI
|
||||
import mods.betterfoliage.util.rot
|
||||
import mods.betterfoliage.util.vec
|
||||
import net.minecraft.client.renderer.model.BakedQuad
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
@@ -126,4 +120,6 @@ fun crossModelsTinted(
|
||||
|
||||
fun List<Quad>.withOpposites() = flatMap { listOf(it, it.flipped) }
|
||||
fun List<List<Quad>>.buildTufts(applyDiffuseLighting: Boolean = false) =
|
||||
map { it.withOpposites().bake(applyDiffuseLighting) }.toTypedArray()
|
||||
map { it.withOpposites().bake(applyDiffuseLighting) }.toTypedArray()
|
||||
|
||||
fun List<List<Quad>>.transform(trans: Quad.(Int)-> Quad) = mapIndexed { idx, qList -> qList.map { it.trans(idx) } }
|
||||
@@ -2,7 +2,7 @@ package mods.betterfoliage.render
|
||||
|
||||
import mods.betterfoliage.config.Config
|
||||
import mods.betterfoliage.render.old.AbstractEntityFX
|
||||
import mods.betterfoliage.render.old.HSB
|
||||
import mods.betterfoliage.model.HSB
|
||||
import mods.betterfoliage.util.Double3
|
||||
import mods.betterfoliage.util.PI2
|
||||
import mods.betterfoliage.util.minmax
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package mods.betterfoliage.render
|
||||
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import net.minecraft.client.renderer.model.IBakedModel
|
||||
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.WeightedRandom
|
||||
import java.util.Random
|
||||
import java.util.function.Function
|
||||
|
||||
interface ISpecialRenderModel : IBakedModel {
|
||||
fun render(ctx: RenderCtxBase, noDecorations: Boolean = false)
|
||||
}
|
||||
|
||||
open class SpecialRenderWrapper(val baseModel: IBakedModel) : IBakedModel by baseModel, ISpecialRenderModel {
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
ctx.renderFallback(baseModel)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If any of the variants in this [VariantList] bake to [ISpecialRenderModel], give back a
|
||||
* [SpecialRenderVariantList] so that variants can take advantage of extra features.
|
||||
* Otherwise, give back null.
|
||||
*/
|
||||
fun VariantList.bakeSpecial(bakery: ModelBakery, spriteGetter: Function<Material, TextureAtlasSprite>): SpecialRenderVariantList? {
|
||||
val bakedModels = variantList.map { bakery.getBakedModel(it.modelLocation, it, spriteGetter) }
|
||||
if (bakedModels.all { it !is ISpecialRenderModel }) return null
|
||||
val weightedItems = (variantList zip bakedModels)
|
||||
.filter { it.second != null }
|
||||
.map { (variant, model) ->
|
||||
val modelWrapped = (model!! as? ISpecialRenderModel) ?: SpecialRenderWrapper(model)
|
||||
SpecialRenderVariantList.WeightedModel(modelWrapped, variant.weight)
|
||||
}
|
||||
return SpecialRenderVariantList(weightedItems, weightedItems[0].model)
|
||||
}
|
||||
|
||||
open class SpecialRenderVariantList(
|
||||
val models: List<WeightedModel>, baseModel: ISpecialRenderModel
|
||||
): IBakedModel by baseModel, ISpecialRenderModel {
|
||||
class WeightedModel(val model: ISpecialRenderModel, weight: Int) : WeightedRandom.Item(weight)
|
||||
val totalWeight = models.sumBy { it.itemWeight }
|
||||
|
||||
fun getModel(random: Random) = WeightedRandom.getRandomItem(models, random.nextInt(totalWeight))
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) = getModel(ctx.random).model.render(ctx, noDecorations)
|
||||
}
|
||||
@@ -1,57 +1,77 @@
|
||||
package mods.betterfoliage.render.block.vanilla
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.Client
|
||||
import mods.betterfoliage.config.Config
|
||||
import mods.betterfoliage.render.ISpecialRenderModel
|
||||
import mods.betterfoliage.render.old.HalfBakedSpecialWrapper
|
||||
import mods.betterfoliage.render.old.HalfBakedWrapKey
|
||||
import mods.betterfoliage.model.Color
|
||||
import mods.betterfoliage.model.HalfBakedSpecialWrapper
|
||||
import mods.betterfoliage.model.HalfBakedWrapperKey
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.model.SpriteSetDelegate
|
||||
import mods.betterfoliage.model.buildTufts
|
||||
import mods.betterfoliage.model.tuftModelSet
|
||||
import mods.betterfoliage.model.tuftShapeSet
|
||||
import mods.betterfoliage.render.lighting.LightingPreferredFace
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import mods.betterfoliage.resource.discovery.ModelBakeKey
|
||||
import mods.betterfoliage.resource.discovery.ModelReplacer
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxVanilla
|
||||
import mods.betterfoliage.resource.discovery.AbstractModelDiscovery
|
||||
import mods.betterfoliage.resource.discovery.BakeWrapperManager
|
||||
import mods.betterfoliage.resource.discovery.ModelBakingKey
|
||||
import mods.betterfoliage.resource.generated.CenteredSprite
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.util.Int3
|
||||
import mods.betterfoliage.util.LazyInvalidatable
|
||||
import mods.betterfoliage.util.get
|
||||
import mods.betterfoliage.util.offset
|
||||
import mods.betterfoliage.util.randomI
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.RenderTypeLookup
|
||||
import net.minecraft.client.renderer.model.BlockModel
|
||||
import net.minecraft.client.renderer.model.ModelBakery
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraft.world.biome.Biome
|
||||
|
||||
object StandardDirtDiscovery : ModelReplacer() {
|
||||
val dirtBlocks = listOf(Blocks.DIRT, Blocks.COARSE_DIRT, Blocks.PODZOL)
|
||||
object StandardDirtDiscovery : AbstractModelDiscovery() {
|
||||
val DIRT_BLOCKS = listOf(Blocks.DIRT, Blocks.COARSE_DIRT, Blocks.PODZOL)
|
||||
override fun processModel(
|
||||
bakery: ModelBakery,
|
||||
state: BlockState,
|
||||
location: ResourceLocation,
|
||||
sprites: MutableSet<ResourceLocation>,
|
||||
replacements: MutableMap<ResourceLocation, ModelBakeKey>
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
): Boolean {
|
||||
val model = bakery.getUnbakedModel(location)
|
||||
if (model is BlockModel && state.block in dirtBlocks) {
|
||||
if (model is BlockModel && state.block in DIRT_BLOCKS) {
|
||||
Client.blockTypes.dirt.add(state)
|
||||
replacements[location] = StandardDirtKey
|
||||
RenderTypeLookup.setRenderLayer(state.block, RenderType.getCutout())
|
||||
// RenderTypeLookup.setRenderLayer(state.block, RenderType.getCutout())
|
||||
RenderTypeLookup.setRenderLayer(state.block, RenderType.getCutoutMipped())
|
||||
return true
|
||||
}
|
||||
return super.processModel(bakery, state, location, sprites, replacements)
|
||||
}
|
||||
}
|
||||
|
||||
object StandardDirtKey : HalfBakedWrapKey() {
|
||||
override fun replace(wrapped: ISpecialRenderModel) = StandardDirtModel(wrapped)
|
||||
object StandardDirtKey : HalfBakedWrapperKey() {
|
||||
override fun replace(wrapped: SpecialRenderModel) = StandardDirtModel(wrapped)
|
||||
}
|
||||
|
||||
class StandardDirtModel(
|
||||
wrapped: ISpecialRenderModel
|
||||
wrapped: SpecialRenderModel
|
||||
) : HalfBakedSpecialWrapper(wrapped) {
|
||||
val vanillaTuftLighting = LightingPreferredFace(UP)
|
||||
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
if (!Config.enabled || noDecorations) return super.render(ctx, false)
|
||||
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
|
||||
if (isConnectedGrass) {
|
||||
(ctx.blockModelShapes.getModel(stateUp) as? ISpecialRenderModel)?.let { grassModel ->
|
||||
(ctx.blockModelShapes.getModel(stateUp) as? SpecialRenderModel)?.let { grassModel ->
|
||||
ctx.renderMasquerade(UP.offset) {
|
||||
grassModel.render(ctx, true)
|
||||
}
|
||||
@@ -61,5 +81,39 @@ class StandardDirtModel(
|
||||
}
|
||||
|
||||
super.render(ctx, false)
|
||||
|
||||
val isWater = stateUp.material == Material.WATER
|
||||
val isDeepWater = isWater && ctx.offset(Int3(2 to UP)).state.material == Material.WATER
|
||||
val isShallowWater = isWater && ctx.offset(Int3(2 to UP)).state.isAir
|
||||
val isSaltWater = isWater && ctx.biome?.category in SALTWATER_BIOMES
|
||||
|
||||
if (Config.algae.enabled(ctx.random) && isDeepWater) {
|
||||
(ctx as? RenderCtxVanilla)?.vertexLighter = vanillaTuftLighting
|
||||
ctx.render(algaeModels[ctx.random])
|
||||
} else if (Config.reed.enabled(ctx.random) && isShallowWater && !isSaltWater) {
|
||||
(ctx as? RenderCtxVanilla)?.vertexLighter = vanillaTuftLighting
|
||||
ctx.render(reedModels[ctx.random])
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val SALTWATER_BIOMES = listOf(Biome.Category.BEACH, Biome.Category.OCEAN)
|
||||
|
||||
val algaeSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx ->
|
||||
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_algae_$idx")
|
||||
}
|
||||
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) }
|
||||
)
|
||||
val algaeModels by LazyInvalidatable(BakeWrapperManager) {
|
||||
val shapes = Config.algae.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) }
|
||||
tuftModelSet(shapes, Color.white) { algaeSprites[randomI()] }.buildTufts()
|
||||
}
|
||||
val reedModels by LazyInvalidatable(BakeWrapperManager) {
|
||||
val shapes = Config.reed.let { tuftShapeSet(2.0, it.heightMin, it.heightMax, it.hOffset) }
|
||||
tuftModelSet(shapes, Color.white) { reedSprites[randomI()] }.buildTufts()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,22 +6,22 @@ import mods.betterfoliage.config.BlockConfig
|
||||
import mods.betterfoliage.config.Config
|
||||
import mods.betterfoliage.config.ConfigurableBlockMatcher
|
||||
import mods.betterfoliage.config.ModelTextureList
|
||||
import mods.betterfoliage.render.ISpecialRenderModel
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.render.lighting.LightingPreferredFace
|
||||
import mods.betterfoliage.render.old.Color
|
||||
import mods.betterfoliage.render.old.HalfBakedSpecialWrapper
|
||||
import mods.betterfoliage.render.old.HalfBakedWrapKey
|
||||
import mods.betterfoliage.model.Color
|
||||
import mods.betterfoliage.model.HalfBakedSpecialWrapper
|
||||
import mods.betterfoliage.model.HalfBakedWrapperKey
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxVanilla
|
||||
import mods.betterfoliage.resource.discovery.BakeWrapperManager
|
||||
import mods.betterfoliage.resource.discovery.ConfigurableModelReplacer
|
||||
import mods.betterfoliage.resource.discovery.ModelBakeKey
|
||||
import mods.betterfoliage.resource.model.SpriteSetDelegate
|
||||
import mods.betterfoliage.resource.model.buildTufts
|
||||
import mods.betterfoliage.resource.model.fullCubeTextured
|
||||
import mods.betterfoliage.resource.model.fullCubeTinted
|
||||
import mods.betterfoliage.resource.model.tuftModelSet
|
||||
import mods.betterfoliage.resource.model.tuftShapeSet
|
||||
import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
|
||||
import mods.betterfoliage.resource.discovery.ModelBakingKey
|
||||
import mods.betterfoliage.model.SpriteSetDelegate
|
||||
import mods.betterfoliage.model.buildTufts
|
||||
import mods.betterfoliage.model.fullCubeTextured
|
||||
import mods.betterfoliage.model.fullCubeTinted
|
||||
import mods.betterfoliage.model.tuftModelSet
|
||||
import mods.betterfoliage.model.tuftShapeSet
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.util.LazyInvalidatable
|
||||
import mods.betterfoliage.util.LazyMapInvalidatable
|
||||
@@ -29,14 +29,11 @@ import mods.betterfoliage.util.get
|
||||
import mods.betterfoliage.util.isSnow
|
||||
import mods.betterfoliage.util.randomI
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.RenderTypeLookup
|
||||
import net.minecraft.util.Direction.DOWN
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
|
||||
object StandardGrassDiscovery : ConfigurableModelReplacer() {
|
||||
object StandardGrassDiscovery : ConfigurableModelDiscovery() {
|
||||
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.grassBlocks
|
||||
override val modelTextures: List<ModelTextureList> get() = BlockConfig.grassModels.modelList
|
||||
|
||||
@@ -45,36 +42,33 @@ object StandardGrassDiscovery : ConfigurableModelReplacer() {
|
||||
location: ResourceLocation,
|
||||
textureMatch: List<ResourceLocation>,
|
||||
sprites: MutableSet<ResourceLocation>,
|
||||
replacements: MutableMap<ResourceLocation, ModelBakeKey>
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
): Boolean {
|
||||
replacements[location] = StandardGrassKey(textureMatch[0])
|
||||
Client.blockTypes.grass.add(state)
|
||||
RenderTypeLookup.setRenderLayer(state.block, RenderType.getCutout())
|
||||
// RenderTypeLookup.setRenderLayer(state.block, RenderType.getCutout())
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
data class StandardGrassKey(
|
||||
val grassLocation: ResourceLocation
|
||||
) : HalfBakedWrapKey() {
|
||||
override fun replace(wrapped: ISpecialRenderModel): ISpecialRenderModel {
|
||||
) : HalfBakedWrapperKey() {
|
||||
override fun replace(wrapped: SpecialRenderModel): SpecialRenderModel {
|
||||
Atlas.BLOCKS[grassLocation].logColorOverride(detailLogger, Config.shortGrass.saturationThreshold)
|
||||
return StandardGrassModel(wrapped, this)
|
||||
}
|
||||
}
|
||||
|
||||
class StandardGrassModel(
|
||||
wrapped: ISpecialRenderModel,
|
||||
wrapped: SpecialRenderModel,
|
||||
key: StandardGrassKey
|
||||
) : HalfBakedSpecialWrapper(wrapped) {
|
||||
|
||||
val tuftNormal by grassTuftMeshesNormal.delegate(key)
|
||||
val tuftSnowed by grassTuftMeshesSnowed.delegate(key)
|
||||
val fullBlock by grassFullBlockMeshes.delegate(key)
|
||||
|
||||
val upNormal = arrayOf(0.0f, 1.0f, 0.0f, 0.0f).toFloatArray()
|
||||
|
||||
val vanillaTuftLighting = LightingPreferredFace(UP)
|
||||
val tuftLighting = LightingPreferredFace(UP)
|
||||
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
if (!Config.enabled || noDecorations) return super.render(ctx, noDecorations)
|
||||
@@ -94,7 +88,7 @@ class StandardGrassModel(
|
||||
}
|
||||
|
||||
if (Config.shortGrass.enabled(ctx.random) && !ctx.isNeighborSolid(UP)) {
|
||||
(ctx as? RenderCtxVanilla)?.let { it.vertexLighter = vanillaTuftLighting }
|
||||
(ctx as? RenderCtxVanilla)?.let { it.vertexLighter = tuftLighting }
|
||||
ctx.render(if (isSnowed) tuftSnowed[ctx.random] else tuftNormal[ctx.random])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,21 +6,21 @@ import mods.betterfoliage.config.BlockConfig
|
||||
import mods.betterfoliage.config.Config
|
||||
import mods.betterfoliage.config.ConfigurableBlockMatcher
|
||||
import mods.betterfoliage.config.ModelTextureList
|
||||
import mods.betterfoliage.render.ISpecialRenderModel
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.render.lighting.RoundLeafLighting
|
||||
import mods.betterfoliage.render.old.Color
|
||||
import mods.betterfoliage.render.old.HalfBakedSpecialWrapper
|
||||
import mods.betterfoliage.render.old.HalfBakedWrapKey
|
||||
import mods.betterfoliage.model.Color
|
||||
import mods.betterfoliage.model.HalfBakedSpecialWrapper
|
||||
import mods.betterfoliage.model.HalfBakedWrapperKey
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxVanilla
|
||||
import mods.betterfoliage.resource.discovery.BakeWrapperManager
|
||||
import mods.betterfoliage.resource.discovery.ConfigurableModelReplacer
|
||||
import mods.betterfoliage.resource.discovery.ModelBakeKey
|
||||
import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
|
||||
import mods.betterfoliage.resource.discovery.ModelBakingKey
|
||||
import mods.betterfoliage.resource.generated.GeneratedLeaf
|
||||
import mods.betterfoliage.resource.model.SpriteSetDelegate
|
||||
import mods.betterfoliage.resource.model.crossModelsRaw
|
||||
import mods.betterfoliage.resource.model.crossModelsTextured
|
||||
import mods.betterfoliage.resource.model.crossModelsTinted
|
||||
import mods.betterfoliage.model.SpriteSetDelegate
|
||||
import mods.betterfoliage.model.crossModelsRaw
|
||||
import mods.betterfoliage.model.crossModelsTextured
|
||||
import mods.betterfoliage.model.crossModelsTinted
|
||||
import mods.betterfoliage.texture.LeafParticleRegistry
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.util.LazyMapInvalidatable
|
||||
@@ -33,7 +33,7 @@ import net.minecraft.util.ResourceLocation
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
import org.apache.logging.log4j.Logger
|
||||
|
||||
object StandardLeafDiscovery : ConfigurableModelReplacer() {
|
||||
object StandardLeafDiscovery : ConfigurableModelDiscovery() {
|
||||
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.leafBlocks
|
||||
override val modelTextures: List<ModelTextureList> get() = BlockConfig.leafModels.modelList
|
||||
|
||||
@@ -42,11 +42,11 @@ object StandardLeafDiscovery : ConfigurableModelReplacer() {
|
||||
location: ResourceLocation,
|
||||
textureMatch: List<ResourceLocation>,
|
||||
sprites: MutableSet<ResourceLocation>,
|
||||
replacements: MutableMap<ResourceLocation, ModelBakeKey>
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
): Boolean {
|
||||
val leafType = LeafParticleRegistry.typeMappings.getType(textureMatch[0]) ?: "default"
|
||||
val generated = GeneratedLeaf(textureMatch[0], leafType)
|
||||
.register(Client.asyncPack)
|
||||
.register(Client.generatedPack)
|
||||
.apply { sprites.add(this) }
|
||||
|
||||
detailLogger.log(INFO, " particle $leafType")
|
||||
@@ -72,15 +72,15 @@ fun TextureAtlasSprite.getColorOverride(threshold: Double) = averageColor.let {
|
||||
data class StandardLeafKey(
|
||||
val roundLeafTexture: ResourceLocation,
|
||||
val leafType: String
|
||||
) : HalfBakedWrapKey() {
|
||||
override fun replace(wrapped: ISpecialRenderModel): ISpecialRenderModel {
|
||||
) : HalfBakedWrapperKey() {
|
||||
override fun replace(wrapped: SpecialRenderModel): SpecialRenderModel {
|
||||
Atlas.BLOCKS[roundLeafTexture].logColorOverride(BetterFoliageMod.detailLogger(this), 0.1)
|
||||
return StandardLeafModel(wrapped, this)
|
||||
}
|
||||
}
|
||||
|
||||
class StandardLeafModel(
|
||||
model: ISpecialRenderModel,
|
||||
model: SpecialRenderModel,
|
||||
key: StandardLeafKey
|
||||
) : HalfBakedSpecialWrapper(model) {
|
||||
val leafNormal by leafModelsNormal.delegate(key)
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package mods.betterfoliage.render.block.vanilla
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.config.Config
|
||||
import mods.betterfoliage.model.Color
|
||||
import mods.betterfoliage.model.HalfBakedSpecialWrapper
|
||||
import mods.betterfoliage.model.HalfBakedWrapperKey
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.model.SpriteSetDelegate
|
||||
import mods.betterfoliage.model.buildTufts
|
||||
import mods.betterfoliage.model.tuftModelSet
|
||||
import mods.betterfoliage.model.tuftShapeSet
|
||||
import mods.betterfoliage.render.lighting.LightingPreferredFace
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import mods.betterfoliage.resource.discovery.AbstractModelDiscovery
|
||||
import mods.betterfoliage.resource.discovery.BakeWrapperManager
|
||||
import mods.betterfoliage.resource.discovery.ModelBakingKey
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.util.LazyInvalidatable
|
||||
import mods.betterfoliage.util.get
|
||||
import mods.betterfoliage.util.randomI
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.RenderTypeLookup
|
||||
import net.minecraft.client.renderer.model.BlockModel
|
||||
import net.minecraft.client.renderer.model.ModelBakery
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.ResourceLocation
|
||||
|
||||
object StandardMyceliumDiscovery : AbstractModelDiscovery() {
|
||||
val MYCELIUM_BLOCKS = listOf(Blocks.MYCELIUM)
|
||||
|
||||
override fun processModel(
|
||||
bakery: ModelBakery,
|
||||
state: BlockState,
|
||||
location: ResourceLocation,
|
||||
sprites: MutableSet<ResourceLocation>,
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
): Boolean {
|
||||
val model = bakery.getUnbakedModel(location)
|
||||
if (model is BlockModel && state.block in MYCELIUM_BLOCKS) {
|
||||
replacements[location] = StandardMyceliumKey
|
||||
RenderTypeLookup.setRenderLayer(state.block, RenderType.getCutout())
|
||||
return true
|
||||
}
|
||||
return super.processModel(bakery, state, location, sprites, replacements)
|
||||
}
|
||||
}
|
||||
|
||||
object StandardMyceliumKey : HalfBakedWrapperKey() {
|
||||
override fun replace(wrapped: SpecialRenderModel) = StandardMyceliumModel(wrapped)
|
||||
}
|
||||
|
||||
class StandardMyceliumModel(
|
||||
wrapped: SpecialRenderModel
|
||||
) : HalfBakedSpecialWrapper(wrapped) {
|
||||
|
||||
val tuftLighting = LightingPreferredFace(Direction.UP)
|
||||
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
super.render(ctx, noDecorations)
|
||||
|
||||
if (Config.shortGrass.enabled &&
|
||||
Config.shortGrass.myceliumEnabled &&
|
||||
Config.shortGrass.enabled(ctx.random) &&
|
||||
ctx.state(Direction.UP).isAir(ctx.world, ctx.pos)
|
||||
) {
|
||||
ctx.vertexLighter = tuftLighting
|
||||
ctx.render(myceliumTuftModels[ctx.random])
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val myceliumTuftSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx ->
|
||||
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_mycel_$idx")
|
||||
}
|
||||
val myceliumTuftModels by LazyInvalidatable(BakeWrapperManager) {
|
||||
val shapes = Config.shortGrass.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) }
|
||||
tuftModelSet(shapes, Color.white) { idx -> myceliumTuftSprites[randomI()] }.buildTufts()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package mods.betterfoliage.render.block.vanilla
|
||||
|
||||
import mods.betterfoliage.render.column.ColumnBlockKey
|
||||
import mods.betterfoliage.resource.discovery.ModelBakeKey
|
||||
import mods.betterfoliage.resource.discovery.ModelBakingKey
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.ResourceLocation
|
||||
|
||||
@@ -9,5 +9,5 @@ data class RoundLogKey(
|
||||
override val axis: Direction.Axis?,
|
||||
val barkSprite: ResourceLocation,
|
||||
val endSprite: ResourceLocation
|
||||
) : ColumnBlockKey, ModelBakeKey {
|
||||
) : ColumnBlockKey, ModelBakingKey {
|
||||
}
|
||||
118
src/main/kotlin/mods/betterfoliage/render/block/vanilla/Sand.kt
Normal file
118
src/main/kotlin/mods/betterfoliage/render/block/vanilla/Sand.kt
Normal file
@@ -0,0 +1,118 @@
|
||||
package mods.betterfoliage.render.block.vanilla
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.Client
|
||||
import mods.betterfoliage.config.Config
|
||||
import mods.betterfoliage.model.Color
|
||||
import mods.betterfoliage.model.HalfBakedSpecialWrapper
|
||||
import mods.betterfoliage.model.HalfBakedWrapperKey
|
||||
import mods.betterfoliage.model.Quad
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.model.SpriteSetDelegate
|
||||
import mods.betterfoliage.model.bake
|
||||
import mods.betterfoliage.model.buildTufts
|
||||
import mods.betterfoliage.model.transform
|
||||
import mods.betterfoliage.model.tuftModelSet
|
||||
import mods.betterfoliage.model.tuftShapeSet
|
||||
import mods.betterfoliage.render.block.vanilla.StandardDirtModel.Companion.SALTWATER_BIOMES
|
||||
import mods.betterfoliage.render.lighting.LightingPreferredFace
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import mods.betterfoliage.resource.discovery.AbstractModelDiscovery
|
||||
import mods.betterfoliage.resource.discovery.BakeWrapperManager
|
||||
import mods.betterfoliage.resource.discovery.ModelBakingKey
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.util.LazyInvalidatable
|
||||
import mods.betterfoliage.util.Rotation
|
||||
import mods.betterfoliage.util.allDirections
|
||||
import mods.betterfoliage.util.get
|
||||
import mods.betterfoliage.util.mapArray
|
||||
import mods.betterfoliage.util.randomB
|
||||
import mods.betterfoliage.util.randomD
|
||||
import mods.betterfoliage.util.randomI
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.RenderTypeLookup
|
||||
import net.minecraft.client.renderer.model.BlockModel
|
||||
import net.minecraft.client.renderer.model.ModelBakery
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
|
||||
object StandardSandDiscovery : AbstractModelDiscovery() {
|
||||
val SAND_BLOCKS = listOf(Blocks.SAND, Blocks.RED_SAND)
|
||||
override fun processModel(
|
||||
bakery: ModelBakery,
|
||||
state: BlockState,
|
||||
location: ResourceLocation,
|
||||
sprites: MutableSet<ResourceLocation>,
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
): Boolean {
|
||||
val model = bakery.getUnbakedModel(location)
|
||||
if (model is BlockModel && state.block in SAND_BLOCKS) {
|
||||
Client.blockTypes.dirt.add(state)
|
||||
replacements[location] = StandardSandKey
|
||||
RenderTypeLookup.setRenderLayer(state.block, RenderType.getCutoutMipped())
|
||||
return true
|
||||
}
|
||||
return super.processModel(bakery, state, location, sprites, replacements)
|
||||
}
|
||||
}
|
||||
|
||||
object StandardSandKey : HalfBakedWrapperKey() {
|
||||
override fun replace(wrapped: SpecialRenderModel) = StandardSandModel(wrapped)
|
||||
}
|
||||
|
||||
class StandardSandModel(
|
||||
wrapped: SpecialRenderModel
|
||||
) : HalfBakedSpecialWrapper(wrapped) {
|
||||
val coralLighting = Direction.values().mapArray { LightingPreferredFace(it) }
|
||||
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
super.render(ctx, noDecorations)
|
||||
if (noDecorations || !Config.enabled || !Config.coral.enabled(ctx.random)) return
|
||||
if (ctx.biome?.category !in SALTWATER_BIOMES) return
|
||||
|
||||
allDirections.filter { ctx.random.nextInt(64) < Config.coral.chance }.forEach { face ->
|
||||
val isWater = ctx.state(face).material == Material.WATER
|
||||
val isDeepWater = isWater && ctx.offset(face).state(UP).material == Material.WATER
|
||||
if (isDeepWater) {
|
||||
ctx.vertexLighter = coralLighting[face]
|
||||
ctx.render(coralCrustModels[face][ctx.random])
|
||||
ctx.render(coralTuftModels[face][ctx.random])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val coralTuftSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx ->
|
||||
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_coral_$idx")
|
||||
}
|
||||
val coralCrustSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx ->
|
||||
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_crust_$idx")
|
||||
}
|
||||
val coralTuftModels by LazyInvalidatable(BakeWrapperManager) {
|
||||
val shapes = Config.coral.let { tuftShapeSet(it.size, 1.0, 1.0, it.hOffset) }
|
||||
allDirections.mapArray { face ->
|
||||
tuftModelSet(shapes, Color.white) { coralTuftSprites[randomI()] }
|
||||
.transform { rotate(Rotation.fromUp[face]) }
|
||||
.buildTufts()
|
||||
}
|
||||
}
|
||||
val coralCrustModels by LazyInvalidatable(BakeWrapperManager) {
|
||||
allDirections.map { face ->
|
||||
Array(64) { idx ->
|
||||
listOf(
|
||||
Quad.horizontalRectangle(x1 = -0.5, x2 = 0.5, z1 = -0.5, z2 = 0.5, y = 0.0)
|
||||
.scale(Config.coral.crustSize)
|
||||
.move(0.5 + randomD(0.01, Config.coral.vOffset) to UP)
|
||||
.rotate(Rotation.fromUp[face])
|
||||
.mirrorUV(randomB(), randomB()).rotateUV(randomI(max = 4))
|
||||
.sprite(coralCrustSprites[idx]).colorAndIndex(null)
|
||||
).bake(applyDiffuseLighting = false)
|
||||
}
|
||||
}.toTypedArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,27 +7,4 @@ interface ForgeVertexLighterAccess {
|
||||
interface ForgeVertexLighter {
|
||||
fun updateVertexLightmap(normal: FloatArray, lightmap: FloatArray, x: Float, y: Float, z: Float)
|
||||
fun updateVertexColor(normal: FloatArray, color: FloatArray, x: Float, y: Float, z: Float, tint: Float, multiplier: Int)
|
||||
}
|
||||
|
||||
fun ForgeVertexLighter.grass() = object: ForgeVertexLighter {
|
||||
override fun updateVertexLightmap(normal: FloatArray, lightmap: FloatArray, x: Float, y: Float, z: Float) {
|
||||
this@grass.updateVertexLightmap(normal, lightmap, x * 0.5f, 1.0f, z * 0.5f)
|
||||
}
|
||||
|
||||
override fun updateVertexColor(normal: FloatArray, color: FloatArray, x: Float, y: Float, z: Float, tint: Float, multiplier: Int) {
|
||||
this@grass.updateVertexColor(normal, color, x * 0.5f, 1.0f, z * 0.5f, tint, multiplier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun ForgeVertexLighter.grassSimple() = object: ForgeVertexLighter {
|
||||
val normalUp = floatArrayOf(0.0f, 1.0f, 0.0f, 0.0f)
|
||||
override fun updateVertexLightmap(normal: FloatArray, lightmap: FloatArray, x: Float, y: Float, z: Float) {
|
||||
this@grassSimple.updateVertexLightmap(normalUp, lightmap, 0.0f, 1.0f, 0.0f)
|
||||
}
|
||||
|
||||
override fun updateVertexColor(normal: FloatArray, color: FloatArray, x: Float, y: Float, z: Float, tint: Float, multiplier: Int) {
|
||||
this@grassSimple.updateVertexColor(normalUp, color, 0.0f, 1.0f, 0.0f, tint, multiplier
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package mods.betterfoliage.render.lighting
|
||||
|
||||
import mods.betterfoliage.render.old.HalfBakedQuad
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import mods.betterfoliage.util.Double3
|
||||
import mods.betterfoliage.util.EPSILON
|
||||
import mods.betterfoliage.util.minBy
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package mods.betterfoliage.render.old
|
||||
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraft.world.ILightReader
|
||||
|
||||
/**
|
||||
* Delegating [IBlockAccess] that fakes a _modified_ location to return values from a _target_ location.
|
||||
* All other locations are handled normally.
|
||||
*
|
||||
* @param[original] the [IBlockAccess] that is delegated to
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE", "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS", "HasPlatformType")
|
||||
open class OffsetBlockReader(open val original: IBlockReader, val modded: BlockPos, val target: BlockPos) : IBlockReader {
|
||||
inline fun actualPos(pos: BlockPos) = if (pos != null && pos.x == modded.x && pos.y == modded.y && pos.z == modded.z) target else pos
|
||||
|
||||
override fun getBlockState(pos: BlockPos) = original.getBlockState(actualPos(pos))
|
||||
override fun getTileEntity(pos: BlockPos) = original.getTileEntity(actualPos(pos))
|
||||
override fun getFluidState(pos: BlockPos) = original.getFluidState(actualPos(pos))
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE", "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS", "HasPlatformType")
|
||||
class OffsetEnvBlockReader(val original: ILightReader, val modded: BlockPos, val target: BlockPos) : ILightReader by original {
|
||||
inline fun actualPos(pos: BlockPos) = if (pos.x == modded.x && pos.y == modded.y && pos.z == modded.z) target else pos
|
||||
|
||||
override fun getBlockState(pos: BlockPos) = original.getBlockState(actualPos(pos))
|
||||
override fun getTileEntity(pos: BlockPos) = original.getTileEntity(actualPos(pos))
|
||||
override fun getFluidState(pos: BlockPos) = original.getFluidState(actualPos(pos))
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily replaces the [IBlockReader] used by this [BlockContext] and the corresponding [ExtendedRenderBlocks]
|
||||
* to use an [OffsetEnvBlockReader] while executing this lambda.
|
||||
*
|
||||
* @param[modded] the _modified_ location
|
||||
* @param[target] the _target_ location
|
||||
* @param[func] the lambda to execute
|
||||
*/
|
||||
//inline fun <reified T> BlockContext.withOffset(modded: Int3, target: Int3, func: () -> T): T {
|
||||
// val original = reader!!
|
||||
// reader = OffsetEnvBlockReader(original, pos + modded, pos + target)
|
||||
// val result = func()
|
||||
// reader = original
|
||||
// return result
|
||||
//}
|
||||
@@ -3,17 +3,27 @@ package mods.betterfoliage.render.pipeline
|
||||
import com.mojang.blaze3d.matrix.MatrixStack
|
||||
import mods.betterfoliage.chunk.BasicBlockCtx
|
||||
import mods.betterfoliage.chunk.BlockCtx
|
||||
import mods.betterfoliage.render.old.HalfBakedQuad
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.render.lighting.VanillaFullBlockLighting
|
||||
import mods.betterfoliage.render.lighting.VanillaQuadLighting
|
||||
import mods.betterfoliage.render.lighting.VanillaVertexLighter
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import mods.betterfoliage.util.Int3
|
||||
import mods.betterfoliage.util.plus
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.model.IBakedModel
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import java.util.Random
|
||||
|
||||
/**
|
||||
* Rendering context for drawing [SpecialRenderModel] models.
|
||||
*
|
||||
* This class (and others in its constellation) basically form a replacement, highly customizable,
|
||||
* push-based partial rendering pipeline for [SpecialRenderModel] instances.
|
||||
*/
|
||||
abstract class RenderCtxBase(
|
||||
world: ILightReader,
|
||||
pos: BlockPos,
|
||||
@@ -23,12 +33,17 @@ abstract class RenderCtxBase(
|
||||
val modelData: IModelData
|
||||
) : BlockCtx by BasicBlockCtx(world, pos) {
|
||||
|
||||
abstract fun renderQuad(quad: HalfBakedQuad)
|
||||
|
||||
var hasRendered = false
|
||||
val blockModelShapes = Minecraft.getInstance().blockRendererDispatcher.blockModelShapes
|
||||
inline fun Direction?.shouldRender() = this == null || !checkSides || Block.shouldSideBeRendered(state, world, pos, this)
|
||||
var vertexLighter: VanillaVertexLighter = VanillaFullBlockLighting
|
||||
protected val lightingData = RenderCtxBase.lightingData.get().apply {
|
||||
calc.reset(this@RenderCtxBase)
|
||||
blockColors = Minecraft.getInstance().blockColors
|
||||
}
|
||||
|
||||
protected abstract fun renderQuad(quad: HalfBakedQuad)
|
||||
abstract fun renderFallback(model: IBakedModel)
|
||||
inline fun Direction?.shouldRender() = this == null || !checkSides || Block.shouldSideBeRendered(state, world, pos, this)
|
||||
|
||||
fun render(quads: Iterable<HalfBakedQuad>) {
|
||||
quads.forEach { quad ->
|
||||
@@ -39,5 +54,13 @@ abstract class RenderCtxBase(
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun renderMasquerade(offset: Int3, func: ()->Unit)
|
||||
fun renderMasquerade(offset: Int3, func: () -> Unit) {
|
||||
lightingData.calc.blockPos += offset
|
||||
func()
|
||||
lightingData.calc.blockPos = pos
|
||||
}
|
||||
|
||||
companion object {
|
||||
val lightingData = ThreadLocal.withInitial { VanillaQuadLighting() }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,12 @@
|
||||
package mods.betterfoliage.render.pipeline
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack
|
||||
import mods.betterfoliage.render.ISpecialRenderModel
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.render.lighting.ForgeVertexLighter
|
||||
import mods.betterfoliage.render.lighting.ForgeVertexLighterAccess
|
||||
import mods.betterfoliage.render.old.HalfBakedQuad
|
||||
import mods.betterfoliage.util.Int3
|
||||
import mods.betterfoliage.util.directionsAndNull
|
||||
import mods.betterfoliage.util.get
|
||||
import mods.octarinecore.VertexLighterFlat_blockInfo
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.renderer.model.IBakedModel
|
||||
import net.minecraft.client.renderer.LightTexture
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
@@ -25,28 +21,28 @@ class RenderCtxForge(
|
||||
checkSides: Boolean,
|
||||
random: Random,
|
||||
modelData: IModelData
|
||||
): RenderCtxBase(world, pos, matrixStack, checkSides, random, modelData), ForgeVertexLighterAccess {
|
||||
): RenderCtxBase(world, pos, matrixStack, checkSides, random, modelData), ForgeVertexLighter {
|
||||
|
||||
val blockInfo = lighter[VertexLighterFlat_blockInfo]
|
||||
override var vertexLighter: ForgeVertexLighter
|
||||
get() = (lighter as ForgeVertexLighterAccess).vertexLighter
|
||||
set(value) { (lighter as ForgeVertexLighterAccess).vertexLighter = value }
|
||||
override fun renderQuad(quad: HalfBakedQuad) {
|
||||
// set Forge lighter AO calculator to us
|
||||
vertexLighter.updateLightmapAndColor(quad, lightingData)
|
||||
quad.baked.pipe(lighter)
|
||||
}
|
||||
|
||||
override fun renderQuad(quad: HalfBakedQuad) { quad.baked.pipe(lighter) }
|
||||
|
||||
override fun renderFallback(model: IBakedModel) {
|
||||
directionsAndNull.forEach { face ->
|
||||
model.getQuads(state, null, random, modelData).forEach { quad ->
|
||||
if (quad.face.shouldRender()) {
|
||||
quad.pipe(lighter)
|
||||
hasRendered = true
|
||||
}
|
||||
}
|
||||
// somewhat ugly hack to pipe lighting values into the Forge pipeline
|
||||
var vIdx = 0
|
||||
override fun updateVertexLightmap(normal: FloatArray, lightmap: FloatArray, x: Float, y: Float, z: Float) {
|
||||
lightingData.packedLight[vIdx].let { packedLight ->
|
||||
lightmap[0] = LightTexture.getLightBlock(packedLight) / 0xF.toFloat()
|
||||
lightmap[1] = LightTexture.getLightSky(packedLight) / 0xF.toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
override fun renderMasquerade(offset: Int3, func: () -> Unit) {
|
||||
TODO("Not yet implemented")
|
||||
override fun updateVertexColor(normal: FloatArray, color: FloatArray, x: Float, y: Float, z: Float, tint: Float, multiplier: Int) {
|
||||
color[0] = lightingData.tint[0] * lightingData.colorMultiplier[vIdx]
|
||||
color[1] = lightingData.tint[1] * lightingData.colorMultiplier[vIdx]
|
||||
color[2] = lightingData.tint[2] * lightingData.colorMultiplier[vIdx]
|
||||
vIdx++
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -54,7 +50,7 @@ class RenderCtxForge(
|
||||
fun render(
|
||||
lighter: VertexLighterFlat,
|
||||
world: ILightReader,
|
||||
model: ISpecialRenderModel,
|
||||
model: SpecialRenderModel,
|
||||
state: BlockState,
|
||||
pos: BlockPos,
|
||||
matrixStack: MatrixStack,
|
||||
@@ -68,6 +64,7 @@ class RenderCtxForge(
|
||||
rand.setSeed(seed)
|
||||
lighter.updateBlockInfo()
|
||||
return RenderCtxForge(world, pos, lighter, matrixStack, checkSides, rand, modelData).let {
|
||||
(lighter as ForgeVertexLighterAccess).vertexLighter = it
|
||||
model.render(it, false)
|
||||
lighter.resetBlockInfo()
|
||||
it.hasRendered
|
||||
|
||||
@@ -2,17 +2,10 @@ package mods.betterfoliage.render.pipeline
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder
|
||||
import mods.betterfoliage.render.ISpecialRenderModel
|
||||
import mods.betterfoliage.render.lighting.VanillaFullBlockLighting
|
||||
import mods.betterfoliage.render.lighting.VanillaVertexLighter
|
||||
import mods.betterfoliage.render.lighting.VanillaQuadLighting
|
||||
import mods.betterfoliage.render.old.HalfBakedQuad
|
||||
import mods.betterfoliage.util.Int3
|
||||
import mods.betterfoliage.util.ThreadLocalDelegate
|
||||
import mods.betterfoliage.util.plus
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.renderer.BlockModelRenderer
|
||||
import net.minecraft.client.renderer.model.IBakedModel
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
@@ -32,30 +25,14 @@ class RenderCtxVanilla(
|
||||
val useAO: Boolean
|
||||
): RenderCtxBase(world, pos, matrixStack, checkSides, random, modelData) {
|
||||
|
||||
private val blockColors = renderer.blockColors
|
||||
var vertexLighter: VanillaVertexLighter = VanillaFullBlockLighting
|
||||
|
||||
override fun renderQuad(quad: HalfBakedQuad) {
|
||||
lightingData.let { lighting ->
|
||||
vertexLighter.updateLightmapAndColor(quad, lighting)
|
||||
buffer.addQuad(
|
||||
matrixStack.last, quad.baked,
|
||||
lighting.colorMultiplier,
|
||||
lighting.tint[0], lighting.tint[1], lighting.tint[2],
|
||||
lighting.packedLight, combinedOverlay, true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun renderFallback(model: IBakedModel) {
|
||||
if (useAO) renderer.renderModelSmooth(world, model, state, pos, matrixStack, buffer, checkSides, random, seed, combinedOverlay, modelData)
|
||||
else renderer.renderModelFlat(world, model, state, pos, matrixStack, buffer, checkSides, random, seed, combinedOverlay, modelData)
|
||||
}
|
||||
|
||||
override fun renderMasquerade(offset: Int3, func: () -> Unit) {
|
||||
lightingData.calc.blockPos += offset
|
||||
func()
|
||||
lightingData.calc.blockPos = pos
|
||||
vertexLighter.updateLightmapAndColor(quad, lightingData)
|
||||
buffer.addQuad(
|
||||
matrixStack.last, quad.baked,
|
||||
lightingData.colorMultiplier,
|
||||
lightingData.tint[0], lightingData.tint[1], lightingData.tint[2],
|
||||
lightingData.packedLight, combinedOverlay, true
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -63,7 +40,7 @@ class RenderCtxVanilla(
|
||||
fun render(
|
||||
renderer: BlockModelRenderer,
|
||||
world: ILightReader,
|
||||
model: ISpecialRenderModel,
|
||||
model: SpecialRenderModel,
|
||||
state: BlockState,
|
||||
pos: BlockPos,
|
||||
matrixStack: MatrixStack,
|
||||
@@ -78,13 +55,12 @@ class RenderCtxVanilla(
|
||||
random.setSeed(rand)
|
||||
val ctx = RenderCtxVanilla(renderer, world, pos, buffer, combinedOverlay, matrixStack, checkSides, random, rand, modelData, smooth)
|
||||
lightingData.apply {
|
||||
calc.reset(ctx)
|
||||
blockColors = renderer.blockColors
|
||||
|
||||
}
|
||||
model.render(ctx, false)
|
||||
return ctx.hasRendered
|
||||
}
|
||||
|
||||
val lightingData by ThreadLocalDelegate { VanillaQuadLighting() }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package mods.betterfoliage.resource.discovery
|
||||
|
||||
import mods.betterfoliage.ModelDefinitionsLoadedEvent
|
||||
import mods.betterfoliage.render.bakeSpecial
|
||||
import mods.betterfoliage.model.SpecialRenderVariantList
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.util.HasLogger
|
||||
import mods.betterfoliage.util.Invalidator
|
||||
import mods.betterfoliage.util.SimpleInvalidator
|
||||
import mods.betterfoliage.util.asBlockMaterial
|
||||
import net.minecraft.client.renderer.model.IBakedModel
|
||||
import net.minecraft.client.renderer.model.IModelTransform
|
||||
import net.minecraft.client.renderer.model.IUnbakedModel
|
||||
@@ -17,11 +16,9 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.client.event.ModelBakeEvent
|
||||
import net.minecraftforge.client.event.TextureStitchEvent
|
||||
import net.minecraftforge.common.ForgeConfig
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
import net.minecraftforge.fml.loading.progress.StartupMessageManager
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.function.Function
|
||||
|
||||
@@ -29,13 +26,12 @@ interface ModelDiscovery {
|
||||
fun onModelsLoaded(
|
||||
bakery: ModelBakery,
|
||||
sprites: MutableSet<ResourceLocation>,
|
||||
replacements: MutableMap<ResourceLocation, ModelBakeKey>
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
)
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ModelBakeKey {
|
||||
fun replace(
|
||||
interface ModelBakingKey {
|
||||
fun bake(
|
||||
location: ResourceLocation,
|
||||
unbaked: IUnbakedModel,
|
||||
transform: IModelTransform,
|
||||
@@ -44,28 +40,6 @@ interface ModelBakeKey {
|
||||
): IBakedModel? = unbaked.bakeModel(bakery, spriteGetter, transform, location)
|
||||
}
|
||||
|
||||
interface ModelWrapperKey : ModelBakeKey {
|
||||
override fun replace(
|
||||
location: ResourceLocation,
|
||||
unbaked: IUnbakedModel,
|
||||
transform: IModelTransform,
|
||||
bakery: ModelBakery,
|
||||
spriteGetter: Function<Material, TextureAtlasSprite>
|
||||
): IBakedModel? {
|
||||
val baked = super.replace(location, unbaked, transform, bakery, spriteGetter) ?: return null
|
||||
val sprites = { res: ResourceLocation -> spriteGetter.apply(res.asBlockMaterial) }
|
||||
return replace(location, baked, sprites)
|
||||
}
|
||||
|
||||
fun replace(
|
||||
location: ResourceLocation,
|
||||
wrapped: IBakedModel,
|
||||
sprites: (ResourceLocation) -> TextureAtlasSprite
|
||||
) = replace(wrapped)
|
||||
|
||||
fun replace(wrapped: IBakedModel) = wrapped
|
||||
}
|
||||
|
||||
object BakeWrapperManager : Invalidator, HasLogger() {
|
||||
val discoverers = mutableListOf<ModelDiscovery>()
|
||||
override val callbacks = mutableListOf<WeakReference<()->Unit>>()
|
||||
@@ -73,7 +47,7 @@ object BakeWrapperManager : Invalidator, HasLogger() {
|
||||
val modelsValid = SimpleInvalidator()
|
||||
val spritesValid = SimpleInvalidator()
|
||||
|
||||
private val replacements = mutableMapOf<ResourceLocation, ModelBakeKey>()
|
||||
private val replacements = mutableMapOf<ResourceLocation, ModelBakingKey>()
|
||||
private val sprites = mutableSetOf<ResourceLocation>()
|
||||
|
||||
@SubscribeEvent
|
||||
@@ -82,7 +56,7 @@ object BakeWrapperManager : Invalidator, HasLogger() {
|
||||
StartupMessageManager.addModMessage("BetterFoliage: discovering models")
|
||||
logger.log(INFO, "starting model discovery (${discoverers.size} listeners)")
|
||||
discoverers.forEach { listener ->
|
||||
val replacementsLocal = mutableMapOf<ResourceLocation, ModelBakeKey>()
|
||||
val replacementsLocal = mutableMapOf<ResourceLocation, ModelBakingKey>()
|
||||
listener.onModelsLoaded(event.bakery, sprites, replacementsLocal)
|
||||
replacements.putAll(replacementsLocal)
|
||||
}
|
||||
@@ -113,10 +87,10 @@ 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.replace(location, unbaked, transform, bakery, spriteGetter)
|
||||
return replacement.bake(location, unbaked, transform, bakery, spriteGetter)
|
||||
}
|
||||
// container model support
|
||||
if (unbaked is VariantList) unbaked.bakeSpecial(bakery, spriteGetter)?.let {
|
||||
if (unbaked is VariantList) SpecialRenderVariantList.bakeIfSpecial(location, unbaked, bakery, spriteGetter)?.let {
|
||||
detailLogger.log(INFO, "Wrapping container [${unbaked::class.java.simpleName}] $location")
|
||||
return it
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class BlockTypeCache {
|
||||
val dirt = mutableSetOf<BlockState>()
|
||||
|
||||
companion object : ModelDiscovery {
|
||||
override fun onModelsLoaded(bakery: ModelBakery, sprites: MutableSet<ResourceLocation>, replacements: MutableMap<ResourceLocation, ModelBakeKey>
|
||||
override fun onModelsLoaded(bakery: ModelBakery, sprites: MutableSet<ResourceLocation>, replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
) {
|
||||
Client.blockTypes = BlockTypeCache()
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.registries.ForgeRegistries
|
||||
import org.apache.logging.log4j.Level
|
||||
|
||||
abstract class ModelReplacer : HasLogger(), ModelDiscovery {
|
||||
abstract class AbstractModelDiscovery : HasLogger(), ModelDiscovery {
|
||||
override fun onModelsLoaded(
|
||||
bakery: ModelBakery,
|
||||
sprites: MutableSet<ResourceLocation>,
|
||||
replacements: MutableMap<ResourceLocation, ModelBakeKey>
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
) {
|
||||
ForgeRegistries.BLOCKS
|
||||
.flatMap { block -> block.stateContainer.validStates }
|
||||
@@ -38,7 +38,7 @@ abstract class ModelReplacer : HasLogger(), ModelDiscovery {
|
||||
state: BlockState,
|
||||
location: ResourceLocation,
|
||||
sprites: MutableSet<ResourceLocation>,
|
||||
replacements: MutableMap<ResourceLocation, ModelBakeKey>
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
): Boolean {
|
||||
// built-in support for container models
|
||||
return when (val model = bakery.getUnbakedModel(location)) {
|
||||
@@ -59,9 +59,7 @@ abstract class ModelReplacer : HasLogger(), ModelDiscovery {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
abstract class ConfigurableModelReplacer : ModelReplacer() {
|
||||
abstract class ConfigurableModelDiscovery : AbstractModelDiscovery() {
|
||||
abstract val matchClasses: IBlockMatcher
|
||||
abstract val modelTextures: List<ModelTextureList>
|
||||
|
||||
@@ -70,7 +68,7 @@ abstract class ConfigurableModelReplacer : ModelReplacer() {
|
||||
location: ResourceLocation,
|
||||
textureMatch: List<ResourceLocation>,
|
||||
sprites: MutableSet<ResourceLocation>,
|
||||
replacements: MutableMap<ResourceLocation, ModelBakeKey>
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
): Boolean
|
||||
|
||||
override fun processModel(
|
||||
@@ -78,7 +76,7 @@ abstract class ConfigurableModelReplacer : ModelReplacer() {
|
||||
state: BlockState,
|
||||
location: ResourceLocation,
|
||||
sprites: MutableSet<ResourceLocation>,
|
||||
replacements: MutableMap<ResourceLocation, ModelBakeKey>
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
): Boolean {
|
||||
val model = bakery.getUnbakedModel(location)
|
||||
if (model is BlockModel) {
|
||||
@@ -1,6 +1,6 @@
|
||||
package mods.betterfoliage.util
|
||||
|
||||
import mods.betterfoliage.render.old.HSB
|
||||
import mods.betterfoliage.model.HSB
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.model.Material
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture
|
||||
|
||||
Reference in New Issue
Block a user