adding a shape that can display a item or a block (#1365)

added 'polygon', 'item' and 'block' to scarpet rendered shapes
This commit is contained in:
ch-yx authored and GitHub committed 2022-09-12 00:38:52 +02:00
1 parent c528695d1a
commit 179f5a6006
5 files changed
+868 -6

No files matched your search

@@ -2,30 +2,81 @@ package carpet.script.utils;
import carpet.CarpetSettings;
import carpet.utils.CarpetProfiler;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.blaze3d.vertex.VertexFormat.Mode;
import com.mojang.datafixers.util.Either;
import com.mojang.math.Vector3f;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.stream.Stream;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.Material;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.TagKey;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.ShulkerBoxBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.entity.LevelEntityGetter;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.scores.Scoreboard;
import net.minecraft.world.ticks.LevelTickAccess;
public class ShapesRenderer
{
@@ -41,6 +92,9 @@ public class ShapesRenderer
put("sphere", RenderedSphere::new);
put("cylinder", RenderedCylinder::new);
put("label", RenderedText::new);
put("polygon",RenderedPolyface::new);
put("block",(c,s)->new RenderedSprite(c,s).set_isitem(false));
put("item",(c,s)->new RenderedSprite(c,s).set_isitem(true));
}};
public ShapesRenderer(Minecraft minecraftClient)
@@ -82,6 +136,7 @@ public class ShapesRenderer
double cameraX = camera.getPosition().x;
double cameraY = camera.getPosition().y;
double cameraZ = camera.getPosition().z;
boolean hasf3b = client.getEntityRenderDispatcher().shouldRenderHitBoxes();
if (shapes.size() != 0) { synchronized (shapes) {
shapes.get(dimensionType).long2ObjectEntrySet().removeIf(
@@ -95,12 +150,12 @@ public class ShapesRenderer
// lines
RenderSystem.lineWidth(0.5F);
shapes.get(dimensionType).values().forEach( s -> {
if (s.shouldRender(dimensionType)) s.renderLines(matrices, tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
if ( (!s.shape.needf3b ||hasf3b ) && s.shouldRender(dimensionType)) s.renderLines(matrices, tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
});
// faces
RenderSystem.lineWidth(0.1F);
shapes.get(dimensionType).values().forEach(s -> {
if (s.shouldRender(dimensionType)) s.renderFaces(tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
if ( (!s.shape.needf3b ||hasf3b ) && s.shouldRender(dimensionType)) s.renderFaces(tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
});
RenderSystem.lineWidth(1.0F);
matrixStack.popPose();
@@ -113,7 +168,7 @@ public class ShapesRenderer
entry -> entry.getValue().isExpired(currentTime)
);
labels.get(dimensionType).values().forEach(s -> {
if (s.shouldRender(dimensionType)) s.renderLines(matrices, tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
if ( (!s.shape.needf3b || hasf3b) && s.shouldRender(dimensionType)) s.renderLines(matrices, tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
});
}}
RenderSystem.enableCull();
@@ -233,6 +288,175 @@ public class ShapesRenderer
}
}
public static class RenderedSprite extends RenderedShape<ShapeDispatcher.DisplayedSprite> {
private boolean isitem;
public RenderedSprite set_isitem(boolean isitem) {
this.isitem = isitem;
return this;
}
private BlockPos blockPos;
private BlockState blockState;
private BlockEntity BlockEntity = null;
protected RenderedSprite(Minecraft client, ShapeDispatcher.ExpiringShape shape) {
super(client, (ShapeDispatcher.DisplayedSprite) shape);
}
@Override
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder builder, double cx, double cy,
double cz, float partialTick) {
if (shape.a == 0.0)
return;
Vec3 v1 = shape.relativiseRender(client.level, shape.pos, partialTick);
Camera camera1 = client.gameRenderer.getMainCamera();
matrices.pushPose();
if (!isitem)// blocks should use its center as the origin
matrices.translate(0.5, 0.5, 0.5);
matrices.translate(v1.x - cx, v1.y - cy, v1.z - cz);
if (shape.facing == null) {
matrices.mulPose(camera1.rotation());
matrices.mulPose(Vector3f.YP.rotationDegrees(180));
} else {
switch (shape.facing) {
case NORTH:
break;
case SOUTH:
matrices.mulPose(Vector3f.YP.rotationDegrees(180));
break;
case EAST:
matrices.mulPose(Vector3f.YP.rotationDegrees(270));
break;
case WEST:
matrices.mulPose(Vector3f.YP.rotationDegrees(90));
break;
case UP:
matrices.mulPose(Vector3f.XP.rotationDegrees(90));
break;
case DOWN:
matrices.mulPose(Vector3f.XP.rotationDegrees(-90));
break;
}
}
if (shape.tilt != 0.0f)
matrices.mulPose(Vector3f.ZP.rotationDegrees(shape.tilt));
if (shape.lean != 0.0f)
matrices.mulPose(Vector3f.XP.rotationDegrees(shape.lean));
if (shape.turn != 0.0f)
matrices.mulPose(Vector3f.YP.rotationDegrees(shape.turn));
matrices.scale(shape.scale_x, shape.scale_y, shape.scale_z);
if (!isitem)// blocks should use its center as the origin
matrices.translate(-0.5, -0.5, -0.5);
RenderSystem.depthMask(true);
RenderSystem.enableCull();
RenderSystem.enableDepthTest();
blockPos = new BlockPos(v1);
int light;
light = LightTexture.pack(
shape.light_fromblock < 0 ? client.level.getBrightness(LightLayer.BLOCK, blockPos)
: shape.light_fromblock,
shape.light_fromsky < 0 ? client.level.getBrightness(LightLayer.SKY, blockPos)
: shape.light_fromsky);
blockState = shape.blockState;
MultiBufferSource.BufferSource immediate = client.renderBuffers().bufferSource();
if (!isitem) {
// draw the block itself
if (blockState.getRenderShape() == RenderShape.MODEL) {
var bakedModel = client.getBlockRenderer().getBlockModel(blockState);
int color = client.getBlockColors().getColor(blockState,client.level,blockPos,0);
//dont know why there is a 0.
//see https://github.com/senseiwells/EssentialClient/blob/4db1f291936f502304791ee323f369c206b3021d/src/main/java/me/senseiwells/essentialclient/utils/render/RenderHelper.java#L464
float red = (color >> 16 & 0xFF) / 255.0F;
float green = (color >> 8 & 0xFF) / 255.0F;
float blue = (color & 0xFF) / 255.0F;
client.getBlockRenderer().getModelRenderer().renderModel(matrices.last(), immediate.getBuffer(ItemBlockRenderTypes.getRenderType(blockState, false)), blockState, bakedModel, red, green, blue, light, OverlayTexture.NO_OVERLAY);
}
// draw the block`s entity part
if (BlockEntity == null) {
if (blockState.getBlock() instanceof EntityBlock eb) {
BlockEntity = eb.newBlockEntity(blockPos, blockState);
if (BlockEntity != null) {
BlockEntity.setLevel(client.level);
if (shape.blockEntity != null)
BlockEntity.load(shape.blockEntity);
}
}
}
if (BlockEntity instanceof ShulkerBoxBlockEntity sbBlockEntity){
sbrender(sbBlockEntity, partialTick,
matrices, immediate, light, OverlayTexture.NO_OVERLAY);
}else
if (BlockEntity != null && client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity) != null) {
client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity).render(BlockEntity, partialTick,
matrices, immediate, light, OverlayTexture.NO_OVERLAY);
}
} else {
// draw item
if (shape.item != null)
client.getItemRenderer().renderStatic(shape.item, shape.item_transform_type, light,
OverlayTexture.NO_OVERLAY, matrices, immediate, (int) shape.key());
}
matrices.popPose();
immediate.endBatch();
RenderSystem.disableCull();
RenderSystem.disableDepthTest();
RenderSystem.depthMask(false);
}
@Override
public boolean stageDeux() {
return true;
}
// copy and modifiy a bit from net.minecraft.client.renderer.blockentity.ShulkerBoxRenderer.render
public void sbrender(ShulkerBoxBlockEntity shulkerBoxBlockEntity, float f, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, int j) {
Direction direction = Direction.UP;
if (shulkerBoxBlockEntity.hasLevel()) {
BlockState blockState = shulkerBoxBlockEntity.getBlockState();
if (blockState.getBlock() instanceof ShulkerBoxBlock) {
direction = blockState.getValue(ShulkerBoxBlock.FACING);
}
}
DyeColor dyeColor = shulkerBoxBlockEntity.getColor();
Material material;
if (dyeColor == null) {
material = Sheets.DEFAULT_SHULKER_TEXTURE_LOCATION;
} else {
material = (Material)Sheets.SHULKER_TEXTURE_LOCATION.get(dyeColor.getId());
}
poseStack.pushPose();
poseStack.translate(0.5, 0.5, 0.5);
float g = 0.9995F;
poseStack.scale(0.9995F, 0.9995F, 0.9995F);
poseStack.mulPose(direction.getRotation());
poseStack.scale(1.0F, -1.0F, -1.0F);
poseStack.translate(0.0, -1.0, 0.0);
ModelPart modelPart = ((carpet.mixins.ShulkerBoxAccessMixin)(Object)(client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity))).getModel().getLid();
modelPart.setPos(0.0F, 24.0F - shulkerBoxBlockEntity.getProgress(f) * 0.5F * 16.0F, 0.0F);
modelPart.yRot = 270.0F * shulkerBoxBlockEntity.getProgress(f) * (float) (Math.PI / 180.0);
VertexConsumer vertexConsumer = material.buffer(multiBufferSource, RenderType::entityCutoutNoCull);
((carpet.mixins.ShulkerBoxAccessMixin)(Object)(client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity))).getModel().renderToBuffer(poseStack, vertexConsumer, i, j, 1.0F, 1.0F, 1.0F, 1.0F);
poseStack.popPose();
}
}
public static class RenderedText extends RenderedShape<ShapeDispatcher.DisplayedText>
{
@@ -386,7 +610,140 @@ public class ShapesRenderer
);
}
}
public static class RenderedPolyface extends RenderedShape<ShapeDispatcher.Polyface>
{
public RenderedPolyface(Minecraft client, ShapeDispatcher.ExpiringShape shape)
{
super(client, (ShapeDispatcher.Polyface)shape);
}
@Override
public void renderFaces(Tesselator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick)
{
if(shape.fa==0){return;}
if (shape.doublesided)
RenderSystem.disableCull();
else
RenderSystem.enableCull();
bufferBuilder.begin(shape.mode, DefaultVertexFormat.POSITION_COLOR);
for(int i=0;i<shape.vertex_list.size();i++){
Vec3 vec=shape.vertex_list.get(i);
if(shape.relative.get(i)){
vec=shape.relativiseRender(client.level, vec, partialTick);
}
bufferBuilder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.fr, shape.fg, shape.fb, shape.fa).endVertex();
}
tessellator.end();
RenderSystem.disableCull();
RenderSystem.depthMask(false);
//RenderSystem.enableDepthTest();
}
@Override
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder builder, double cx, double cy,
double cz, float partialTick) {
if(shape.a==0){return;}
if (shape.mode==Mode.TRIANGLE_FAN){
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
Vec3 vec0=null;
for(int i=0;i<shape.vertex_list.size();i++){
Vec3 vec=shape.vertex_list.get(i);
if(shape.relative.get(i)){
vec=shape.relativiseRender(client.level, vec, partialTick);
}
if(i==0)vec0=vec;
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
}
builder.vertex(vec0.x()-cx, vec0.y()-cy, vec0.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
tessellator.end();
if(shape.inneredges){
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
for(int i=1;i<shape.vertex_list.size()-1;i++){
Vec3 vec = shape.vertex_list.get(i);
if(shape.relative.get(i)){
vec=shape.relativiseRender(client.level, vec, partialTick);
}
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
builder.vertex(vec0.x()-cx, vec0.y()-cy, vec0.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
}
tessellator.end();
}
return;
}
if (shape.mode==Mode.TRIANGLE_STRIP){
//02468
//1357*
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
Vec3 vec=shape.vertex_list.get(1);
if(shape.relative.get(1)){
vec=shape.relativiseRender(client.level, vec, partialTick);
}
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
int i;
for(i=0;i<shape.vertex_list.size();i+=2){
vec=shape.vertex_list.get(i);
if(shape.relative.get(i)){
vec=shape.relativiseRender(client.level, vec, partialTick);
}
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
}
i=shape.vertex_list.size()-1;
for(i-=1-i%2;i>0;i-=2){
vec=shape.vertex_list.get(i);
if(shape.relative.get(i)){
vec=shape.relativiseRender(client.level, vec, partialTick);
}
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
}
if(shape.inneredges){
for(i=2;i<shape.vertex_list.size()-1;i++){
vec=shape.vertex_list.get(i);
if(shape.relative.get(i)){
vec=shape.relativiseRender(client.level, vec, partialTick);
}
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
}
}
tessellator.end();
return;
}
if (shape.mode==Mode.TRIANGLES){
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
for (int i=0;i<shape.vertex_list.size();i++){
Vec3 vecA=shape.vertex_list.get(i);
if(shape.relative.get(i)){
vecA=shape.relativiseRender(client.level, vecA, partialTick);
}
i++;
Vec3 vecB=shape.vertex_list.get(i);
if(shape.relative.get(i)){
vecB=shape.relativiseRender(client.level, vecB, partialTick);
}
i++;
Vec3 vecC=shape.vertex_list.get(i);
if(shape.relative.get(i)){
vecC=shape.relativiseRender(client.level, vecC, partialTick);
}
builder.vertex(vecA.x()-cx, vecA.y()-cy, vecA.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
builder.vertex(vecB.x()-cx, vecB.y()-cy, vecB.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
builder.vertex(vecB.x()-cx, vecB.y()-cy, vecB.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
builder.vertex(vecC.x()-cx, vecC.y()-cy, vecC.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
builder.vertex(vecC.x()-cx, vecC.y()-cy, vecC.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
builder.vertex(vecA.x()-cx, vecA.y()-cy, vecA.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
}
tessellator.end();
return;
}
}
}
public static class RenderedSphere extends RenderedShape<ShapeDispatcher.Sphere>
{
public RenderedSphere(Minecraft client, ShapeDispatcher.ExpiringShape shape)