Jump to content

[1.9.4] Render Items in TESR


XFactHD

Recommended Posts

This is what I have got right now:

The custom model:

package XFactHD.thermalreactors.client.render.models;

import XFactHD.thermalreactors.common.utils.property.PropertyHolder;
import com.google.common.base.Optional;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.*;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.common.model.IModelPart;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.TRSRTransformation;
import net.minecraftforge.common.property.IExtendedBlockState;

import javax.annotation.Nullable;
import javax.vecmath.Matrix3f;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ModelLeadChest implements IBakedModel
{
    private IBakedModel chest;
    private Map<PositionWrapper, IBakedModel> items = new HashMap<PositionWrapper, IBakedModel>();

    public ModelLeadChest(IBakedModel chest)
    {
        this.chest = chest;
    }

    @Override
    public ItemOverrideList getOverrides()
    {
        return chest.getOverrides();
    }

    @Override
    public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand)
    {
        List<BakedQuad> quads = new ArrayList<BakedQuad>();
        quads.addAll(chest.getQuads(state, side, rand));
        if (state != null)
        {
            ItemStack[] stackArray = ((IExtendedBlockState)state).getValue(PropertyHolder.INVENTORY_9);
            EnumFacing facing = state.getValue(PropertyHolder.ORIENTATION);
            HashMap<Integer, ItemStack> stacks = new HashMap<Integer, ItemStack>();
            for (int i = 0; i < stackArray.length; ++i)
            {
                stacks.put(i, stackArray[i]);
            }
            quads.addAll(constructContainedItems(stacks, side, rand, facing));
        }
        return quads;
    }

    @Override
    public TextureAtlasSprite getParticleTexture()
    {
        return chest.getParticleTexture();
    }

    @Override
    public ItemCameraTransforms getItemCameraTransforms()
    {
        return ItemCameraTransforms.DEFAULT;
    }

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

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

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

    private class PositionWrapper
    {
        private EnumFacing facing;
        private int slot;
        private ItemStack stack;

        public PositionWrapper(EnumFacing facing, int slot, ItemStack stack)
        {
            this.facing = facing;
            this.slot = slot;
            this.stack = stack;
        }

        public EnumFacing getFacing()
        {
            return facing;
        }

        public int getSlot()
        {
            return slot;
        }

        public ItemStack getStack()
        {
            return stack;
        }
    }

    private List<BakedQuad> constructContainedItems(HashMap<Integer, ItemStack> stacks, EnumFacing side, long rand, EnumFacing facing)
    {
        List<BakedQuad> quads = new ArrayList<BakedQuad>();
        IModel[] models = new IModel[9];
        for (int i = 0; i < 9; ++i)
        {
            if (stacks.get(i) == null)
            {
                continue;
            }

            PositionWrapper wrapper = new PositionWrapper(facing, i, stacks.get(i));
            if (!items.containsKey(wrapper))
            {
                models[i] = ModelLoaderLeadChest.INSTANCE.getModel(stacks.get(i)); //FIXME: get the model
                TRSRTransformation transformation = new TRSRTransformation(new Matrix4f(new Matrix3f(0, 0, 0, 0, 0, 0, 0, 0, 0), new Vector3f(0, 0, 0), 1F));
                items.put(wrapper, models[i].bake(transformation, DefaultVertexFormats.ITEM, ModelLoader.defaultTextureGetter()));
            }

            quads.addAll(items.get(wrapper).getQuads(null, side, rand));
        }
        return quads;
    }
}

 

And the ModelLoader:

package XFactHD.thermalreactors.client.render.models;

import com.google.common.base.Function;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.*;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.*;
import net.minecraftforge.common.model.IModelState;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;

public enum  ModelLoaderLeadChest implements ICustomModelLoader
{
    INSTANCE;

    @Override
    public boolean accepts(ResourceLocation modelLocation)
    {
        return false;
    }

    @Override
    public IModel loadModel(ResourceLocation modelLocation) throws Exception
    {
        return new Model();
    }

    @Override
    public void onResourceManagerReload(IResourceManager resourceManager)
    {

    }

    @Override
    public String toString()
    {
        return "LeadChestLoader.INSTANCE";
    }

    public IModel getModel(ItemStack stack)
    {
        Item item = stack.getItem(); //Here I am trying to get the Model
        int meta = stack.getMetadata();
        IModel model = null;
        return model;
    }

    public class Model implements IModel
    {
        @Override
        public Collection<ResourceLocation> getDependencies()
        {
            return null;
        }

        @Override
        public IModelState getDefaultState()
        {
            return null;
        }

        @Override
        public Collection<ResourceLocation> getTextures()
        {
            return null;
        }

        @Override
        public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter)
        {
            return new BakedModel();
        }
    }

    public class BakedModel implements IBakedModel
    {
        @Override
        public ItemOverrideList getOverrides()
        {
            return null;
        }

        @Override
        public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand)
        {
            return null;
        }

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

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

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

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

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

 

My problem is now that I have no idea how to get the IModel from the information I can get from the ItemStack.

Link to comment
Share on other sites

[*]I fixed that.

[*]I have no knowledge over the Items that implement the API interface that makes them compatible to the chest.

[*]For that method I need a ResourceLocation but I only have an ItemStack to get any information from and a ResourceLocation needs a modid

Link to comment
Share on other sites

How is this relevant?

I don't know what the item model's file endings are.

 

Right, I was thinking the wrong way around.

You want

RenderItem#getItemModelWithOverrides

.

That method gives me an IBakedModel but I need an IModel to be able to bake it myself.

Link to comment
Share on other sites

Again, how is this relevant?

If not the Item's ModelResourceLocation, which one would the ModelLoader be for?

 

You don't bake it yourself.

I have to bake the models of the items that are in the chest myself to be able to apply a TRSRTransformation

Link to comment
Share on other sites

In the event, I take the chest's model, create a new IBakedModel (the one I posted before) and feed it with the old chest model. Then I put the new model into the registry. In the new model, I can easily handle the textures, etc.

 

This is what I tried to do to get the models to render:

private List<BakedQuad> constructContainedItems(HashMap<Integer, ItemStack> stacks, EnumFacing side, long rand, EnumFacing facing)
    {
        List<BakedQuad> quads = new ArrayList<BakedQuad>();
        IModel[] models = new IModel[9];
        for (int i = 0; i < 9; ++i)
        {
            ItemStack stack = stacks.get(i);
            if (stack == null)
            {
                continue;
            }

            PositionWrapper wrapper = new PositionWrapper(facing, i, stack);
            if (!items.containsKey(wrapper) || items.get(wrapper) == null)
            {
                models[i] = getModel(stack);
                //TRSRTransformation transformation = new TRSRTransformation(new Matrix4f(new Matrix3f(0, 0, 0, 0, 0, 0, 0, 0, 0), new Vector3f(0, 1, 0), 1F));
                TRSRTransformation transformation = new TRSRTransformation(new ItemTransformVec3f(new Vector3f(0, 0, 0), new Vector3f(0, 2, 0), new Vector3f(1, 1, 1)));
                    items.put(wrapper, models[i].bake(transformation, DefaultVertexFormats.ITEM, ModelLoader.defaultTextureGetter()));
            }

            quads.addAll(items.get(wrapper).getQuads(null, side, rand));
        }
        return quads;
    }

    private IModel getModel(ItemStack stack)
    {
        Item item = stack.getItem();
        Block block = Block.getBlockFromItem(item);
        ResourceLocation loc = block != null ? Block.REGISTRY.getNameForObject(block) : Item.REGISTRY.getNameForObject(item);
        ModelResourceLocation mloc = new ModelResourceLocation(loc.getResourceDomain() + ":" + loc.getResourcePath(), "inventory");
        IModel model;
        try
        {
            model = ModelLoaderRegistry.getModel(mloc);
        }
        catch (Exception e)
        {
            model = ModelLoaderRegistry.getMissingModel();
        }
        return model;
    }

 

I kinda works. I get a model but it's the missing model thingy. I checked the ModelResourceLocation and it is correct but stuff is still not working. Seems like a TESR is inavoidable without stuff becoming a huge pain in the back side.

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.

×
×
  • Create New...

Important Information

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