Jump to content

[1.15.1] [Solved] Baked models for different block states


PianoManu

Recommended Posts

Hey guys, it's me again.

I have another question regarding baked models. I made some blocks, that take on the texture of the block they are clicked on with. Full blocks are working flawless and slabs almost too, but I'm wondering if I really have to make a baked model for every block state. Well, for slabs there are only three block states and it's not a big deal to make two baked models and two loaders (for bottom half and top half). But currently I'm trying to get buttons to work and they have 12 block states (6 directions * 2 pressed or not) and I would have to make 12 baked models and 12 loaders. Of course, I tried rotating the model in the blockstates json-file, but it seems that this does not affect baked models.

 

Now my question is: Is there a way to rotate/translate the baked model without making a new baked model class for every possible blockstate?

As you can see in the following pictures, these two buttons on the floor have two different rotations, and the model I made works correctly for the right button, but not for the left button, which is rotated by 90 degrees.

 

I don't know if you need it, but this is the code for the baked model:

public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData) {
        //get block saved in frame tile
        BlockState mimic = extraData.getData(FrameBlockTile.MIMIC);
        if (mimic != null && !(mimic.getBlock() instanceof FrameBlock)) {
            ModelResourceLocation location = BlockModelShapes.getModelLocation(mimic);
            if (location != null) {
                IBakedModel model = Minecraft.getInstance().getModelManager().getModel(location);
                model.getBakedModel().getQuads(mimic, side, rand, extraData);
                if (model != null) {
                    //only if model (from block saved in tile entity) exists:
                    return getMimicQuads(mimic, side, rand, extraData);
                }
            }
        }
        return Collections.emptyList();
    }

 

The getMimicQuads method, which is called:

public List<BakedQuad> getMimicQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData) {
        if (side != null) {
            return Collections.emptyList();
        }
        BlockState mimic = extraData.getData(FrameBlockTile.MIMIC);
        if (mimic!=null) {
            //get texture from block in tile entity and apply it to the quads
            TextureAtlasSprite texture = Minecraft.getInstance().getAtlasSpriteGetter(AtlasTexture.LOCATION_BLOCKS_TEXTURE).apply(new ResourceLocation(mimic.getBlock().getRegistryName().getNamespace(), "block/" + mimic.getBlock().getRegistryName().getPath()));
            List<BakedQuad> quads = new ArrayList<>();
            //down
            quads.add(createUpDownQuad(v(5 / 16f, 0, 6 / 16f), v(11 / 16f, 0, 6 / 16f), v(11 / 16f, 0, 10 / 16f), v(5 / 16f, 0, 10 / 16f), texture));
            //up
            quads.add(createUpDownQuad(v(5 / 16f, 2/16f, 10 / 16f), v(11 / 16f, 2/16f, 10 / 16f), v(11 / 16f, 2/16f, 6 / 16f), v(5 / 16f, 2/16f, 6 / 16f), texture));
            //sides
            quads.add(createLongSideQuad(v(5/16f, 0, 10/16f), v(5/16f, 2/16f, 10/16f), v(5/16f, 2/16f, 6/16f), v(5/16f, 0, 6/16f), texture));
            quads.add(createLongSideQuad(v(11/16f, 0, 6/16f), v(11/16f, 2/16f, 6/16f), v(11/16f, 2/16f, 10/16f), v(11/16f, 0, 10/16f), texture));
            quads.add(createShortSideQuad(v(5/16f, 0, 6/16f), v(5/16f, 2/16f, 6/16f), v(11/16f, 2/16f, 6/16f), v(11/16f, 0, 6/16f), texture));
            quads.add(createShortSideQuad(v(11/16f, 0, 10/16f), v(11/16f, 2/16f, 10/16f), v(5/16f, 2/16f, 10/16f), v(5/16f, 0, 10/16f), texture));

            return quads;
        }
        return Collections.emptyList();
    }

 

createUpDownQuad, createLongSideQuad and createShortSideQuad have very similar code and only differ in the arguments for putVertex():

private BakedQuad createUpDownQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, TextureAtlasSprite sprite) {
        Vec3d normal = v3.subtract(v2).crossProduct(v1.subtract(v2)).normalize();
        BakedQuadBuilder builder = new BakedQuadBuilder(sprite);
        builder.setQuadOrientation(Direction.getFacingFromVector(normal.x, normal.y, normal.z));
        builder.setApplyDiffuseLighting(true);
        putVertex(builder, normal, v1.x, v1.y, v1.z, 5, 6, sprite, 1.0f, 1.0f, 1.0f);
        putVertex(builder, normal, v2.x, v2.y, v2.z, 5, 10, sprite, 1.0f, 1.0f, 1.0f);
        putVertex(builder, normal, v3.x, v3.y, v3.z, 11, 10, sprite, 1.0f, 1.0f, 1.0f);
        putVertex(builder, normal, v4.x, v4.y, v4.z, 11, 6, sprite, 1.0f, 1.0f, 1.0f);
        return builder.build();
    }

 

the putVertex method:

private void putVertex(BakedQuadBuilder builder, Vec3d normal,
                           double x, double y, double z, float u, float v, TextureAtlasSprite sprite, float r, float g, float b) {
        ImmutableList<VertexFormatElement> elements = SLAB_BLOCK.getElements().asList();
        for (int j = 0 ; j < elements.size() ; j++) {
            VertexFormatElement e = elements.get(j);
            switch (e.getUsage()) {
                case POSITION:
                    builder.put(j, (float) x, (float) y, (float) z, 1.0f);
                    break;
                case COLOR:
                    builder.put(j, r, g, b, 1.0f);
                    break;
                case UV:
                    switch (e.getIndex()) {
                        case 0:
                            float iu = sprite.getInterpolatedU(u);
                            float iv = sprite.getInterpolatedV(v);
                            builder.put(j, iu, iv);
                            break;
                        case 2:
                            builder.put(j, (short)0, (short)0);
                            break;
                        default:
                            builder.put(j);
                            break;
                    }
                    break;
                case NORMAL:
                    builder.put(j, (float) normal.x, (float) normal.y, (float) normal.z);
                    break;
                default:
                    builder.put(j);
                    break;
            }
        }
        builder.setApplyDiffuseLighting(true);
    }

 

Thanks for help in advance! :D

Regards, Manu

2020-06-13_12.33.17.png

2020-06-13_12.33.20.png

2020-06-13_12.33.27.png

 

Edit: I know about the BakedQuadBuilder method "setQuadOrientation()", but I cannot use it as I don't have any information about the block, when creating the baked model. At least that's how I understand it, because the baked model is created in a static context and the tile entity is not. Or am I wrong?

Edited by PianoManu
addendum regarding setQuadOrientation()
Link to comment
Share on other sites

Thanks for your reply!

Yeah, that's what I tried at first, but the problem is, that this state only determines the block, that is saved in the button, not the button itself. I just tried it again, but Minecraft crashes and I get the error "Cannot get property DirectionProperty{name=facing, clazz=class net.minecraft.util.Direction, values=[north, south, west, east]} as it does not exist in Block{minecraft:spruce_planks}", obviously because Minecraft tries to get directions from planks, which have no directions...

 

I still haven't found a solution

 

Nevermind, SoulQuantum is right and I'm retarded (see last post)

Edited by PianoManu
correction - I'm wrong
Link to comment
Share on other sites

23 hours ago, QuantumSoul said:

Can't you do the rotations in getMimicQuads using the provided BlockState ?

I'M COMPLETELY STUPID. You're right, at least nearly. I put the wrong blockstate in the getMimicQuads

method, that's why I got those errors. It's working pretty well by now. That means I only had to change the first parameter from the method from "mimic" (which would be the block in the slab) to "state" (which is the state of the button)

 

So I changed in the code from

if (model != null) {
    //only if model (from block saved in tile entity) exists:
    return getMimicQuads(mimic, side, rand, extraData);
}

to

if (model != null) {
    //only if model (from block saved in tile entity) exists:
    return getMimicQuads(state, side, rand, extraData); //first parameter was the problem
}

 

Thank you very much, dear SoulQuantum!

(Thread can be closed, Problem is solved)

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.