diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/BlockModel.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/BlockModel.java.patch index 772aaf1f9c..2e1d224909 100644 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/BlockModel.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/block/model/BlockModel.java.patch @@ -17,17 +17,22 @@ this.parent = p_377823_.resolve(this.parentLocation); } } -@@ -110,6 +_,9 @@ +@@ -110,14 +_,20 @@ public BakedModel bake( TextureSlots p_378598_, ModelBaker p_378458_, ModelState p_111453_, boolean p_111455_, boolean p_377435_, ItemTransforms p_378085_ ) { + if (this.customData.getCustomGeometry() != null) + return this.customData.getCustomGeometry().bake(customData, p_378458_, p_378598_, p_111453_); ++ ++ var wrapped = net.minecraftforge.client.ForgeHooksClient.wrapRenderType(p_378458_, this.customData.getRenderType()); + return this.elements.isEmpty() && this.parent != null - ? this.parent.bake(p_378598_, p_378458_, p_111453_, p_111455_, p_377435_, p_378085_) - : SimpleBakedModel.bakeElements(this.elements, p_378598_, p_378458_.sprites(), p_111453_, p_111455_, p_377435_, true, p_378085_); -@@ -118,6 +_,7 @@ +- ? this.parent.bake(p_378598_, p_378458_, p_111453_, p_111455_, p_377435_, p_378085_) +- : SimpleBakedModel.bakeElements(this.elements, p_378598_, p_378458_.sprites(), p_111453_, p_111455_, p_377435_, true, p_378085_); ++ ? this.parent.bake(p_378598_, wrapped, p_111453_, p_111455_, p_377435_, p_378085_) ++ : SimpleBakedModel.bakeElements(this.elements, p_378598_, p_378458_.sprites(), p_111453_, p_111455_, p_377435_, true, p_378085_, wrapped.renderType()); + } + @Nullable @VisibleForTesting List getElements() { diff --git a/patches/minecraft/net/minecraft/client/resources/model/ModelBaker.java.patch b/patches/minecraft/net/minecraft/client/resources/model/ModelBaker.java.patch new file mode 100644 index 0000000000..f1acbd833c --- /dev/null +++ b/patches/minecraft/net/minecraft/client/resources/model/ModelBaker.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/client/resources/model/ModelBaker.java ++++ b/net/minecraft/client/resources/model/ModelBaker.java +@@ -13,4 +_,10 @@ + + @VisibleForDebug + ModelDebugName rootName(); ++ ++ /** Forge: Return the render type to use when baking this model, its a dirty hack to pass down this value to parents */ ++ @org.jetbrains.annotations.Nullable ++ default net.minecraftforge.client.RenderTypeGroup renderType() { ++ return null; ++ } + } diff --git a/patches/minecraft/net/minecraft/client/resources/model/SimpleBakedModel.java.patch b/patches/minecraft/net/minecraft/client/resources/model/SimpleBakedModel.java.patch index 82cd20b248..16097bb78a 100644 --- a/patches/minecraft/net/minecraft/client/resources/model/SimpleBakedModel.java.patch +++ b/patches/minecraft/net/minecraft/client/resources/model/SimpleBakedModel.java.patch @@ -1,55 +1,79 @@ --- a/net/minecraft/client/resources/model/SimpleBakedModel.java +++ b/net/minecraft/client/resources/model/SimpleBakedModel.java -@@ -29,6 +_,19 @@ +@@ -29,6 +_,17 @@ private final boolean usesBlockLight; private final TextureAtlasSprite particleIcon; private final ItemTransforms transforms; -+ /* + protected final net.minecraftforge.client.ChunkRenderTypeSet blockRenderTypes; ++ /* + protected final List itemRenderTypes; + protected final List fabulousItemRenderTypes; + */ + -+ /* @deprecated Forge: Use {@linkplain #SimpleBakedModel(List, Map, boolean, boolean, boolean, TextureAtlasSprite, ItemTransforms, net.minecraftforge.client.RenderTypeGroup) variant with RenderTypeGroup} **/ -+ /* ++ /** @deprecated Forge: Use {@linkplain #SimpleBakedModel(List, Map, boolean, boolean, boolean, TextureAtlasSprite, ItemTransforms, net.minecraftforge.client.RenderTypeGroup) variant with RenderTypeGroup} **/ + @Deprecated + public SimpleBakedModel(List p_119489_, Map> p_119490_, boolean p_119491_, boolean p_119492_, boolean p_119493_, TextureAtlasSprite p_119494_, ItemTransforms p_119495_) { + this(p_119489_, p_119490_, p_119491_, p_119492_, p_119493_, p_119494_, p_119495_, net.minecraftforge.client.RenderTypeGroup.EMPTY); + } -+ */ public SimpleBakedModel( List p_119489_, -@@ -38,6 +_,7 @@ +@@ -37,7 +_,8 @@ + boolean p_119492_, boolean p_119493_, TextureAtlasSprite p_119494_, - ItemTransforms p_119495_ -+ //net.minecraftforge.client.RenderTypeGroup renderTypes +- ItemTransforms p_119495_ ++ ItemTransforms p_119495_, ++ net.minecraftforge.client.RenderTypeGroup renderTypes ) { this.unculledFaces = p_119489_; this.culledFaces = p_119490_; -@@ -46,6 +_,11 @@ +@@ -46,6 +_,15 @@ this.usesBlockLight = p_119492_; this.particleIcon = p_119494_; this.transforms = p_119495_; -+ /* + this.blockRenderTypes = !renderTypes.isEmpty() ? net.minecraftforge.client.ChunkRenderTypeSet.of(renderTypes.block()) : null; ++ /* + this.itemRenderTypes = !renderTypes.isEmpty() ? List.of(renderTypes.entity()) : null; + this.fabulousItemRenderTypes = !renderTypes.isEmpty() ? List.of(renderTypes.entityFabulous()) : null; + */ ++ } ++ ++ public static BakedModel bakeElements(List p_377425_, TextureSlots p_378525_, SpriteGetter p_375793_, ModelState p_376680_, boolean p_375745_, boolean p_376866_, boolean p_376846_, ItemTransforms p_376883_) { ++ return bakeElements(p_377425_, p_378525_, p_375793_, p_376680_, p_375745_, p_376866_, p_376846_, p_376883_, null); } public static BakedModel bakeElements( +@@ -56,7 +_,8 @@ + boolean p_375745_, + boolean p_376866_, + boolean p_376846_, +- ItemTransforms p_376883_ ++ ItemTransforms p_376883_, ++ @Nullable net.minecraftforge.client.RenderTypeGroup renderType + ) { + TextureAtlasSprite textureatlassprite = findSprite(p_375793_, p_378525_, "particle"); + SimpleBakedModel.Builder simplebakedmodel$builder = new SimpleBakedModel.Builder(p_375745_, p_376866_, p_376846_, p_376883_) +@@ -77,6 +_,9 @@ + } + } + ++ if (renderType != null) ++ simplebakedmodel$builder.renderTypes(renderType); ++ + return simplebakedmodel$builder.build(); + } + @@ -123,6 +_,27 @@ return this.transforms; } -+ /* + @Override + public net.minecraftforge.client.ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, net.minecraftforge.client.model.data.ModelData data) { + return blockRenderTypes != null ? blockRenderTypes : BakedModel.super.getRenderTypes(state, rand, data); + } + ++ /* + @Override + public List getRenderTypes(net.minecraft.world.item.ItemStack itemStack, boolean fabulous) { + if (!fabulous) { @@ -68,17 +92,15 @@ @OnlyIn(Dist.CLIENT) public static class Builder { private final ImmutableList.Builder unculledFaces = ImmutableList.builder(); -@@ -164,13 +_,21 @@ +@@ -164,13 +_,19 @@ return this; } -+ /* + private net.minecraftforge.client.RenderTypeGroup renderTypes = net.minecraftforge.client.RenderTypeGroup.EMPTY; + public SimpleBakedModel.Builder renderTypes(net.minecraftforge.client.RenderTypeGroup renderTypes) { + this.renderTypes = renderTypes; + return this; + } -+ */ + public BakedModel build() { if (this.particleIcon == null) { @@ -87,7 +109,7 @@ Map> map = Maps.transformValues(this.culledFaces, ImmutableList.Builder::build); return new SimpleBakedModel( - this.unculledFaces.build(), new EnumMap<>(map), this.hasAmbientOcclusion, this.usesBlockLight, this.isGui3d, this.particleIcon, this.transforms -+ this.unculledFaces.build(), new EnumMap<>(map), this.hasAmbientOcclusion, this.usesBlockLight, this.isGui3d, this.particleIcon, this.transforms/*, this.renderTypes*/ ++ this.unculledFaces.build(), new EnumMap<>(map), this.hasAmbientOcclusion, this.usesBlockLight, this.isGui3d, this.particleIcon, this.transforms, this.renderTypes ); } } diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index fe6cd6c582..e52852a2a3 100644 --- a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -14,20 +14,14 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.shaders.FogShape; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.SheetedDecalTextureGenerator; import com.mojang.datafixers.util.Either; -import com.mojang.math.Constants; import com.mojang.math.Transformation; import net.minecraft.ChatFormatting; import net.minecraft.FileUtil; -import net.minecraft.Util; import net.minecraft.client.Camera; -import net.minecraft.client.ClientRecipeBook; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; import net.minecraft.client.color.block.BlockColors; @@ -35,7 +29,6 @@ import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.ChatComponent; import net.minecraft.client.gui.components.LerpingBossEvent; -import net.minecraft.client.gui.components.toasts.Toast; import net.minecraft.client.gui.screens.ConfirmScreen; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.TitleScreen; @@ -54,7 +47,6 @@ import net.minecraft.client.particle.ParticleRenderType; import net.minecraft.client.player.ClientInput; import net.minecraft.client.renderer.FogParameters; import net.minecraft.client.renderer.FogRenderer; -import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; @@ -63,7 +55,6 @@ import net.minecraft.client.renderer.ShaderProgram; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BlockElement; import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.client.renderer.entity.state.HumanoidRenderState; import net.minecraft.client.renderer.texture.SpriteContents; import net.minecraft.client.renderer.texture.TextureAtlas; @@ -71,14 +62,15 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.metadata.animation.FrameSize; import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.Material; +import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelBakery; +import net.minecraft.client.resources.model.ModelDebugName; import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.SpriteGetter; import net.minecraft.client.resources.sounds.SoundInstance; import net.minecraft.client.sounds.SoundEngine; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.locale.Language; import net.minecraft.network.Connection; import net.minecraft.network.chat.ChatType; @@ -100,10 +92,8 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.RecipeManager; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.GameType; import net.minecraft.world.level.block.Blocks; @@ -113,20 +103,17 @@ import net.minecraft.world.level.material.FogType; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.HitResult; -import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.ClientChatEvent; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.client.event.ClientPauseChangeEvent; import net.minecraftforge.client.event.ClientPlayerChangeGameTypeEvent; import net.minecraftforge.client.event.SystemMessageReceivedEvent; -import net.minecraftforge.client.event.ComputeFovModifierEvent; import net.minecraftforge.client.event.CustomizeGuiOverlayEvent; import net.minecraftforge.client.event.EntityRenderersEvent; import net.minecraftforge.client.event.ForgeEventFactoryClient; import net.minecraftforge.client.event.InputEvent; import net.minecraftforge.client.event.ModelEvent; import net.minecraftforge.client.event.MovementInputUpdateEvent; -import net.minecraftforge.client.event.RecipesUpdatedEvent; import net.minecraftforge.client.event.RegisterClientReloadListenersEvent; import net.minecraftforge.client.event.RegisterColorHandlersEvent; import net.minecraftforge.client.event.RegisterKeyMappingsEvent; @@ -137,7 +124,6 @@ import net.minecraftforge.client.event.RenderHighlightEvent; import net.minecraftforge.client.event.RenderTooltipEvent; import net.minecraftforge.client.event.ScreenEvent; import net.minecraftforge.client.event.TextureStitchEvent; -import net.minecraftforge.client.event.ToastAddEvent; import net.minecraftforge.client.event.ViewportEvent; import net.minecraftforge.client.event.sound.PlaySoundEvent; import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions; @@ -150,16 +136,13 @@ import net.minecraftforge.client.model.geometry.GeometryLoaderManager; import net.minecraftforge.client.model.geometry.IUnbakedGeometry; import net.minecraftforge.client.textures.ForgeTextureMetadata; import net.minecraftforge.client.textures.TextureAtlasSpriteLoaderManager; -import net.minecraftforge.common.ForgeConfig; import net.minecraftforge.common.ForgeI18n; import net.minecraftforge.common.ForgeMod; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.IExtensionPoint; import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModLoader; import net.minecraftforge.fml.VersionChecker; -import net.minecraftforge.fml.common.Mod; import net.minecraftforge.gametest.ForgeGameTestHooks; import net.minecraftforge.network.NetworkContext; import net.minecraftforge.network.NetworkInitialization; @@ -174,13 +157,11 @@ import org.apache.logging.log4j.MarkerManager; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.joml.Matrix4f; import org.joml.Vector3f; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -188,7 +169,6 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.Stack; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; @@ -934,4 +914,34 @@ public class ForgeHooksClient { return model; } + + /** This is a dirty fucking hack, but it needs to send in the top most render type. */ + public static ModelBaker wrapRenderType(ModelBaker parent, RenderTypeGroup group) { + if (group == null || group == RenderTypeGroup.EMPTY || parent.renderType() != null) + return parent; + return new WrapedModelBaker(parent, group); + } + + // a record for performance reasons + private record WrapedModelBaker(ModelBaker parent, RenderTypeGroup group) implements ModelBaker { + @Override + public RenderTypeGroup renderType() { + return group; + } + + @Override + public BakedModel bake(ResourceLocation name, ModelState state) { + return parent.bake(name, state); + } + + @Override + public SpriteGetter sprites() { + return parent.sprites(); + } + + @Override + public ModelDebugName rootName() { + return parent.rootName(); + } + } } diff --git a/src/main/java/net/minecraftforge/client/model/CompositeModel.java b/src/main/java/net/minecraftforge/client/model/CompositeModel.java index 4d8ec110cd..39fa470c0e 100644 --- a/src/main/java/net/minecraftforge/client/model/CompositeModel.java +++ b/src/main/java/net/minecraftforge/client/model/CompositeModel.java @@ -213,7 +213,7 @@ public class CompositeModel implements IUnbakedGeometry { } private void addLayer(RenderTypeGroup renderTypes, List quads) { - var modelBuilder = IModelBuilder.of(isAmbientOcclusion, isSideLit, isGui3d, transforms, particle/*, renderTypes*/); + var modelBuilder = IModelBuilder.of(isAmbientOcclusion, isSideLit, isGui3d, transforms, particle, renderTypes); quads.forEach(modelBuilder::addUnculledFace); children.add(modelBuilder.build()); } diff --git a/src/main/java/net/minecraftforge/client/model/IModelBuilder.java b/src/main/java/net/minecraftforge/client/model/IModelBuilder.java index 7911d0d0da..443569117e 100644 --- a/src/main/java/net/minecraftforge/client/model/IModelBuilder.java +++ b/src/main/java/net/minecraftforge/client/model/IModelBuilder.java @@ -11,6 +11,8 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.SimpleBakedModel; import net.minecraft.core.Direction; +import net.minecraftforge.client.RenderTypeGroup; + import java.util.List; /** @@ -30,7 +32,18 @@ public interface IModelBuilder> { ItemTransforms transforms, TextureAtlasSprite particle ){ - return new Simple(hasAmbientOcclusion, usesBlockLight, isGui3d, transforms, particle); + return of(hasAmbientOcclusion, usesBlockLight, isGui3d, transforms, particle, RenderTypeGroup.EMPTY); + } + + static IModelBuilder of( + boolean hasAmbientOcclusion, + boolean usesBlockLight, + boolean isGui3d, + ItemTransforms transforms, + TextureAtlasSprite particle, + RenderTypeGroup renderTypes + ){ + return new Simple(hasAmbientOcclusion, usesBlockLight, isGui3d, transforms, particle, renderTypes); } /** @@ -52,9 +65,10 @@ public interface IModelBuilder> { private Simple( boolean hasAmbientOcclusion, boolean usesBlockLight, boolean isGui3d, - ItemTransforms transforms, TextureAtlasSprite particle + ItemTransforms transforms, TextureAtlasSprite particle, RenderTypeGroup renderTypes ) { this.builder = new SimpleBakedModel.Builder(hasAmbientOcclusion, usesBlockLight, isGui3d, transforms).particle(particle); + this.builder.renderTypes(renderTypes); } @Override @@ -69,7 +83,6 @@ public interface IModelBuilder> { return this; } - @Deprecated @Override public BakedModel build() { return builder.build(); diff --git a/src/main/java/net/minecraftforge/client/model/SimpleModelState.java b/src/main/java/net/minecraftforge/client/model/SimpleModelState.java index 24f55fb074..e22f7cbc09 100644 --- a/src/main/java/net/minecraftforge/client/model/SimpleModelState.java +++ b/src/main/java/net/minecraftforge/client/model/SimpleModelState.java @@ -11,31 +11,8 @@ import net.minecraft.client.resources.model.ModelState; /** * Simple implementation of {@link ModelState}. */ -public final class SimpleModelState implements ModelState -{ - private final Transformation transformation; - private final boolean uvLocked; - - public SimpleModelState(Transformation transformation, boolean uvLocked) - { - this.transformation = transformation; - this.uvLocked = uvLocked; - } - - public SimpleModelState(Transformation transformation) - { +public record SimpleModelState(Transformation getRotation, boolean isUvLocked) implements ModelState { + public SimpleModelState(Transformation transformation) { this(transformation, false); } - - @Override - public Transformation getRotation() - { - return transformation; - } - - @Override - public boolean isUvLocked() - { - return uvLocked; - } } diff --git a/src/main/java/net/minecraftforge/client/model/geometry/IGeometryBakingContext.java b/src/main/java/net/minecraftforge/client/model/geometry/IGeometryBakingContext.java index 70193a2ed6..fd9b73cdfc 100644 --- a/src/main/java/net/minecraftforge/client/model/geometry/IGeometryBakingContext.java +++ b/src/main/java/net/minecraftforge/client/model/geometry/IGeometryBakingContext.java @@ -68,4 +68,12 @@ public interface IGeometryBakingContext { default RenderTypeGroup getRenderType(ResourceLocation name) { return NamedRenderTypeManager.get(name); } + + /** + * {@return a {@link RenderTypeGroup} from the {@link #getRenderTypeHint()}, or the empty group if not found.} + */ + default RenderTypeGroup getRenderType() { + var hint = getRenderTypeHint(); + return hint == null ? RenderTypeGroup.EMPTY : getRenderType(hint); + } } diff --git a/src/main/java/net/minecraftforge/client/model/geometry/SimpleUnbakedGeometry.java b/src/main/java/net/minecraftforge/client/model/geometry/SimpleUnbakedGeometry.java index cbcf5aab4b..590a9bacef 100644 --- a/src/main/java/net/minecraftforge/client/model/geometry/SimpleUnbakedGeometry.java +++ b/src/main/java/net/minecraftforge/client/model/geometry/SimpleUnbakedGeometry.java @@ -10,6 +10,7 @@ import net.minecraft.client.renderer.block.model.TextureSlots; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; +import net.minecraftforge.client.RenderTypeGroup; import net.minecraftforge.client.model.IModelBuilder; /** @@ -21,10 +22,8 @@ public abstract class SimpleUnbakedGeometry> public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, TextureSlots textures, ModelState modelState) { var particle = baker.sprites().maybeMissing(textures, "particle"); - //var renderTypeHint = context.getRenderTypeHint(); - //var renderTypes = renderTypeHint != null ? context.getRenderType(renderTypeHint) : RenderTypeGroup.EMPTY; IModelBuilder builder = IModelBuilder.of(context.useAmbientOcclusion(), context.useBlockLight(), context.isGui3d(), - context.getTransforms(), particle/*, renderTypes*/); + context.getTransforms(), particle, context.getRenderType()); addQuads(context, builder, baker, textures, modelState); diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index ac10472ac7..c0763e1d1d 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -301,6 +301,7 @@ protected net.minecraft.client.data.models.BlockModelGenerators$BlockFamilyProvi protected net.minecraft.client.data.models.BlockModelGenerators$BlockFamilyProvider m_373633_(Lnet/minecraft/data/BlockFamily$Variant;Lnet/minecraft/world/level/block/Block;)V # lambda$generateFor$1 protected net.minecraft.client.data.models.BlockModelGenerators$BlockFamilyProvider m_373732_(Lnet/minecraft/world/level/block/Block;)Lnet/minecraft/client/data/models/BlockModelGenerators$BlockFamilyProvider; # fullBlockVariant #endgroup +public net.minecraft.client.data.models.BlockModelGenerators$PlantType public net.minecraft.client.data.models.BlockModelGenerators$WoodProvider #group protected net.minecraft.client.data.models.ItemModelGenerators *() protected net.minecraft.client.data.models.ItemModelGenerators m_372103_(Lnet/minecraft/world/item/Item;I)V # generateDyedItem diff --git a/src/test/generated/model_render_type/assets/model_render_type/blockstates/cutout_block.json b/src/test/generated/model_render_type/assets/model_render_type/blockstates/cutout_block.json new file mode 100644 index 0000000000..c7ff378f4d --- /dev/null +++ b/src/test/generated/model_render_type/assets/model_render_type/blockstates/cutout_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "model_render_type:block/cutout_block" + } + } +} \ No newline at end of file diff --git a/src/test/generated/model_render_type/assets/model_render_type/items/cutout_block.json b/src/test/generated/model_render_type/assets/model_render_type/items/cutout_block.json new file mode 100644 index 0000000000..85cc44c55d --- /dev/null +++ b/src/test/generated/model_render_type/assets/model_render_type/items/cutout_block.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "model_render_type:item/cutout_block" + } +} \ No newline at end of file diff --git a/src/test/generated/model_render_type/assets/model_render_type/models/block/cutout_block.json b/src/test/generated/model_render_type/assets/model_render_type/models/block/cutout_block.json new file mode 100644 index 0000000000..595d5110f6 --- /dev/null +++ b/src/test/generated/model_render_type/assets/model_render_type/models/block/cutout_block.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cross", + "render_type": "minecraft:cutout", + "textures": { + "cross": "minecraft:block/acacia_sapling" + } +} \ No newline at end of file diff --git a/src/test/generated/model_render_type/assets/model_render_type/models/item/cutout_block.json b/src/test/generated/model_render_type/assets/model_render_type/models/item/cutout_block.json new file mode 100644 index 0000000000..89e557914e --- /dev/null +++ b/src/test/generated/model_render_type/assets/model_render_type/models/item/cutout_block.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "minecraft:block/acacia_sapling" + } +} \ No newline at end of file diff --git a/src/test/java/net/minecraftforge/debug/client/AdditionalModelTest.java b/src/test/java/net/minecraftforge/debug/client/AdditionalModelTest.java index 2cd91e2f41..0b921a94fe 100644 --- a/src/test/java/net/minecraftforge/debug/client/AdditionalModelTest.java +++ b/src/test/java/net/minecraftforge/debug/client/AdditionalModelTest.java @@ -128,7 +128,7 @@ public class AdditionalModelTest extends BaseTestMod { var key = new ModelResourceLocation(rl("cow_head"), ""); var model = manager.getModel(key); - if (model == null) + if (model == null || model == manager.getMissingModel()) helper.fail("Failed to retreive " + key + " block model"); helper.succeed(); @@ -196,7 +196,7 @@ public class AdditionalModelTest extends BaseTestMod { } protected Stream getKnownBlocks() { - return Stream.of(PIG_HEAD.get(), COW_HEAD.get()); + return Stream.of(COW_HEAD.get()); // We don't include PIG_HEAD because it doesn't need a blockstate file } protected Stream getKnownItems() { diff --git a/src/test/java/net/minecraftforge/debug/client/ModelRenderLayerTest.java b/src/test/java/net/minecraftforge/debug/client/ModelRenderLayerTest.java new file mode 100644 index 0000000000..d5a82fcbb5 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/client/ModelRenderLayerTest.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.debug.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.data.models.BlockModelGenerators; +import net.minecraft.client.data.models.ItemModelGenerators; +import net.minecraft.client.data.models.model.ItemModelUtils; +import net.minecraft.client.data.models.model.ModelLocationUtils; +import net.minecraft.client.data.models.model.ModelTemplates; +import net.minecraft.client.data.models.model.TextureMapping; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.CachedOutput; +import net.minecraft.data.DataProvider; +import net.minecraft.data.PackOutput; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SaplingBlock; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.grower.TreeGrower; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.MapColor; +import net.minecraft.world.level.material.PushReaction; +import net.minecraftforge.client.model.data.ModelData; +import net.minecraftforge.data.event.GatherDataEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.gametest.GameTestHolder; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; +import net.minecraftforge.test.BaseTestMod; + +import java.nio.file.Path; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import com.google.gson.JsonElement; + +@Mod(ModelRenderLayerTest.MODID) +@GameTestHolder("forge." + ModelRenderLayerTest.MODID) +public class ModelRenderLayerTest extends BaseTestMod { + public static final String MODID = "model_render_type"; + private static final String BLOCK_NAME = "cutout_block"; + + private static final DeferredRegister BLOCKS = DeferredRegister.create(Registries.BLOCK, MODID); + public static final RegistryObject BLOCK = BLOCKS.register(BLOCK_NAME, + () -> new SaplingBlock( + TreeGrower.ACACIA, + BlockBehaviour.Properties.of() + .setId(BLOCKS.key(BLOCK_NAME)) + .mapColor(MapColor.PLANT) + .noCollission() + .randomTicks() + .instabreak() + .sound(SoundType.GRASS) + .pushReaction(PushReaction.DESTROY) + ) + ); + + private static final DeferredRegister ITEMS = DeferredRegister.create(Registries.ITEM, MODID); + public static final RegistryObject ITEM = ITEMS.register(BLOCK_NAME, () -> new BlockItem(BLOCK.get(), new Item.Properties().setId(ITEMS.key(BLOCK_NAME)))); + + private static ResourceLocation rl(String path) { + return ResourceLocation.fromNamespaceAndPath(MODID, path); + } + + public ModelRenderLayerTest(FMLJavaModLoadingContext context) { + super(context); + testItem(lookup -> new ItemStack(ITEM.get())); + } + + @SubscribeEvent + public void runData(GatherDataEvent event) { + var out = event.getGenerator().getPackOutput(); + event.getGenerator().addProvider(event.includeClient(), new ModelProvider(out)); + } + + @SuppressWarnings("resource") + @GameTest(template = "forge:empty3x3x3") + public static void type_from_model(GameTestHelper helper) { + var manager = Minecraft.getInstance().getModelManager(); + + var key = new ModelResourceLocation(rl(BLOCK_NAME), "stage=0"); + var model = manager.getModel(key); + + if (model == manager.getMissingModel()) + helper.fail("Failed to retreive " + key + " block model"); + + var state = BLOCK.get().defaultBlockState(); + var random = helper.getLevel().random; + var layer = model.getRenderTypes(state, random, ModelData.EMPTY); + if (!layer.contains(RenderType.cutout())) + helper.fail("Block model does not have cutout layer"); + + helper.succeed(); + } + + public class ModelProvider extends net.minecraft.client.data.models.ModelProvider { + public ModelProvider(PackOutput output) { + super(output); + } + + protected Stream getKnownBlocks() { + return Stream.of(BLOCK.get()); + } + + protected Stream getKnownItems() { + return Stream.of(ITEM.get()); + } + + protected BlockModelGenerators getBlockModelGenerators(BlockStateGeneratorCollector blocks, ItemInfoCollector items, SimpleModelCollector models) { + return new BlockModelGenerators(blocks, items, models) { + @Override + public void run() { + var textures = PlantType.NOT_TINTED.getTextureMapping(Blocks.ACACIA_SAPLING); + var cutout = PlantType.NOT_TINTED.getCross().create(BLOCK.get(), textures, (name, model) -> { + var json = model.get().getAsJsonObject(); + json.addProperty("render_type", "minecraft:cutout"); + this.modelOutput.accept(name, () -> json); + }); + this.blockStateOutput.accept(createSimpleBlock(BLOCK.get(), cutout)); + + var item = ModelTemplates.FLAT_ITEM.create(ITEM.get(), TextureMapping.layer0(Blocks.ACACIA_SAPLING), this.modelOutput); + this.itemModelOutput.accept(ITEM.get(), ItemModelUtils.plainModel(item)); + } + }; + } + + protected ItemModelGenerators getItemModelGenerators(ItemInfoCollector items, SimpleModelCollector models) { + return new ItemModelGenerators(items, models) { + public void run() { + } + }; + } + + static CompletableFuture saveAll(CachedOutput p_378816_, Function p_377914_, Map> p_377836_) { + return DataProvider.saveAll(p_378816_, Supplier::get, p_377914_, p_377836_); + } + } +}