Fixed rendering of multi-segment blocks

This commit is contained in:
Sollace 2024-05-23 19:59:56 +01:00
parent 98f612cd13
commit e22f181f41
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
3 changed files with 63 additions and 37 deletions

View file

@ -9,15 +9,18 @@ import com.minelittlepony.unicopia.entity.behaviour.Disguise;
import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance;
import com.minelittlepony.unicopia.mixin.MixinBlockEntity; import com.minelittlepony.unicopia.mixin.MixinBlockEntity;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.OverlayTexture; import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.LivingEntityRenderer; import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.FallingBlockEntity;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -49,11 +52,11 @@ class EntityDisguiseRenderer {
} }
render(ve, e, x, y, z, fireTicks, tickDelta, matrices, vertices, light); render(ve, e, x, y, z, fireTicks, tickDelta, matrices, vertices, light);
ve.getAttachments().forEach(ee -> { ve.getAttachments().forEach(attachment -> {
PehkUtil.copyScale(pony.asEntity(), ee); PehkUtil.copyScale(pony.asEntity(), attachment.entity());
Vec3d difference = ee.getPos().subtract(e.getPos()); Vec3d difference = attachment.entity().getPos().subtract(e.getPos());
render(ve, ee, x + difference.x, y + difference.y, z + difference.z, fireTicks, tickDelta, matrices, vertices, light); render(ve, attachment.entity(), x + difference.x, y + difference.y, z + difference.z, fireTicks, tickDelta, matrices, vertices, light);
PehkUtil.clearScale(ee); PehkUtil.clearScale(attachment.entity());
}); });
matrices.push(); matrices.push();
@ -66,6 +69,7 @@ class EntityDisguiseRenderer {
return true; return true;
} }
@SuppressWarnings("deprecation")
private void render(EntityAppearance ve, Entity e, private void render(EntityAppearance ve, Entity e,
double x, double y, double z, double x, double y, double z,
int fireTicks, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) { int fireTicks, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
@ -84,6 +88,9 @@ class EntityDisguiseRenderer {
BlockEntityRenderer<BlockEntity> r = MinecraftClient.getInstance().getBlockEntityRenderDispatcher().get(blockEntity); BlockEntityRenderer<BlockEntity> r = MinecraftClient.getInstance().getBlockEntityRenderDispatcher().get(blockEntity);
if (r != null) { if (r != null) {
((MixinBlockEntity)blockEntity).setPos(e.getBlockPos()); ((MixinBlockEntity)blockEntity).setPos(e.getBlockPos());
if (e instanceof FallingBlockEntity fbe) {
blockEntity.setCachedState(fbe.getBlockState());
}
blockEntity.setWorld(e.getWorld()); blockEntity.setWorld(e.getWorld());
matrices.push(); matrices.push();
matrices.translate(x, y, z); matrices.translate(x, y, z);
@ -92,8 +99,11 @@ class EntityDisguiseRenderer {
r.render(blockEntity, 1, matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV); r.render(blockEntity, 1, matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV);
matrices.pop(); matrices.pop();
blockEntity.setWorld(null);
return; BlockRenderType type = blockEntity.getCachedState().getRenderType();
if (type == BlockRenderType.ENTITYBLOCK_ANIMATED) {
return;
}
} }
} }
@ -104,7 +114,15 @@ class EntityDisguiseRenderer {
} }
e.setFireTicks(fireTicks); e.setFireTicks(fireTicks);
delegate.client.getEntityRenderDispatcher().render(e, x, y, z, e.getYaw(), tickDelta, matrices, vertexConsumers, light);
EntityRenderDispatcher dispatcher = delegate.client.getEntityRenderDispatcher();
if (e instanceof FallingBlockEntity) {
dispatcher.setRenderShadows(false);
}
dispatcher.render(e, x, y, z, e.getYaw(), tickDelta, matrices, vertexConsumers, light);
if (e instanceof FallingBlockEntity) {
dispatcher.setRenderShadows(true);
}
e.setFireTicks(0); e.setFireTicks(0);
if (model != null) { if (model != null) {

View file

@ -48,21 +48,22 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ShulkerBulletEntity; import net.minecraft.entity.projectile.ShulkerBulletEntity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtElement;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provider, FlightType.Provider, EntityCollisions.ComplexCollidable { public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provider, FlightType.Provider, EntityCollisions.ComplexCollidable {
private static final Optional<Float> BLOCK_HEIGHT = Optional.of(0.5F); private static final Optional<Float> BLOCK_HEIGHT = Optional.of(0.5F);
@NotNull @NotNull
private String entityId = ""; private transient String entityId = "";
@Nullable @Nullable
private Entity entity; private transient Entity entity;
@Nullable @Nullable
private BlockEntity blockEntity; private transient BlockEntity blockEntity;
private List<Entity> attachments = new ArrayList<>(); private transient List<Attachment> attachments = new ArrayList<>();
private Optional<EntityDimensions> dimensions = Optional.empty(); private Optional<EntityDimensions> dimensions = Optional.empty();
@ -71,7 +72,7 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
* This is not serialized, so should only be used for server-side data. * This is not serialized, so should only be used for server-side data.
*/ */
@Nullable @Nullable
private NbtCompound tag; private transient NbtCompound tag;
@Nullable @Nullable
private NbtCompound entityNbt; private NbtCompound entityNbt;
@ -86,16 +87,21 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
return blockEntity; return blockEntity;
} }
public List<Entity> getAttachments() { public List<Attachment> getAttachments() {
return attachments; return attachments;
} }
public void addBlockEntity(BlockEntity blockEntity) { public record Attachment(Vec3d offset, Entity entity) {}
public void setBlockEntity(@Nullable BlockEntity blockEntity) {
if (this.blockEntity != null) {
this.blockEntity.markRemoved();
}
this.blockEntity = blockEntity; this.blockEntity = blockEntity;
} }
public void attachExtraEntity(Entity entity) { public void attachExtraEntity(Vec3d offset, Entity entity) {
attachments.add(entity); attachments.add(new Attachment(offset, entity));
} }
public void setAppearance(@Nullable Entity entity) { public void setAppearance(@Nullable Entity entity) {
@ -384,7 +390,7 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
@Override @Override
public void getCollissionShapes(ShapeContext context, Consumer<VoxelShape> output) { public void getCollissionShapes(ShapeContext context, Consumer<VoxelShape> output) {
EntityCollisions.getCollissionShapes(getAppearance(), context, output); EntityCollisions.getCollissionShapes(getAppearance(), context, output);
getAttachments().forEach(e -> EntityCollisions.getCollissionShapes(e, context, output)); getAttachments().forEach(e -> EntityCollisions.getCollissionShapes(e.entity(), context, output));
} }
} }

View file

@ -1,6 +1,5 @@
package com.minelittlepony.unicopia.entity.behaviour; package com.minelittlepony.unicopia.entity.behaviour;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
@ -11,27 +10,26 @@ import com.minelittlepony.unicopia.mixin.MixinFallingBlock;
import com.minelittlepony.unicopia.mixin.MixinFallingBlockEntity; import com.minelittlepony.unicopia.mixin.MixinFallingBlockEntity;
import com.minelittlepony.unicopia.util.Tickable; import com.minelittlepony.unicopia.util.Tickable;
import net.minecraft.block.BedBlock;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.DoorBlock;
import net.minecraft.block.FallingBlock; import net.minecraft.block.FallingBlock;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.ChestBlockEntity; import net.minecraft.block.entity.ChestBlockEntity;
import net.minecraft.block.entity.EnderChestBlockEntity; import net.minecraft.block.entity.EnderChestBlockEntity;
import net.minecraft.block.enums.BedPart;
import net.minecraft.block.enums.ChestType;
import net.minecraft.block.enums.DoubleBlockHalf; import net.minecraft.block.enums.DoubleBlockHalf;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.FallingBlockEntity; import net.minecraft.entity.FallingBlockEntity;
import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.damage.DamageSource;
import net.minecraft.state.property.Properties; import net.minecraft.state.property.Properties;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
public class FallingBlockBehaviour extends EntityBehaviour<FallingBlockEntity> { public class FallingBlockBehaviour extends EntityBehaviour<FallingBlockEntity> {
private static final Vec3d UP = Vec3d.of(Direction.UP.getVector());
private static final Optional<EntityDimensions> FULL_BLOCK = Optional.of(EntityDimensions.changing(0.6F, 0.9F)); private static final Optional<EntityDimensions> FULL_BLOCK = Optional.of(EntityDimensions.changing(0.6F, 0.9F));
@Override @Override
@ -70,22 +68,27 @@ public class FallingBlockBehaviour extends EntityBehaviour<FallingBlockEntity> {
public FallingBlockEntity onCreate(FallingBlockEntity entity, EntityAppearance context, boolean replaceOld) { public FallingBlockEntity onCreate(FallingBlockEntity entity, EntityAppearance context, boolean replaceOld) {
super.onCreate(entity, context, replaceOld); super.onCreate(entity, context, replaceOld);
BlockState state = entity.getBlockState(); BlockState state = entity.getBlockState()
.withIfExists(Properties.CHEST_TYPE, ChestType.SINGLE)
.withIfExists(Properties.BED_PART, BedPart.HEAD)
.withIfExists(Properties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.LOWER);
Block block = state.getBlock(); Block block = state.getBlock();
context.setBlockEntity(block instanceof BlockEntityProvider bep ? bep.createBlockEntity(entity.getBlockPos(), state) : null);
if (block instanceof BlockEntityProvider bep) { if (state.contains(Properties.BED_PART)) {
context.addBlockEntity(bep.createBlockEntity(entity.getBlockPos(), state)); Vec3i offset = BedBlock.getOppositePartDirection(state).getVector();
BlockState foot = state.with(Properties.BED_PART, BedPart.FOOT);
context.attachExtraEntity(Vec3d.of(offset), configure(MixinFallingBlockEntity.createInstance(entity.getWorld(), entity.getX() + offset.getX(), entity.getY() + offset.getY(), entity.getZ() + offset.getZ(), foot), block));
} }
if (block instanceof DoorBlock) { if (state.contains(Properties.DOUBLE_BLOCK_HALF)) {
BlockState lowerState = state.with(DoorBlock.HALF, DoubleBlockHalf.LOWER); BlockState upperState = state.with(Properties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.UPPER);
BlockState upperState = state.with(DoorBlock.HALF, DoubleBlockHalf.UPPER); context.attachExtraEntity(new Vec3d(0, 1, 0), configure(MixinFallingBlockEntity.createInstance(entity.getWorld(), entity.getX(), entity.getY() + 1, entity.getZ(), upperState), block));
context.attachExtraEntity(configure(MixinFallingBlockEntity.createInstance(entity.getWorld(), entity.getX(), entity.getY(), entity.getZ(), upperState), block));
return configure(MixinFallingBlockEntity.createInstance(entity.getWorld(), entity.getX(), entity.getY() + 1, entity.getZ(), lowerState), block);
} }
if (state != entity.getBlockState()) {
entity = MixinFallingBlockEntity.createInstance(entity.getWorld(), entity.getX(), entity.getY(), entity.getZ(), state);
}
return configure(entity, block); return configure(entity, block);
} }
@ -117,9 +120,8 @@ public class FallingBlockBehaviour extends EntityBehaviour<FallingBlockEntity> {
be.setWorld(null); be.setWorld(null);
} }
List<Entity> attachments = disguise.getAttachments(); for (var attachment : disguise.getAttachments()) {
if (attachments.size() > 0) { copyBaseAttributes(source.asEntity(), attachment.entity(), attachment.offset());
copyBaseAttributes(source.asEntity(), attachments.get(0), UP);
} }
} }
} }