Jump to content

Multipart model rotation on x axis (1.19.2)


ChamoisEST

Recommended Posts

Hello!

I have a multipart blockstate consisting of two different models - block base model (block/void_filter) and a connector model (block/filter_connector) that is only shown when a condition is true. The connector model should rotate automatically to the side where the condition is true.

While it works great on north, east, south and west sides (y rotation), it doesn't seem to work on up and down sides (x rotation). Is it not possible to rotate a multipart blockstate part on x axis or am I missing something obvious here?

blocstates\void_filter.json

Spoiler
{
  "multipart": [
    {
      "apply": {
        "model": "miningmadness:block/void_filter"
      }
    },
    {
      "apply": {
        "model": "miningmadness:block/filter_connector",
        "uvlock": false,
        "x": 270
      },
      "when": {
        "up": "true"
      }
    },
    {
      "apply": {
        "model": "miningmadness:block/filter_connector",
        "uvlock": false,
        "x": 90
      },
      "when": {
        "down": "true"
      }
    },
    {
      "apply": {
        "model": "miningmadness:block/filter_connector",
        "uvlock": false
      },
      "when": {
        "north": "true"
      }
    },
    {
      "apply": {
        "model": "miningmadness:block/filter_connector",
        "uvlock": false,
        "y": 90
      },
      "when": {
        "east": "true"
      }
    },
    {
      "apply": {
        "model": "miningmadness:block/filter_connector",
        "uvlock": false,
        "y": 180
      },
      "when": {
        "south": "true"
      }
    },
    {
      "apply": {
        "model": "miningmadness:block/filter_connector",
        "uvlock": false,
        "y": 270
      },
      "when": {
        "west": "true"
      }
    }
  ]
}

 

 

VoidFilterBlock.java

Currently the blockState values are hard-coded just for testing purposes.

Spoiler
package com.chamoisest.miningmadness.common.block;

import com.chamoisest.miningmadness.common.block.base.BaseCustomEntityBlock;
import com.chamoisest.miningmadness.common.block.entity.VoidFilterBlockEntity;
import com.chamoisest.miningmadness.common.init.MMBlockEntities;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;

import java.util.stream.Stream;

public class VoidFilterBlock extends BaseCustomEntityBlock {

    public static final BooleanProperty NORTH = BlockStateProperties.NORTH;
    public static final BooleanProperty SOUTH = BlockStateProperties.SOUTH;
    public static final BooleanProperty EAST = BlockStateProperties.EAST;
    public static final BooleanProperty WEST = BlockStateProperties.WEST;
    public static final BooleanProperty UP = BlockStateProperties.UP;
    public static final BooleanProperty DOWN = BlockStateProperties.DOWN;

    public VoidFilterBlock(Properties pProperties) {
        super(pProperties);
        this.registerDefaultState(this.stateDefinition.any().setValue(NORTH, Boolean.FALSE).setValue(EAST, Boolean.FALSE).setValue(SOUTH, Boolean.FALSE).setValue(WEST, Boolean.FALSE).setValue(UP, Boolean.TRUE).setValue(DOWN, Boolean.TRUE));
    }

    //private static final VoxelShape SHAPE = Block.box(0,0,0,7,7,7);

    private static final VoxelShape SHAPE = Stream.of(
            Block.box(2,2,2,14,14,14)

    ).reduce((v1, v2) -> {
        return Shapes.join(v1, v2, BooleanOp.OR);
    }).get();

    @Override
    public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
        return SHAPE;
    }

    @Override
    protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder){
        super.createBlockStateDefinition(builder);
        builder.add(NORTH, SOUTH, EAST, WEST, UP, DOWN);
    }

    /* BLOCK ENTITY*/

    @Nullable
    @Override
    public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
        return new VoidFilterBlockEntity(pos, state);
    }

    @Nullable
    @Override
    public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
        return createTickerHelper(type, MMBlockEntities.VOID_FILTER.get(), VoidFilterBlockEntity::tick);
    }
}

 

 

Edited by ChamoisEST
Link to comment
Share on other sites

  • ChamoisEST changed the title to Multipart model rotation on x axis (1.19.2)
1 hour ago, ChampionAsh5357 said:

No, it is. Chorus plants do the exact same thing. I would guess that it might be a transparent texture is being applied since you aren't preserving the UV through the lock.

The texture isn't transparent. It's there, it just isn't rotated. If I also add a y rotation, it still rotates on the y axis, but still no rotation on the x axis.

The image in the spoiler shows what it looks like right now (should've added it in the original post, just forgot). Since UP and DOWN are both true and the rest are false, the only connections should be on the top and bottom. Instead, both of the connectors show up in the front, overlapping each other.

Spoiler

filter-not-correct.png

 

Link to comment
Share on other sites

2 hours ago, ChamoisEST said:

The image in the spoiler shows what it looks like right now (should've added it in the original post, just forgot). Since UP and DOWN are both true and the rest are false, the only connections should be on the top and bottom. Instead, both of the connectors show up in the front, overlapping each other.

 

If they were both on the front, there should be some z-fighting which it doesn't look like there is. I'm curious, if you load up a debug world, fly over to all your block states, and then look at the results using f3, which models are properly rendered and which aren't? Based on your blockstate json, I see nothing wrong unless I'm missing something in the block model itself.

Link to comment
Share on other sites

18 hours ago, ChampionAsh5357 said:

If they were both on the front, there should be some z-fighting which it doesn't look like there is. I'm curious, if you load up a debug world, fly over to all your block states, and then look at the results using f3, which models are properly rendered and which aren't? Based on your blockstate json, I see nothing wrong unless I'm missing something in the block model itself.

The ones where UP and DOWN are false are properly rendered. Whenever either one of those is true, the model's front face is rendered, whether the front face actually needs to be rendered or not.

Filter_connector model json:

Spoiler
{
	"credit": "Made with Blockbench",
	"texture_size": [32, 32],
	"textures": {
		"0": "miningmadness:block/filter_connector",
		"particle": "miningmadness:block/filter_connector"
	},
	"elements": [
		{
			"from": [14, 5, 5],
			"to": [15, 11, 11],
			"faces": {
				"north": {"uv": [6, 6, 6.5, 9], "texture": "#0"},
				"east": {"uv": [4, 0, 7, 3], "texture": "#0"},
				"south": {"uv": [6.5, 6, 7, 9], "texture": "#0"},
				"west": {"uv": [4, 3, 7, 6], "texture": "#0"},
				"up": {"uv": [7.5, 3, 7, 0], "texture": "#0"},
				"down": {"uv": [7.5, 3, 7, 6], "texture": "#0"}
			}
		},
		{
			"from": [15, 4, 4],
			"to": [16, 12, 12],
			"faces": {
				"north": {"uv": [4, 6, 4.5, 10], "texture": "#0"},
				"east": {"uv": [0, 0, 4, 4], "texture": "#0"},
				"south": {"uv": [4.5, 6, 5, 10], "texture": "#0"},
				"west": {"uv": [0, 4, 4, 8], "texture": "#0"},
				"up": {"uv": [5.5, 10, 5, 6], "texture": "#0"},
				"down": {"uv": [6, 6, 5.5, 10], "texture": "#0"}
			}
		}
	],
	"groups": [
		{
			"name": "Connector",
			"origin": [8, 8, 8],
			"color": 0,
			"children": [0, 1]
		}
	]
}

 

 

Link to comment
Share on other sites

Ah ha! I figured it out! The initial position of your model is facing east, not north. As such, when rotating in the x axis, it just rotates left and right, which makes sense since you don't see any difference except for maybe the texture looking slightly different.

Try using this for the filter connector instead, I've adjust the base model to point north:

{
	"credit": "Made with Blockbench",
	"texture_size": [32, 32],
	"textures": {
		"0": "miningmadness:block/filter_connector",
		"particle": "miningmadness:block/filter_connector"
	},
	"elements": [
		{
			"from": [5, 5, 1],
			"to": [11, 11, 2],
			"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
			"faces": {
				"north": {"uv": [4, 0, 7, 3], "texture": "#0"},
				"east": {"uv": [6.5, 6, 7, 9], "texture": "#0"},
				"south": {"uv": [4, 3, 7, 6], "texture": "#0"},
				"west": {"uv": [6, 6, 6.5, 9], "texture": "#0"},
				"up": {"uv": [7.5, 3, 7, 0], "rotation": 270, "texture": "#0"},
				"down": {"uv": [7.5, 3, 7, 6], "rotation": 90, "texture": "#0"}
			}
		},
		{
			"from": [4, 4, 0],
			"to": [12, 12, 1],
			"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
			"faces": {
				"north": {"uv": [0, 0, 4, 4], "texture": "#0"},
				"east": {"uv": [4.5, 6, 5, 10], "texture": "#0"},
				"south": {"uv": [0, 4, 4, 8], "texture": "#0"},
				"west": {"uv": [4, 6, 4.5, 10], "texture": "#0"},
				"up": {"uv": [5.5, 10, 5, 6], "rotation": 270, "texture": "#0"},
				"down": {"uv": [6, 6, 5.5, 10], "rotation": 90, "texture": "#0"}
			}
		}
	],
	"groups": [
		{
			"name": "Connector",
			"origin": [8, 8, 8],
			"color": 0,
			"children": [0, 1]
		}
	]
}

 

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • plz help me fix this!!: it wasn't doing this before, whenever I try to join my world it just stucks on the options screen and the 0% never ever shows up, and the game is now frozen! help me, please HELP! https://paste.gg/p/anonymous/0b4686cd036d496db16ec497b1ec7fb9
    • Internal ExeptIon server bug Image LInk  l V https://lens.google.com/search?ep=gsbubb&hl=en-CA&re=df&p=AbrfA8p0hRZLHI5ozxFtMWh8xA21sqBQ71eivErBLG_oF8j-5G7yFOjJQP7DxnD3oOFBAYE4ajAvyOag8ykwGITxwfBg-8CpFUB0plaWJyrGKiw28bj9LohjoyyI07OsFTE5vJa1o3aKF80ocbEG8U_v5QhX_B5B3k370goGoohHkTodvClNPrBATvS6rYMKO43iTr_QbdYL_78wxQ%3D%3D#lns=W251bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsLG51bGwsIkVrY0tKR1E1T1RjeU5ETTVMV05pTVRVdE5HWXdNeTA1TmpWbUxXUXdOekZtWVdZeE9EWTJZaElmYTNoV05VWmFVREJJYTFGVWMwNXBYM3AxVm1GWlRWVTNSRnBoTFVob2F3PT0iLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsLG51bGwsWyI4ZDdmNDE1Yi00ZWViLTQ2NzItOWQyOS05MTA2MWNmMzYyNjciXV0=
    • Ensure your system is running the latest version of Java. Sodium requires Java 17 or later for newer Minecraft versions (like 1.17+). 
    • Hi I wanted to my custom mob to hold any sword item, but didn’t rendered properly.   In entity class, make entity hold items as below: @Override public InteractionResult mobInteract(Player pPlayer, InteractionHand pHand) { //… ItemStack itemstack = pPlayer.getItemInHand(pHand); if (this.isTame()) { if ( (itemstack.is(Items.MELON_SLICE) || itemstack.is(Items.HONEY_BOTTLE)) && this.getHealth() < this.getMaxHealth() ) { //… } /* Handle holding sword */ else if (itemstack.getItem() instanceof SwordItem) { pPlayer.displayClientMessage(Component.literal("Clicked with item: " + itemstack.getDisplayName().getString()).withStyle(ChatFormatting.GOLD), true); //Return sword //pPlayer.getInventory().add(this.getItemInHand(InteractionHand.MAIN_HAND)); pPlayer.getInventory().add(this.getItemBySlot(EquipmentSlot.MAINHAND)); //The entity holds item //this.setItemInHand(InteractionHand.MAIN_HAND, itemstack); this.setItemSlot(EquipmentSlot.MAINHAND, itemstack.copy()); //Give copy of itemstack //If player is not in creative mode. From mobInteract() in wolf. if (!pPlayer.getAbilities().instabuild) { //Decrement sword count in hand pPlayer.getItemInHand(pHand).shrink(1); } return InteractionResult.SUCCESS; } else { //If player is sneaking pPlayer.displayClientMessage(getItemInHand(InteractionHand.MAIN_HAND).getDisplayName(), false); if (pPlayer.isShiftKeyDown()) { //Return sword //pPlayer.getInventory().add(this.getItemInHand(InteractionHand.MAIN_HAND)); pPlayer.getInventory().add(this.getItemBySlot(EquipmentSlot.MAINHAND)); //The entity holds nothing this.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); return InteractionResult.SUCCESS; } else { //… } } else { return interactionresult; } }   And in render class, render the item as below: @Override public void render(RanaEntity pEntity, float pEntityYaw, float pPartialTicks, PoseStack pMatrixStack, MultiBufferSource pBuffer, int pPackedLight) { if(pEntity.isBaby()) { pMatrixStack.scale(0.5f, 0.5f, 0.5f); } model.setupAnim(pEntity, 0, 0, 0, pEntityYaw, 0); // //Get location and rotation of arm bone ModelPart rightArm = model.rightArm(); //Get right arm //Get location and rotation of item according to arm bone pMatrixStack.pushPose(); pMatrixStack.translate(rightArm.x, rightArm.y, rightArm.z); //Move to bone location pMatrixStack.mulPose(Axis.XP.rotationDegrees(rightArm.xRot)); //Rotate X pMatrixStack.mulPose(Axis.YP.rotationDegrees(rightArm.yRot)); //Rotate Y pMatrixStack.mulPose(Axis.ZP.rotationDegrees(rightArm.zRot)); //Rotate Z //Draw item //ItemStack itemStack = pEntity.getItemInHand(InteractionHand.MAIN_HAND); ItemStack itemStack = pEntity.getItemBySlot(EquipmentSlot.MAINHAND); if (!itemStack.isEmpty()) { //Offset pMatrixStack.translate(0.0, 0.0, 0.1); // Render the item //Minecraft.getInstance().getItemRenderer().renderStatic(itemStack, ItemDisplayContext.THIRD_PERSON_RIGHT_HAND, pPackedLight, OverlayTexture.NO_OVERLAY, pMatrixStack, pBuffer, pEntity.level(), pEntity.getId()); //itemRenderer.renderStatic(itemStack, ItemDisplayContext.THIRD_PERSON_RIGHT_HAND, pPackedLight, OverlayTexture.NO_OVERLAY, pMatrixStack, pBuffer, pEntity.level(), pEntity.getId()); itemInHandRenderer.renderItem(pEntity, itemStack, ItemDisplayContext.THIRD_PERSON_RIGHT_HAND, false, pMatrixStack, pBuffer, pEntity.getId()); } pMatrixStack.popPose(); super.render(pEntity, pEntityYaw, pPartialTicks, pMatrixStack, pBuffer, pPackedLight); }   I confirmed the entity can properly hold item(logically) but the item which the entity holds is not rendered at all.   Full code: https://github.com/sakiiiiika/ranamod   Thanks.
  • Topics

×
×
  • Create New...

Important Information

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