Jump to content

[1.8] Custom model block rendering in inventory?


61352151511

Recommended Posts

This is probably answered somewhere, if so a link to it will suffice, I did a few quick searches and found nothing. Basically in 1.7.10 we used IItemRenderer to make custom models render in the inventory, these are models that are just java files (Like the chest) and not json, is there still a way to get these to render in the inventory?

MinecraftForgeClient.registerItemRenderer(item, IItemRenderer) still exists however it doesn't seem to work.

Link to comment
Share on other sites

Hi

 

I would recommend converting your obj model to the json blockmodel format.  With an ISmartItemModel you can return whatever list of Quads you want for rendering.

 

Otherwise -

IItemRenderer has been abandoned; Forge doesn't support using models for item rendering (yet?) so you will need to use Reflection to insert your rendering code into the right place. 

 

If it were me, I would probably create a custom class extending RenderItem, override the    public void renderItemIntoGUI(ItemStack stack, int x, int y) to call my custom rendering code if stack==myItem.  Use reflection to insert your custom class into the vanilla code, either right at creation in Minecraft.startGame() if possible, or otherwise overwriting the various fields that it is stored in.

 

No guarantee it will work, and it's not terribly compatible with any other mods who think to do the same, but it's the only way I can think of.  Stick with ISmartItemModel if you can...

 

-TGG

 

 

Link to comment
Share on other sites

I have no idea how ISmartItemModel works, I know there's a few tutorials but I just can't wrap my head around any of them. I don't jave a .obj model as I said it is a java file, like ModelChest and ModelBanner things like that. If there's a tool to convert those into the json block model format a link would be great.

 

package com.sixonethree.randomutilities.client.model;

import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;

public class ModelMagicChest extends ModelBase {
public ModelRenderer shape1;
public ModelRenderer shape1_1;
public ModelRenderer shape1_2;
public ModelRenderer shape1_3;
public ModelRenderer shape1_4;
public ModelRenderer shape1_5;
public ModelRenderer shape1_6;
public ModelRenderer shape1_7;

public ModelMagicChest() {
	this.textureWidth = 64;
	this.textureHeight = 64;
	this.shape1 = new ModelRenderer(this, 0, 17);
	this.shape1.setRotationPoint(-7.0F, 9.0F, -7.0F);
	this.shape1.addBox(0.0F, 0.0F, 0.0F, 14, 1, 14, 0.0F);
	this.shape1_6 = new ModelRenderer(this, 0, 0);
	this.shape1_6.setRotationPoint(-8.0F, 23.0F, -8.0F);
	this.shape1_6.addBox(0.0F, 0.0F, 0.0F, 16, 1, 16, 0.0F);
	this.shape1_5 = new ModelRenderer(this, 0, 48);
	this.shape1_5.setRotationPoint(-8.0F, 9.0F, -8.0F);
	this.shape1_5.addBox(0.0F, 0.0F, 0.0F, 1, 14, 1, 0.0F);
	this.shape1_7 = new ModelRenderer(this, 0, 17);
	this.shape1_7.setRotationPoint(-7.0F, 22.0F, -7.0F);
	this.shape1_7.addBox(0.0F, 0.0F, 0.0F, 14, 1, 14, 0.0F);
	this.shape1_2 = new ModelRenderer(this, 0, 0);
	this.shape1_2.setRotationPoint(-8.0F, 8.0F, -8.0F);
	this.shape1_2.addBox(0.0F, 0.0F, 0.0F, 16, 1, 16, 0.0F);
	this.shape1_4 = new ModelRenderer(this, 0, 48);
	this.shape1_4.setRotationPoint(7.0F, 9.0F, 7.0F);
	this.shape1_4.addBox(0.0F, 0.0F, 0.0F, 1, 14, 1, 0.0F);
	this.shape1_3 = new ModelRenderer(this, 0, 48);
	this.shape1_3.setRotationPoint(7.0F, 9.0F, -8.0F);
	this.shape1_3.addBox(0.0F, 0.0F, 0.0F, 1, 14, 1, 0.0F);
	this.shape1_1 = new ModelRenderer(this, 0, 48);
	this.shape1_1.setRotationPoint(-8.0F, 9.0F, 7.0F);
	this.shape1_1.addBox(0.0F, 0.0F, 0.0F, 1, 14, 1, 0.0F);
}

@Override public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) {
	this.shape1.render(f5);
	this.shape1_6.render(f5);
	this.shape1_5.render(f5);
	this.shape1_7.render(f5);
	this.shape1_2.render(f5);
	this.shape1_4.render(f5);
	this.shape1_3.render(f5);
	this.shape1_1.render(f5);
}

/** This is a helper function from Tabula to set the rotation of model parts */
public void setRotateAngle(ModelRenderer modelRenderer, float x, float y, float z) {
	modelRenderer.rotateAngleX = x;
	modelRenderer.rotateAngleY = y;
	modelRenderer.rotateAngleZ = z;
}
}

 

That's what I use for the actual block, I use a TESR for it and it works fine, however rendering in the inventory it does not.

Link to comment
Share on other sites

Hi

 

There's no tool I know of that will convert that automatically.

 

You could perhaps fiddle with the model renderer to (eg) pull out the ModelBox quad lists and convert them to a BlockModel quad list; your ISmartItemModel.handleItemState() could update the animation settings and generate the new quadlist.

 

So it would look something like

 

ISmartItemModel.handleItemState(): set up the ModelRenderer as per your code, and copy the model quads into a format suitable for BlockModel, so that IBlockModel.getGeneralQuads() returns the list of quads that would normally be rendered by the ModelRenderer.render().

 

I think that would be hard work to implement even for a rather experience modder.  But it might be useful to a lot of people if you could crack it.

 

-TGG

 

 

Link to comment
Share on other sites

As I said though I can't seem to wrap my head around the ISmartItemModel, IBakedModel, anything like that. I'm sure it's possible to convert

 

public class ModelMagicChest extends ModelBase {
public ModelRenderer shape1;
public ModelRenderer shape1_1;
public ModelRenderer shape1_2;
public ModelRenderer shape1_3;
public ModelRenderer shape1_4;
public ModelRenderer shape1_5;
public ModelRenderer shape1_6;
public ModelRenderer shape1_7;

public ModelMagicChest() {
	this.textureWidth = 64;
	this.textureHeight = 64;
	this.shape1 = new ModelRenderer(this, 0, 17);
	this.shape1.setRotationPoint(-7.0F, 9.0F, -7.0F);
	this.shape1.addBox(0.0F, 0.0F, 0.0F, 14, 1, 14, 0.0F);
	this.shape1_6 = new ModelRenderer(this, 0, 0);
	this.shape1_6.setRotationPoint(-8.0F, 23.0F, -8.0F);
	this.shape1_6.addBox(0.0F, 0.0F, 0.0F, 16, 1, 16, 0.0F);
	this.shape1_5 = new ModelRenderer(this, 0, 48);
	this.shape1_5.setRotationPoint(-8.0F, 9.0F, -8.0F);
	this.shape1_5.addBox(0.0F, 0.0F, 0.0F, 1, 14, 1, 0.0F);
	this.shape1_7 = new ModelRenderer(this, 0, 17);
	this.shape1_7.setRotationPoint(-7.0F, 22.0F, -7.0F);
	this.shape1_7.addBox(0.0F, 0.0F, 0.0F, 14, 1, 14, 0.0F);
	this.shape1_2 = new ModelRenderer(this, 0, 0);
	this.shape1_2.setRotationPoint(-8.0F, 8.0F, -8.0F);
	this.shape1_2.addBox(0.0F, 0.0F, 0.0F, 16, 1, 16, 0.0F);
	this.shape1_4 = new ModelRenderer(this, 0, 48);
	this.shape1_4.setRotationPoint(7.0F, 9.0F, 7.0F);
	this.shape1_4.addBox(0.0F, 0.0F, 0.0F, 1, 14, 1, 0.0F);
	this.shape1_3 = new ModelRenderer(this, 0, 48);
	this.shape1_3.setRotationPoint(7.0F, 9.0F, -8.0F);
	this.shape1_3.addBox(0.0F, 0.0F, 0.0F, 1, 14, 1, 0.0F);
	this.shape1_1 = new ModelRenderer(this, 0, 48);
	this.shape1_1.setRotationPoint(-8.0F, 9.0F, 7.0F);
	this.shape1_1.addBox(0.0F, 0.0F, 0.0F, 1, 14, 1, 0.0F);
}

@Override public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) {
	this.shape1.render(f5);
	this.shape1_6.render(f5);
	this.shape1_5.render(f5);
	this.shape1_7.render(f5);
	this.shape1_2.render(f5);
	this.shape1_4.render(f5);
	this.shape1_3.render(f5);
	this.shape1_1.render(f5);
}

/** This is a helper function from Tabula to set the rotation of model parts */
public void setRotateAngle(ModelRenderer modelRenderer, float x, float y, float z) {
	modelRenderer.rotateAngleX = x;
	modelRenderer.rotateAngleY = y;
	modelRenderer.rotateAngleZ = z;
}
}

 

to

 

public class ModelMagicChestRefactor implements ISmartItemModel {
@Override public List getFaceQuads(EnumFacing facing) {
	return null;
}

@Override public List getGeneralQuads() {
	return null;
}

@Override public boolean isAmbientOcclusion() {
	return false;
}

@Override public boolean isGui3d() {
	return false;
}

@Override public boolean isBuiltInRenderer() {
	return false;
}

@Override public TextureAtlasSprite getTexture() {
	return null;
}

@Override public ItemCameraTransforms getItemCameraTransforms() {
	return null;
}

@Override public IBakedModel handleItemState(ItemStack stack) {
	return null;
}
}

 

However I don't understand how any of that works :( If there's a tutorial specifically for this that explains it in detail I'd love that.

Link to comment
Share on other sites

To render a TESR you need to have a class extending TileEntityItemStackRenderer

and example would be.

//From a mod I'm currently writting
public class CrystalMagicRenderHelper extends TileEntityItemStackRenderer {
//the Tile enitty you want to render
    private TileFlare flareRender = new TileFlare();
    @Override
    public void renderByItem(ItemStack itemStack) {
        Block block = Block.getBlockFromItem(itemStack.getItem());
//Your custom block
        if (block == CMBlocks.flare) {
            TileEntityRendererDispatcher.instance.renderTileEntityAt(this.flareRender, 0.0D, 0.0D, 0.0D, 0.0F);
        }else {
//for minecraft to render its own tile entities such as the chest
            super.renderByItem(itemStack);
        }
    }
}

in your client proxy you need to have the call which is

TileEntityItemStackRenderer.instance = new CrystalMagicRenderHelper();

best to also remove minecraft looking for the blockstate file with

Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getModelManager().getBlockModelShapes().registerBuiltInBlocks(block);

and finally your item json needs to be

{
  "parent": "builtin/entity"
}

and that should make the TESR render as an item

EDIT:Unless I've forgotten something

Did you really need to know?

Link to comment
Share on other sites

In client proxy:

@Override public void registerRenderInformation() {
	TileEntitySpecialRenderer mcr = new MagicChestRenderer(Minecraft.getMinecraft().getRenderManager());
	ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMagicChest.class, mcr);
	LogHelper.warn("A");
	TileEntityItemStackRenderer.instance = new MagicChestInventoryRenderer();
	// MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(ModBlocks.magicChest), new MagicChestInventoryRenderer(mcr, new TileEntityMagicChest()));
}

 

"A" is put into the log

 

public class MagicChestInventoryRenderer extends TileEntityItemStackRenderer {
private Map<Integer, TileEntityMagicChest> itemRenders = Maps.newHashMap();

public MagicChestInventoryRenderer() {
	LogHelper.warn("B");
	itemRenders.put(0, (TileEntityMagicChest) new TileEntityMagicChest());
}

@Override public void renderByItem(ItemStack itemStack) {
	Block block = Block.getBlockFromItem(itemStack.getItem());
	LogHelper.warn("C");
	if (block == ModBlocks.magicChest) {
		LogHelper.warn("D");
		TileEntityRendererDispatcher.instance.renderTileEntityAt(itemRenders.get(0), 0.0D, 0.0D, 0.0D, 0.0F);
	} else {
		super.renderByItem(itemStack);
	}
}
}

 

"B" is put into the logs

"C" and "D" is not put into the logs

 

I do have everything you told me to put

Link to comment
Share on other sites

Right below it:

ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMagicChest.class, mcr);

I made it a variable because in 1.7 I needed to use it for the inventory renderer too, however now it doesn't really need to be a variable. The RenderManager is because in the actual block when placed down it renders items. I probably could just use Minecraft.getMinecraft().getRenderManager() in the constructor for it.

Link to comment
Share on other sites

Going through a bit of my backend code i realized that i forgot to mention that you still have to register the item render to the inventory using

Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item,metadata,new ModelResourceLocation(itemname,"inventory"));

Edit:Maybe should read my ModelHelper

Did you really need to know?

Link to comment
Share on other sites

IMO My naming conventions are fine. I don't get what you mean by "nothing was linking to each other" I didn't push my build.gradle so the mappings used were wrong, but on my end all the names are correct. You commented out important stuff like the PacketHandler, Config, etc. So I didn't want to copy it exactly, I copied what I thought was relevant, yet it still does not work.

 

Changed getRenderType to 2

Set the unlocalized name and copied the "BlockRU" class (Although I really don't think having block. instead of tile. would make a difference)

Got rid of unlocalized name stuff in ItemBlock

Switched from IProxy to CommonProxy and set up the methods seperately (bindTileEntitySpecialRenderers, registerRenderInformation, registerItemRenderers) All this is called in the init portion of the mod.

 

The things you pushed other than that were irrelevant to the rendering in the inventory, so unless for some reason my workspace is broken in some way, I don't understand why it doesn't work.

 

Edit: I forgot to refresh the resources folder >_> I should not be up this late. It works.

Link to comment
Share on other sites

tile is so it follows naming conventions cause every block in minecraft starts with tile most of it was just my sorting through the code and making it readable for me and somethings were just to make it work in my environment cause somethings didn't work and were giving me errors. Pretty much eliminate everything that wasn't needed to solve the problem so that the actual problem identified itself.

Did you really need to know?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.