Skip to content

Commit d9b3a03

Browse files
committed
Merge branch 'new-projector-render' into 1.16.x
2 parents 095255a + 1a3686e commit d9b3a03

14 files changed

+346
-36
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package dev.compactmods.crafting.capability;
2+
3+
import javax.annotation.Nullable;
4+
import net.minecraft.nbt.CompoundNBT;
5+
import net.minecraft.nbt.INBT;
6+
import net.minecraft.util.Direction;
7+
import net.minecraftforge.common.capabilities.Capability;
8+
import net.minecraftforge.common.capabilities.CapabilityInject;
9+
import net.minecraftforge.common.capabilities.CapabilityManager;
10+
11+
public class CapabilityProjectorRenderInfo {
12+
@CapabilityInject(IProjectorRenderInfo.class)
13+
public static Capability<IProjectorRenderInfo> TEMP_PROJECTOR_RENDERING = null;
14+
15+
public static void setup() {
16+
CapabilityManager.INSTANCE.register(
17+
IProjectorRenderInfo.class,
18+
new Capability.IStorage<IProjectorRenderInfo>() {
19+
@Nullable
20+
@Override
21+
public INBT writeNBT(Capability<IProjectorRenderInfo> capability, IProjectorRenderInfo instance, Direction side) {
22+
return new CompoundNBT();
23+
}
24+
25+
@Override
26+
public void readNBT(Capability<IProjectorRenderInfo> capability, IProjectorRenderInfo instance, Direction side, INBT nbt) {
27+
28+
}
29+
}, null);
30+
}
31+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package dev.compactmods.crafting.capability;
2+
3+
import java.util.Set;
4+
import com.mojang.blaze3d.matrix.MatrixStack;
5+
import net.minecraft.util.math.BlockPos;
6+
import net.minecraft.world.World;
7+
8+
public interface IProjectorRenderInfo {
9+
10+
Set<BlockPos> getMissingProjectors();
11+
12+
int getRenderTimeLeft();
13+
14+
void render(MatrixStack matrixStack);
15+
16+
void tick();
17+
18+
void resetRenderTime();
19+
20+
void setProjector(World world, BlockPos pos);
21+
}

src/main/java/dev/compactmods/crafting/client/ClientConfig.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ public class ClientConfig {
1414

1515
private static ForgeConfigSpec.ConfigValue<String> PROJECTOR_COLOR;
1616
private static ForgeConfigSpec.ConfigValue<String> PROJECTOR_OFF_COLOR;
17+
private static ForgeConfigSpec.IntValue PLACEMENT_TIME;
1718

1819
public static ForgeConfigSpec.BooleanValue ENABLE_DEBUG_ON_F3;
1920

2021
public static int projectorColor = 0xFFFFFFFF;
2122
public static int projectorOffColor = 0xFFFFFFFF;
23+
public static int placementTime = 60;
2224

2325
static {
2426
generateConfig();
@@ -50,6 +52,10 @@ private static void generateConfig() {
5052
.comment("Whether or not activating F3 will enable debug renderers.")
5153
.define("projectorDebugger", false);
5254

55+
PLACEMENT_TIME = builder
56+
.comment("How long (ticks) the placement helper will show on right-clicking a projector.")
57+
.defineInRange("placementTime", 160, 60, 240);
58+
5359
builder.pop();
5460

5561
CONFIG = builder.build();
@@ -59,6 +65,7 @@ private static void generateConfig() {
5965
public static void onLoad(final ModConfig.ModConfigEvent configEvent) {
6066
projectorColor = extractHexColor(PROJECTOR_COLOR.get(), 0x00FF6A00);
6167
projectorOffColor = extractHexColor(PROJECTOR_OFF_COLOR.get(), 0x00898989);
68+
placementTime = PLACEMENT_TIME.get();
6269
}
6370

6471
private static int extractHexColor(String hex, int def) {

src/main/java/dev/compactmods/crafting/client/ClientEventHandler.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
import dev.compactmods.crafting.CompactCrafting;
55
import dev.compactmods.crafting.api.EnumCraftingState;
66
import dev.compactmods.crafting.api.field.IActiveWorldFields;
7+
import dev.compactmods.crafting.capability.CapabilityProjectorRenderInfo;
8+
import dev.compactmods.crafting.capability.IProjectorRenderInfo;
79
import dev.compactmods.crafting.field.capability.CapabilityActiveWorldFields;
810
import dev.compactmods.crafting.field.render.CraftingPreviewRenderer;
911
import net.minecraft.client.Minecraft;
12+
import net.minecraft.client.entity.player.ClientPlayerEntity;
1013
import net.minecraft.client.renderer.ActiveRenderInfo;
1114
import net.minecraft.client.renderer.IRenderTypeBuffer;
12-
import net.minecraft.client.renderer.WorldRenderer;
1315
import net.minecraft.client.renderer.texture.OverlayTexture;
1416
import net.minecraft.client.world.ClientWorld;
1517
import net.minecraft.util.math.BlockPos;
@@ -28,6 +30,12 @@ public class ClientEventHandler {
2830
public static void onTick(final TickEvent.ClientTickEvent evt) {
2931
if (evt.phase != TickEvent.Phase.START) return;
3032

33+
final ClientPlayerEntity player = Minecraft.getInstance().player;
34+
if(player != null) {
35+
player.getCapability(CapabilityProjectorRenderInfo.TEMP_PROJECTOR_RENDERING)
36+
.ifPresent(IProjectorRenderInfo::tick);
37+
}
38+
3139
ClientWorld level = Minecraft.getInstance().level;
3240
if (level != null && !Minecraft.getInstance().isPaused()) {
3341
level.getCapability(CapabilityActiveWorldFields.ACTIVE_WORLD_FIELDS)
@@ -37,13 +45,14 @@ public static void onTick(final TickEvent.ClientTickEvent evt) {
3745

3846
@SubscribeEvent
3947
public static void onWorldRender(final RenderWorldLastEvent event) {
40-
final WorldRenderer renderer = event.getContext();
41-
4248
final Minecraft mc = Minecraft.getInstance();
4349

4450
if (mc.level == null)
4551
return;
4652

53+
mc.player.getCapability(CapabilityProjectorRenderInfo.TEMP_PROJECTOR_RENDERING)
54+
.ifPresent(render -> render.render(event.getMatrixStack()));
55+
4756
final ActiveRenderInfo mainCamera = mc.gameRenderer.getMainCamera();
4857
final RayTraceResult hitResult = mc.hitResult;
4958

@@ -77,5 +86,7 @@ public static void onWorldRender(final RenderWorldLastEvent event) {
7786
stack.popPose();
7887
});
7988
});
89+
90+
buffers.endBatch();
8091
}
8192
}

src/main/java/dev/compactmods/crafting/projector/render/CCRenderTypes.java renamed to src/main/java/dev/compactmods/crafting/client/render/CCRenderTypes.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.compactmods.crafting.projector.render;
1+
package dev.compactmods.crafting.client.render;
22

33
import com.mojang.blaze3d.platform.GlStateManager;
44
import com.mojang.blaze3d.systems.RenderSystem;
@@ -36,13 +36,12 @@ public CCRenderTypes(String p_i225992_1_, VertexFormat p_i225992_2_, int p_i2259
3636
.setWriteMaskState(COLOR_WRITE)
3737
.createCompositeState(false));
3838

39-
// public static final RenderType FIELD_PROJECTION_ARC = RenderType.create("projection_field_arc",
40-
// DefaultVertexFormats.POSITION_COLOR, GL11.GL_QUADS, 256,
41-
// RenderType.State.builder()
42-
// .setTransparencyState(PROJECTION_TRANSPARENCY)
43-
// .setCullState(new RenderState.CullState(false))
44-
// .setWriteMaskState(new RenderState.WriteMaskState(true, true))
45-
// .createCompositeState(false));
39+
public static final RenderType PHANTOM = create("phantom", DefaultVertexFormats.BLOCK, 7, 2097152, true, false, RenderType.State.builder()
40+
.setShadeModelState(RenderState.SMOOTH_SHADE)
41+
.setLightmapState(RenderState.LIGHTMAP)
42+
.setTextureState(BLOCK_SHEET_MIPPED)
43+
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
44+
.createCompositeState(true));
4645

4746

4847

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package dev.compactmods.crafting.client.render;
2+
3+
import java.util.HashMap;
4+
import java.util.Optional;
5+
import java.util.Set;
6+
import com.mojang.blaze3d.matrix.MatrixStack;
7+
import dev.compactmods.crafting.Registration;
8+
import dev.compactmods.crafting.api.field.MiniaturizationFieldSize;
9+
import dev.compactmods.crafting.capability.IProjectorRenderInfo;
10+
import dev.compactmods.crafting.client.ClientConfig;
11+
import dev.compactmods.crafting.projector.FieldProjectorBlock;
12+
import dev.compactmods.crafting.projector.ProjectorHelper;
13+
import net.minecraft.block.AbstractBlock;
14+
import net.minecraft.block.BlockState;
15+
import net.minecraft.block.Blocks;
16+
import net.minecraft.client.Minecraft;
17+
import net.minecraft.client.renderer.ActiveRenderInfo;
18+
import net.minecraft.client.renderer.IRenderTypeBuffer;
19+
import net.minecraft.client.world.ClientWorld;
20+
import net.minecraft.util.Direction;
21+
import net.minecraft.util.math.BlockPos;
22+
import net.minecraft.util.math.vector.Vector3d;
23+
import net.minecraft.world.World;
24+
25+
public class ClientProjectorRenderInfo implements IProjectorRenderInfo {
26+
27+
private final BlockState baseState;
28+
private final HashMap<BlockPos, Direction> remainingProjectors;
29+
private int renderTime;
30+
31+
32+
public ClientProjectorRenderInfo() {
33+
this.remainingProjectors = new HashMap<>(4);
34+
this.baseState = Registration.FIELD_PROJECTOR_BLOCK.get().defaultBlockState();
35+
}
36+
37+
@Override
38+
public Set<BlockPos> getMissingProjectors() {
39+
return remainingProjectors.keySet();
40+
}
41+
42+
@Override
43+
public int getRenderTimeLeft() {
44+
return renderTime;
45+
}
46+
47+
@Override
48+
public void render(MatrixStack matrixStack) {
49+
if (this.renderTime == 0) return;
50+
if (this.remainingProjectors.isEmpty()) return;
51+
52+
final Minecraft mc = Minecraft.getInstance();
53+
final IRenderTypeBuffer.Impl buffers = mc.renderBuffers().bufferSource();
54+
final ActiveRenderInfo mainCamera = mc.gameRenderer.getMainCamera();
55+
final ClientWorld level = mc.level;
56+
57+
matrixStack.pushPose();
58+
Vector3d projectedView = mainCamera.getPosition();
59+
matrixStack.translate(-projectedView.x, -projectedView.y, -projectedView.z);
60+
61+
remainingProjectors.forEach((pos, dir) -> {
62+
matrixStack.pushPose();
63+
matrixStack.translate(
64+
(double) pos.getX() + 0.05,
65+
(double) pos.getY() + 0.05,
66+
(double) pos.getZ() + 0.05
67+
);
68+
69+
matrixStack.scale(0.9f, 0.9f, 0.9f);
70+
71+
GhostRenderer.renderTransparentBlock(baseState.setValue(FieldProjectorBlock.FACING, dir), pos, matrixStack, buffers, renderTime);
72+
matrixStack.popPose();
73+
74+
for (int y = -1; y > -10; y--) {
75+
BlockPos realPos = new BlockPos(pos.getX(), pos.getY() + y, pos.getZ());
76+
if(!level.isStateAtPosition(realPos, AbstractBlock.AbstractBlockState::isAir))
77+
break;
78+
79+
matrixStack.pushPose();
80+
matrixStack.translate(
81+
(double) pos.getX() + 0.15,
82+
(double) pos.getY() + 0.15 + y,
83+
(double) pos.getZ() + 0.15
84+
);
85+
86+
matrixStack.scale(0.6f, 0.6f, 0.6f);
87+
GhostRenderer.renderTransparentBlock(Blocks.BLACK_STAINED_GLASS.defaultBlockState(), null, matrixStack, buffers, renderTime);
88+
matrixStack.popPose();
89+
}
90+
});
91+
92+
matrixStack.popPose();
93+
buffers.endBatch();
94+
}
95+
96+
@Override
97+
public void tick() {
98+
if (renderTime > 0) this.renderTime--;
99+
if (renderTime < 0) this.renderTime = 0;
100+
}
101+
102+
@Override
103+
public void resetRenderTime() {
104+
this.renderTime = ClientConfig.placementTime;
105+
}
106+
107+
@Override
108+
public void setProjector(World level, BlockPos initial) {
109+
remainingProjectors.clear();
110+
111+
Optional<MiniaturizationFieldSize> fieldSize = ProjectorHelper.getClosestOppositeSize(level, initial);
112+
final Direction initialFacing = FieldProjectorBlock.getDirection(level, initial).orElse(Direction.UP);
113+
if(fieldSize.isPresent()) {
114+
final BlockPos center = fieldSize.get().getCenterFromProjector(initial, initialFacing);
115+
Direction.Plane.HORIZONTAL.stream()
116+
.forEach(dir -> {
117+
if(dir == initialFacing) return;
118+
119+
final BlockPos location = fieldSize.get().getProjectorLocationForDirection(center, dir);
120+
remainingProjectors.put(location, dir.getOpposite());
121+
});
122+
} else {
123+
ProjectorHelper.getValidOppositePositions(initial, initialFacing)
124+
.forEach(pos -> this.remainingProjectors.put(pos, initialFacing.getOpposite()));
125+
}
126+
}
127+
}

src/main/java/dev/compactmods/crafting/projector/render/CubeRenderHelper.java renamed to src/main/java/dev/compactmods/crafting/client/render/CubeRenderHelper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.compactmods.crafting.projector.render;
1+
package dev.compactmods.crafting.client.render;
22

33
import com.mojang.blaze3d.matrix.MatrixStack;
44
import com.mojang.blaze3d.vertex.IVertexBuilder;
@@ -98,7 +98,7 @@ public static Vector3d getCubeFacePoint(AxisAlignedBB cube, Direction face, Enum
9898

9999
public static double getScanLineHeight(AxisAlignedBB cube, double gameTime) {
100100
// Get the height of the scan line
101-
double zAngle = ((Math.sin(Math.toDegrees(gameTime) / -FieldProjectorRenderer.RotationSpeed.MEDIUM.getSpeed()) + 1.0d) / 2) * (cube.getYsize());
101+
double zAngle = ((Math.sin(Math.toDegrees(gameTime) / -RotationSpeed.MEDIUM.getSpeed()) + 1.0d) / 2) * (cube.getYsize());
102102
double scanHeight = (cube.minY + zAngle);
103103

104104
return scanHeight;

src/main/java/dev/compactmods/crafting/projector/render/EnumCubeFaceCorner.java renamed to src/main/java/dev/compactmods/crafting/client/render/EnumCubeFaceCorner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.compactmods.crafting.projector.render;
1+
package dev.compactmods.crafting.client.render;
22

33
public enum EnumCubeFaceCorner {
44
BOTTOM_LEFT,
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package dev.compactmods.crafting.client.render;
2+
3+
import javax.annotation.Nullable;
4+
import java.util.Random;
5+
import com.mojang.blaze3d.matrix.MatrixStack;
6+
import com.mojang.blaze3d.vertex.IVertexBuilder;
7+
import net.minecraft.block.BlockState;
8+
import net.minecraft.client.Minecraft;
9+
import net.minecraft.client.renderer.IRenderTypeBuffer;
10+
import net.minecraft.client.renderer.LightTexture;
11+
import net.minecraft.client.renderer.color.BlockColors;
12+
import net.minecraft.client.renderer.model.BakedQuad;
13+
import net.minecraft.client.renderer.model.IBakedModel;
14+
import net.minecraft.client.renderer.texture.OverlayTexture;
15+
import net.minecraft.util.ColorHelper;
16+
import net.minecraft.util.Direction;
17+
import net.minecraft.util.math.BlockPos;
18+
import net.minecraft.util.math.MathHelper;
19+
import net.minecraftforge.client.model.data.EmptyModelData;
20+
21+
public class GhostRenderer {
22+
public static void renderTransparentBlock(BlockState state, @Nullable BlockPos pos, MatrixStack matrix, IRenderTypeBuffer buffer) {
23+
renderTransparentBlock(state, pos, matrix, buffer, 100);
24+
}
25+
26+
public static void renderTransparentBlock(BlockState state, @Nullable BlockPos pos, MatrixStack matrix, IRenderTypeBuffer buffer, int ticksLeft) {
27+
final Minecraft mc = Minecraft.getInstance();
28+
final BlockColors colors = mc.getBlockColors();
29+
30+
// clamp b/n 0-100, effective range 0 - 0.9f
31+
final float alpha = ticksLeft >= 100 ? 0.9f : 0.9f * Math.max(ticksLeft / 100f, .1f);
32+
33+
IVertexBuilder builder = buffer.getBuffer(CCRenderTypes.PHANTOM);
34+
IBakedModel model = mc.getBlockRenderer().getBlockModel(state.getBlockState());
35+
if (model != mc.getModelManager().getMissingModel()) {
36+
for(Direction dir : Direction.values())
37+
model.getQuads(state.getBlockState(), dir, new Random(42L), EmptyModelData.INSTANCE)
38+
.forEach(quad -> addQuad(state, pos, matrix, mc, colors, builder, quad, alpha));
39+
40+
model.getQuads(state.getBlockState(), null, new Random(42L), EmptyModelData.INSTANCE)
41+
.forEach(quad -> addQuad(state, pos, matrix, mc, colors, builder, quad, alpha));
42+
}
43+
}
44+
45+
private static void addQuad(BlockState state, @Nullable BlockPos pos, MatrixStack matrix, Minecraft mc, BlockColors colors, IVertexBuilder builder, BakedQuad quad, float alpha) {
46+
int color = quad.isTinted() ? colors.getColor(state, mc.level, pos, quad.getTintIndex()) :
47+
ColorHelper.PackedColor.color(255, 255, 255, 255);
48+
49+
final float red = ColorHelper.PackedColor.red(color) / 255f;
50+
final float green = ColorHelper.PackedColor.green(color) / 255f;
51+
final float blue = ColorHelper.PackedColor.blue(color) / 255f;
52+
53+
final float trueAlpha = MathHelper.clamp(0.01f, alpha, 0.06f);
54+
builder.addVertexData(matrix.last(), quad,
55+
red,
56+
green,
57+
blue,
58+
trueAlpha,
59+
LightTexture.pack(15, 15), OverlayTexture.NO_OVERLAY);
60+
}
61+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package dev.compactmods.crafting.client.render;
2+
3+
public enum RotationSpeed {
4+
SLOW(5000),
5+
MEDIUM(2500),
6+
FAST(1000);
7+
8+
private int speed;
9+
10+
RotationSpeed(int speed) {
11+
this.speed = speed;
12+
}
13+
14+
public int getSpeed() {
15+
return speed;
16+
}
17+
}

0 commit comments

Comments
 (0)