From b8add23d9bc1c225ca0e25a3e3419e6ed89b1879 Mon Sep 17 00:00:00 2001 From: RainWarrior Date: Wed, 4 Feb 2015 09:45:23 +0300 Subject: [PATCH] ModelBakeEvent now has ModelLoader as an argument instead of ModelBakery; Added various static hooks to ModelLoader to allow registering model-related information before it's needed (prevents file-not-found errors on first baking pass); ModelLoader waits until ModelBakeEvent is done before showing any missing model exceptions; It's now possible to define models completely in-code (as illustrated by ModelBakeEventDebug). --- .../renderer/BlockModelShapes.java.patch | 10 +++ .../renderer/entity/RenderItem.java.patch | 9 +- .../resources/model/ModelBakery.java.patch | 14 ++- .../client/ForgeHooksClient.java | 5 +- .../client/event/ModelBakeEvent.java | 10 +-- .../client/model/ModelLoader.java | 90 +++++++++++++++++-- .../debug/ModelBakeEventDebug.java | 51 +++++------ .../debug/ModelLoaderRegistryDebug.java | 13 ++- .../blockstates/custom_model_block.json | 4 - .../models/item/custom_model_block.json | 3 - 10 files changed, 144 insertions(+), 65 deletions(-) create mode 100644 patches/minecraft/net/minecraft/client/renderer/BlockModelShapes.java.patch delete mode 100644 src/test/resources/assets/forgedebugmodelbakeevent/blockstates/custom_model_block.json delete mode 100644 src/test/resources/assets/forgedebugmodelbakeevent/models/item/custom_model_block.json diff --git a/patches/minecraft/net/minecraft/client/renderer/BlockModelShapes.java.patch b/patches/minecraft/net/minecraft/client/renderer/BlockModelShapes.java.patch new file mode 100644 index 0000000000..ae731a3e87 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/renderer/BlockModelShapes.java.patch @@ -0,0 +1,10 @@ +--- ../src-base/minecraft/net/minecraft/client/renderer/BlockModelShapes.java ++++ ../src-work/minecraft/net/minecraft/client/renderer/BlockModelShapes.java +@@ -321,6 +321,7 @@ + return new ModelResourceLocation(s + "_double_slab", s1); + } + }); ++ net.minecraftforge.client.model.ModelLoader.onRegisterAllBlocks(this); + } + + @SideOnly(Side.CLIENT) diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/RenderItem.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/RenderItem.java.patch index 48162e109d..498fc5d5ec 100644 --- a/patches/minecraft/net/minecraft/client/renderer/entity/RenderItem.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/entity/RenderItem.java.patch @@ -81,7 +81,14 @@ GlStateManager.func_179141_d(); GlStateManager.func_179098_w(); GlStateManager.func_179145_e(); -@@ -1078,6 +1072,19 @@ +@@ -1072,12 +1066,26 @@ + this.func_175029_a(Blocks.field_150420_aW, BlockHugeMushroom.EnumType.ALL_INSIDE.func_176896_a(), "brown_mushroom_block"); + this.func_175029_a(Blocks.field_150419_aX, BlockHugeMushroom.EnumType.ALL_INSIDE.func_176896_a(), "red_mushroom_block"); + this.func_175031_a(Blocks.field_150380_bt, "dragon_egg"); ++ net.minecraftforge.client.model.ModelLoader.onRegisterItems(this.field_175059_m); + } + + public void func_110549_a(IResourceManager p_110549_1_) { this.field_175059_m.func_178085_b(); } diff --git a/patches/minecraft/net/minecraft/client/resources/model/ModelBakery.java.patch b/patches/minecraft/net/minecraft/client/resources/model/ModelBakery.java.patch index 0c6385f13d..83642656d8 100644 --- a/patches/minecraft/net/minecraft/client/resources/model/ModelBakery.java.patch +++ b/patches/minecraft/net/minecraft/client/resources/model/ModelBakery.java.patch @@ -9,7 +9,15 @@ } } catch (Exception exception1) -@@ -499,6 +499,11 @@ +@@ -172,6 +172,7 @@ + } + } + } ++ catch (FileNotFoundException e) {} + catch (IOException ioexception) + { + throw new RuntimeException("Encountered an exception when loading model definition of model " + resourcelocation1.toString(), ioexception); +@@ -499,6 +500,11 @@ private IBakedModel func_177578_a(ModelBlock p_177578_1_, ModelRotation p_177578_2_, boolean p_177578_3_) { @@ -21,7 +29,7 @@ TextureAtlasSprite textureatlassprite = (TextureAtlasSprite)this.field_177599_g.get(new ResourceLocation(p_177578_1_.func_178308_c("particle"))); SimpleBakedModel.Builder builder = (new SimpleBakedModel.Builder(p_177578_1_)).func_177646_a(textureatlassprite); Iterator iterator = p_177578_1_.func_178298_a().iterator(); -@@ -516,11 +521,11 @@ +@@ -516,11 +522,11 @@ if (blockpartface.field_178244_b == null) { @@ -35,7 +43,7 @@ } } } -@@ -530,9 +535,14 @@ +@@ -530,9 +536,14 @@ private BakedQuad func_177589_a(BlockPart p_177589_1_, BlockPartFace p_177589_2_, TextureAtlasSprite p_177589_3_, EnumFacing p_177589_4_, ModelRotation p_177589_5_, boolean p_177589_6_) { diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index f93959cb73..2407f52212 100644 --- a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -59,6 +59,7 @@ import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.client.event.sound.PlaySoundEvent; import net.minecraftforge.client.model.IPerspectiveAwareModel; +import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.ForgeModContainer; import net.minecraftforge.common.ForgeVersion; import net.minecraftforge.common.ForgeVersion.Status; @@ -487,7 +488,9 @@ public class ForgeHooksClient public static void onModelBake(ModelManager modelManager, IRegistry modelRegistry, ModelBakery modelBakery) { - MinecraftForge.EVENT_BUS.post(new ModelBakeEvent(modelManager, modelRegistry, modelBakery)); + ModelLoader loader = (ModelLoader)modelBakery; + MinecraftForge.EVENT_BUS.post(new ModelBakeEvent(modelManager, modelRegistry, loader)); + loader.onPostBakeEvent(modelRegistry); } public static Matrix4f getMatrix(ItemTransformVec3f transform) diff --git a/src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java b/src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java index 502454f071..3c124d80f7 100644 --- a/src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java @@ -1,9 +1,9 @@ package net.minecraftforge.client.event; -import net.minecraftforge.fml.common.eventhandler.Event; -import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelManager; import net.minecraft.util.IRegistry; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.common.eventhandler.Event; /** * Fired when the ModelManager is notified of the resource manager reloading. @@ -13,12 +13,12 @@ public class ModelBakeEvent extends Event { public final ModelManager modelManager; public final IRegistry modelRegistry; - public final ModelBakery modelBakery; + public final ModelLoader modelLoader; - public ModelBakeEvent(ModelManager modelManager, IRegistry modelRegistry, ModelBakery modelBakery) + public ModelBakeEvent(ModelManager modelManager, IRegistry modelRegistry, ModelLoader modelLoader) { this.modelManager = modelManager; this.modelRegistry = modelRegistry; - this.modelBakery = modelBakery; + this.modelLoader = modelLoader; } } diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoader.java b/src/main/java/net/minecraftforge/client/model/ModelLoader.java index 894299557d..91ea08db90 100644 --- a/src/main/java/net/minecraftforge/client/model/ModelLoader.java +++ b/src/main/java/net/minecraftforge/client/model/ModelLoader.java @@ -11,8 +11,11 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.BlockModelShapes; +import net.minecraft.client.renderer.ItemMeshDefinition; +import net.minecraft.client.renderer.ItemModelMesher; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.block.model.ItemModelGenerator; import net.minecraft.client.renderer.block.model.ModelBlock; @@ -20,6 +23,7 @@ import net.minecraft.client.renderer.block.model.ModelBlockDefinition; import net.minecraft.client.renderer.block.model.ModelBlockDefinition.MissingVariantException; import net.minecraft.client.renderer.block.model.ModelBlockDefinition.Variant; import net.minecraft.client.renderer.block.model.ModelBlockDefinition.Variants; +import net.minecraft.client.renderer.block.statemap.IStateMapper; import net.minecraft.client.renderer.texture.IIconCreator; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; @@ -35,7 +39,9 @@ import net.minecraft.util.IRegistry; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.registry.GameData; +import net.minecraftforge.fml.common.registry.RegistryDelegate; +import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.Level; import com.google.common.base.Function; @@ -44,6 +50,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; public class ModelLoader extends ModelBakery { @@ -51,6 +59,13 @@ public class ModelLoader extends ModelBakery private final Set resolveTextures = new HashSet(); private final Set textures = new HashSet(); private final Set loadingModels = new HashSet(); + private final Set missingVariants = Sets.newHashSet(); + + private boolean isLoading = false; + public boolean isLoading() + { + return isLoading; + } public ModelLoader(IResourceManager manager, TextureMap map, BlockModelShapes shapes) { @@ -62,6 +77,7 @@ public class ModelLoader extends ModelBakery @Override public IRegistry setupModelRegistry() { + isLoading = true; loadBlocks(); loadItems(); stateModels.put(MODEL_MISSING, getModel(new ResourceLocation(MODEL_MISSING.getResourceDomain(), MODEL_MISSING.getResourcePath()))); @@ -103,19 +119,15 @@ public class ModelLoader extends ModelBakery { variants = definition.getVariants(location.getVariant()); } - catch(MissingVariantException e) {} - if(variants == null) + catch(MissingVariantException e) { - // adding default variant for simple blocks - ResourceLocation loc = new ResourceLocation(location.getResourceDomain(), "block/" + location.getResourcePath()); - variants = new Variants("normal", Lists.newArrayList(new Variant(loc, ModelRotation.X0_Y0, false, 1))); + missingVariants.add(location); } - if(!variants.getVariants().isEmpty()) + if(variants != null && !variants.getVariants().isEmpty()) { try { stateModels.put(location, new WeightedRandomModel(variants)); - } catch(Throwable e) { @@ -135,7 +147,11 @@ public class ModelLoader extends ModelBakery ModelResourceLocation memory = new ModelResourceLocation(s, "inventory"); resolveTextures.add(ModelLoaderRegistry.getActualLocation(file)); IModel model = getModel(file); - if(model != null) stateModels.put(memory, model); + if(model == null || model == getMissingModel()) + { + missingVariants.add(memory); + } + else stateModels.put(memory, model); } } } @@ -415,9 +431,65 @@ public class ModelLoader extends ModelBakery } catch(IOException e) { - FMLLog.log(Level.ERROR, e, "Exception loading model %s with vanilla loader, skipping", modelLocation); + if(loader.isLoading) + { + // holding error until onPostBakeEvent + } + else FMLLog.log(Level.ERROR, e, "Exception loading model %s with vanilla loader, skipping", modelLocation); return loader.getMissingModel(); } } } + + public void onPostBakeEvent(IRegistry modelRegistry) + { + for(ModelResourceLocation missing : missingVariants) + { + if(modelRegistry.getObject(missing) == null) + { + FMLLog.severe("Model definition for location %s not found", missing); + } + } + isLoading = false; + } + + private static final Map, IStateMapper> customStateMappers = Maps.newHashMap(); + + public static void setCustomStateMapper(Block block, IStateMapper mapper) + { + customStateMappers.put(block.delegate, mapper); + } + + public static void onRegisterAllBlocks(BlockModelShapes shapes) + { + for (Entry, IStateMapper> e : customStateMappers.entrySet()) + { + shapes.registerBlockWithStateMapper(e.getKey().get(), e.getValue()); + } + } + + private static final Map, ItemMeshDefinition> customMeshDefinitions = com.google.common.collect.Maps.newHashMap(); + private static final Map, Pair> customModels = com.google.common.collect.Maps.newHashMap(); + + public static void setCustomModelResourceLocation(Item item, int metadata, ModelResourceLocation model) + { + customModels.put(item.delegate, Pair.of(metadata, model)); + } + + public static void setCustomMeshDefinition(Item item, ItemMeshDefinition meshDefinition) + { + customMeshDefinitions.put(item.delegate, meshDefinition); + } + + public static void onRegisterItems(ItemModelMesher mesher) + { + for (Map.Entry, ItemMeshDefinition> e : customMeshDefinitions.entrySet()) + { + mesher.register(e.getKey().get(), e.getValue()); + } + for (Entry, Pair> e : customModels.entrySet()) + { + mesher.register(e.getKey().get(), e.getValue().getLeft(), e.getValue().getRight()); + } + } } diff --git a/src/test/java/net/minecraftforge/debug/ModelBakeEventDebug.java b/src/test/java/net/minecraftforge/debug/ModelBakeEventDebug.java index c8de9a48be..96f9aa5f11 100644 --- a/src/test/java/net/minecraftforge/debug/ModelBakeEventDebug.java +++ b/src/test/java/net/minecraftforge/debug/ModelBakeEventDebug.java @@ -11,10 +11,9 @@ import net.minecraft.block.properties.PropertyInteger; import net.minecraft.block.state.BlockState; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemMeshDefinition; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; -import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.renderer.block.statemap.StateMapperBase; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; @@ -31,6 +30,7 @@ import net.minecraft.world.World; import net.minecraftforge.client.event.ModelBakeEvent; import net.minecraftforge.client.model.ISmartBlockModel; import net.minecraftforge.client.model.ISmartItemModel; +import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; @@ -39,8 +39,7 @@ import net.minecraftforge.common.property.Properties; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.SidedProxy; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.registry.GameRegistry; @@ -69,47 +68,35 @@ public class ModelBakeEventDebug public static CommonProxy proxy; @EventHandler - public void init(FMLInitializationEvent event) { proxy.init(event); } - - @EventHandler - public void postInit(FMLPostInitializationEvent event) { proxy.postInit(event); } + public void preInit(FMLPreInitializationEvent event) { proxy.preInit(event); } public static class CommonProxy { - public void init(FMLInitializationEvent event) + public void preInit(FMLPreInitializationEvent event) { GameRegistry.registerBlock(CustomModelBlock.instance, CustomModelBlock.name); GameRegistry.registerTileEntity(CustomTileEntity.class, MODID.toLowerCase() + ":custom_tile_entity"); } - - public void postInit(FMLPostInitializationEvent event) {} } public static class ClientProxy extends CommonProxy { - private static ModelResourceLocation modelLocation = new ModelResourceLocation(blockName, null); + private static ModelResourceLocation blockLocation = new ModelResourceLocation(blockName, "normal"); + private static ModelResourceLocation itemLocation = new ModelResourceLocation(blockName, "inventory"); @Override - public void init(FMLInitializationEvent event) + public void preInit(FMLPreInitializationEvent event) { - super.init(event); - MinecraftForge.EVENT_BUS.register(BakeEventHandler.instance); - } - - @Override - public void postInit(FMLPostInitializationEvent event) { - super.postInit(event); + super.preInit(event); Item item = Item.getItemFromBlock(CustomModelBlock.instance); - RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); - if(renderItem != null) - { - renderItem.getItemModelMesher().register(item, new ItemMeshDefinition() { - public ModelResourceLocation getModelLocation(ItemStack stack) - { - return modelLocation; - } - }); - } + ModelLoader.setCustomModelResourceLocation(item, 0, itemLocation); + ModelLoader.setCustomStateMapper(CustomModelBlock.instance, new StateMapperBase(){ + protected ModelResourceLocation getModelResourceLocation(IBlockState p_178132_1_) + { + return blockLocation; + } + }); + MinecraftForge.EVENT_BUS.register(BakeEventHandler.instance); } } @@ -124,7 +111,9 @@ public class ModelBakeEventDebug { TextureAtlasSprite base = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite("minecraft:blocks/slime"); TextureAtlasSprite overlay = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite("minecraft:blocks/redstone_block"); - event.modelRegistry.putObject(ClientProxy.modelLocation, new CustomModel(base, overlay)); + IBakedModel customModel = new CustomModel(base, overlay); + event.modelRegistry.putObject(ClientProxy.blockLocation, customModel); + event.modelRegistry.putObject(ClientProxy.itemLocation, customModel); } } diff --git a/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java b/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java index 8a8ecd6c8c..b0d08782fa 100644 --- a/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java +++ b/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java @@ -31,6 +31,7 @@ import net.minecraftforge.client.model.ICustomModelLoader; import net.minecraftforge.client.model.IFlexibleBakedModel; import net.minecraftforge.client.model.IModel; import net.minecraftforge.client.model.IModelState; +import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoaderRegistry; import net.minecraftforge.client.model.b3d.B3DLoader; import net.minecraftforge.common.property.ExtendedBlockState; @@ -58,15 +59,11 @@ public class ModelLoaderRegistryDebug B3DLoader.instance.addDomain(MODID.toLowerCase()); GameRegistry.registerBlock(CustomModelBlock.instance, CustomModelBlock.name); //ModelBakery.addVariantName(Item.getItemFromBlock(CustomModelBlock.instance), "forgedebug:dummymodel"); - ModelBakery.addVariantName(Item.getItemFromBlock(CustomModelBlock.instance), MODID.toLowerCase() + ":untitled2.b3d"); - } - - @EventHandler - public void init(FMLInitializationEvent event) - { + String modelLocation = MODID.toLowerCase() + ":untitled2.b3d"; + ModelBakery.addVariantName(Item.getItemFromBlock(CustomModelBlock.instance), modelLocation); Item item = Item.getItemFromBlock(CustomModelBlock.instance); - //Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, new ModelResourceLocation("forgedebug:dummymodel", "inventory")); - Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, new ModelResourceLocation(MODID.toLowerCase() + ":untitled2.b3d", "inventory")); + ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(modelLocation, "inventory")); + //ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation("forgedebug:dummymodel", "inventory")); } public static class CustomModelBlock extends Block diff --git a/src/test/resources/assets/forgedebugmodelbakeevent/blockstates/custom_model_block.json b/src/test/resources/assets/forgedebugmodelbakeevent/blockstates/custom_model_block.json deleted file mode 100644 index c2352ff438..0000000000 --- a/src/test/resources/assets/forgedebugmodelbakeevent/blockstates/custom_model_block.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "variants": { - } -} diff --git a/src/test/resources/assets/forgedebugmodelbakeevent/models/item/custom_model_block.json b/src/test/resources/assets/forgedebugmodelbakeevent/models/item/custom_model_block.json deleted file mode 100644 index 43a272a605..0000000000 --- a/src/test/resources/assets/forgedebugmodelbakeevent/models/item/custom_model_block.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "builtin/entity" -}