Skip to content

Commit

Permalink
Merge pull request #183 from robotman2412/lines
Browse files Browse the repository at this point in the history
Line rendering improvements
  • Loading branch information
Sm0keySa1m0n committed Feb 25, 2024
2 parents 3db0047 + 71ec267 commit c7d4cad
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 87 deletions.
4 changes: 2 additions & 2 deletions src/api/java/mods/railcraft/api/signal/TokenRing.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ This work (the API) is licensed under the "MIT" License,

import java.util.Set;
import java.util.UUID;
import net.minecraft.core.BlockPos;
import net.minecraft.world.phys.Vec3;

public interface TokenRing extends SignalNetwork<TokenSignalEntity> {

Set<UUID> getTrackedCarts();

UUID getId();

BlockPos getCentroid();
Vec3 getCentroid();
}
4 changes: 2 additions & 2 deletions src/api/java/mods/railcraft/api/signal/TokenSignalEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ This work (the API) is licensed under the "MIT" License,

import java.util.UUID;
import mods.railcraft.api.signal.entity.MonitoringSignalEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.phys.Vec3;

public interface TokenSignalEntity extends MonitoringSignalEntity<TokenSignalEntity> {

BlockPos ringCentroidPos();
Vec3 ringCentroidPos();

UUID ringId();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@

import java.util.Collection;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import mods.railcraft.client.util.RenderUtil;
import mods.railcraft.client.util.LineRenderer;
import mods.railcraft.network.play.LinkedCartsMessage;
import mods.railcraft.world.item.GogglesItem;
import mods.railcraft.world.item.RailcraftItems;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;

public class ShuntingAuraRenderer {

Expand Down Expand Up @@ -48,36 +47,13 @@ public void render(PoseStack poseStack, Camera mainCamera, float partialTick) {
continue;
}

var consumer = bufferSource.getBuffer(RenderType.lines());
var pose = poseStack.last();

var renderer = LineRenderer.create(bufferSource);
final int color = linkedCart.trainId().hashCode();
float red = RenderUtil.getRed(color);
float green = RenderUtil.getGreen(color);
float blue = RenderUtil.getBlue(color);

final var cartPosition = cart.getPosition(partialTick);
final float cartX = (float) cartPosition.x();
final float cartY = (float) cartPosition.y();
final float cartZ = (float) cartPosition.z();

var matrix4f = pose.pose();
var matrix3f = pose.normal();
consumer
.vertex(matrix4f, cartX, cartY, cartZ)
.color(red, green, blue, 1)
.normal(matrix3f, 0, 0, 0)
.endVertex();
consumer
.vertex(matrix4f, cartX, cartY + 2, cartZ)
.color(red, green, blue, 1)
.normal(matrix3f, 0, 0, 0)
.endVertex();

this.renderLink(level, cartX, cartY, cartZ, linkedCart.linkAId(), red,
green, blue, partialTick, consumer, pose);
this.renderLink(level, cartX, cartY, cartZ, linkedCart.linkBId(), red,
green, blue, partialTick, consumer, pose);
renderer.renderLine(poseStack, color, cartPosition, cartPosition.add(0, 2, 0));
this.renderLink(level, cartPosition, linkedCart.linkAId(), color, partialTick, renderer, poseStack);
this.renderLink(level, cartPosition, linkedCart.linkBId(), color, partialTick, renderer, poseStack);

bufferSource.endBatch();
}
Expand All @@ -86,9 +62,7 @@ public void render(PoseStack poseStack, Camera mainCamera, float partialTick) {
}
}

private void renderLink(Level level, float cartX, float cartY, float cartZ, int cartId,
float red, float green, float blue, float partialTick, VertexConsumer consumer,
PoseStack.Pose pose) {
private void renderLink(Level level, Vec3 cartPosition, int cartId, int color, float partialTick, LineRenderer renderer, PoseStack poseStack) {
if (cartId == -1) {
return;
}
Expand All @@ -99,16 +73,6 @@ private void renderLink(Level level, float cartX, float cartY, float cartZ, int
}

var cartAPosition = cartA.getPosition(partialTick);
consumer
.vertex(pose.pose(), cartX, cartY + 2, cartZ)
.color(red, green, blue, 1)
.normal(pose.normal(), 0, 0, 0)
.endVertex();
consumer
.vertex(pose.pose(), (float) cartAPosition.x(), (float) cartAPosition.y() + 1.5F,
(float) cartAPosition.z())
.color(red, green, blue, 1)
.normal(pose.normal(), 0, 0, 0)
.endVertex();
renderer.renderLine(poseStack, color, cartAPosition.add(0, 1.5f, 0), cartPosition.add(0, 2, 0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
import mods.railcraft.api.signal.TokenSignalEntity;
import mods.railcraft.api.signal.entity.SignalControllerEntity;
import mods.railcraft.client.util.RenderUtil;
import mods.railcraft.client.util.SimpleLineRenderer;
import mods.railcraft.world.item.GogglesItem;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.phys.Vec3;

public class SignalAuraRenderUtil {

Expand Down Expand Up @@ -41,50 +42,65 @@ public static void tryRenderSignalAura(BlockEntity blockEntity,
} else if (blockEntity instanceof TokenSignalEntity tokenSignal) {
var centroid = Collections.singletonList(tokenSignal.ringCentroidPos());
if (GogglesItem.isGoggleAuraActive(GogglesItem.Aura.SURVEYING)) {
renderSignalAura(blockEntity, poseStack, bufferSource, centroid,
renderSignalAuraf(blockEntity, poseStack, bufferSource, centroid,
(t, s, d) -> tokenSignal.ringId().hashCode());
} else if (GogglesItem.isGoggleAuraActive(GogglesItem.Aura.SIGNALLING)) {
renderSignalAura(blockEntity, poseStack, bufferSource, centroid,
renderSignalAuraf(blockEntity, poseStack, bufferSource, centroid,
ColorProfile.CONSTANT_BLUE);
}
}
}

private static void renderSignalAuraf(
BlockEntity blockEntity, PoseStack poseStack, MultiBufferSource bufferSource,
Collection<Vec3> endPoints, ColorSupplier colorProfile) {
if (endPoints.isEmpty()) {
return;
}

var renderer = new SimpleLineRenderer(bufferSource);
for (Vec3 target : endPoints) {
int color = colorProfile.getColor(blockEntity, blockEntity.getBlockPos(), BlockPos.containing(target));
float red = RenderUtil.getRed(color);
float green = RenderUtil.getGreen(color);
float blue = RenderUtil.getBlue(color);

float endX = (float) target.x() - blockEntity.getBlockPos().getX();
float endY = (float) target.y() - blockEntity.getBlockPos().getY();
float endZ = (float) target.z() - blockEntity.getBlockPos().getZ();

renderer.renderLine(poseStack,
red ,green, blue,
0.5F, 0.5F, 0.5F,
endX, endY, endZ
);
}
}

private static void renderSignalAura(
BlockEntity blockEntity, PoseStack poseStack, MultiBufferSource bufferSource,
Collection<BlockPos> endPoints, ColorSupplier colorProfile) {
if (endPoints.isEmpty()) {
return;
}

poseStack.pushPose();
var consumer = bufferSource.getBuffer(RenderType.lines());
var matrix = poseStack.last().pose();
var normal = poseStack.last().normal();

var renderer = new SimpleLineRenderer(bufferSource);
for (BlockPos target : endPoints) {
int color = colorProfile.getColor(blockEntity, blockEntity.getBlockPos(), target);
float red = RenderUtil.getRed(color);
float green = RenderUtil.getGreen(color);
float blue = RenderUtil.getBlue(color);

consumer
.vertex(matrix, 0.5F, 0.5F, 0.5F)
.color(red, green, blue, 1)
.normal(normal, 1, 0, 0)
.endVertex();

float endX = 0.5F + target.getX() - blockEntity.getBlockPos().getX();
float endY = 0.5F + target.getY() - blockEntity.getBlockPos().getY();
float endZ = 0.5F + target.getZ() - blockEntity.getBlockPos().getZ();

consumer
.vertex(matrix, endX, endY, endZ)
.color(red, green, blue, 1)
.normal(normal, 1, 0, 0)
.endVertex();
renderer.renderLine(poseStack,
red, green, blue,
0.5F, 0.5F, 0.5F,
endX, endY, endZ
);
}
poseStack.popPose();
}

@FunctionalInterface
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/mods/railcraft/client/util/LineRenderer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package mods.railcraft.client.util;

import org.joml.Vector3f;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.world.phys.Vec3;

public interface LineRenderer {
static LineRenderer create(MultiBufferSource bufferSource) {
return new SimpleLineRenderer(bufferSource);
}

default void renderLine(PoseStack poseStack, int color, Vec3 from, Vec3 to) {
renderLine(poseStack,
RenderUtil.getRed(color), RenderUtil.getGreen(color), RenderUtil.getBlue(color),
(float) from.x, (float) from.y, (float) from.z,
(float) to.x, (float) to.y, (float) to.z
);
}

default void renderLine(PoseStack poseStack, int color, Vector3f from, Vector3f to) {
renderLine(poseStack,
RenderUtil.getRed(color), RenderUtil.getGreen(color), RenderUtil.getBlue(color),
from.x, from.y, from.z,
to.x, to.y, to.z
);
}

void renderLine(PoseStack poseStack, float r, float g, float b, float x0, float y0, float z0, float x1, float y1, float z1);
}
38 changes: 38 additions & 0 deletions src/main/java/mods/railcraft/client/util/SimpleLineRenderer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package mods.railcraft.client.util;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;

public class SimpleLineRenderer implements LineRenderer {
private final VertexConsumer consumer;

public SimpleLineRenderer(MultiBufferSource bufferSource) {
consumer = bufferSource.getBuffer(RenderType.lines());
}

public void renderLine(PoseStack poseStack, float r, float g, float b, float x0, float y0, float z0, float x1, float y1, float z1) {
poseStack.pushPose();
var matrix = poseStack.last().pose();
var normal = poseStack.last().normal();

// Draw a copy with each UV value to make the line visible from all angles.
for (int i = 0; i < 3; i++) {
int nx = i == 0 ? 1 : 0;
int ny = i == 1 ? 1 : 0;
int nz = i == 2 ? 1 : 0;
consumer
.vertex(matrix, x0, y0, z0)
.color(r, g, b, 1)
.normal(normal, nx, ny, nz)
.endVertex();
consumer
.vertex(matrix, x1, y1, z1)
.color(r, g, b, 1)
.normal(normal, nx, ny, nz)
.endVertex();
}
poseStack.popPose();
}
}
14 changes: 7 additions & 7 deletions src/main/java/mods/railcraft/util/MathUtil.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
package mods.railcraft.util;

import java.util.Collection;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.world.phys.Vec3;

public final class MathUtil {

public static boolean nearZero(double f) {
return Math.abs(f) < 0.001;
}

public static BlockPos centroid(Collection<? extends Vec3i> points) {
public static Vec3 centroid(Collection<? extends Vec3i> points) {
if (points.isEmpty()) {
return BlockPos.ZERO;
return Vec3.ZERO;
}
double x = 0;
double y = 0;
double z = 0;
for (var pos : points) {
x += pos.getX();
y += pos.getY();
z += pos.getZ();
x += pos.getX() + 0.5;
y += pos.getY() + 0.5;
z += pos.getZ() + 0.5;
}
int size = points.size();
x /= size;
y /= size;
z /= size;
return BlockPos.containing(x, y, z);
return new Vec3(x, y, z);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;

public class TokenSignalBlockEntity extends AbstractSignalBlockEntity
implements SignalControllerEntity, TokenSignalEntity {
Expand All @@ -29,7 +30,7 @@ public class TokenSignalBlockEntity extends AbstractSignalBlockEntity
__ -> this.level.getLightEngine().checkBlock(this.getBlockPos()));

private UUID ringId = UUID.randomUUID();
private BlockPos ringCentroidPos;
private Vec3 ringCentroidPos;

private final TimerBag<UUID> cartTimers = new TimerBag<>(8);
private final TrackLocator trackLocator;
Expand Down Expand Up @@ -110,15 +111,17 @@ public void load(CompoundTag tag) {
public void writeToBuf(FriendlyByteBuf data) {
super.writeToBuf(data);
this.signalController.writeToBuf(data);
data.writeBlockPos(this.signalNetwork().getCentroid());
data.writeFloat((float) this.ringCentroidPos.x());
data.writeFloat((float) this.ringCentroidPos.y());
data.writeFloat((float) this.ringCentroidPos.z());
data.writeUUID(this.ringId);
}

@Override
public void readFromBuf(FriendlyByteBuf data) {
super.readFromBuf(data);
this.signalController.readFromBuf(data);
this.ringCentroidPos = data.readBlockPos();
this.ringCentroidPos = new Vec3(data.readFloat(), data.readFloat(), data.readFloat());
this.ringId = data.readUUID();
}

Expand All @@ -132,9 +135,9 @@ public void setRingId(UUID tokenRingId) {
}

@Override
public BlockPos ringCentroidPos() {
public Vec3 ringCentroidPos() {
if (this.ringCentroidPos == null)
return this.getBlockPos();
return this.getBlockPos().getCenter();
return this.ringCentroidPos;
}

Expand Down

0 comments on commit c7d4cad

Please sign in to comment.