Using Create outlines and ghost blocks for block previews.

Fixed item names.
This commit is contained in:
Christian Knaapen
2023-01-16 01:53:09 +01:00
parent c2d413fad0
commit fa1aadcd86
9 changed files with 158 additions and 81 deletions

View File

@@ -0,0 +1,31 @@
package nl.requios.effortlessbuilding.create;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
@Mod.EventBusSubscriber(Dist.CLIENT)
public class CreateClientTest {
@SubscribeEvent
public static void onTick(TickEvent.ClientTickEvent event) {
CreateClient.GHOST_BLOCKS.showGhostState(1, Blocks.SPRUCE_LOG.defaultBlockState())
.at(0, 120, 0)
.breathingAlpha();
CreateClient.GHOST_BLOCKS.showGhostState(2, Blocks.SPRUCE_LOG.defaultBlockState())
.at(1, 120, 0)
.breathingAlpha();
CreateClient.OUTLINER.showAABB(1, new AABB(0, 0, 0, 10, 2, 6)
.move(10, 120, 0))
.withFaceTexture(AllSpecialTextures.CHECKERED)
.colored(new Color(0.11f, 0.49f, 0.7f, 1f))
// .colored(0xbfbfbf)
.disableNormals()
.lineWidth(1 / 32f);
}
}

View File

@@ -35,8 +35,8 @@ public class ClientEvents {
Level world = Minecraft.getInstance().level;
AnimationTickHolder.tick();
CreateClient.OUTLINER.tickOutlines();
CreateClient.GHOST_BLOCKS.tickGhosts();
CreateClient.OUTLINER.tickOutlines();
CameraAngleAnimationService.tick();
}
@@ -89,7 +89,7 @@ public class ClientEvents {
event.setPitch(CameraAngleAnimationService.getPitch(partialTicks));
}
protected static boolean isGameActive() {
public static boolean isGameActive() {
return !(Minecraft.getInstance().level == null || Minecraft.getInstance().player == null);
}

View File

@@ -75,7 +75,7 @@ public abstract class GhostBlockRenderer {
BlockState state = params.state;
BlockPos pos = params.pos;
float alpha = params.alphaSupplier.get() * .75f/* * PlacementHelpers.getCurrentAlpha()*/;
float alpha = params.alphaSupplier.get()/* * .75f* PlacementHelpers.getCurrentAlpha()*/;
BakedModel model = dispatcher.getBlockModel(state);
RenderType layer = RenderType.translucent();
@@ -88,7 +88,7 @@ public abstract class GhostBlockRenderer {
ms.scale(.85f, .85f, .85f);
ms.translate(-.5, -.5, -.5);
renderModel(ms.last(), vb, state, model, 1f, 1f, 1f, alpha,
renderModel(ms.last(), vb, state, model, 0f, 1f, 1f, alpha,
LevelRenderer.getLightColor(mc.level, pos), OverlayTexture.NO_OVERLAY,
ModelUtil.VIRTUAL_DATA, layer);

View File

@@ -33,7 +33,7 @@ public class DiamondRandomizerBagItem extends AbstractRandomizerBagItem{
@Override
public Component getDisplayName() {
return Component.translatable("effortlessbuilding:diamond_randomizer_bag");
return Component.translatable("item.effortlessbuilding.diamond_randomizer_bag");
}
@Nullable

View File

@@ -33,7 +33,7 @@ public class GoldenRandomizerBagItem extends AbstractRandomizerBagItem{
@Override
public Component getDisplayName() {
return Component.translatable("effortlessbuilding:golden_randomizer_bag");
return Component.translatable("item.effortlessbuilding.golden_randomizer_bag");
}
@Nullable

View File

@@ -33,7 +33,7 @@ public class RandomizerBagItem extends AbstractRandomizerBagItem {
@Override
public Component getDisplayName() {
return Component.translatable("effortlessbuilding:randomizer_bag");
return Component.translatable("item.effortlessbuilding.randomizer_bag");
}
@Nullable

View File

@@ -32,6 +32,9 @@ import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings;
import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.create.AllSpecialTextures;
import nl.requios.effortlessbuilding.create.CreateClient;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem;
@@ -51,7 +54,7 @@ public class BlockPreviewRenderer {
private static BlockPos previousSecondPos;
private static int soundTime = 0;
public static void render(PoseStack matrixStack, MultiBufferSource.BufferSource renderTypeBuffer, Player player, ModifierSettings modifierSettings, ModeSettings modeSettings) {
public static void render(PoseStack ms, MultiBufferSource.BufferSource buffer, Player player, ModifierSettings modifierSettings, ModeSettings modeSettings) {
//Render placed blocks with dissolve effect
//Use fancy shader if config allows, otherwise no dissolve
@@ -62,7 +65,7 @@ public class BlockPreviewRenderer {
double totalTime = Mth.clampedLerp(30, 60, placed.firstPos.distSqr(placed.secondPos) / 100.0) * BuildConfig.visuals.dissolveTimeMultiplier.get();
float dissolve = (ClientEvents.ticksInGame - placed.time) / (float) totalTime;
renderBlockPreviews(matrixStack, renderTypeBuffer, placed.coordinates, placed.blockStates, placed.itemStacks, dissolve, placed.firstPos, placed.secondPos, false, placed.breaking);
renderBlockPreviews(ms, buffer, placed.coordinates, placed.blockStates, placed.itemStacks, dissolve, placed.firstPos, placed.secondPos, false, placed.breaking);
}
}
}
@@ -188,22 +191,45 @@ public class BlockPreviewRenderer {
if (blockStates.size() != 0 && newCoordinates.size() == blockStates.size()) {
int blockCount;
//Use fancy shader if config allows, otherwise outlines
if (BuildConfig.visuals.useShaders.get() && newCoordinates.size() < BuildConfig.visuals.shaderThreshold.get()) {
blockCount = renderBlockPreviews(matrixStack, renderTypeBuffer, newCoordinates, blockStates, itemStacks, 0f, firstPos, secondPos, !breaking, breaking);
} else {
VertexConsumer buffer = RenderHandler.beginLines(renderTypeBuffer);
if (!breaking) {
//Use fancy shader if config allows, otherwise outlines
if (BuildConfig.visuals.useShaders.get() && newCoordinates.size() < BuildConfig.visuals.shaderThreshold.get()) {
blockCount = renderBlockPreviews(ms, buffer, newCoordinates, blockStates, itemStacks, 0f, firstPos, secondPos, !breaking, breaking);
Vec3 color = new Vec3(1f, 1f, 1f);
if (breaking) color = new Vec3(1f, 0f, 0f);
CreateClient.OUTLINER.showCluster("blockpreviews", newCoordinates)
.withFaceTexture(AllSpecialTextures.CHECKERED)
.disableNormals()
.lineWidth(1 / 32f)
.colored(new Color(1f, 1f, 1f, 1f));
} else {
// VertexConsumer vc = RenderHandler.beginLines(buffer);
//
// Vec3 color = new Vec3(1f, 1f, 1f);
// if (breaking) color = new Vec3(1f, 0f, 0f);
//
// for (int i = newCoordinates.size() - 1; i >= 0; i--) {
// VoxelShape collisionShape = blockStates.get(i).getCollisionShape(player.level, newCoordinates.get(i));
// RenderHandler.renderBlockOutline(ms, vc, newCoordinates.get(i), collisionShape, color);
// }
//
// RenderHandler.endLines(buffer);
for (int i = newCoordinates.size() - 1; i >= 0; i--) {
VoxelShape collisionShape = blockStates.get(i).getCollisionShape(player.level, newCoordinates.get(i));
RenderHandler.renderBlockOutline(matrixStack, buffer, newCoordinates.get(i), collisionShape, color);
CreateClient.OUTLINER.showCluster("blockpreviews", newCoordinates)
.withFaceTexture(AllSpecialTextures.HIGHLIGHT_CHECKERED)
.disableNormals()
.lineWidth(1 / 16f)
.colored(new Color(1f, 1f, 1f, 1f));
blockCount = newCoordinates.size();
}
RenderHandler.endLines(renderTypeBuffer);
} else {
//Breaking
CreateClient.OUTLINER.showCluster("blockpreviews", newCoordinates)
.withFaceTexture(AllSpecialTextures.THIN_CHECKERED)
.disableNormals()
.lineWidth(1 / 16f)
.colored(new Color(0.8f, 0.1f, 0.1f, 1f));
blockCount = newCoordinates.size();
}
@@ -240,29 +266,29 @@ public class BlockPreviewRenderer {
//Draw outlines if no block in hand
//Find proper raytrace: either normal range or increased range depending on canBreakFar
VertexConsumer buffer = RenderHandler.beginLines(renderTypeBuffer);
HitResult objectMouseOver = Minecraft.getInstance().hitResult;
HitResult breakingRaytrace = ReachHelper.canBreakFar(player) ? lookingAt : objectMouseOver;
if (player.isCreative() && noBlockInHand && breakingRaytrace != null && breakingRaytrace.getType() == HitResult.Type.BLOCK) {
BlockHitResult blockBreakingRaytrace = (BlockHitResult) breakingRaytrace;
List<BlockPos> breakCoordinates = BuildModifiers.findCoordinates(player, blockBreakingRaytrace.getBlockPos());
//Only render first outline if further than normal reach
boolean excludeFirst = objectMouseOver != null && objectMouseOver.getType() == HitResult.Type.BLOCK;
for (int i = excludeFirst ? 1 : 0; i < breakCoordinates.size(); i++) {
BlockPos coordinate = breakCoordinates.get(i);
BlockState blockState = player.level.getBlockState(coordinate);
if (!blockState.isAir()) {
if (SurvivalHelper.canBreak(player.level, player, coordinate) || i == 0) {
VoxelShape collisionShape = blockState.getCollisionShape(player.level, coordinate);
RenderHandler.renderBlockOutline(matrixStack, buffer, coordinate, collisionShape, new Vec3(0f, 0f, 0f));
}
}
}
}
RenderHandler.endLines(renderTypeBuffer);
// VertexConsumer vc = RenderHandler.beginLines(buffer);
// HitResult objectMouseOver = Minecraft.getInstance().hitResult;
// HitResult breakingRaytrace = ReachHelper.canBreakFar(player) ? lookingAt : objectMouseOver;
//
// if (player.isCreative() && noBlockInHand && breakingRaytrace != null && breakingRaytrace.getType() == HitResult.Type.BLOCK) {
// BlockHitResult blockBreakingRaytrace = (BlockHitResult) breakingRaytrace;
// List<BlockPos> breakCoordinates = BuildModifiers.findCoordinates(player, blockBreakingRaytrace.getBlockPos());
//
// //Only render first outline if further than normal reach
// boolean excludeFirst = objectMouseOver != null && objectMouseOver.getType() == HitResult.Type.BLOCK;
// for (int i = excludeFirst ? 1 : 0; i < breakCoordinates.size(); i++) {
// BlockPos coordinate = breakCoordinates.get(i);
//
// BlockState blockState = player.level.getBlockState(coordinate);
// if (!blockState.isAir()) {
// if (SurvivalHelper.canBreak(player.level, player, coordinate) || i == 0) {
// VoxelShape collisionShape = blockState.getCollisionShape(player.level, coordinate);
// RenderHandler.renderBlockOutline(ms, vc, coordinate, collisionShape, new Vec3(0f, 0f, 0f));
// }
// }
// }
// }
// RenderHandler.endLines(buffer);
}
}
@@ -290,9 +316,9 @@ public class BlockPreviewRenderer {
if (CompatHelper.isItemBlockProxy(itemstack))
itemstack = CompatHelper.getItemBlockByState(itemstack, blockState);
//Check if can place
//Check if we can place
//If check is turned off, check if blockstate is the same (for dissolve effect)
if ((!checkCanPlace /*&& player.world.getNewBlockState(blockPos) == blockState*/) || //TODO enable (breaks the breaking shader)
if ((!checkCanPlace && player.level.getBlockState(blockPos) == blockState) || //TODO enable (breaks the breaking shader)
SurvivalHelper.canPlace(player.level, player, blockPos, blockState, itemstack, modifierSettings.doQuickReplace(), Direction.UP)) {
RenderHandler.renderBlockPreview(matrixStack, renderTypeBuffer, dispatcher, blockPos, blockState, dissolve, firstPos, secondPos, red);

View File

@@ -14,6 +14,7 @@ import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
@@ -22,11 +23,14 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderLevelLastEvent;
import net.minecraftforge.client.event.RenderLevelStageEvent;
import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.create.CreateClient;
import nl.requios.effortlessbuilding.create.events.ClientEvents;
/***
* Main render class for Effortless Building
@@ -34,6 +38,17 @@ import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
@EventBusSubscriber(Dist.CLIENT)
public class RenderHandler {
@SubscribeEvent
public static void onTick(TickEvent.ClientTickEvent event) {
if (!ClientEvents.isGameActive()) return;
Player player = Minecraft.getInstance().player;
ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player);
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
BlockPreviewRenderer.render(null, null, player, modifierSettings, modeSettings);
}
@SubscribeEvent
public static void onRender(RenderLevelLastEvent event) {
Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition();
@@ -83,39 +98,44 @@ public class RenderHandler {
renderTypeBuffer.endBatch();
}
protected static void renderBlockPreview(PoseStack matrixStack, MultiBufferSource.BufferSource renderTypeBuffer, BlockRenderDispatcher dispatcher,
protected static void renderBlockPreview(PoseStack ms, MultiBufferSource.BufferSource buffer, BlockRenderDispatcher dispatcher,
BlockPos blockPos, BlockState blockState, float dissolve, BlockPos firstPos, BlockPos secondPos, boolean red) {
if (blockState == null) return;
matrixStack.pushPose();
matrixStack.translate(blockPos.getX(), blockPos.getY(), blockPos.getZ());
// matrixStack.rotate(Vector3f.YP.rotationDegrees(-90f));
matrixStack.translate(-0.01f, -0.01f, -0.01f);
matrixStack.scale(1.02f, 1.02f, 1.02f);
CreateClient.GHOST_BLOCKS.showGhostState(blockPos.toShortString(), blockState)
// .breathingAlpha()
.alpha(0.7f)
.at(blockPos);
//Begin block preview rendering
RenderType blockPreviewRenderType = BuildRenderTypes.getBlockPreviewRenderType(dissolve, blockPos, firstPos, secondPos, red);
VertexConsumer buffer = renderTypeBuffer.getBuffer(blockPreviewRenderType);
try {
BakedModel model = dispatcher.getBlockModel(blockState);
dispatcher.getModelRenderer().renderModel(matrixStack.last(), buffer, blockState, model,
1f, 1f, 1f, 0, OverlayTexture.NO_OVERLAY, ModelData.EMPTY, blockPreviewRenderType);
} catch (NullPointerException e) {
EffortlessBuilding.logger.warn("RenderHandler::renderBlockPreview cannot render " + blockState.getBlock().toString());
//Render outline as backup, escape out of the current renderstack
matrixStack.popPose();
renderTypeBuffer.endBatch();
VertexConsumer lineBuffer = beginLines(renderTypeBuffer);
renderBlockOutline(matrixStack, lineBuffer, blockPos, new Vec3(1f, 1f, 1f));
endLines(renderTypeBuffer);
buffer = renderTypeBuffer.getBuffer(Sheets.translucentCullBlockSheet()); //any type will do, as long as we have something on the stack
matrixStack.pushPose();
}
renderTypeBuffer.endBatch();
matrixStack.popPose();
// ms.pushPose();
// ms.translate(blockPos.getX(), blockPos.getY(), blockPos.getZ());
//// ms.rotate(Vector3f.YP.rotationDegrees(-90f));
// ms.translate(-0.01f, -0.01f, -0.01f);
// ms.scale(1.02f, 1.02f, 1.02f);
//
// //Begin block preview rendering
// RenderType blockPreviewRenderType = BuildRenderTypes.getBlockPreviewRenderType(dissolve, blockPos, firstPos, secondPos, red);
// VertexConsumer vc = buffer.getBuffer(blockPreviewRenderType);
//
// try {
// BakedModel model = dispatcher.getBlockModel(blockState);
// dispatcher.getModelRenderer().renderModel(ms.last(), vc, blockState, model,
// 1f, 1f, 1f, 0, OverlayTexture.NO_OVERLAY, ModelData.EMPTY, blockPreviewRenderType);
// } catch (NullPointerException e) {
// EffortlessBuilding.logger.warn("RenderHandler::renderBlockPreview cannot render " + blockState.getBlock().toString());
//
// //Render outline as backup, escape out of the current renderstack
// ms.popPose();
// buffer.endBatch();
// VertexConsumer lineBuffer = beginLines(buffer);
// renderBlockOutline(ms, lineBuffer, blockPos, new Vec3(1f, 1f, 1f));
// endLines(buffer);
// vc = buffer.getBuffer(Sheets.translucentCullBlockSheet()); //any type will do, as long as we have something on the stack
// ms.pushPose();
// }
//
// buffer.endBatch();
// ms.popPose();
}
protected static void renderBlockOutline(PoseStack matrixStack, VertexConsumer buffer, BlockPos pos, Vec3 color) {