Jump to content

[1.11] Ways to render in a TESR


Recommended Posts

Posted

I'm working on a TileEntitySpecialRender for my robot. I'm wondering, since I have little experience with them in this version, how I should render my TileEntity? Would a Techne model be acceptable, or would I use a tessellator?

Posted

Yes, I'm pretty sure. The TileEntity would have a model where different parts rotate depending on which inventory around the TileEntity it is interacting with, if that makes sense. Code in an ItemStack (last topic) would tell it where to move/which inventory to interact with. I'm thinking this might be way more complex than a IBakedModel or something along those lines could provide.

Posted

Would I have to define something in a blockstate/model json file?

Posted

What format would the int array passed to VertexBuffer#addVertexData use?

Posted

Thank you. I now have this basic code for my renderer:

protected static BlockRendererDispatcher blockRenderer;

    @Override
    public void renderTileEntityFast(TileEntityRobot te, double x, double y, double z, float partialTicks, int destroyStage, VertexBuffer renderer) {
        if(blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher();
        BlockPos pos = te.getPos();
        IBlockAccess world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos);
        IBlockState state = world.getBlockState(pos);

        IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState(state);

        renderer.setTranslation(x - pos.getX(), y - pos.getY(), z - pos.getZ());

        blockRenderer.getBlockModelRenderer().renderModel(world, model, state, pos, renderer, false);
    }

 

I have tested it by adding an offset to the translation (for testing), and it works. It renders the model I defined in my blockstate file. Now how would I add rotation/change the position of some of the parts of the model?

Posted

Does anyone know how I could do this?

 

PS: Kind of off-topic but these spammers are getting really annoying. So glad the moderators are working on getting it fixed. I translated one of their user names on google translate from Chinese and it meant "Make a Fortune". They are obviously gaining something from this.

Posted

well you need to extract the posotion floats from the int[] you are passing an manualy change them with sin and cos

catch(Exception e)

{

 

}

Yay, Pokémon exception handling, gotta catch 'em all (and then do nothing with 'em).

Posted

I know this is probably fairly easy to do, but I'm struggling a little bit. Which vertexes use cos and which use sin? I've taken trigonometry but this is way beyond me. All I want is a basic rotation on the x axis.

Posted

I don't completely understand matrices yet, as I am only in grade 12 math currently. I tried it and got this code in my Renderer:

    protected static BlockRendererDispatcher blockRenderer;

    @Override
    public void renderTileEntityFast(TileEntityRobot te, double x, double y, double z, float partialTicks, int destroyStage, VertexBuffer renderer) {
        if(blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher();
        BlockPos pos = te.getPos();
        IBlockAccess world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos);
        IBlockState state = world.getBlockState(pos);

        IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState(state);

        renderer.setTranslation(x - pos.getX() + 2.0f, y - pos.getY(), z - pos.getZ() + 2.0f);

        BakedQuad bq = model.getQuads(state, null, 0L).get(0);

        int[] vertexData = handleXRotation(bq.getVertexData(), 45);

        model.getQuads(state, null, 0L).set(0, new BakedQuad(vertexData, bq.getTintIndex(), bq.getFace(), bq.getSprite(), bq.shouldApplyDiffuseLighting(), bq.getFormat()));

        blockRenderer.getBlockModelRenderer().renderModel(world, model, state, pos, renderer, false);
    }

    public int[] handleXRotation(int[] vertexData, double rot) {
        int vx = vertexData[0];
        int vy = vertexData[1];

        vx = (int)((vx * Math.cos(Math.toRadians(rot))) - (vy * Math.sin(Math.toRadians(rot))));
        vy = (int)((vx * Math.sin(Math.toRadians(rot))) + (vy * Math.cos(Math.toRadians(rot))));

        vertexData[0] = vx;
        vertexData[1] = vy;

        //Next Vertex
        vx = vertexData[8];
        vy = vertexData[9];

        vx = (int)((vx * Math.cos(Math.toRadians(rot))) - (vy * Math.sin(Math.toRadians(rot))));
        vy = (int)((vx * Math.sin(Math.toRadians(rot))) + (vy * Math.cos(Math.toRadians(rot))));

        vertexData[8] = vx;
        vertexData[9] = vy;

        //Next Vertex
        vx = vertexData[14];
        vy = vertexData[15];

        vx = (int)((vx * Math.cos(Math.toRadians(-rot))) - (vy * Math.sin(Math.toRadians(-rot))));
        vy = (int)((vx * Math.sin(Math.toRadians(-rot))) + (vy * Math.cos(Math.toRadians(-rot))));

        vertexData[14] = vx;
        vertexData[15] = vy;

        //Next Vertex
        vx = vertexData[20];
        vy = vertexData[21];

        vx = (int)((vx * Math.cos(Math.toRadians(-rot))) - (vy * Math.sin(Math.toRadians(-rot))));
        vy = (int)((vx * Math.sin(Math.toRadians(-rot))) + (vy * Math.cos(Math.toRadians(-rot))));

        vertexData[20] = vx;
        vertexData[21] = vy;

        return vertexData;
    }

 

The method handleXRotation only handles the top face so far. I'm probably doing this way wrong, but this what I got. When I test this code the top face disappears.

Posted

Ok, I now have the following code, and it isn't rotating like I wanted it to.

Spoiler

    protected static BlockRendererDispatcher blockRenderer;

    @Override
    public void renderTileEntityFast(TileEntityRobot te, double x, double y, double z, float partialTicks, int destroyStage, VertexBuffer renderer) {
        if(blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher();
        BlockPos pos = te.getPos();
        IBlockAccess world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos);
        IBlockState state = world.getBlockState(pos);

        IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState(state);

        renderer.setTranslation(x - pos.getX() + 2.0f, y - pos.getY(), z - pos.getZ() + 2.0f);

        BakedQuad bq = model.getQuads(state, null, 0L).get(0);

        transform(bq, new TRSRTransformation(new Vector3f(0, 0, 0), new Quat4f(-0.49f, 0, 0, -0.87f), new Vector3f(1, 1, 1), new Quat4f(0.49f, 0, 0, 0.87f)));

        model.getQuads(state, null, 0L).set(0, bq);

        blockRenderer.getBlockModelRenderer().renderModel(world, model, state, pos, renderer, false);
    }

    public static BakedQuad transform(BakedQuad quad, final TRSRTransformation transform) {
        UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(DefaultVertexFormats.BLOCK);
        final IVertexConsumer consumer = new VertexTransformer(builder) {
            @Override
            public void put(int element, float... data) {
                VertexFormatElement formatElement = DefaultVertexFormats.BLOCK.getElement(element);
                switch(formatElement.getUsage()) {
                    case POSITION: {
                        float[] newData = new float[3];
                        Vector3f vec = new Vector3f(data);
                        transform.getMatrix().transform(vec);
                        vec.get(newData);
                        parent.put(element, newData);
                        break;
                    }
                    default: {
                        parent.put(element, data);
                        break;
                    }
                }
            }
        };

        quad.pipe(consumer);
        return builder.build();
    }

 

 

Posted

It's still not working.

Spoiler

protected static BlockRendererDispatcher blockRenderer;

    public int curStep = 0;
    public int totalSteps = 0;

    @Override
    public void renderTileEntityFast(TileEntityRobot te, double x, double y, double z, float partialTicks, int destroyStage, VertexBuffer renderer) {
        if(blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher();
        BlockPos pos = te.getPos();
        IBlockAccess world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos);
        IBlockState state = world.getBlockState(pos);

        IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState(state);

        renderer.setTranslation(x - pos.getX() + 2.0f, y - pos.getY(), z - pos.getZ() + 2.0f);

        List<BakedQuad> quadList = model.getQuads(state, null, 0L);

        for(BakedQuad quad : quadList) {
            transform(quad, new TRSRTransformation(new Vector3f(0, 0, 0), new Quat4f(-0.49f, 0, 0, -0.87f), new Vector3f(1, 1, 1), new Quat4f(0.49f, 0, 0, 0.87f)));
        }

        blockRenderer.getBlockModelRenderer().renderModel(world, model, state, pos, renderer, false);
    }

    public static BakedQuad transform(BakedQuad quad, final TRSRTransformation transform) {
        UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(DefaultVertexFormats.BLOCK);
        final IVertexConsumer consumer = new VertexTransformer(builder) {
            @Override
            public void put(int element, float... data) {
                VertexFormatElement formatElement = DefaultVertexFormats.BLOCK.getElement(element);
                switch(formatElement.getUsage()) {
                    case POSITION: {
                        float[] newData = new float[3];
                        Vector3f vec = new Vector3f(data);
                        transform.getMatrix().transform(vec);
                        vec.get(newData);
                        parent.put(element, newData);
                        break;
                    }
                    default: {
                        parent.put(element, data);
                        break;
                    }
                }
            }
        };

        quad.pipe(consumer);
        return builder.build();
    }

 

 

10 minutes ago, diesieben07 said:
  • Don't try to modify the model's quads, this is a terrible idea.

Isn't that what I'm doing? I'm rotating one of the cubes?

Posted

Ok. I tried that and it only renders the top face (unrotated). I'm probably still doing it wrong.

    protected static BlockRendererDispatcher blockRenderer;

    public int curStep = 0;
    public int totalSteps = 0;

    @Override
    public void renderTileEntityFast(TileEntityRobot te, double x, double y, double z, float partialTicks, int destroyStage, VertexBuffer renderer) {
        if(blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher();
        BlockPos pos = te.getPos();
        IBlockAccess world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos);
        IBlockState state = world.getBlockState(pos);

        final IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState(state);

        renderer.setTranslation(x - pos.getX() + 2.0f, y - pos.getY(), z - pos.getZ() + 2.0f);

        final List<BakedQuad> quadList = model.getQuads(state, null, 0L);

        for(BakedQuad quad : quadList) {
            transform(quad, new TRSRTransformation(new Vector3f(0, 0, 0), new Quat4f(-0.49f, 0, 0, -0.87f), new Vector3f(1, 1, 1), new Quat4f(0.49f, 0, 0, 0.87f)));
        }

        final IBakedModel newModel = new IBakedModel() {
            @Override
            public List<BakedQuad> getQuads(IBlockState state, EnumFacing side, long rand) {
                return quadList;
            }

            @Override
            public boolean isAmbientOcclusion() {
                return model.isAmbientOcclusion();
            }

            @Override
            public boolean isGui3d() {
                return model.isGui3d();
            }

            @Override
            public boolean isBuiltInRenderer() {
                return model.isBuiltInRenderer();
            }

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

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

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

        blockRenderer.getBlockModelRenderer().renderModel(world, newModel, state, pos, renderer, false);
    }

    //This method was borrowed from Vazkii's mod called Botania. It was modified to work for a block instead of an item.
    public static BakedQuad transform(BakedQuad quad, final TRSRTransformation transform) {
        UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(DefaultVertexFormats.BLOCK);
        final IVertexConsumer consumer = new VertexTransformer(builder) {
            @Override
            public void put(int element, float... data) {
                VertexFormatElement formatElement = DefaultVertexFormats.BLOCK.getElement(element);
                switch(formatElement.getUsage()) {
                    case POSITION: {
                        float[] newData = new float[3];
                        Vector3f vec = new Vector3f(data);
                        transform.getMatrix().transform(vec);
                        vec.get(newData);
                        parent.put(element, newData);
                        break;
                    }
                    default: {
                        parent.put(element, data);
                        break;
                    }
                }
            }
        };

        quad.pipe(consumer);
        return builder.build();
    }

 

Mind you, I am creating a new instance of the model every rendering tick. Not sure how to get around that.

Posted (edited)

Thanks for pointing that out. Now it isn't rendering.

protected static BlockRendererDispatcher blockRenderer;

    @Override
    public void renderTileEntityFast(TileEntityRobot te, double x, double y, double z, float partialTicks, int destroyStage, VertexBuffer renderer) {
        if(blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher();
        BlockPos pos = te.getPos();
        IBlockAccess world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos);
        IBlockState state = world.getBlockState(pos);

        final IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState(state);

        renderer.setTranslation(x - pos.getX() + 2.0f, y - pos.getY(), z - pos.getZ() + 2.0f);

        final List<BakedQuad> quadList = model.getQuads(state, null, 0L);
        final List<BakedQuad> newQuadList = Lists.newArrayList();


        for(BakedQuad quad : quadList) {
            newQuadList.add(transform(quad, new TRSRTransformation(new Vector3f(0, 0, 0), new Quat4f(-0.49f, 0, 0, -0.87f), new Vector3f(1, 1, 1), new Quat4f(0.49f, 0, 0, 0.87f))));
        }

        final IBakedModel newModel = new IBakedModel() {
            @Override
            public List<BakedQuad> getQuads(IBlockState state, EnumFacing side, long rand) {
                return newQuadList;
            }

            @Override
            public boolean isAmbientOcclusion() {
                return model.isAmbientOcclusion();
            }

            @Override
            public boolean isGui3d() {
                return model.isGui3d();
            }

            @Override
            public boolean isBuiltInRenderer() {
                return model.isBuiltInRenderer();
            }

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

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

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

        blockRenderer.getBlockModelRenderer().renderModel(world, newModel, state, pos, renderer, false);
    }

    //This method was borrowed from Vazkii's mod called Botania. It was modified to work for a block instead of an item.
    public static BakedQuad transform(BakedQuad quad, final TRSRTransformation transform) {
        UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(DefaultVertexFormats.BLOCK);
        final IVertexConsumer consumer = new VertexTransformer(builder) {
            @Override
            public void put(int element, float... data) {
                VertexFormatElement formatElement = DefaultVertexFormats.BLOCK.getElement(element);
                switch(formatElement.getUsage()) {
                    case POSITION: {
                        float[] newData = new float[3];
                        Vector3f vec = new Vector3f(data);
                        transform.getMatrix().transform(vec);
                        vec.get(newData);
                        parent.put(element, newData);
                        break;
                    }
                    default: {
                        parent.put(element, data);
                        break;
                    }
                }
            }
        };

        quad.pipe(consumer);
        return builder.build();
    }

 

Did I get the Quat4fs right? I haven't really worked with them. I used this to get the numbers for them.

Edited by Awesome_Spider
Posted

Ok. I think I'm doing that now. But it isn't rendering.

 

protected static BlockRendererDispatcher blockRenderer;

    @Override
    public void renderTileEntityFast(TileEntityRobot te, double x, double y, double z, float partialTicks, int destroyStage, VertexBuffer renderer) {
        if(blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher();
        BlockPos pos = te.getPos();
        IBlockAccess world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos);
        IBlockState state = world.getBlockState(pos);

        final IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState(state);

        renderer.setTranslation(x - pos.getX() + 2.0f, y - pos.getY(), z - pos.getZ() + 2.0f);

        for(int i = 0; i > model.getQuads(state, null, 0L).size(); i++) {
            BakedQuad quad = model.getQuads(state, null, 0L).get(i);
            quad = transform(quad, new TRSRTransformation(new Vector3f(0, 0, 0), new Quat4f(-0.49f, 0, 0, -0.87f), new Vector3f(1, 1, 1), new Quat4f(0.49f, 0, 0, 0.87f)));

            renderer.addVertexData(quad.getVertexData());
        }
    }

    //This method was borrowed from Vazkii's mod called Botania. It was modified to work for a block instead of an item.
    public static BakedQuad transform(BakedQuad quad, final TRSRTransformation transform) {
        UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(DefaultVertexFormats.BLOCK);
        final IVertexConsumer consumer = new VertexTransformer(builder) {
            @Override
            public void put(int element, float... data) {
                VertexFormatElement formatElement = DefaultVertexFormats.BLOCK.getElement(element);
                switch(formatElement.getUsage()) {
                    case POSITION: {
                        float[] newData = new float[3];
                        Vector3f vec = new Vector3f(data);
                        transform.getMatrix().transform(vec);
                        vec.get(newData);
                        parent.put(element, newData);
                        break;
                    }
                    default: {
                        parent.put(element, data);
                        break;
                    }
                }
            }
        };

        quad.pipe(consumer);
        return builder.build();
    }

 

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.