[WIP] start port to 1.15.2

This commit is contained in:
octarine-noise
2021-04-29 11:33:23 +02:00
parent f1fa629c5c
commit b46fdeaeef
44 changed files with 442 additions and 468 deletions

View File

@@ -2,8 +2,8 @@ import net.fabricmc.loom.task.RemapJarTask
import org.ajoberstar.grgit.Grgit import org.ajoberstar.grgit.Grgit
plugins { plugins {
kotlin("jvm").version("1.3.60")
id("fabric-loom").version("0.2.6-SNAPSHOT") id("fabric-loom").version("0.2.6-SNAPSHOT")
kotlin("jvm").version("1.4.31")
id("org.ajoberstar.grgit").version("3.1.1") id("org.ajoberstar.grgit").version("3.1.1")
} }
apply(plugin = "org.ajoberstar.grgit") apply(plugin = "org.ajoberstar.grgit")
@@ -40,7 +40,7 @@ dependencies {
// "modImplementation"("grondag:canvas:0.7.+") // "modImplementation"("grondag:canvas:0.7.+")
// Optifabric // Optifabric
"modImplementation"("com.github.modmuss50:OptiFabric:df03dc2c22") // "modImplementation"("com.github.modmuss50:OptiFabric:1.0.0")
"implementation"("org.zeroturnaround:zt-zip:1.13") "implementation"("org.zeroturnaround:zt-zip:1.13")
} }

View File

@@ -7,15 +7,14 @@ jarName = BetterFoliage-Forge
version = 2.5.1 version = 2.5.1
mcVersion = 1.14.4 mcVersion = 1.15.2
yarnMappings=1.14.4+build.15 yarnMappings=1.15.2+build.17
loaderVersion=0.7.3+build.176 loaderVersion=0.11.3
fabricVersion=0.4.2+build.246-1.14 fabricVersion=0.28.5+1.15
loomVersion=0.2.6-SNAPSHOT
kotlinVersion=1.3.60 kotlinVersion=1.3.60
fabricKotlinVersion=1.3.60+build.1 fabricKotlinVersion=1.5.0+kotlin.1.4.31
clothConfigVersion=1.8 clothConfigVersion=2.14.2
modMenuVersion=1.7.6+build.115 modMenuVersion=1.10.6
fiberVersion=0.8.0-2 fiberVersion=0.8.0-2

View File

@@ -19,8 +19,8 @@ import java.util.Random;
@Mixin(Block.class) @Mixin(Block.class)
public class MixinBlock { public class MixinBlock {
private static final String shouldSideBeRendered = "shouldDrawSide(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Z"; private static final String shouldSideBeRendered = "Lnet/minecraft/block/Block;shouldDrawSide(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Z";
private static final String getVoxelShape = "Lnet/minecraft/block/BlockState;getCullShape(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Lnet/minecraft/util/shape/VoxelShape;"; private static final String getVoxelShape = "Lnet/minecraft/block/BlockState;getCullingFace(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Lnet/minecraft/util/shape/VoxelShape;";
private static final String randomDisplayTick = "randomDisplayTick(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Ljava/util/Random;)V"; private static final String randomDisplayTick = "randomDisplayTick(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Ljava/util/Random;)V";
/** /**

View File

@@ -5,6 +5,7 @@ import net.minecraft.client.world.ClientChunkManager;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.PacketByteBuf; import net.minecraft.util.PacketByteBuf;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.biome.source.BiomeArray;
import net.minecraft.world.chunk.WorldChunk; import net.minecraft.world.chunk.WorldChunk;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@@ -14,10 +15,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ClientChunkManager.class) @Mixin(ClientChunkManager.class)
public class MixinClientChunkManager { public class MixinClientChunkManager {
private static final String onLoadChunkFromPacket = "loadChunkFromPacket(Lnet/minecraft/world/World;IILnet/minecraft/util/PacketByteBuf;Lnet/minecraft/nbt/CompoundTag;IZ)Lnet/minecraft/world/chunk/WorldChunk;"; private static final String onLoadChunkFromPacket = "loadChunkFromPacket(IILnet/minecraft/world/biome/source/BiomeArray;Lnet/minecraft/util/PacketByteBuf;Lnet/minecraft/nbt/CompoundTag;I)Lnet/minecraft/world/chunk/WorldChunk;";
@Inject(method = onLoadChunkFromPacket, at = @At(value = "RETURN", ordinal = 2)) @Inject(method = onLoadChunkFromPacket, at = @At(value = "RETURN", ordinal = 2))
void onLoadChunkFromPacket(World world, int chunkX, int chunkZ, PacketByteBuf data, CompoundTag nbt, int updatedSectionsBits, boolean clearOld, CallbackInfoReturnable<WorldChunk> ci) { void onLoadChunkFromPacket(int chunkX, int chunkZ, BiomeArray biomeArray, PacketByteBuf data, CompoundTag nbt, int updatedSectionsBits, CallbackInfoReturnable<WorldChunk> ci) {
ClientChunkLoadCallback.EVENT.invoker().loadChunk(ci.getReturnValue()); ClientChunkLoadCallback.EVENT.invoker().loadChunk(ci.getReturnValue());
} }
} }

View File

@@ -10,9 +10,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(targets = {"net.minecraft.client.world.ClientChunkManager$ClientChunkMap"}) @Mixin(targets = {"net.minecraft.client.world.ClientChunkManager$ClientChunkMap"})
public class MixinClientChunkManagerChunkMap { public class MixinClientChunkManagerChunkMap {
private static final String onSetAndCompare = "method_20183(ILnet/minecraft/world/chunk/WorldChunk;Lnet/minecraft/world/chunk/WorldChunk;)Lnet/minecraft/world/chunk/WorldChunk;"; private static final String onCompareAndSet = "Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap;compareAndSet(ILnet/minecraft/world/chunk/WorldChunk;Lnet/minecraft/world/chunk/WorldChunk;)Lnet/minecraft/world/chunk/WorldChunk;";
@Inject(method = onSetAndCompare, at = @At("HEAD")) @Inject(method = onCompareAndSet, at = @At("HEAD"))
void onSetAndCompare(int i, WorldChunk oldChunk, WorldChunk newChunk, CallbackInfoReturnable<WorldChunk> ci) { void onSetAndCompare(int i, WorldChunk oldChunk, WorldChunk newChunk, CallbackInfoReturnable<WorldChunk> ci) {
ClientChunkLoadCallback.EVENT.invoker().unloadChunk(oldChunk); ClientChunkLoadCallback.EVENT.invoker().unloadChunk(oldChunk);
} }

View File

@@ -21,7 +21,7 @@ import java.util.Random;
public class MixinClientWorld { public class MixinClientWorld {
private static final String ctor = "<init>(Lnet/minecraft/client/network/ClientPlayNetworkHandler;Lnet/minecraft/world/level/LevelInfo;Lnet/minecraft/world/dimension/DimensionType;ILnet/minecraft/util/profiler/Profiler;Lnet/minecraft/client/render/WorldRenderer;)V"; private static final String ctor = "<init>(Lnet/minecraft/client/network/ClientPlayNetworkHandler;Lnet/minecraft/world/level/LevelInfo;Lnet/minecraft/world/dimension/DimensionType;ILnet/minecraft/util/profiler/Profiler;Lnet/minecraft/client/render/WorldRenderer;)V";
private static final String scheduleBlockRender = "scheduleBlockRender(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;)V"; private static final String checkBlockRender = "Lnet/minecraft/client/world/ClientWorld;checkBlockRerender(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;)V";
private static final String rendererNotify = "Lnet/minecraft/client/render/WorldRenderer;method_21596(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;)V"; private static final String rendererNotify = "Lnet/minecraft/client/render/WorldRenderer;method_21596(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;)V";
private static final String worldDisplayTick = "randomBlockDisplayTick(IIIILjava/util/Random;ZLnet/minecraft/util/math/BlockPos$Mutable;)V"; private static final String worldDisplayTick = "randomBlockDisplayTick(IIIILjava/util/Random;ZLnet/minecraft/util/math/BlockPos$Mutable;)V";
private static final String blockDisplayTick = "Lnet/minecraft/block/Block;randomDisplayTick(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Ljava/util/Random;)V"; private static final String blockDisplayTick = "Lnet/minecraft/block/Block;randomDisplayTick(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Ljava/util/Random;)V";
@@ -30,7 +30,7 @@ public class MixinClientWorld {
* Inject callback to get notified of client-side blockstate changes. * Inject callback to get notified of client-side blockstate changes.
* Used to invalidate caches in the {@link mods.betterfoliage.chunk.ChunkOverlayManager} * Used to invalidate caches in the {@link mods.betterfoliage.chunk.ChunkOverlayManager}
*/ */
@Inject(method = scheduleBlockRender, at = @At(value = "HEAD")) @Inject(method = checkBlockRender, at = @At(value = "HEAD"))
void onClientBlockChanged(BlockPos pos, BlockState oldState, BlockState newState, CallbackInfo ci) { void onClientBlockChanged(BlockPos pos, BlockState oldState, BlockState newState, CallbackInfo ci) {
Hooks.onClientBlockChanged((ClientWorld) (Object) this, pos, oldState, newState); Hooks.onClientBlockChanged((ClientWorld) (Object) this, pos, oldState, newState);
} }

View File

@@ -55,8 +55,8 @@ object BetterFoliage : ClientModInitializer {
override fun onInitializeClient() { override fun onInitializeClient() {
// Register generated resource pack // Register generated resource pack
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(generatedPack) ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(generatedPack.reloader)
MinecraftClient.getInstance().resourcePackContainerManager.addCreator(generatedPack.finder) MinecraftClient.getInstance().resourcePackManager.registerProvider(generatedPack.finder)
// Add standard block support // Add standard block support
modelReplacer.discoverers.add(StandardLeafDiscovery) modelReplacer.discoverers.add(StandardLeafDiscovery)

View File

@@ -0,0 +1,17 @@
package mods.betterfoliage
import it.unimi.dsi.fastutil.ints.IntList
import mods.betterfoliage.util.YarnHelper
import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.texture.Sprite
import net.minecraft.util.WeightedPicker
import net.minecraft.world.World
val WeightedBakedModel_totalWeight = YarnHelper.requiredField<Int>("net.minecraft.class_1097", "field_5433", "I")
val WeightedBakedModel_models = YarnHelper.requiredField<List<WeightedPicker.Entry>>("net.minecraft.class_1097", "field_5434", "Ljava/util/List;")
val WeightedBakedModelEntry_model = YarnHelper.requiredField<BakedModel>("net.minecraft.class_1097\$class_1099", "field_5437", "Lnet/minecraft/class_1087;")
val WeightedPickerEntry_weight = YarnHelper.requiredField<Int>("net.minecraft.class_3549\$class_3550", "field_15774", "I")
val VertexFormat_offsets = YarnHelper.requiredField<IntList>("net.minecraft.class_293", "field_1597", "Lit/unimi/dsi/fastutil/ints/IntList;")
val BakedQuad_sprite = YarnHelper.requiredField<Sprite>("net.minecraft.class_777", "field_4176", "Lnet/minecraft/class_1058;")
val WorldChunk_world = YarnHelper.requiredField<World>("net.minecraft.class_2818", "field_12858", "Lnet/minecraft/class_1937;")
val ChunkRendererRegion_world = YarnHelper.requiredField<World>("net.minecraft.class_853", "field_4490", "Lnet/minecraft/class_1937;")

View File

@@ -2,19 +2,15 @@
package mods.betterfoliage package mods.betterfoliage
import mods.betterfoliage.chunk.ChunkOverlayManager import mods.betterfoliage.chunk.ChunkOverlayManager
import mods.betterfoliage.render.particle.FallingLeafParticle
import mods.betterfoliage.render.particle.RisingSoulParticle
import mods.betterfoliage.render.block.vanilla.LeafKey import mods.betterfoliage.render.block.vanilla.LeafKey
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.RisingSoulParticle
import mods.betterfoliage.util.offset import mods.betterfoliage.util.offset
import mods.betterfoliage.util.plus import mods.betterfoliage.util.plus
import mods.betterfoliage.util.randomD import mods.betterfoliage.util.randomD
import net.minecraft.block.BlockRenderLayer
import net.minecraft.block.BlockRenderLayer.CUTOUT
import net.minecraft.block.BlockRenderLayer.CUTOUT_MIPPED
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.block.Blocks import net.minecraft.block.Blocks
import net.minecraft.client.MinecraftClient
import net.minecraft.client.world.ClientWorld import net.minecraft.client.world.ClientWorld
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction import net.minecraft.util.math.Direction
@@ -63,5 +59,6 @@ fun getVoxelShapeOverride(state: BlockState, reader: BlockView, pos: BlockPos, d
if (BetterFoliage.modelReplacer[state] is RoundLogKey) { if (BetterFoliage.modelReplacer[state] is RoundLogKey) {
return VoxelShapes.empty() return VoxelShapes.empty()
} }
return state.getCullShape(reader, pos, dir) // TODO ?
return state.getCullingFace(reader, pos, dir)
} }

View File

@@ -1,5 +1,6 @@
package mods.betterfoliage.chunk package mods.betterfoliage.chunk
import mods.betterfoliage.ChunkRendererRegion_world
import mods.betterfoliage.util.Int3 import mods.betterfoliage.util.Int3
import mods.betterfoliage.util.allDirections import mods.betterfoliage.util.allDirections
import mods.betterfoliage.util.offset import mods.betterfoliage.util.offset
@@ -7,9 +8,11 @@ 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.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.minecraft.client.render.chunk.ChunkRendererRegion
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction import net.minecraft.util.math.Direction
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import net.minecraft.world.WorldView
import net.minecraft.world.biome.Biome import net.minecraft.world.biome.Biome
/** /**
@@ -17,7 +20,7 @@ import net.minecraft.world.biome.Biome
* block-relative coordinates. * block-relative coordinates.
*/ */
interface BlockCtx { interface BlockCtx {
val world: ExtendedBlockView val world: BlockRenderView
val pos: BlockPos val pos: BlockPos
fun offset(dir: Direction) = offset(dir.offset) fun offset(dir: Direction) = offset(dir.offset)
@@ -27,7 +30,8 @@ interface BlockCtx {
fun state(dir: Direction) = world.getBlockState(pos + dir.offset) fun state(dir: Direction) = world.getBlockState(pos + dir.offset)
fun state(offset: Int3) = world.getBlockState(pos + offset) fun state(offset: Int3) = world.getBlockState(pos + offset)
val biome: Biome get() = world.getBiome(pos) val biome: Biome? get() =
ChunkRendererRegion_world[world]?.getBiome(pos)
val isNormalCube: Boolean get() = state.isSimpleFullBlock(world, pos) val isNormalCube: Boolean get() = state.isSimpleFullBlock(world, pos)
@@ -40,7 +44,7 @@ interface BlockCtx {
} }
open class BasicBlockCtx( open class BasicBlockCtx(
override val world: ExtendedBlockView, override val world: BlockRenderView,
override val pos: BlockPos override val pos: BlockPos
) : BlockCtx { ) : BlockCtx {
override val state = world.getBlockState(pos) override val state = world.getBlockState(pos)
@@ -48,8 +52,8 @@ open class BasicBlockCtx(
fun cache() = CachedBlockCtx(world, pos) fun cache() = CachedBlockCtx(world, pos)
} }
open class CachedBlockCtx(world: ExtendedBlockView, pos: BlockPos) : BasicBlockCtx(world, pos) { open class CachedBlockCtx(world: BlockRenderView, pos: BlockPos) : BasicBlockCtx(world, pos) {
var neighbors = Array<BlockState>(6) { world.getBlockState(pos + allDirections[it].offset) } var neighbors = Array<BlockState>(6) { world.getBlockState(pos + allDirections[it].offset) }
override var biome: Biome = world.getBiome(pos) override var biome: Biome? = super.biome
override fun state(dir: Direction) = neighbors[dir.ordinal] override fun state(dir: Direction) = neighbors[dir.ordinal]
} }

View File

@@ -2,8 +2,8 @@ package mods.betterfoliage.chunk
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.world.BlockView import net.minecraft.world.BlockView
import net.minecraft.world.ExtendedBlockView
import net.minecraft.world.LightType import net.minecraft.world.LightType
import net.minecraft.world.WorldView
/** /**
* Delegating [IBlockAccess] that fakes a _modified_ location to return values from a _target_ location. * Delegating [IBlockAccess] that fakes a _modified_ location to return values from a _target_ location.
@@ -21,7 +21,7 @@ open class OffsetBlockView(open val original: BlockView, val modded: BlockPos, v
} }
@Suppress("NOTHING_TO_INLINE", "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS", "HasPlatformType") @Suppress("NOTHING_TO_INLINE", "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS", "HasPlatformType")
class OffsetExtBlockView(val original: ExtendedBlockView, val modded: BlockPos, val target: BlockPos) : ExtendedBlockView by original { class OffsetExtBlockView(val original: WorldView, val modded: BlockPos, val target: BlockPos) : WorldView by original {
inline fun actualPos(pos: BlockPos) = if (pos != null && pos.x == modded.x && pos.y == modded.y && pos.z == modded.z) target else pos 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 getBlockState(pos: BlockPos) = original.getBlockState(actualPos(pos))
@@ -29,7 +29,7 @@ class OffsetExtBlockView(val original: ExtendedBlockView, val modded: BlockPos,
override fun getFluidState(pos: BlockPos) = original.getFluidState(actualPos(pos)) override fun getFluidState(pos: BlockPos) = original.getFluidState(actualPos(pos))
override fun getLightLevel(type: LightType, pos: BlockPos) = original.getLightLevel(type, actualPos(pos)) override fun getLightLevel(type: LightType, pos: BlockPos) = original.getLightLevel(type, actualPos(pos))
override fun getLightmapIndex(pos: BlockPos, light: Int) = original.getLightmapIndex(actualPos(pos), light) override fun getBaseLightLevel(pos: BlockPos, light: Int) = original.getBaseLightLevel(actualPos(pos), light)
override fun getBiome(pos: BlockPos) = original.getBiome(actualPos(pos)) override fun getBiome(pos: BlockPos) = original.getBiome(actualPos(pos))
} }

View File

@@ -7,9 +7,9 @@ import net.minecraft.client.render.chunk.ChunkRendererRegion
import net.minecraft.client.world.ClientWorld import net.minecraft.client.world.ClientWorld
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.ChunkPos import net.minecraft.util.math.ChunkPos
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import net.minecraft.world.ViewableWorld
import net.minecraft.world.World import net.minecraft.world.World
import net.minecraft.world.WorldView
import net.minecraft.world.chunk.WorldChunk import net.minecraft.world.chunk.WorldChunk
import net.minecraft.world.dimension.DimensionType import net.minecraft.world.dimension.DimensionType
import java.util.* import java.util.*
@@ -21,13 +21,8 @@ import kotlin.collections.mutableListOf
import kotlin.collections.mutableMapOf import kotlin.collections.mutableMapOf
import kotlin.collections.set import kotlin.collections.set
// net.minecraft.world.chunk.WorldChunk.world val BlockRenderView.dimType: DimensionType get() = when {
val WorldChunk_world = YarnHelper.requiredField<World>("net.minecraft.class_2818", "field_12858", "Lnet/minecraft/class_1937;") this is WorldView -> dimension.type
// net.minecraft.client.render.chunk.ChunkRendererRegion.world
val ChunkRendererRegion_world = YarnHelper.requiredField<World>("net.minecraft.class_853", "field_4490", "Lnet/minecraft/class_1937;")
val ExtendedBlockView.dimType: DimensionType get() = when {
this is ViewableWorld -> dimension.type
this is ChunkRendererRegion -> this[ChunkRendererRegion_world]!!.dimension.type this is ChunkRendererRegion -> this[ChunkRendererRegion_world]!!.dimension.type
// this.isInstance(ChunkCacheOF) -> this[ChunkCacheOF.chunkCache]!!.dimType // this.isInstance(ChunkCacheOF) -> this[ChunkCacheOF.chunkCache]!!.dimType
else -> throw IllegalArgumentException("DimensionType of world with class ${this::class.qualifiedName} cannot be determined!") else -> throw IllegalArgumentException("DimensionType of world with class ${this::class.qualifiedName} cannot be determined!")
@@ -38,7 +33,7 @@ val ExtendedBlockView.dimType: DimensionType get() = when {
*/ */
interface ChunkOverlayLayer<T> { interface ChunkOverlayLayer<T> {
fun calculate(ctx: BlockCtx): T fun calculate(ctx: BlockCtx): T
fun onBlockUpdate(world: ExtendedBlockView, pos: BlockPos) fun onBlockUpdate(world: WorldView, pos: BlockPos)
} }
/** /**

View File

@@ -1,110 +0,0 @@
package mods.betterfoliage.integration
/*
val TextureLeaves = ClassRefOld<Any>("forestry.arboriculture.models.TextureLeaves")
val TextureLeaves_leafTextures = FieldRefOld(TextureLeaves, "leafTextures", Map)
val TextureLeaves_plain = FieldRefOld(TextureLeaves, "plain", Identifier)
val TextureLeaves_fancy = FieldRefOld(TextureLeaves, "fancy", Identifier)
val TextureLeaves_pollinatedPlain = FieldRefOld(TextureLeaves, "pollinatedPlain", Identifier)
val TextureLeaves_pollinatedFancy = FieldRefOld(TextureLeaves, "pollinatedFancy", Identifier)
val TileLeaves = ClassRefOld<Any>("forestry.arboriculture.tiles.TileLeaves")
val TileLeaves_getLeaveSprite = MethodRefOld(TileLeaves, "getLeaveSprite", Identifier, boolean)
val PropertyWoodType = ClassRefOld<Any>("forestry.arboriculture.blocks.PropertyWoodType")
val IWoodType = ClassRefOld<Any>("forestry.api.arboriculture.IWoodType")
val IWoodType_barkTex = MethodRefOld(IWoodType, "getBarkTexture", String)
val IWoodType_heartTex = MethodRefOld(IWoodType, "getHeartTexture", String)
val PropertyTreeType = ClassRefOld<Any>("forestry.arboriculture.blocks.PropertyTreeType")
val IAlleleTreeSpecies = ClassRefOld<Any>("forestry.api.arboriculture.IAlleleTreeSpecies")
val ILeafSpriteProvider = ClassRefOld<Any>("forestry.api.arboriculture.ILeafSpriteProvider")
val TreeDefinition = ClassRefOld<Any>("forestry.arboriculture.genetics.TreeDefinition")
val IAlleleTreeSpecies_getLeafSpriteProvider = MethodRefOld(IAlleleTreeSpecies, "getLeafSpriteProvider", ILeafSpriteProvider)
val TreeDefinition_species = FieldRefOld(TreeDefinition, "species", IAlleleTreeSpecies)
val ILeafSpriteProvider_getSprite = MethodRefOld(ILeafSpriteProvider, "getSprite", Identifier, boolean, boolean)
object ForestryIntegration {
init {
}
}
*/
/*
object ForestryLeafDiscovery : HasLogger, AsyncSpriteProvider<ModelLoader>, ModelRenderRegistry<LeafInfo> {
override val logger = BetterFoliage.logDetail
var idToValue = emptyMap<Identifier, LeafInfo>()
override fun get(state: BlockState, world: BlockView, pos: BlockPos): LeafInfo? {
// check variant property (used in decorative leaves)
state.entries.entries.find {
PropertyTreeType.isInstance(it.key) && TreeDefinition.isInstance(it.value)
} ?.let {
val species = it.value[TreeDefinition_species]!!
val spriteProvider = species[IAlleleTreeSpecies_getLeafSpriteProvider]()
val textureLoc = spriteProvider[ILeafSpriteProvider_getSprite](false, MinecraftClient.isFancyGraphicsEnabled())
return idToValue[textureLoc]
}
// extract leaf texture information from TileEntity
val tile = world.getBlockEntity(pos) ?: return null
if (!TileLeaves.isInstance(tile)) return null
val textureLoc = tile[TileLeaves_getLeaveSprite](MinecraftClient.isFancyGraphicsEnabled())
return idToValue[textureLoc]
}
override fun setup(manager: ResourceManager, bakeryF: CompletableFuture<ModelLoader>, atlasFuture: AtlasFuture): StitchPhases {
val futures = mutableMapOf<Identifier, CompletableFuture<LeafInfo>>()
return StitchPhases(
discovery = bakeryF.thenRunAsync {
val allLeaves = TextureLeaves_leafTextures.getStatic()
allLeaves!!.entries.forEach { (type, leaves) ->
log("base leaf type $type")
leaves!!
listOf(
leaves[TextureLeaves_plain], leaves[TextureLeaves_pollinatedPlain],
leaves[TextureLeaves_fancy], leaves[TextureLeaves_pollinatedFancy]
).forEach { textureLocation ->
futures[textureLocation!!] = defaultRegisterLeaf(textureLocation, atlasFuture)
}
}
},
cleanup = atlasFuture.runAfter {
idToValue = futures.mapValues { it.value.get() }
}
)
}
}
object ForestryLogDiscovery : ModelDiscovery<ColumnTextureInfo>() {
override val logger = BetterFoliage.logDetail
override fun processModel(ctx: ModelDiscoveryContext, atlas: AtlasFuture): CompletableFuture<ColumnTextureInfo>? {
// respect class list to avoid triggering on fences, stairs, etc.
if (!BetterFoliageMod.blockConfig.logBlocks.matchesClass(ctx.state.block)) return null
// find wood type property
val woodType = ctx.state.entries.entries.find {
PropertyWoodType.isInstance(it.key) && IWoodType.isInstance(it.value)
}
if (woodType != null) {
logger.log(Level.DEBUG, "ForestryLogRegistry: block state ${ctx.state}")
logger.log(Level.DEBUG, "ForestryLogRegistry: variant ${woodType.value}")
// get texture names for wood type
val bark = woodType.value[IWoodType_barkTex]()
val heart = woodType.value[IWoodType_heartTex]()
logger.log(Level.DEBUG, "ForestryLogSupport: textures [heart=$heart, bark=$bark]")
val heartSprite = atlas.sprite(heart)
val barkSprite = atlas.sprite(bark)
return atlas.mapAfter {
SimpleColumnInfo(AsyncLogDiscovery.getAxis(ctx.state), heartSprite.get(), heartSprite.get(), listOf(barkSprite.get()))
}
}
return null
}
}
*/

View File

@@ -1,9 +1,12 @@
package mods.betterfoliage.resource.model package mods.betterfoliage.model
import mods.betterfoliage.BakedQuad_sprite
import mods.betterfoliage.VertexFormat_offsets
import mods.betterfoliage.util.Double3 import mods.betterfoliage.util.Double3
import mods.betterfoliage.util.allDirections import mods.betterfoliage.util.allDirections
import mods.betterfoliage.util.findFirst import mods.betterfoliage.util.findFirst
import net.minecraft.block.BlockRenderLayer import mods.betterfoliage.util.get
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.client.render.VertexFormat import net.minecraft.client.render.VertexFormat
import net.minecraft.client.render.VertexFormatElement import net.minecraft.client.render.VertexFormatElement
@@ -17,6 +20,9 @@ import net.minecraft.client.render.model.BakedQuad
import net.minecraft.util.math.Direction import net.minecraft.util.math.Direction
import java.lang.Float import java.lang.Float
import java.util.* import java.util.*
import kotlin.Boolean
import kotlin.Int
import kotlin.let
interface BakedModelConverter { interface BakedModelConverter {
/** /**
@@ -50,11 +56,11 @@ val COMMON_MESH_CONVERTERS = listOf(WrappedWeightedModel.converter)
/** /**
* Convert [BakedModel] into one using fabric-rendering-api [Mesh] instead of the vanilla pipeline. * Convert [BakedModel] into one using fabric-rendering-api [Mesh] instead of the vanilla pipeline.
* @param renderLayerOverride Use the given [BlockRenderLayer] for the [Mesh] * @param blendModeOverride Use the given [BlockRenderLayer] for the [Mesh]
* instead of the one declared by the corresponding [Block] * instead of the one declared by the corresponding [Block]
*/ */
fun meshifyStandard(model: BakedModel, state: BlockState, renderLayerOverride: BlockRenderLayer? = null) = fun meshifyStandard(model: BakedModel, state: BlockState, blendModeOverride: BlendMode? = null) =
(COMMON_MESH_CONVERTERS + WrappedMeshModel.converter(state, renderLayerOverride = renderLayerOverride)).convert(model) (COMMON_MESH_CONVERTERS + WrappedMeshModel.converter(state, blendModeOverride = blendModeOverride)).convert(model)
/** /**
* Convert a vanilla [BakedModel] into intermediate [Quad]s * Convert a vanilla [BakedModel] into intermediate [Quad]s
@@ -64,7 +70,7 @@ fun meshifyStandard(model: BakedModel, state: BlockState, renderLayerOverride: B
fun unbakeQuads(model: BakedModel, state: BlockState, random: Random, unshade: Boolean): List<Quad> { fun unbakeQuads(model: BakedModel, state: BlockState, random: Random, unshade: Boolean): List<Quad> {
return (allDirections.toList() + null as Direction?).flatMap { face -> return (allDirections.toList() + null as Direction?).flatMap { face ->
model.getQuads(state, face, random).mapIndexed { qIdx, bakedQuad -> model.getQuads(state, face, random).mapIndexed { qIdx, bakedQuad ->
var quad = Quad(Vertex(), Vertex(), Vertex(), Vertex(), face = face, colorIndex = bakedQuad.colorIndex, sprite = bakedQuad.sprite) var quad = Quad(Vertex(), Vertex(), Vertex(), Vertex(), face = face, colorIndex = bakedQuad.colorIndex, sprite = bakedQuad[BakedQuad_sprite])
val format = quadVertexFormat(bakedQuad) val format = quadVertexFormat(bakedQuad)
val stride = format.vertexSizeInteger val stride = format.vertexSizeInteger
@@ -98,7 +104,7 @@ fun unbakeQuads(model: BakedModel, state: BlockState, random: Random, unshade: B
fun VertexFormat.getByteOffset(type: VertexFormatElement.Type, format: VertexFormatElement.Format, count: Int, index: Int = 0): Int? { fun VertexFormat.getByteOffset(type: VertexFormatElement.Type, format: VertexFormatElement.Format, count: Int, index: Int = 0): Int? {
elements.forEachIndexed { idx, element -> elements.forEachIndexed { idx, element ->
if (element.type == type && element.format == format && element.count == count && element.index == index) if (element.type == type && element.format == format && element.count == count && element.index == index)
return getElementOffset(idx) return VertexFormat_offsets[this]!!.getInt(idx)
} }
return null return null
} }
@@ -111,4 +117,4 @@ fun VertexFormat.getIntOffset(type: VertexFormatElement.Type, format: VertexForm
getByteOffset(type, format, count, index)?.let { if (it % 4 == 0) it / 4 else null } getByteOffset(type, format, count, index)?.let { if (it % 4 == 0) it / 4 else null }
/** Function to determine [VertexFormat] used by [BakedQuad] */ /** Function to determine [VertexFormat] used by [BakedQuad] */
var quadVertexFormat: (BakedQuad)->VertexFormat = { VertexFormats.POSITION_COLOR_UV_LMAP } var quadVertexFormat: (BakedQuad)->VertexFormat = { VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL }

View File

@@ -1,11 +1,11 @@
package mods.betterfoliage.resource.model package mods.betterfoliage.model
import mods.betterfoliage.util.Atlas import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.* import mods.betterfoliage.util.*
import mods.betterfoliage.util.minmax import mods.betterfoliage.util.minmax
import net.fabricmc.fabric.api.renderer.v1.RendererAccess import net.fabricmc.fabric.api.renderer.v1.RendererAccess
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh
import net.minecraft.block.BlockRenderLayer
import net.minecraft.client.texture.MissingSprite import net.minecraft.client.texture.MissingSprite
import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.Sprite
import net.minecraft.util.math.Direction import net.minecraft.util.math.Direction
@@ -166,9 +166,9 @@ fun Array<List<Quad>>.withOpposites() = map { it.withOpposites() }.toTypedArray(
/** /**
* Pour quad data into a fabric-renderer-api Mesh * Pour quad data into a fabric-renderer-api Mesh
*/ */
fun List<Quad>.build(layer: BlockRenderLayer, noDiffuse: Boolean = false, flatLighting: Boolean = false): Mesh { fun List<Quad>.build(blendMode: BlendMode, noDiffuse: Boolean = false, flatLighting: Boolean = false): Mesh {
val renderer = RendererAccess.INSTANCE.renderer val renderer = RendererAccess.INSTANCE.renderer
val material = renderer.materialFinder().blendMode(0, layer).disableAo(0, flatLighting).disableDiffuse(0, noDiffuse).find() val material = renderer.materialFinder().blendMode(0, blendMode).disableAo(0, flatLighting).disableDiffuse(0, noDiffuse).find()
val builder = renderer.meshBuilder() val builder = renderer.meshBuilder()
builder.emitter.apply { builder.emitter.apply {
forEach { quad -> forEach { quad ->
@@ -190,7 +190,7 @@ fun List<Quad>.build(layer: BlockRenderLayer, noDiffuse: Boolean = false, flatLi
return builder.build() return builder.build()
} }
fun Array<List<Quad>>.build(layer: BlockRenderLayer, noDiffuse: Boolean = false, flatLighting: Boolean = false) = map { it.build(layer, noDiffuse, flatLighting) }.toTypedArray() fun Array<List<Quad>>.build(blendMode: BlendMode, noDiffuse: Boolean = false, flatLighting: Boolean = false) = map { it.build(blendMode, noDiffuse, flatLighting) }.toTypedArray()
/** /**
* The model should be positioned so that (0,0,0) is the block center. * The model should be positioned so that (0,0,0) is the block center.

View File

@@ -1,4 +1,4 @@
package mods.betterfoliage.resource.model package mods.betterfoliage.model
import mods.betterfoliage.util.Atlas import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.get import mods.betterfoliage.util.get
@@ -47,7 +47,12 @@ class SpriteDelegate(val atlas: Atlas, val idFunc: ()->Identifier) : ReadOnlyPro
} }
} }
class SpriteSetDelegate(val atlas: Atlas, val idRegister: (Identifier)->Identifier = { it }, val idFunc: (Int)->Identifier) : ReadOnlyProperty<Any, SpriteSet>, ClientSpriteRegistryCallback {
class SpriteSetDelegate(
val atlas: Atlas,
val idRegister: (Identifier)->Identifier = { it },
val idFunc: (Int)->Identifier
) : ReadOnlyProperty<Any, SpriteSet>, ClientSpriteRegistryCallback {
private var idList: List<Identifier> = emptyList() private var idList: List<Identifier> = emptyList()
private var spriteSet: SpriteSet? = null private var spriteSet: SpriteSet? = null
init { ClientSpriteRegistryCallback.event(atlas.resourceId).register(this) } init { ClientSpriteRegistryCallback.event(atlas.resourceId).register(this) }

View File

@@ -1,11 +1,8 @@
package mods.betterfoliage.resource.model package mods.betterfoliage.model
import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.* import mods.betterfoliage.util.*
import net.fabricmc.fabric.api.renderer.v1.RendererAccess import net.fabricmc.fabric.api.renderer.v1.material.BlendMode
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh
import net.minecraft.block.BlockRenderLayer
import net.minecraft.block.BlockRenderLayer.CUTOUT_MIPPED
import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.Sprite
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.Direction.UP import net.minecraft.util.math.Direction.UP
@@ -49,7 +46,7 @@ fun fullCubeTextured(spriteId: Identifier, overrideColor: Int?, scrambleUV: Bool
.map { if (!scrambleUV) it else it.rotateUV(randomI(max = 4)) } .map { if (!scrambleUV) it else it.rotateUV(randomI(max = 4)) }
.map { it.sprite(sprite) } .map { it.sprite(sprite) }
.map { it.colorAndIndex(overrideColor) } .map { it.colorAndIndex(overrideColor) }
.build(BlockRenderLayer.SOLID) .build(BlendMode.SOLID)
} }
fun crossModelsRaw(num: Int, size: Double, hOffset: Double, vOffset: Double): Array<List<Quad>> { fun crossModelsRaw(num: Int, size: Double, hOffset: Double, vOffset: Double): Array<List<Quad>> {
@@ -68,7 +65,7 @@ fun crossModelsTextured(leafBase: Array<List<Quad>>, overrideColor: Int?, scramb
leaf.map { if (scrambleUV) it.scrambleUV(random, canFlipU = true, canFlipV = true, canRotate = true) else it } leaf.map { if (scrambleUV) it.scrambleUV(random, canFlipU = true, canFlipV = true, canRotate = true) else it }
.map { it.colorAndIndex(overrideColor) } .map { it.colorAndIndex(overrideColor) }
.mapIndexed { idx, quad -> quad.sprite(spriteGetter(idx)) } .mapIndexed { idx, quad -> quad.sprite(spriteGetter(idx)) }
.withOpposites().build(CUTOUT_MIPPED) .withOpposites().build(BlendMode.CUTOUT_MIPPED)
}.toTypedArray() }.toTypedArray()
fun Array<List<Quad>>.buildTufts() = withOpposites().build(CUTOUT_MIPPED) fun Array<List<Quad>>.buildTufts() = withOpposites().build(BlendMode.CUTOUT_MIPPED)

View File

@@ -1,31 +1,26 @@
package mods.betterfoliage.resource.model package mods.betterfoliage.model
import mods.betterfoliage.util.YarnHelper import mods.betterfoliage.WeightedBakedModelEntry_model
import mods.betterfoliage.WeightedBakedModel_models
import mods.betterfoliage.WeightedBakedModel_totalWeight
import mods.betterfoliage.WeightedPickerEntry_weight
import mods.betterfoliage.util.get import mods.betterfoliage.util.get
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.block.BlockRenderLayer
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.client.render.RenderLayers
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.BasicBakedModel import net.minecraft.client.render.model.BasicBakedModel
import net.minecraft.client.render.model.WeightedBakedModel import net.minecraft.client.render.model.WeightedBakedModel
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.util.WeightedPicker import net.minecraft.util.WeightedPicker
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.*
import java.util.function.Supplier import java.util.function.Supplier
// net.minecraft.client.render.model.WeightedBakedModel.totalWeight
val WeightedBakedModel_totalWeight = YarnHelper.requiredField<Int>("net.minecraft.class_1097", "field_5433", "I")
// net.minecraft.client.render.model.WeightedBakedModel.models
val WeightedBakedModel_models = YarnHelper.requiredField<List<WeightedPicker.Entry>>("net.minecraft.class_1097", "field_5434", "Ljava/util/List;")
// net.minecraft.client.render.model.WeightedBakedModel.ModelEntry.model
val WeightedBakedModelEntry_model = YarnHelper.requiredField<BakedModel>("net.minecraft.class_1097\$class_1099", "field_5437", "Lnet/minecraft/class_1087;")
// net.minecraft.util.WeightedPicker.Entry.weight
val WeightedPickerEntry_weight = YarnHelper.requiredField<Int>("net.minecraft.class_3549\$class_3550", "field_15774", "I")
abstract class WrappedBakedModel(val wrapped: BakedModel) : BakedModel by wrapped, FabricBakedModel { abstract class WrappedBakedModel(val wrapped: BakedModel) : BakedModel by wrapped, FabricBakedModel {
override fun isVanillaAdapter() = false override fun isVanillaAdapter() = false
@@ -33,13 +28,13 @@ abstract class WrappedBakedModel(val wrapped: BakedModel) : BakedModel by wrappe
(wrapped as FabricBakedModel).emitItemQuads(stack, randomSupplier, context) (wrapped as FabricBakedModel).emitItemQuads(stack, randomSupplier, context)
} }
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
(wrapped as FabricBakedModel).emitBlockQuads(blockView, state, pos, randomSupplier, context) (wrapped as FabricBakedModel).emitBlockQuads(blockView, state, pos, randomSupplier, context)
} }
} }
class WrappedMeshModel(wrapped: BasicBakedModel, val mesh: Mesh) : WrappedBakedModel(wrapped) { class WrappedMeshModel(wrapped: BasicBakedModel, val mesh: Mesh) : WrappedBakedModel(wrapped) {
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
context.meshConsumer().accept(mesh) context.meshConsumer().accept(mesh)
} }
@@ -49,12 +44,12 @@ class WrappedMeshModel(wrapped: BasicBakedModel, val mesh: Mesh) : WrappedBakedM
* @param state [BlockState] to use when querying [BakedModel] * @param state [BlockState] to use when querying [BakedModel]
* @param unshade undo vanilla diffuse lighting when unbaking the [BakedModel] * @param unshade undo vanilla diffuse lighting when unbaking the [BakedModel]
* @param noDiffuse disable diffuse lighting when baking the [Mesh] * @param noDiffuse disable diffuse lighting when baking the [Mesh]
* @param renderLayerOverride [BlockRenderLayer] to use instead of the one declared by the corresponding [Block] * @param blendModeOverride [BlockRenderLayer] to use instead of the one declared by the corresponding [Block]
*/ */
fun converter(state: BlockState, unshade: Boolean = false, noDiffuse: Boolean = true, renderLayerOverride: BlockRenderLayer? = null) = BakedModelConverter.of { model, _ -> fun converter(state: BlockState, unshade: Boolean = false, noDiffuse: Boolean = true, blendModeOverride: BlendMode? = null) = BakedModelConverter.of { model, _ ->
if (model is BasicBakedModel) { if (model is BasicBakedModel) {
val mesh = unbakeQuads(model, state, Random(42L), unshade).build( val mesh = unbakeQuads(model, state, Random(42L), unshade).build(
layer = renderLayerOverride ?: state.block.renderLayer, blendMode = blendModeOverride ?: BlendMode.fromRenderLayer(RenderLayers.getBlockLayer(state)),
noDiffuse = noDiffuse, noDiffuse = noDiffuse,
flatLighting = !model.useAmbientOcclusion() flatLighting = !model.useAmbientOcclusion()
) )
@@ -70,7 +65,7 @@ class WrappedWeightedModel(wrapped: WeightedBakedModel, transformer: BakedModelC
Entry(transformer.convert(entry[WeightedBakedModelEntry_model]!!, transformer)!!, entry[WeightedPickerEntry_weight]!!) Entry(transformer.convert(entry[WeightedBakedModelEntry_model]!!, transformer)!!, entry[WeightedPickerEntry_weight]!!)
} }
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
(WeightedPicker.getRandom(randomSupplier.get(), models, totalWeight).model as FabricBakedModel).emitBlockQuads(blockView, state, pos, randomSupplier, context) (WeightedPicker.getRandom(randomSupplier.get(), models, totalWeight).model as FabricBakedModel).emitBlockQuads(blockView, state, pos, randomSupplier, context)
} }

View File

@@ -2,15 +2,15 @@ package mods.betterfoliage.render
import mods.betterfoliage.util.Double3 import mods.betterfoliage.util.Double3
import net.minecraft.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.minecraft.client.particle.ParticleTextureSheet
import net.minecraft.client.particle.SpriteBillboardParticle import net.minecraft.client.particle.SpriteBillboardParticle
import net.minecraft.client.render.BufferBuilder
import net.minecraft.client.render.Camera import net.minecraft.client.render.Camera
import net.minecraft.client.render.VertexConsumer
import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.math.Vector3f
import net.minecraft.util.math.MathHelper
import net.minecraft.world.World import net.minecraft.world.World
import kotlin.math.cos
import kotlin.math.sin
fun VertexConsumer.vertex(v: Double3) = vertex(v.x, v.y, v.z)
abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) : SpriteBillboardParticle(world, x, y, z) { abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) : SpriteBillboardParticle(world, x, y, z) {
@@ -34,9 +34,6 @@ abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) :
velocityX = velocity.x; velocityY = velocity.y; velocityZ = velocity.z; velocityX = velocity.x; velocityY = velocity.y; velocityZ = velocity.z;
} }
/** Render the particle. */
abstract fun render(worldRenderer: BufferBuilder, partialTickTime: Float)
/** Update particle on world tick. */ /** Update particle on world tick. */
abstract fun update() abstract fun update()
@@ -46,81 +43,57 @@ abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) :
/** Add the particle to the effect renderer if it is valid. */ /** Add the particle to the effect renderer if it is valid. */
fun addIfValid() { if (isValid) MinecraftClient.getInstance().particleManager.addParticle(this) } fun addIfValid() { if (isValid) MinecraftClient.getInstance().particleManager.addParticle(this) }
override fun buildGeometry(buffer: BufferBuilder, camera: Camera, tickDelta: Float, rotX: Float, rotZ: Float, rotYZ: Float, rotXY: Float, rotXZ: Float) { override fun buildGeometry(vertexConsumer: VertexConsumer, camera: Camera, tickDelta: Float) {
billboardRot.first.setTo(rotX + rotXY, rotZ, rotYZ + rotXZ) renderParticleQuad(vertexConsumer, camera, tickDelta)
billboardRot.second.setTo(rotX - rotXY, -rotZ, rotYZ - rotXZ)
render(buffer, tickDelta)
} }
/** /**
* Render a particle quad. * Render a particle quad.
* *
* @param[tessellator] the [Tessellator] instance to use * @param[tessellator] the [Tessellator] instance to use
* @param[partialTickTime] partial tick time * @param[tickDelta] partial tick time
* @param[currentPos] render position * @param[currentPos] render position
* @param[prevPos] previous tick position for interpolation * @param[prevPos] previous tick position for interpolation
* @param[size] particle size * @param[size] particle size
* @param[rotation] viewpoint-dependent particle rotation (64 steps) * @param[currentAngle] viewpoint-dependent particle rotation (64 steps)
* @param[sprite] particle texture * @param[sprite] particle texture
* @param[isMirrored] mirror particle texture along V-axis * @param[isMirrored] mirror particle texture along V-axis
* @param[alpha] aplha blending * @param[alpha] aplha blending
*/ */
fun renderParticleQuad(worldRenderer: BufferBuilder, fun renderParticleQuad(vertexConsumer: VertexConsumer,
partialTickTime: Float, camera: Camera,
tickDelta: Float,
currentPos: Double3 = this.currentPos, currentPos: Double3 = this.currentPos,
prevPos: Double3 = this.prevPos, prevPos: Double3 = this.prevPos,
size: Double = scale.toDouble(), size: Double = scale.toDouble(),
rotation: Double = 0.0, currentAngle: Float = this.angle,
prevAngle: Float = this.prevAngle,
sprite: Sprite = this.sprite, sprite: Sprite = this.sprite,
isMirrored: Boolean = false,
alpha: Float = this.colorAlpha) { alpha: Float = this.colorAlpha) {
val minU = (if (isMirrored) sprite.minU else sprite.maxU).toDouble() val center = Double3.lerp(tickDelta.toDouble(), prevPos, currentPos)
val maxU = (if (isMirrored) sprite.maxU else sprite.minU).toDouble() val angle = MathHelper.lerp(tickDelta, prevAngle, currentAngle)
val minV = sprite.minV.toDouble() val rotation = camera.rotation.copy().apply { hamiltonProduct(Vector3f.POSITIVE_Z.getRadialQuaternion(angle)) }
val maxV = sprite.maxV.toDouble() val lightmapCoord = getColorMultiplier(tickDelta)
val center = currentPos.copy().sub(prevPos).mul(partialTickTime.toDouble()).add(prevPos).sub(cameraX, cameraY, cameraZ) val coords = arrayOf(
Double3(-1.0, -1.0, 0.0),
Double3(-1.0, 1.0, 0.0),
Double3(1.0, 1.0, 0.0),
Double3(1.0, -1.0, 0.0)
).map { it.rotate(rotation).mul(size).add(center).sub(camera.pos.x, camera.pos.y, camera.pos.z) }
val cosRotation = cos(rotation); val sinRotation = sin(rotation) fun renderVertex(vertex: Double3, u: Float, v: Float) = vertexConsumer
val v1 = Double3.weight(billboardRot.first, cosRotation * size, billboardRot.second, sinRotation * size) .vertex(vertex.x, vertex.y, vertex.z).texture(u, v)
val v2 = Double3.weight(billboardRot.first, -sinRotation * size, billboardRot.second, cosRotation * size) .color(colorRed, colorGreen, colorBlue, alpha).light(lightmapCoord)
val renderBrightness = this.getColorMultiplier(partialTickTime)
val brHigh = renderBrightness shr 16 and 65535
val brLow = renderBrightness and 65535
worldRenderer
.vertex(center.x - v1.x, center.y - v1.y, center.z - v1.z)
.texture(maxU, maxV)
.color(colorRed, colorGreen, colorBlue, alpha)
.texture(brHigh, brLow)
.next() .next()
worldRenderer renderVertex(coords[0], sprite.maxU, sprite.maxV)
.vertex(center.x - v2.x, center.y - v2.y, center.z - v2.z) renderVertex(coords[1], sprite.maxU, sprite.minV)
.texture(maxU, minV) renderVertex(coords[2], sprite.minU, sprite.minV)
.color(colorRed, colorGreen, colorBlue, alpha) renderVertex(coords[3], sprite.minU, sprite.maxV)
.texture(brHigh, brLow)
.next()
worldRenderer
.vertex(center.x + v1.x, center.y + v1.y, center.z + v1.z)
.texture(minU, minV)
.color(colorRed, colorGreen, colorBlue, alpha)
.texture(brHigh, brLow)
.next()
worldRenderer
.vertex(center.x + v2.x, center.y + v2.y, center.z + v2.z)
.texture(minU, maxV)
.color(colorRed, colorGreen, colorBlue, alpha)
.texture(brHigh, brLow)
.next()
} }
override fun getType() = ParticleTextureSheet.PARTICLE_SHEET_OPAQUE
fun setColor(color: Int) { fun setColor(color: Int) {
colorBlue = (color and 255) / 256.0f colorBlue = (color and 255) / 256.0f
colorGreen = ((color shr 8) and 255) / 256.0f colorGreen = ((color shr 8) and 255) / 256.0f

View File

@@ -4,9 +4,9 @@ import net.minecraft.block.Blocks
import net.minecraft.block.Material import net.minecraft.block.Material
import net.minecraft.world.biome.Biome import net.minecraft.world.biome.Biome
val DIRT_BLOCKS = listOf(Blocks.DIRT, Blocks.COARSE_DIRT) val DIRT_BLOCKS = listOf(Blocks.DIRT, Blocks.COARSE_DIRT, Blocks.PODZOL)
val SAND_BLOCKS = listOf(Blocks.SAND, Blocks.RED_SAND) val SAND_BLOCKS = listOf(Blocks.SAND, Blocks.RED_SAND)
val SALTWATER_BIOMES = listOf(Biome.Category.BEACH, Biome.Category.OCEAN) val SALTWATER_BIOMES = listOf(Biome.Category.BEACH, Biome.Category.OCEAN)
val SNOW_MATERIALS = listOf(Material.SNOW, Material.SNOW_BLOCK) val SNOW_MATERIALS = listOf(Material.SNOW_BLOCK)

View File

@@ -4,11 +4,10 @@ import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.render.lighting.getBufferBuilder import mods.betterfoliage.render.lighting.getBufferBuilder
import mods.betterfoliage.util.getAllMethods import mods.betterfoliage.util.getAllMethods
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.block.BlockRenderLayer
import net.minecraft.block.BlockRenderLayer.CUTOUT_MIPPED
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.block.Blocks import net.minecraft.block.Blocks
import net.minecraft.client.render.BufferBuilder import net.minecraft.client.render.BufferBuilder
import net.minecraft.client.render.RenderLayer
/** /**
* Integration for ShadersMod. * Integration for ShadersMod.
@@ -32,7 +31,7 @@ object ShadersModIntegration {
} }
/** Quads rendered inside this block will use the given block entity data in shader programs. */ /** Quads rendered inside this block will use the given block entity data in shader programs. */
inline fun renderAs(ctx: RenderContext, state: BlockState, layer: BlockRenderLayer, enabled: Boolean = true, func: ()->Unit) { inline fun renderAs(ctx: RenderContext, state: BlockState, layer: RenderLayer, enabled: Boolean = true, func: ()->Unit) {
if (isAvailable && enabled) { if (isAvailable && enabled) {
val sVertexBuilder = BufferBuilder_SVertexBuilder!!.get(ctx.getBufferBuilder(layer)) val sVertexBuilder = BufferBuilder_SVertexBuilder!!.get(ctx.getBufferBuilder(layer))
val aliasBlockId = BlockAliases_getAliasBlockId!!.invoke(null, state) val aliasBlockId = BlockAliases_getAliasBlockId!!.invoke(null, state)
@@ -46,9 +45,9 @@ object ShadersModIntegration {
/** Quads rendered inside this block will behave as tallgrass blocks in shader programs. */ /** Quads rendered inside this block will behave as tallgrass blocks in shader programs. */
inline fun grass(ctx: RenderContext, enabled: Boolean = true, func: ()->Unit) = inline fun grass(ctx: RenderContext, enabled: Boolean = true, func: ()->Unit) =
renderAs(ctx, defaultGrass, CUTOUT_MIPPED, enabled, func) renderAs(ctx, defaultGrass, RenderLayer.getCutoutMipped(), enabled, func)
/** Quads rendered inside this block will behave as leaf blocks in shader programs. */ /** Quads rendered inside this block will behave as leaf blocks in shader programs. */
inline fun leaves(ctx: RenderContext, enabled: Boolean = true, func: ()->Unit) = inline fun leaves(ctx: RenderContext, enabled: Boolean = true, func: ()->Unit) =
renderAs(ctx, defaultLeaves, CUTOUT_MIPPED, enabled, func) renderAs(ctx, defaultLeaves, RenderLayer.getCutoutMipped(), enabled, func)
} }

View File

@@ -1,13 +1,31 @@
package mods.betterfoliage.render.block.vanilla package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliage import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.render.lighting.grassTuftLighting import mods.betterfoliage.render.lighting.grassTuftLighting
import mods.betterfoliage.render.lighting.roundLeafLighting import mods.betterfoliage.render.lighting.roundLeafLighting
import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.resource.discovery.BlockRenderKey
import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
import mods.betterfoliage.resource.discovery.ModelTextureList
import mods.betterfoliage.resource.discovery.SimpleBlockMatcher
import mods.betterfoliage.model.Color
import mods.betterfoliage.model.SpriteDelegate
import mods.betterfoliage.model.SpriteSetDelegate
import mods.betterfoliage.model.WrappedBakedModel
import mods.betterfoliage.model.buildTufts
import mods.betterfoliage.model.crossModelsRaw
import mods.betterfoliage.model.crossModelsTextured
import mods.betterfoliage.model.meshifyStandard
import mods.betterfoliage.model.transform
import mods.betterfoliage.model.tuftModelSet
import mods.betterfoliage.model.tuftShapeSet
import mods.betterfoliage.util.Atlas import mods.betterfoliage.util.Atlas
import mods.betterfoliage.resource.discovery.* import mods.betterfoliage.util.LazyMap
import mods.betterfoliage.resource.model.* import mods.betterfoliage.util.Rotation
import mods.betterfoliage.util.* import mods.betterfoliage.util.get
import mods.betterfoliage.util.horizontalDirections
import mods.betterfoliage.util.randomD
import mods.betterfoliage.util.randomI
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
@@ -16,8 +34,8 @@ import net.minecraft.client.render.model.BakedModel
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction.DOWN import net.minecraft.util.math.Direction.DOWN
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.Random
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
@@ -33,9 +51,8 @@ object StandardCactusDiscovery : ConfigurableModelDiscovery() {
override val matchClasses = SimpleBlockMatcher(CactusBlock::class.java) override val matchClasses = SimpleBlockMatcher(CactusBlock::class.java)
override val modelTextures = listOf(ModelTextureList("block/cactus", "top", "bottom", "side")) override val modelTextures = listOf(ModelTextureList("block/cactus", "top", "bottom", "side"))
override fun processModel(state: BlockState, textures: List<String>, atlas: Consumer<Identifier>): BlockRenderKey? { override fun processModel(state: BlockState, textures: List<Identifier>, atlas: Consumer<Identifier>): BlockRenderKey? {
val sprites = textures.map { Identifier(it) } return CactusModel.Key(textures[0], textures[1], textures[2])
return CactusModel.Key(sprites[0], sprites[1], sprites[2])
} }
} }
@@ -46,7 +63,7 @@ class CactusModel(val key: Key, wrapped: BakedModel) : WrappedBakedModel(wrapped
val armLighting = horizontalDirections.map { grassTuftLighting(it) } val armLighting = horizontalDirections.map { grassTuftLighting(it) }
val crossLighting = roundLeafLighting() val crossLighting = roundLeafLighting()
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
(wrapped as FabricBakedModel).emitBlockQuads(blockView, state, pos, randomSupplier, context) (wrapped as FabricBakedModel).emitBlockQuads(blockView, state, pos, randomSupplier, context)
if (!BetterFoliage.config.enabled || !BetterFoliage.config.cactus.enabled) return if (!BetterFoliage.config.enabled || !BetterFoliage.config.cactus.enabled) return

View File

@@ -14,18 +14,17 @@ import mods.betterfoliage.resource.discovery.BlockRenderKey
import mods.betterfoliage.resource.discovery.ModelDiscoveryBase import mods.betterfoliage.resource.discovery.ModelDiscoveryBase
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
import mods.betterfoliage.resource.generated.CenteredSprite import mods.betterfoliage.resource.generated.CenteredSprite
import mods.betterfoliage.resource.model.* import mods.betterfoliage.model.*
import mods.betterfoliage.util.* import mods.betterfoliage.util.*
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.block.BlockRenderLayer
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.block.Material import net.minecraft.block.Material
import net.minecraft.client.MinecraftClient
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction.UP import net.minecraft.util.math.Direction.UP
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.*
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
@@ -46,7 +45,7 @@ class DirtModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
val algaeLighting = grassTuftLighting(UP) val algaeLighting = grassTuftLighting(UP)
val reedLighting = reedLighting() val reedLighting = reedLighting()
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
if (!BetterFoliage.config.enabled) return super.emitBlockQuads(blockView, state, pos, randomSupplier, context) if (!BetterFoliage.config.enabled) return super.emitBlockQuads(blockView, state, pos, randomSupplier, context)
val ctx = BasicBlockCtx(blockView, pos) val ctx = BasicBlockCtx(blockView, pos)
@@ -56,7 +55,7 @@ class DirtModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
val isWater = stateUp.material == Material.WATER val isWater = stateUp.material == Material.WATER
val isDeepWater = isWater && ctx.offset(Int3(2 to UP)).state.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 isShallowWater = isWater && ctx.offset(Int3(2 to UP)).state.isAir
val isSaltWater = isWater && ctx.biome.category in SALTWATER_BIOMES val isSaltWater = isWater && ctx.biome?.category in SALTWATER_BIOMES
if (BetterFoliage.config.connectedGrass.enabled && keyUp is GrassKey) { if (BetterFoliage.config.connectedGrass.enabled && keyUp is GrassKey) {
val grassBaseModel = (ctx.model(UP) as WrappedBakedModel).wrapped val grassBaseModel = (ctx.model(UP) as WrappedBakedModel).wrapped
@@ -93,14 +92,14 @@ class DirtModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
val shapes = BetterFoliage.config.algae.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) } val shapes = BetterFoliage.config.algae.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) }
tuftModelSet(shapes, Color.white.asInt) { algaeSprites[randomI()] } tuftModelSet(shapes, Color.white.asInt) { algaeSprites[randomI()] }
.withOpposites() .withOpposites()
.build(BlockRenderLayer.CUTOUT_MIPPED, flatLighting = false) .build(BlendMode.CUTOUT_MIPPED, flatLighting = false)
} }
val reedModels by LazyInvalidatable(BetterFoliage.modelReplacer) { val reedModels by LazyInvalidatable(BetterFoliage.modelReplacer) {
val shapes = BetterFoliage.config.reed.let { tuftShapeSet(2.0, it.heightMin, it.heightMax, it.hOffset) } val shapes = BetterFoliage.config.reed.let { tuftShapeSet(2.0, it.heightMin, it.heightMax, it.hOffset) }
tuftModelSet(shapes, Color.white.asInt) { reedSprites[randomI()] } tuftModelSet(shapes, Color.white.asInt) { reedSprites[randomI()] }
.withOpposites() .withOpposites()
.build(BlockRenderLayer.CUTOUT_MIPPED, flatLighting = false) .build(BlendMode.CUTOUT_MIPPED, flatLighting = false)
} }
} }
} }

View File

@@ -4,22 +4,20 @@ import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.chunk.BasicBlockCtx import mods.betterfoliage.chunk.BasicBlockCtx
import mods.betterfoliage.render.SNOW_MATERIALS import mods.betterfoliage.render.SNOW_MATERIALS
import mods.betterfoliage.render.ShadersModIntegration import mods.betterfoliage.render.ShadersModIntegration
import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.render.lighting.grassTuftLighting import mods.betterfoliage.render.lighting.grassTuftLighting
import mods.betterfoliage.util.Atlas import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.resource.discovery.* import mods.betterfoliage.resource.discovery.*
import mods.betterfoliage.resource.model.* import mods.betterfoliage.model.*
import mods.betterfoliage.util.* import mods.betterfoliage.util.*
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.block.BlockRenderLayer
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.tag.BlockTags
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction.* import net.minecraft.util.math.Direction.*
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.*
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
@@ -41,8 +39,8 @@ object StandardGrassDiscovery : ConfigurableModelDiscovery() {
override val matchClasses: ConfigurableBlockMatcher get() = BetterFoliage.blockConfig.grassBlocks override val matchClasses: ConfigurableBlockMatcher get() = BetterFoliage.blockConfig.grassBlocks
override val modelTextures: List<ModelTextureList> get() = BetterFoliage.blockConfig.grassModels.modelList override val modelTextures: List<ModelTextureList> get() = BetterFoliage.blockConfig.grassModels.modelList
override fun processModel(state: BlockState, textures: List<String>, atlas: Consumer<Identifier>): BlockRenderKey? { override fun processModel(state: BlockState, textures: List<Identifier>, atlas: Consumer<Identifier>): BlockRenderKey? {
val grassId = Identifier(textures[0]) val grassId = textures[0]
log(" block state $state") log(" block state $state")
log(" texture $grassId") log(" texture $grassId")
return GrassBlockModel.Key(grassId, getAndLogColorOverride(grassId, Atlas.BLOCKS, BetterFoliage.config.shortGrass.saturationThreshold)) return GrassBlockModel.Key(grassId, getAndLogColorOverride(grassId, Atlas.BLOCKS, BetterFoliage.config.shortGrass.saturationThreshold))
@@ -57,7 +55,7 @@ class GrassBlockModel(val key: Key, wrapped: BakedModel) : WrappedBakedModel(wra
val tuftLighting = grassTuftLighting(UP) val tuftLighting = grassTuftLighting(UP)
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
if (!BetterFoliage.config.enabled) return super.emitBlockQuads(blockView, state, pos, randomSupplier, context) if (!BetterFoliage.config.enabled) return super.emitBlockQuads(blockView, state, pos, randomSupplier, context)
val ctx = BasicBlockCtx(blockView, pos) val ctx = BasicBlockCtx(blockView, pos)
@@ -67,8 +65,7 @@ class GrassBlockModel(val key: Key, wrapped: BakedModel) : WrappedBakedModel(wra
val isSnowed = stateAbove.material in SNOW_MATERIALS val isSnowed = stateAbove.material in SNOW_MATERIALS
val connected = BetterFoliage.config.connectedGrass.enabled && val connected = BetterFoliage.config.connectedGrass.enabled &&
(!isSnowed || BetterFoliage.config.connectedGrass.snowEnabled) && ( (!isSnowed || BetterFoliage.config.connectedGrass.snowEnabled) && (
BlockTags.DIRT_LIKE.contains(stateBelow.block) || BetterFoliage.modelReplacer[stateBelow].let { it is DirtKey || it is GrassKey }
BetterFoliage.modelReplacer.getTyped<GrassKey>(stateBelow) != null
) )
val random = randomSupplier.get() val random = randomSupplier.get()
@@ -107,12 +104,12 @@ class GrassBlockModel(val key: Key, wrapped: BakedModel) : WrappedBakedModel(wra
val grassTuftMeshesNormal = LazyMap(BetterFoliage.modelReplacer) { key: GrassKey -> val grassTuftMeshesNormal = LazyMap(BetterFoliage.modelReplacer) { key: GrassKey ->
tuftModelSet(grassTuftShapes[key], key.overrideColor) { idx -> grassTuftSpritesNormal[randomI()] } tuftModelSet(grassTuftShapes[key], key.overrideColor) { idx -> grassTuftSpritesNormal[randomI()] }
.withOpposites() .withOpposites()
.build(BlockRenderLayer.CUTOUT_MIPPED, flatLighting = false) .build(BlendMode.CUTOUT_MIPPED, flatLighting = false)
} }
val grassTuftMeshesSnowed = LazyMap(BetterFoliage.modelReplacer) { key: GrassKey -> val grassTuftMeshesSnowed = LazyMap(BetterFoliage.modelReplacer) { key: GrassKey ->
tuftModelSet(grassTuftShapes[key], Color.white.asInt) { idx -> grassTuftSpritesSnowed[randomI()] } tuftModelSet(grassTuftShapes[key], Color.white.asInt) { idx -> grassTuftSpritesSnowed[randomI()] }
.withOpposites() .withOpposites()
.build(BlockRenderLayer.CUTOUT_MIPPED, flatLighting = false) .build(BlendMode.CUTOUT_MIPPED, flatLighting = false)
} }
val grassFullBlockMeshes = LazyMap(BetterFoliage.modelReplacer) { key: GrassKey -> val grassFullBlockMeshes = LazyMap(BetterFoliage.modelReplacer) { key: GrassKey ->
Array(64) { fullCubeTextured(key.grassTopTexture, key.overrideColor) } Array(64) { fullCubeTextured(key.grassTopTexture, key.overrideColor) }

View File

@@ -1,33 +1,26 @@
package mods.betterfoliage.render.block.vanilla package mods.betterfoliage.render.block.vanilla
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
import mods.betterfoliage.BetterFoliage import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.chunk.BasicBlockCtx import mods.betterfoliage.chunk.BasicBlockCtx
import mods.betterfoliage.render.SNOW_MATERIALS import mods.betterfoliage.render.SNOW_MATERIALS
import mods.betterfoliage.render.ShadersModIntegration import mods.betterfoliage.render.ShadersModIntegration
import mods.betterfoliage.render.lighting.getBufferBuilder
import mods.betterfoliage.render.lighting.withLighting import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.render.lighting.roundLeafLighting import mods.betterfoliage.render.lighting.roundLeafLighting
import mods.betterfoliage.render.particle.LeafParticleRegistry import mods.betterfoliage.render.particle.LeafParticleRegistry
import mods.betterfoliage.util.Atlas import mods.betterfoliage.util.Atlas
import mods.betterfoliage.resource.discovery.* import mods.betterfoliage.resource.discovery.*
import mods.betterfoliage.resource.generated.GeneratedLeafSprite import mods.betterfoliage.resource.generated.GeneratedLeafSprite
import mods.betterfoliage.resource.model.* import mods.betterfoliage.model.*
import mods.betterfoliage.util.* import mods.betterfoliage.util.*
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.fabricmc.fabric.impl.client.indigo.renderer.accessor.AccessBufferBuilder
import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderInfo
import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainMeshConsumer
import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainRenderContext
import net.minecraft.block.BlockRenderLayer
import net.minecraft.block.BlockRenderLayer.CUTOUT_MIPPED
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction.* import net.minecraft.util.math.Direction.*
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.*
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
@@ -47,8 +40,8 @@ object StandardLeafDiscovery : ConfigurableModelDiscovery() {
override val matchClasses: ConfigurableBlockMatcher get() = BetterFoliage.blockConfig.leafBlocks override val matchClasses: ConfigurableBlockMatcher get() = BetterFoliage.blockConfig.leafBlocks
override val modelTextures: List<ModelTextureList> get() = BetterFoliage.blockConfig.leafModels.modelList override val modelTextures: List<ModelTextureList> get() = BetterFoliage.blockConfig.leafModels.modelList
override fun processModel(state: BlockState, textures: List<String>, atlas: Consumer<Identifier>) = override fun processModel(state: BlockState, textures: List<Identifier>, atlas: Consumer<Identifier>) =
defaultRegisterLeaf(Identifier(textures[0]), atlas) defaultRegisterLeaf(textures[0], atlas)
} }
@@ -84,7 +77,7 @@ class NormalLeavesModel(val key: Key, wrapped: BakedModel) : WrappedBakedModel(w
val leafSnowed by leafModelsSnowed.delegate(key) val leafSnowed by leafModelsSnowed.delegate(key)
val leafLighting = roundLeafLighting() val leafLighting = roundLeafLighting()
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
ShadersModIntegration.leaves(context, BetterFoliage.config.leaves.shaderWind) { ShadersModIntegration.leaves(context, BetterFoliage.config.leaves.shaderWind) {
super.emitBlockQuads(blockView, state, pos, randomSupplier, context) super.emitBlockQuads(blockView, state, pos, randomSupplier, context)
if (!BetterFoliage.config.enabled || !BetterFoliage.config.leaves.enabled) return if (!BetterFoliage.config.enabled || !BetterFoliage.config.leaves.enabled) return
@@ -106,7 +99,7 @@ class NormalLeavesModel(val key: Key, wrapped: BakedModel) : WrappedBakedModel(w
override val leafType: String, override val leafType: String,
override val overrideColor: Int? override val overrideColor: Int?
) : LeafKey { ) : LeafKey {
override fun replace(model: BakedModel, state: BlockState) = NormalLeavesModel(this, meshifyStandard(model, state, renderLayerOverride = CUTOUT_MIPPED)) override fun replace(model: BakedModel, state: BlockState) = NormalLeavesModel(this, meshifyStandard(model, state, blendModeOverride = BlendMode.CUTOUT_MIPPED))
} }
companion object { companion object {

View File

@@ -2,16 +2,20 @@ package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliage import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.render.ShadersModIntegration import mods.betterfoliage.render.ShadersModIntegration
import mods.betterfoliage.util.Atlas
import mods.betterfoliage.resource.discovery.BlockRenderKey import mods.betterfoliage.resource.discovery.BlockRenderKey
import mods.betterfoliage.resource.discovery.ModelDiscoveryBase import mods.betterfoliage.resource.discovery.ModelDiscoveryBase
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
import mods.betterfoliage.resource.discovery.RenderKeyFactory import mods.betterfoliage.model.Color
import mods.betterfoliage.resource.model.* import mods.betterfoliage.model.SpriteSetDelegate
import mods.betterfoliage.model.WrappedBakedModel
import mods.betterfoliage.model.buildTufts
import mods.betterfoliage.model.meshifyStandard
import mods.betterfoliage.model.transform
import mods.betterfoliage.model.tuftModelSet
import mods.betterfoliage.model.tuftShapeSet
import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.LazyInvalidatable import mods.betterfoliage.util.LazyInvalidatable
import mods.betterfoliage.util.get import mods.betterfoliage.util.get
import mods.betterfoliage.util.semiRandom
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.block.Blocks import net.minecraft.block.Blocks
@@ -19,8 +23,8 @@ import net.minecraft.client.render.model.BakedModel
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction.DOWN import net.minecraft.util.math.Direction.DOWN
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.Random
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
@@ -35,7 +39,7 @@ object LilyPadDiscovery : ModelDiscoveryBase() {
} }
class LilypadModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) { class LilypadModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
super.emitBlockQuads(blockView, state, pos, randomSupplier, context) super.emitBlockQuads(blockView, state, pos, randomSupplier, context)
if (!BetterFoliage.config.enabled || !BetterFoliage.config.lilypad.enabled) return if (!BetterFoliage.config.enabled || !BetterFoliage.config.lilypad.enabled) return

View File

@@ -2,15 +2,24 @@ package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliage import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.render.ShadersModIntegration import mods.betterfoliage.render.ShadersModIntegration
import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.render.lighting.grassTuftLighting import mods.betterfoliage.render.lighting.grassTuftLighting
import mods.betterfoliage.util.Atlas import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.resource.discovery.BlockRenderKey import mods.betterfoliage.resource.discovery.BlockRenderKey
import mods.betterfoliage.resource.discovery.ModelDiscoveryBase import mods.betterfoliage.resource.discovery.ModelDiscoveryBase
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
import mods.betterfoliage.resource.discovery.RenderKeyFactory import mods.betterfoliage.model.Color
import mods.betterfoliage.resource.model.* import mods.betterfoliage.model.SpriteSetDelegate
import mods.betterfoliage.util.* import mods.betterfoliage.model.WrappedBakedModel
import mods.betterfoliage.model.buildTufts
import mods.betterfoliage.model.meshifyStandard
import mods.betterfoliage.model.tuftModelSet
import mods.betterfoliage.model.tuftShapeSet
import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.LazyInvalidatable
import mods.betterfoliage.util.get
import mods.betterfoliage.util.offset
import mods.betterfoliage.util.plus
import mods.betterfoliage.util.randomI
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.block.Blocks import net.minecraft.block.Blocks
@@ -18,8 +27,8 @@ import net.minecraft.client.render.model.BakedModel
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction.UP import net.minecraft.util.math.Direction.UP
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.Random
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
@@ -38,7 +47,7 @@ class MyceliumModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
val tuftLighting = grassTuftLighting(UP) val tuftLighting = grassTuftLighting(UP)
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
super.emitBlockQuads(blockView, state, pos, randomSupplier, context) super.emitBlockQuads(blockView, state, pos, randomSupplier, context)
val random = randomSupplier.get() val random = randomSupplier.get()

View File

@@ -1,24 +1,22 @@
package mods.betterfoliage.render.block.vanilla package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliage import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.render.lighting.grassTuftLighting import mods.betterfoliage.render.lighting.grassTuftLighting
import mods.betterfoliage.util.Atlas import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.resource.discovery.BlockRenderKey import mods.betterfoliage.resource.discovery.BlockRenderKey
import mods.betterfoliage.resource.discovery.ModelDiscoveryBase import mods.betterfoliage.resource.discovery.ModelDiscoveryBase
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
import mods.betterfoliage.resource.discovery.RenderKeyFactory import mods.betterfoliage.model.*
import mods.betterfoliage.resource.model.*
import mods.betterfoliage.util.* import mods.betterfoliage.util.*
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.block.BlockRenderLayer
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.block.Blocks import net.minecraft.block.Blocks
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction.DOWN import net.minecraft.util.math.Direction.DOWN
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.*
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
@@ -38,7 +36,7 @@ class NetherrackModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
val tuftLighting = grassTuftLighting(DOWN) val tuftLighting = grassTuftLighting(DOWN)
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
super.emitBlockQuads(blockView, state, pos, randomSupplier, context) super.emitBlockQuads(blockView, state, pos, randomSupplier, context)
if (BetterFoliage.config.enabled && if (BetterFoliage.config.enabled &&
BetterFoliage.config.netherrack.enabled && BetterFoliage.config.netherrack.enabled &&
@@ -60,7 +58,7 @@ class NetherrackModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
tuftModelSet(shapes, Color.white.asInt) { netherrackTuftSprites[randomI()] } tuftModelSet(shapes, Color.white.asInt) { netherrackTuftSprites[randomI()] }
.transform { rotate(Rotation.fromUp[DOWN.ordinal]).rotateUV(2) } .transform { rotate(Rotation.fromUp[DOWN.ordinal]).rotateUV(2) }
.withOpposites() .withOpposites()
.build(BlockRenderLayer.CUTOUT_MIPPED, flatLighting = false) .build(BlendMode.CUTOUT_MIPPED, flatLighting = false)
} }
} }
} }

View File

@@ -4,14 +4,13 @@ import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.render.column.* import mods.betterfoliage.render.column.*
import mods.betterfoliage.util.Atlas import mods.betterfoliage.util.Atlas
import mods.betterfoliage.resource.discovery.* import mods.betterfoliage.resource.discovery.*
import mods.betterfoliage.resource.model.meshifyStandard import mods.betterfoliage.model.meshifyStandard
import mods.betterfoliage.util.LazyMap import mods.betterfoliage.util.LazyMap
import mods.betterfoliage.util.get import mods.betterfoliage.util.get
import mods.betterfoliage.util.tryDefault import mods.betterfoliage.util.tryDefault
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.block.LogBlock import net.minecraft.block.LogBlock
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.texture.SpriteAtlasTexture
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.Direction.Axis import net.minecraft.util.math.Direction.Axis
import java.util.function.Consumer import java.util.function.Consumer
@@ -28,10 +27,10 @@ object StandardLogDiscovery : ConfigurableModelDiscovery() {
override val matchClasses: ConfigurableBlockMatcher get() = BetterFoliage.blockConfig.logBlocks override val matchClasses: ConfigurableBlockMatcher get() = BetterFoliage.blockConfig.logBlocks
override val modelTextures: List<ModelTextureList> get() = BetterFoliage.blockConfig.logModels.modelList override val modelTextures: List<ModelTextureList> get() = BetterFoliage.blockConfig.logModels.modelList
override fun processModel(state: BlockState, textures: List<String>, atlas: Consumer<Identifier>): BlockRenderKey? { override fun processModel(state: BlockState, textures: List<Identifier>, atlas: Consumer<Identifier>): BlockRenderKey? {
val axis = getAxis(state) val axis = getAxis(state)
log(" axis $axis") log(" axis $axis")
return RoundLogModel.Key(axis, Identifier(textures[0]), Identifier(textures[1])) return RoundLogModel.Key(axis, textures[0], textures[1])
} }
fun getAxis(state: BlockState): Axis? { fun getAxis(state: BlockState): Axis? {

View File

@@ -4,24 +4,39 @@ import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.chunk.CachedBlockCtx import mods.betterfoliage.chunk.CachedBlockCtx
import mods.betterfoliage.render.SALTWATER_BIOMES import mods.betterfoliage.render.SALTWATER_BIOMES
import mods.betterfoliage.render.SAND_BLOCKS import mods.betterfoliage.render.SAND_BLOCKS
import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.render.lighting.grassTuftLighting import mods.betterfoliage.render.lighting.grassTuftLighting
import mods.betterfoliage.util.Atlas import mods.betterfoliage.render.lighting.withLighting
import mods.betterfoliage.resource.discovery.BlockRenderKey import mods.betterfoliage.resource.discovery.BlockRenderKey
import mods.betterfoliage.resource.discovery.ModelDiscoveryBase import mods.betterfoliage.resource.discovery.ModelDiscoveryBase
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
import mods.betterfoliage.resource.model.* import mods.betterfoliage.model.Color
import mods.betterfoliage.util.* import mods.betterfoliage.model.SpriteSetDelegate
import mods.betterfoliage.model.WrappedBakedModel
import mods.betterfoliage.model.build
import mods.betterfoliage.model.horizontalRectangle
import mods.betterfoliage.model.meshifyStandard
import mods.betterfoliage.model.transform
import mods.betterfoliage.model.tuftModelSet
import mods.betterfoliage.model.tuftShapeSet
import mods.betterfoliage.model.withOpposites
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.randomB
import mods.betterfoliage.util.randomD
import mods.betterfoliage.util.randomI
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.block.BlockRenderLayer.CUTOUT_MIPPED
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.block.Material import net.minecraft.block.Material
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction.UP import net.minecraft.util.math.Direction.UP
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.Random
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
@@ -40,14 +55,14 @@ class SandModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
val coralLighting = allDirections.map { grassTuftLighting(it) }.toTypedArray() val coralLighting = allDirections.map { grassTuftLighting(it) }.toTypedArray()
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
super.emitBlockQuads(blockView, state, pos, randomSupplier, context) super.emitBlockQuads(blockView, state, pos, randomSupplier, context)
val ctx = CachedBlockCtx(blockView, pos) val ctx = CachedBlockCtx(blockView, pos)
val random = randomSupplier.get() val random = randomSupplier.get()
if (!BetterFoliage.config.enabled || !BetterFoliage.config.coral.enabled(random)) return if (!BetterFoliage.config.enabled || !BetterFoliage.config.coral.enabled(random)) return
if (ctx.biome.category !in SALTWATER_BIOMES) return if (ctx.biome?.category !in SALTWATER_BIOMES) return
allDirections.filter { random.nextInt(64) < BetterFoliage.config.coral.chance }.forEach { face -> allDirections.filter { random.nextInt(64) < BetterFoliage.config.coral.chance }.forEach { face ->
val isWater = ctx.state(face).material == Material.WATER val isWater = ctx.state(face).material == Material.WATER
@@ -76,7 +91,7 @@ class SandModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
tuftModelSet(shapes, Color.white.asInt) { coralTuftSprites[randomI()] } tuftModelSet(shapes, Color.white.asInt) { coralTuftSprites[randomI()] }
.transform { rotate(Rotation.fromUp[face]) } .transform { rotate(Rotation.fromUp[face]) }
.withOpposites() .withOpposites()
.build(CUTOUT_MIPPED) .build(BlendMode.CUTOUT_MIPPED)
}.toTypedArray() }.toTypedArray()
} }
val coralCrustModels by LazyInvalidatable(BetterFoliage.modelReplacer) { val coralCrustModels by LazyInvalidatable(BetterFoliage.modelReplacer) {
@@ -88,7 +103,7 @@ class SandModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
.rotate(Rotation.fromUp[face]) .rotate(Rotation.fromUp[face])
.mirrorUV(randomB(), randomB()).rotateUV(randomI(max = 4)) .mirrorUV(randomB(), randomB()).rotateUV(randomI(max = 4))
.sprite(coralCrustSprites[idx]).colorAndIndex(null) .sprite(coralCrustSprites[idx]).colorAndIndex(null)
).build(CUTOUT_MIPPED) ).build(BlendMode.CUTOUT_MIPPED)
} }
}.toTypedArray() }.toTypedArray()
} }

View File

@@ -2,13 +2,25 @@ package mods.betterfoliage.render.column
import mods.betterfoliage.BetterFoliage import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.* import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.INVISIBLE
import mods.betterfoliage.resource.model.* import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.LARGE_RADIUS
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.SMALL_RADIUS
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.SQUARE
import mods.betterfoliage.model.Color
import mods.betterfoliage.model.Quad
import mods.betterfoliage.model.UV
import mods.betterfoliage.model.Vertex
import mods.betterfoliage.model.build
import mods.betterfoliage.model.horizontalRectangle
import mods.betterfoliage.model.verticalRectangle
import mods.betterfoliage.util.Double3 import mods.betterfoliage.util.Double3
import mods.betterfoliage.util.Rotation import mods.betterfoliage.util.Rotation
import net.minecraft.block.BlockRenderLayer.SOLID import net.fabricmc.fabric.api.renderer.v1.material.BlendMode.SOLID
import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.Sprite
import net.minecraft.util.math.Direction.* import net.minecraft.util.math.Direction.Axis
import net.minecraft.util.math.Direction.EAST
import net.minecraft.util.math.Direction.SOUTH
import net.minecraft.util.math.Direction.UP
/** /**
* Collection of dynamically generated meshes used to render rounded columns. * Collection of dynamically generated meshes used to render rounded columns.

View File

@@ -5,13 +5,13 @@ import mods.betterfoliage.chunk.ChunkOverlayManager
import mods.betterfoliage.render.column.ColumnLayerData.NormalRender import mods.betterfoliage.render.column.ColumnLayerData.NormalRender
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.* import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.*
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.* import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.*
import mods.betterfoliage.resource.model.WrappedBakedModel import mods.betterfoliage.model.WrappedBakedModel
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction.Axis import net.minecraft.util.math.Direction.Axis
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.*
import java.util.function.Supplier import java.util.function.Supplier
@@ -21,7 +21,7 @@ abstract class ColumnModelBase(wrapped: BakedModel) : WrappedBakedModel(wrapped)
abstract val connectPerpendicular: Boolean abstract val connectPerpendicular: Boolean
abstract fun getMeshSet(axis: Axis, quadrant: Int): ColumnMeshSet abstract fun getMeshSet(axis: Axis, quadrant: Int): ColumnMeshSet
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) { override fun emitBlockQuads(blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
val ctx = CachedBlockCtx(blockView, pos) val ctx = CachedBlockCtx(blockView, pos)
val roundLog = ChunkOverlayManager.get(overlayLayer, ctx) val roundLog = ChunkOverlayManager.get(overlayLayer, ctx)

View File

@@ -1,20 +1,30 @@
package mods.betterfoliage.render.column package mods.betterfoliage.render.column
import mods.betterfoliage.BetterFoliage import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.chunk.BlockCtx
import mods.betterfoliage.chunk.ChunkOverlayLayer import mods.betterfoliage.chunk.ChunkOverlayLayer
import mods.betterfoliage.chunk.ChunkOverlayManager import mods.betterfoliage.chunk.ChunkOverlayManager
import mods.betterfoliage.chunk.dimType import mods.betterfoliage.chunk.dimType
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.*
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.*
import mods.betterfoliage.chunk.BlockCtx
import mods.betterfoliage.render.block.vanilla.RoundLogKey import mods.betterfoliage.render.block.vanilla.RoundLogKey
import mods.betterfoliage.util.* import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.NONSOLID
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.PARALLEL
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.PERPENDICULAR
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.SOLID
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.INVISIBLE
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.LARGE_RADIUS
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.SMALL_RADIUS
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.SQUARE
import mods.betterfoliage.util.Int3
import mods.betterfoliage.util.Rotation
import mods.betterfoliage.util.allDirections
import mods.betterfoliage.util.face
import mods.betterfoliage.util.plus
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction.Axis import net.minecraft.util.math.Direction.Axis
import net.minecraft.util.math.Direction.AxisDirection import net.minecraft.util.math.Direction.AxisDirection
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.WorldView
/** Index of SOUTH-EAST quadrant. */ /** Index of SOUTH-EAST quadrant. */
const val SE = 0 const val SE = 0
@@ -74,7 +84,7 @@ abstract class ColumnRenderLayer : ChunkOverlayLayer<ColumnLayerData> {
val allNeighborOffsets = (-1..1).flatMap { offsetX -> (-1..1).flatMap { offsetY -> (-1..1).map { offsetZ -> Int3(offsetX, offsetY, offsetZ) }}} val allNeighborOffsets = (-1..1).flatMap { offsetX -> (-1..1).flatMap { offsetY -> (-1..1).map { offsetZ -> Int3(offsetX, offsetY, offsetZ) }}}
override fun onBlockUpdate(world: ExtendedBlockView, pos: BlockPos) { override fun onBlockUpdate(world: WorldView, pos: BlockPos) {
allNeighborOffsets.forEach { offset -> ChunkOverlayManager.clear(world.dimType, this, pos + offset) } allNeighborOffsets.forEach { offset -> ChunkOverlayManager.clear(world.dimType, this, pos + offset) }
} }

View File

@@ -1,43 +1,53 @@
package mods.betterfoliage.render.lighting package mods.betterfoliage.render.lighting
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction import mods.betterfoliage.util.YarnHelper
import mods.betterfoliage.util.get
import mods.betterfoliage.util.reflectField import mods.betterfoliage.util.reflectField
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.fabricmc.fabric.impl.client.indigo.renderer.accessor.AccessBufferBuilder
import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator
import net.fabricmc.fabric.impl.client.indigo.renderer.render.* import net.fabricmc.fabric.impl.client.indigo.renderer.render.*
import net.minecraft.block.BlockRenderLayer
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.VertexConsumer
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.world.ExtendedBlockView import net.minecraft.world.BlockRenderView
import java.util.* import java.util.*
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
val AbstractQuadRenderer_blockInfo2 = YarnHelper.requiredField<TerrainBlockRenderInfo>(
"net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractQuadRenderer",
"blockInfo", "Lnet/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainBlockRenderInfo;"
)
val AbstractQuadRenderer_bufferFunc2 = YarnHelper.requiredField<java.util.function.Function<RenderLayer, VertexConsumer>>(
"net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractQuadRenderer",
"bufferFunc", "Ljava/util/function/Function;"
)
val AbstractQuadRenderer_aoCalc = YarnHelper.requiredField<AoCalculator>(
"net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractQuadRenderer",
"aoCalc", "Lnet/fabricmc/fabric/impl/client/indigo/renderer/aocalc/AoCalculator;"
)
val AbstractQuadRenderer_transform = YarnHelper.requiredField<RenderContext.QuadTransform>(
"net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractQuadRenderer",
"transform", "Lnet/fabricmc/fabric/api/renderer/v1/render/RenderContext\$QuadTransform;"
)
val MODIFIED_CONSUMER_POOL = ThreadLocal<ModifiedTerrainMeshConsumer>() val MODIFIED_CONSUMER_POOL = ThreadLocal<ModifiedTerrainMeshConsumer>()
fun TerrainMeshConsumer.modified() = MODIFIED_CONSUMER_POOL.get() ?: let { fun AbstractMeshConsumer.modified() = MODIFIED_CONSUMER_POOL.get() ?: let {
val blockInfo = reflectField<TerrainBlockRenderInfo>("blockInfo") ModifiedTerrainMeshConsumer(this)
val chunkInfo = reflectField<ChunkRenderInfo>("chunkInfo")
val aoCalc = reflectField<AoCalculator>("aoCalc")
val transform = reflectField<RenderContext.QuadTransform>("transform")
ModifiedTerrainMeshConsumer(blockInfo, chunkInfo, aoCalc, transform)
}.apply { MODIFIED_CONSUMER_POOL.set(this) } }.apply { MODIFIED_CONSUMER_POOL.set(this) }
val TerrainRenderContext_blockInfo = TerrainRenderContext::class.java.declaredFields.find { it.name == "blockInfo" }?.apply { isAccessible = true }
val BlockRenderInfo_layerIndexOrDefault = BlockRenderInfo::class.java.declaredMethods.find { it.name == "layerIndexOrDefault" }?.apply { isAccessible = true }
val AbstractQuadRenderer_bufferFunc = AbstractQuadRenderer::class.java.declaredFields.find { it.name == "bufferFunc" }?.apply { isAccessible = true }
/** /**
* Render the given model at the given position. * Render the given model at the given position.
* Mutates the state of the [RenderContext]!! * Mutates the state of the [RenderContext]!!
*/ */
fun RenderContext.renderMasquerade(model: BakedModel, blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) = when(this) { fun RenderContext.renderMasquerade(model: BakedModel, blockView: BlockRenderView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) = when(this) {
is TerrainRenderContext -> { is TerrainRenderContext -> {
val blockInfo = TerrainRenderContext_blockInfo!!.get(this) as BlockRenderInfo val blockInfo = meshConsumer()[AbstractQuadRenderer_blockInfo2]!!
blockInfo.prepareForBlock(state, pos, model.useAmbientOcclusion()) blockInfo.prepareForBlock(state, pos, model.useAmbientOcclusion())
(model as FabricBakedModel).emitBlockQuads(blockView, state, pos, randomSupplier, context) (model as FabricBakedModel).emitBlockQuads(blockView, state, pos, randomSupplier, context)
} }
@@ -49,7 +59,7 @@ fun RenderContext.renderMasquerade(model: BakedModel, blockView: ExtendedBlockVi
/** Execute the provided block with a mesh consumer using the given custom lighting. */ /** Execute the provided block with a mesh consumer using the given custom lighting. */
fun RenderContext.withLighting(lighter: CustomLighting, func: (Consumer<Mesh>)->Unit) = when(this) { fun RenderContext.withLighting(lighter: CustomLighting, func: (Consumer<Mesh>)->Unit) = when(this) {
is TerrainRenderContext -> { is TerrainRenderContext -> {
val consumer = (meshConsumer() as TerrainMeshConsumer).modified() val consumer = (meshConsumer() as AbstractMeshConsumer).modified()
consumer.clearLighting() consumer.clearLighting()
consumer.lighter = lighter consumer.lighter = lighter
func(consumer) func(consumer)
@@ -59,12 +69,10 @@ fun RenderContext.withLighting(lighter: CustomLighting, func: (Consumer<Mesh>)->
} }
/** Get the [BufferBuilder] responsible for a given [BlockRenderLayer] */ /** Get the [BufferBuilder] responsible for a given [BlockRenderLayer] */
fun RenderContext.getBufferBuilder(layer: BlockRenderLayer) = when(this) { fun RenderContext.getBufferBuilder(layer: RenderLayer) = when(this) {
is TerrainRenderContext -> { is TerrainRenderContext -> {
val blockInfo = TerrainRenderContext_blockInfo!!.get(this) as BlockRenderInfo val bufferFunc = meshConsumer()[AbstractQuadRenderer_bufferFunc2]!!
val layerIdx = BlockRenderInfo_layerIndexOrDefault!!.invoke(blockInfo, layer) as Int bufferFunc.apply(layer)
val bufferFunc = AbstractQuadRenderer_bufferFunc!!.get(meshConsumer()) as Int2ObjectFunction<AccessBufferBuilder>
bufferFunc[layerIdx]
} }
else -> null else -> null
} }

View File

@@ -29,19 +29,20 @@ class FallingLeafParticle(
} }
var rotationSpeed = randomF(min = PI2 / 80.0, max = PI2 / 50.0) var rotationSpeed = randomF(min = PI2 / 80.0, max = PI2 / 50.0)
var rotPositive = true
val isMirrored = randomB() val isMirrored = randomB()
var wasCollided = false var wasCollided = false
init { init {
angle = randomF(max = PI2) angle = randomF(max = PI2)
prevAngle = angle - rotationSpeed
maxAge = MathHelper.floor(randomD(0.6, 1.0) * BetterFoliage.config.fallingLeaves.lifetime * 20.0) maxAge = MathHelper.floor(randomD(0.6, 1.0) * BetterFoliage.config.fallingLeaves.lifetime * 20.0)
velocityY = -BetterFoliage.config.fallingLeaves.speed velocityY = -BetterFoliage.config.fallingLeaves.speed
scale = BetterFoliage.config.fallingLeaves.size.toFloat() * 0.1f scale = BetterFoliage.config.fallingLeaves.size.toFloat() * 0.1f
val state = world.getBlockState(pos) val state = world.getBlockState(pos)
val blockColor = MinecraftClient.getInstance().blockColorMap.getColorMultiplier(state, world, pos, 0) val blockColor = MinecraftClient.getInstance().blockColorMap.getColor(state, world, pos, 0)
sprite = LeafParticleRegistry[leafKey.leafType][randomI(max = 1024)] sprite = LeafParticleRegistry[leafKey.leafType][randomI(max = 1024)]
setParticleColor(leafKey.overrideColor, blockColor) setParticleColor(leafKey.overrideColor, blockColor)
} }
@@ -49,11 +50,12 @@ class FallingLeafParticle(
override val isValid: Boolean get() = (sprite != null) override val isValid: Boolean get() = (sprite != null)
override fun update() { override fun update() {
if (randomF() > 0.95f) rotPositive = !rotPositive if (randomF() > 0.95f) rotationSpeed = -rotationSpeed
if (age > maxAge - 20) colorAlpha = 0.05f * (maxAge - age) if (age > maxAge - 20) colorAlpha = 0.05f * (maxAge - age)
if (onGround || wasCollided) { if (onGround || wasCollided) {
velocity.setTo(0.0, 0.0, 0.0) velocity.setTo(0.0, 0.0, 0.0)
prevAngle = angle
if (!wasCollided) { if (!wasCollided) {
age = age.coerceAtLeast(maxAge - 20) age = age.coerceAtLeast(maxAge - 20)
wasCollided = true wasCollided = true
@@ -62,14 +64,15 @@ class FallingLeafParticle(
val cosRotation = cos(angle).toDouble(); val sinRotation = sin(angle).toDouble() val cosRotation = cos(angle).toDouble(); val sinRotation = sin(angle).toDouble()
velocity.setTo(cosRotation, 0.0, sinRotation).mul(BetterFoliage.config.fallingLeaves.perturb) velocity.setTo(cosRotation, 0.0, sinRotation).mul(BetterFoliage.config.fallingLeaves.perturb)
.add(LeafWindTracker.current).add(0.0, -1.0, 0.0).mul(BetterFoliage.config.fallingLeaves.speed) .add(LeafWindTracker.current).add(0.0, -1.0, 0.0).mul(BetterFoliage.config.fallingLeaves.speed)
angle += if (rotPositive) rotationSpeed else -rotationSpeed prevAngle = angle
angle += rotationSpeed
} }
} }
override fun render(worldRenderer: BufferBuilder, partialTickTime: Float) { // override fun render(worldRenderer: BufferBuilder, partialTickTime: Float) {
val tickAngle = angle + partialTickTime * (if (rotPositive) rotationSpeed else -rotationSpeed) // val tickAngle = angle + partialTickTime * (if (rotPositive) rotationSpeed else -rotationSpeed)
renderParticleQuad(worldRenderer, partialTickTime, rotation = tickAngle.toDouble(), isMirrored = isMirrored) // renderParticleQuad(worldRenderer, partialTickTime, rotation = tickAngle.toDouble(), isMirrored = isMirrored)
} // }
fun setParticleColor(overrideColor: Int?, blockColor: Int) { fun setParticleColor(overrideColor: Int?, blockColor: Int) {
val color = overrideColor ?: blockColor val color = overrideColor ?: blockColor

View File

@@ -1,8 +1,8 @@
package mods.betterfoliage.render.particle package mods.betterfoliage.render.particle
import mods.betterfoliage.BetterFoliage import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.resource.model.FixedSpriteSet import mods.betterfoliage.model.FixedSpriteSet
import mods.betterfoliage.resource.model.SpriteSet import mods.betterfoliage.model.SpriteSet
import mods.betterfoliage.util.* import mods.betterfoliage.util.*
import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback
import net.minecraft.client.texture.SpriteAtlasTexture import net.minecraft.client.texture.SpriteAtlasTexture
@@ -19,7 +19,7 @@ object LeafParticleRegistry : ClientSpriteRegistryCallback {
spriteSets.clear() spriteSets.clear()
typeMappings.loadMappings(Identifier(BetterFoliage.MOD_ID, "leaf_texture_mappings.cfg")) typeMappings.loadMappings(Identifier(BetterFoliage.MOD_ID, "leaf_texture_mappings.cfg"))
(typeMappings.mappings.map { it.type } + "default").distinct().forEach { leafType -> (typeMappings.mappings.map { it.type } + "default").distinct().forEach { leafType ->
val validIds = (0 until 16).map { idx -> Identifier(BetterFoliage.MOD_ID, "falling_leaf_${leafType}_$idx") } val validIds = (0 until 16).map { idx -> Identifier(BetterFoliage.MOD_ID, "particle/falling_leaf_${leafType}_$idx") }
.filter { resourceManager.containsResource(Atlas.PARTICLES.wrap(it)) } .filter { resourceManager.containsResource(Atlas.PARTICLES.wrap(it)) }
ids[leafType] = validIds ids[leafType] = validIds
validIds.forEach { registry.register(it) } validIds.forEach { registry.register(it) }

View File

@@ -2,11 +2,12 @@ package mods.betterfoliage.render.particle
import mods.betterfoliage.BetterFoliage import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.render.AbstractParticle import mods.betterfoliage.render.AbstractParticle
import mods.betterfoliage.resource.model.SpriteDelegate import mods.betterfoliage.model.SpriteDelegate
import mods.betterfoliage.resource.model.SpriteSetDelegate import mods.betterfoliage.model.SpriteSetDelegate
import mods.betterfoliage.util.* import mods.betterfoliage.util.*
import net.minecraft.client.particle.ParticleTextureSheet import net.minecraft.client.particle.ParticleTextureSheet
import net.minecraft.client.render.BufferBuilder import net.minecraft.client.render.Camera
import net.minecraft.client.render.VertexConsumer
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.MathHelper import net.minecraft.util.math.MathHelper
@@ -34,8 +35,9 @@ class RisingSoulParticle(
override val isValid: Boolean get() = true override val isValid: Boolean get() = true
override fun update() { override fun update() {
val phase = initialPhase + (age.toDouble() * PI2 / 64.0 ) val phase = initialPhase + (age.toDouble() * PI2 / 64.0)
val cosPhase = cos(phase); val sinPhase = sin(phase) val cosPhase = cos(phase);
val sinPhase = sin(phase)
velocity.setTo(BetterFoliage.config.risingSoul.perturb.let { Double3(cosPhase * it, 0.1, sinPhase * it) }) velocity.setTo(BetterFoliage.config.risingSoul.perturb.let { Double3(cosPhase * it, 0.1, sinPhase * it) })
particleTrail.addFirst(currentPos.copy()) particleTrail.addFirst(currentPos.copy())
@@ -44,11 +46,12 @@ class RisingSoulParticle(
if (!BetterFoliage.config.enabled) markDead() if (!BetterFoliage.config.enabled) markDead()
} }
override fun render(worldRenderer: BufferBuilder, partialTickTime: Float) { override fun buildGeometry(vertexConsumer: VertexConsumer, camera: Camera, tickDelta: Float) {
var alpha = BetterFoliage.config.risingSoul.opacity.toFloat() var alpha = BetterFoliage.config.risingSoul.opacity.toFloat()
if (age > maxAge - 40) alpha *= (maxAge - age) / 40.0f if (age > maxAge - 40) alpha *= (maxAge - age) / 40.0f
renderParticleQuad(worldRenderer, partialTickTime, renderParticleQuad(
vertexConsumer, camera, tickDelta,
size = BetterFoliage.config.risingSoul.headSize * 0.25, size = BetterFoliage.config.risingSoul.headSize * 0.25,
alpha = alpha alpha = alpha
) )
@@ -57,7 +60,9 @@ class RisingSoulParticle(
particleTrail.forEachPairIndexed { idx, current, previous -> particleTrail.forEachPairIndexed { idx, current, previous ->
scale *= BetterFoliage.config.risingSoul.sizeDecay scale *= BetterFoliage.config.risingSoul.sizeDecay
alpha *= BetterFoliage.config.risingSoul.opacityDecay.toFloat() alpha *= BetterFoliage.config.risingSoul.opacityDecay.toFloat()
if (idx % BetterFoliage.config.risingSoul.trailDensity == 0) renderParticleQuad(worldRenderer, partialTickTime, if (idx % BetterFoliage.config.risingSoul.trailDensity == 0)
renderParticleQuad(
vertexConsumer, camera, tickDelta,
currentPos = current, currentPos = current,
prevPos = previous, prevPos = previous,
size = scale, size = scale,
@@ -70,7 +75,9 @@ class RisingSoulParticle(
override fun getType() = ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT override fun getType() = ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT
companion object { companion object {
val headIcons by SpriteSetDelegate(Atlas.PARTICLES) { idx -> Identifier(BetterFoliage.MOD_ID, "rising_soul_$idx") } val headIcons by SpriteSetDelegate(Atlas.PARTICLES) { idx ->
val trackIcon by SpriteDelegate(Atlas.PARTICLES) { Identifier(BetterFoliage.MOD_ID, "soul_track") } Identifier(BetterFoliage.MOD_ID, "particle/rising_soul_$idx")
}
val trackIcon by SpriteDelegate(Atlas.PARTICLES) { Identifier(BetterFoliage.MOD_ID, "particle/soul_track") }
} }
} }

View File

@@ -7,6 +7,7 @@ import mods.betterfoliage.util.stripStart
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.client.render.model.ModelLoader import net.minecraft.client.render.model.ModelLoader
import net.minecraft.client.render.model.json.JsonUnbakedModel import net.minecraft.client.render.model.json.JsonUnbakedModel
import net.minecraft.client.texture.MissingSprite
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import org.apache.logging.log4j.Level import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Level.DEBUG import org.apache.logging.log4j.Level.DEBUG
@@ -39,7 +40,7 @@ abstract class ConfigurableModelDiscovery : ModelDiscoveryBase() {
return super.discover(loader, atlas) return super.discover(loader, atlas)
} }
abstract fun processModel(state: BlockState, textures: List<String>, atlas: Consumer<Identifier>): BlockRenderKey? abstract fun processModel(state: BlockState, textures: List<Identifier>, atlas: Consumer<Identifier>): BlockRenderKey?
override fun processModel(ctx: ModelDiscoveryContext, atlas: Consumer<Identifier>): BlockRenderKey? { override fun processModel(ctx: ModelDiscoveryContext, atlas: Consumer<Identifier>): BlockRenderKey? {
val matchClass = matchClasses.matchingClass(ctx.state.block) ?: return null val matchClass = matchClasses.matchingClass(ctx.state.block) ?: return null
@@ -51,11 +52,11 @@ abstract class ConfigurableModelDiscovery : ModelDiscoveryBase() {
if (modelMatch != null) { if (modelMatch != null) {
log(DEBUG, " model ${model} matches ${modelMatch.modelLocation}") log(DEBUG, " model ${model} matches ${modelMatch.modelLocation}")
val textures = modelMatch.textureNames.map { it to model.resolveTexture(it) } val textures = modelMatch.textureNames.map { it to model.resolveSprite(it).textureId }
val texMapString = Joiner.on(", ").join(textures.map { "${it.first}=${it.second}" }) val texMapString = Joiner.on(", ").join(textures.map { "${it.first}=${it.second}" })
log(DEBUG, " sprites [$texMapString]") log(DEBUG, " sprites [$texMapString]")
if (textures.all { it.second != "missingno" }) { if (textures.all { it.second != MissingSprite.getMissingSpriteId() }) {
// found a valid model (all required textures exist) // found a valid model (all required textures exist)
return processModel(ctx.state, textures.map { it.second }, atlas).also { return processModel(ctx.state, textures.map { it.second }, atlas).also {
log(DEBUG, " valid model discovered: $it") log(DEBUG, " valid model discovered: $it")

View File

@@ -15,15 +15,13 @@ import net.minecraft.util.Identifier
import net.minecraft.util.registry.Registry import net.minecraft.util.registry.Registry
import java.util.function.Consumer import java.util.function.Consumer
typealias RenderKeyFactory = (SpriteAtlasTexture)->BlockRenderKey
interface BlockRenderKey { interface BlockRenderKey {
fun replace(model: BakedModel, state: BlockState): BakedModel = model fun replace(model: BakedModel, state: BlockState): BakedModel = model
} }
fun ModelLoader.iterateModels(func: (ModelDiscoveryContext)->Unit) { fun ModelLoader.iterateModels(func: (ModelDiscoveryContext)->Unit) {
Registry.BLOCK.flatMap { block -> Registry.BLOCK.flatMap { block ->
block.stateFactory.states.map { state -> state to BlockModels.getModelId(state) } block.stateManager.states.map { state -> state to BlockModels.getModelId(state) }
}.forEach { (state, stateModelResource) -> }.forEach { (state, stateModelResource) ->
func(ModelDiscoveryContext(this, state, stateModelResource)) func(ModelDiscoveryContext(this, state, stateModelResource))
} }

View File

@@ -3,9 +3,8 @@ package mods.betterfoliage.resource.generated
import mods.betterfoliage.util.Atlas import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.HasLogger import mods.betterfoliage.util.HasLogger
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener
import net.minecraft.client.resource.ClientResourcePackContainer import net.minecraft.client.resource.ClientResourcePackProfile
import net.minecraft.resource.* import net.minecraft.resource.*
import net.minecraft.resource.ResourcePackContainer.InsertionPosition
import net.minecraft.resource.ResourceType.CLIENT_RESOURCES import net.minecraft.resource.ResourceType.CLIENT_RESOURCES
import net.minecraft.resource.metadata.ResourceMetadataReader import net.minecraft.resource.metadata.ResourceMetadataReader
import net.minecraft.text.LiteralText import net.minecraft.text.LiteralText
@@ -30,13 +29,14 @@ import java.util.function.Supplier
* @param[packDesc] Description of pack * @param[packDesc] Description of pack
* @param[logger] Logger to log to when generating resources * @param[logger] Logger to log to when generating resources
*/ */
class GeneratedBlockTexturePack(val reloadId: Identifier, val nameSpace: String, val packName: String, val packDesc: String, override val logger: Logger) : HasLogger, ResourcePack, IdentifiableResourceReloadListener { class GeneratedBlockTexturePack(val reloadId: Identifier, val nameSpace: String, val packName: String, val packDesc: String, override val logger: Logger) : HasLogger, ResourcePack {
override fun getName() = reloadId.toString() override fun getName() = reloadId.toString()
override fun getNamespaces(type: ResourceType) = setOf(nameSpace) override fun getNamespaces(type: ResourceType) = setOf(nameSpace)
override fun <T : Any?> parseMetadata(deserializer: ResourceMetadataReader<T>) = null override fun <T : Any?> parseMetadata(deserializer: ResourceMetadataReader<T>) = null
override fun openRoot(id: String) = null override fun openRoot(id: String) = null
override fun findResources(type: ResourceType, path: String, maxDepth: Int, filter: Predicate<String>) = emptyList<Identifier>() override fun findResources(type: ResourceType, path: String, prefix: String, maxDepth: Int, filter: Predicate<String>) = emptyList<Identifier>()
override fun close() {} override fun close() {}
protected var manager: ResourceManager? = null protected var manager: ResourceManager? = null
@@ -64,29 +64,35 @@ class GeneratedBlockTexturePack(val reloadId: Identifier, val nameSpace: String,
override fun contains(type: ResourceType, id: Identifier) = override fun contains(type: ResourceType, id: Identifier) =
type == CLIENT_RESOURCES && resources.containsKey(id) type == CLIENT_RESOURCES && resources.containsKey(id)
/**
* Supplier for this resource pack. Adds pack as always-on and hidden.
*/
val finder = object : ResourcePackProvider {
val packInfo = ClientResourcePackProfile(
packName, true, Supplier { this@GeneratedBlockTexturePack },
LiteralText(packName),
LiteralText(packDesc),
ResourcePackCompatibility.COMPATIBLE, ResourcePackProfile.InsertionPosition.TOP, true, null
)
override fun <T : ResourcePackProfile> register(
registry: MutableMap<String, T>,
factory: ResourcePackProfile.Factory<T>
) {
(registry as MutableMap<String, ResourcePackProfile>)[reloadId.toString()] = packInfo
}
}
val reloader = object : IdentifiableResourceReloadListener {
override fun getFabricId() = reloadId
override fun reload(synchronizer: ResourceReloadListener.Synchronizer, manager: ResourceManager, prepareProfiler: Profiler, applyProfiler: Profiler, prepareExecutor: Executor, applyExecutor: Executor): CompletableFuture<Void> { override fun reload(synchronizer: ResourceReloadListener.Synchronizer, manager: ResourceManager, prepareProfiler: Profiler, applyProfiler: Profiler, prepareExecutor: Executor, applyExecutor: Executor): CompletableFuture<Void> {
this.manager = manager this@GeneratedBlockTexturePack.manager = manager
return synchronizer.whenPrepared(null).thenRun { return synchronizer.whenPrepared(null).thenRun {
this.manager = null this@GeneratedBlockTexturePack.manager = null
identifiers.clear() identifiers.clear()
resources.clear() resources.clear()
} }
} }
override fun getFabricId() = reloadId
/**
* Supplier for this resource pack. Adds pack as always-on and hidden.
*/
val finder = object : ResourcePackCreator {
val packInfo = ClientResourcePackContainer(
packName, true, Supplier { this@GeneratedBlockTexturePack },
LiteralText(packName),
LiteralText(packDesc),
ResourcePackCompatibility.COMPATIBLE, InsertionPosition.TOP, true, null
)
override fun <T : ResourcePackContainer> registerContainer(nameToPackMap: MutableMap<String, T>, packInfoFactory: ResourcePackContainer.Factory<T>) {
(nameToPackMap as MutableMap<String, ResourcePackContainer>)[reloadId.toString()] = packInfo
}
} }
} }

View File

@@ -7,6 +7,7 @@ import net.minecraft.util.math.Direction.Axis.*
import net.minecraft.util.math.Direction.AxisDirection import net.minecraft.util.math.Direction.AxisDirection
import net.minecraft.util.math.Direction.AxisDirection.* import net.minecraft.util.math.Direction.AxisDirection.*
import net.minecraft.util.math.Direction.* import net.minecraft.util.math.Direction.*
import net.minecraft.util.math.Quaternion
// ================================ // ================================
// Axes and directions // Axes and directions
@@ -52,6 +53,7 @@ data class Double3(var x: Double, var y: Double, var z: Double) {
val zero: Double3 get() = Double3(0.0, 0.0, 0.0) val zero: Double3 get() = Double3(0.0, 0.0, 0.0)
fun weight(v1: Double3, weight1: Double, v2: Double3, weight2: Double) = fun weight(v1: Double3, weight1: Double, v2: Double3, weight2: Double) =
Double3(v1.x * weight1 + v2.x * weight2, v1.y * weight1 + v2.y * weight2, v1.z * weight1 + v2.z * weight2) Double3(v1.x * weight1 + v2.x * weight2, v1.y * weight1 + v2.y * weight2, v1.z * weight1 + v2.z * weight2)
fun lerp(delta: Double, first: Double3, second: Double3) = first + (second - first) * delta
} }
// immutable operations // immutable operations
@@ -68,6 +70,13 @@ data class Double3(var x: Double, var y: Double, var z: Double) {
rot.rotatedComponent(SOUTH, x, y, z) rot.rotatedComponent(SOUTH, x, y, z)
) )
/** Rotate vector by the given [Quaternion] */
fun rotate(quat: Quaternion) =
quat.copy()
.apply { hamiltonProduct(Quaternion(x.toFloat(), y.toFloat(), z.toFloat(), 0.0F)) }
.apply { hamiltonProduct(quat.copy().apply(Quaternion::conjugate)) }
.let { Double3(it.b, it.c, it.d) }
// mutable operations // mutable operations
fun setTo(other: Double3): Double3 { x = other.x; y = other.y; z = other.z; return this } fun setTo(other: Double3): Double3 { x = other.x; y = other.y; z = other.z; return this }
fun setTo(x: Double, y: Double, z: Double): Double3 { this.x = x; this.y = y; this.z = z; return this } fun setTo(x: Double, y: Double, z: Double): Double3 { this.x = x; this.y = y; this.z = z; return this }

View File

@@ -1,6 +1,6 @@
package mods.betterfoliage.util package mods.betterfoliage.util
import mods.betterfoliage.resource.model.HSB import mods.betterfoliage.model.HSB
import net.minecraft.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.Sprite
import net.minecraft.client.texture.SpriteAtlasTexture import net.minecraft.client.texture.SpriteAtlasTexture
@@ -15,7 +15,7 @@ import kotlin.math.atan2
enum class Atlas(val basePath: String, val resourceId: Identifier) { enum class Atlas(val basePath: String, val resourceId: Identifier) {
BLOCKS("textures", SpriteAtlasTexture.BLOCK_ATLAS_TEX), BLOCKS("textures", SpriteAtlasTexture.BLOCK_ATLAS_TEX),
PARTICLES("textures/particle", SpriteAtlasTexture.PARTICLE_ATLAS_TEX); PARTICLES("textures", SpriteAtlasTexture.PARTICLE_ATLAS_TEX);
/** Get the fully-qualified resource name for sprites belonging to this atlas*/ /** Get the fully-qualified resource name for sprites belonging to this atlas*/
fun wrap(resource: Identifier) = Identifier(resource.namespace, "$basePath/${resource.path}.png") fun wrap(resource: Identifier) = Identifier(resource.namespace, "$basePath/${resource.path}.png")

View File

@@ -1,11 +1,19 @@
package net.fabricmc.fabric.impl.client.indigo.renderer.render package net.fabricmc.fabric.impl.client.indigo.renderer.render
import mods.betterfoliage.render.lighting.CustomLightingMeshConsumer import mods.betterfoliage.render.lighting.AbstractQuadRenderer_aoCalc
import mods.betterfoliage.render.lighting.AbstractQuadRenderer_blockInfo2
import mods.betterfoliage.render.lighting.AbstractQuadRenderer_bufferFunc2
import mods.betterfoliage.render.lighting.AbstractQuadRenderer_transform
import mods.betterfoliage.render.lighting.CustomLighting import mods.betterfoliage.render.lighting.CustomLighting
import mods.betterfoliage.util.* import mods.betterfoliage.render.lighting.CustomLightingMeshConsumer
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import mods.betterfoliage.util.YarnHelper
import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator import mods.betterfoliage.util.cornerDirFromAo
import mods.betterfoliage.util.get
import mods.betterfoliage.util.offset
import mods.betterfoliage.util.plus
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.WorldRenderer
import net.minecraft.util.math.Direction import net.minecraft.util.math.Direction
val AoCalculator_computeFace = YarnHelper.requiredMethod<Any>( val AoCalculator_computeFace = YarnHelper.requiredMethod<Any>(
@@ -18,11 +26,16 @@ val AoFaceData_toArray = YarnHelper.requiredMethod<Unit>(
) )
open class ModifiedTerrainMeshConsumer( open class ModifiedTerrainMeshConsumer(
blockInfo: TerrainBlockRenderInfo, val original: AbstractMeshConsumer
chunkInfo: ChunkRenderInfo, ) : AbstractMeshConsumer(
aoCalc: AoCalculator, original[AbstractQuadRenderer_blockInfo2],
transform: RenderContext.QuadTransform original[AbstractQuadRenderer_bufferFunc2],
) : TerrainMeshConsumer(blockInfo, chunkInfo, aoCalc, transform), CustomLightingMeshConsumer { original[AbstractQuadRenderer_aoCalc],
original[AbstractQuadRenderer_transform]
), CustomLightingMeshConsumer {
override fun matrix() = original.matrix()
override fun normalMatrix() = original.normalMatrix()
override fun overlay() = original.overlay()
/** Custom lighting to use */ /** Custom lighting to use */
var lighter: CustomLighting? = null var lighter: CustomLighting? = null
@@ -34,21 +47,23 @@ open class ModifiedTerrainMeshConsumer(
/** Cached block brightness values for all neighbors */ /** Cached block brightness values for all neighbors */
val brNeighbor = IntArray(6) val brNeighbor = IntArray(6)
/** Cache validity for block brightness values (neighbors + self) */ /** Cache validity for block brightness values (neighbors + self) */
val brValid = Array(7) { false } val brValid = Array(7) { false }
override var brSelf: Int = -1 override var brSelf: Int = -1
get() { if (brValid[6]) return field else get() {
field = blockInfo.blockView.getBlockState(blockInfo.blockPos).getBlockBrightness(blockInfo.blockView, blockInfo.blockPos) if (brValid[6]) return field else {
field = WorldRenderer.getLightmapCoordinates(blockInfo.blockView, blockInfo.blockPos)
brValid[6] = true brValid[6] = true
return field return field
} }
}
protected set protected set
override fun brNeighbor(dir: Direction): Int { override fun brNeighbor(dir: Direction): Int {
if (brValid[dir.ordinal]) return brNeighbor[dir.ordinal] if (brValid[dir.ordinal]) return brNeighbor[dir.ordinal]
blockInfo.blockView.getBlockState(blockInfo.blockPos) WorldRenderer.getLightmapCoordinates(blockInfo.blockView, blockInfo.blockPos + dir.offset)
.getBlockBrightness(blockInfo.blockView, blockInfo.blockPos + dir.offset)
.let { brNeighbor[dir.ordinal] = it; brValid[dir.ordinal] = true; return it } .let { brNeighbor[dir.ordinal] = it; brValid[dir.ordinal] = true; return it }
} }
@@ -62,7 +77,12 @@ open class ModifiedTerrainMeshConsumer(
override fun fillAoData(lightFace: Direction) { override fun fillAoData(lightFace: Direction) {
if (!aoValid[lightFace.ordinal]) { if (!aoValid[lightFace.ordinal]) {
AoFaceData_toArray.invoke(AoCalculator_computeFace.invoke(aoCalc, lightFace, true), aoFull, lightFull, cornerDirFromAo[lightFace.ordinal]) AoFaceData_toArray.invoke(
AoCalculator_computeFace.invoke(aoCalc, lightFace, true),
aoFull,
lightFull,
cornerDirFromAo[lightFace.ordinal]
)
aoValid[lightFace.ordinal] = true aoValid[lightFace.ordinal] = true
} }
} }
@@ -72,32 +92,23 @@ open class ModifiedTerrainMeshConsumer(
aoCalc.light[vIdx] = light aoCalc.light[vIdx] = light
} }
override fun applyOffsets(quad: MutableQuadViewImpl) { override fun tesselateFlat(q: MutableQuadViewImpl, renderLayer: RenderLayer, blockColorIndex: Int) {
// Moved farther back in the pipeline, after custom lighting is applied
// Might possibly mess emissive multitexturing up, but seems to be OK for now
}
override fun tesselateFlat(q: MutableQuadViewImpl, renderLayer: Int, blockColorIndex: Int) {
lighter?.applyLighting(this, q, flat = true, emissive = false) lighter?.applyLighting(this, q, flat = true, emissive = false)
super.applyOffsets(q)
super.tesselateSmooth(q, renderLayer, blockColorIndex) super.tesselateSmooth(q, renderLayer, blockColorIndex)
} }
override fun tesselateFlatEmissive(q: MutableQuadViewImpl, renderLayer: Int, blockColorIndex: Int, lightmaps: IntArray) { override fun tesselateFlatEmissive(q: MutableQuadViewImpl, renderLayer: RenderLayer, blockColorIndex: Int) {
lighter?.applyLighting(this, q, flat = true, emissive = true) lighter?.applyLighting(this, q, flat = true, emissive = true)
super.applyOffsets(q)
super.tesselateSmoothEmissive(q, renderLayer, blockColorIndex) super.tesselateSmoothEmissive(q, renderLayer, blockColorIndex)
} }
override fun tesselateSmooth(q: MutableQuadViewImpl, renderLayer: Int, blockColorIndex: Int) { override fun tesselateSmooth(q: MutableQuadViewImpl, renderLayer: RenderLayer, blockColorIndex: Int) {
lighter?.applyLighting(this, q, flat = false, emissive = false) lighter?.applyLighting(this, q, flat = false, emissive = false)
super.applyOffsets(q)
super.tesselateSmooth(q, renderLayer, blockColorIndex) super.tesselateSmooth(q, renderLayer, blockColorIndex)
} }
override fun tesselateSmoothEmissive(q: MutableQuadViewImpl, renderLayer: Int, blockColorIndex: Int) { override fun tesselateSmoothEmissive(q: MutableQuadViewImpl, renderLayer: RenderLayer, blockColorIndex: Int) {
lighter?.applyLighting(this, q, flat = false, emissive = true) lighter?.applyLighting(this, q, flat = false, emissive = true)
super.applyOffsets(q)
super.tesselateSmoothEmissive(q, renderLayer, blockColorIndex) super.tesselateSmoothEmissive(q, renderLayer, blockColorIndex)
} }
} }

View File

@@ -39,9 +39,9 @@
], ],
"depends": { "depends": {
"fabricloader": ">=0.7.3", "fabricloader": ">=0.11.3",
"fabric": "*", "fabric": "*",
"fabric-language-kotlin": "*", "fabric-language-kotlin": "*",
"minecraft": "1.14.4" "minecraft": "1.15.2"
} }
} }