Revert "Rewrite outline buffering"

This reverts commit d4106d545b.
This commit is contained in:
techno-sam 2023-05-05 21:16:49 -07:00
parent 171897bed2
commit 726bfaf0b5
17 changed files with 314 additions and 877 deletions

View file

@ -1350,7 +1350,7 @@ public class AllBlocks {
.unlockedBy("has_seat", RegistrateRecipeProvider.has(AllItemTags.SEATS.tag)) .unlockedBy("has_seat", RegistrateRecipeProvider.has(AllItemTags.SEATS.tag))
.save(p, Create.asResource("crafting/kinetics/" + c.getName() + "_from_other_seat")); .save(p, Create.asResource("crafting/kinetics/" + c.getName() + "_from_other_seat"));
}) })
.onRegisterAfter(Registry.ITEM_REGISTRY, v -> TooltipHelper.referTo(v, "block.create.seat")) .onRegisterAfter(Registry.ITEM_REGISTRY, v -> TooltipHelper.referTo(v, "block.create.brown_seat"))
.tag(AllBlockTags.SEATS.tag) .tag(AllBlockTags.SEATS.tag)
.item() .item()
.tag(AllItemTags.SEATS.tag) .tag(AllItemTags.SEATS.tag)

View file

@ -37,7 +37,7 @@ public class ChassisRangeDisplay {
timer = DISPLAY_TIME; timer = DISPLAY_TIME;
CreateClient.OUTLINER.showCluster(getOutlineKey(), createSelection(te)) CreateClient.OUTLINER.showCluster(getOutlineKey(), createSelection(te))
.colored(0xFFFFFF) .colored(0xFFFFFF)
.disableLineNormals() .disableNormals()
.lineWidth(1 / 16f) .lineWidth(1 / 16f)
.withFaceTexture(AllSpecialTextures.HIGHLIGHT_CHECKERED); .withFaceTexture(AllSpecialTextures.HIGHLIGHT_CHECKERED);
} }

View file

@ -100,7 +100,7 @@ public class SuperGlueSelectionHandler {
CreateClient.OUTLINER.showAABB(glueEntity, glueEntity.getBoundingBox()) CreateClient.OUTLINER.showAABB(glueEntity, glueEntity.getBoundingBox())
.colored(h ? HIGHLIGHT : PASSIVE) .colored(h ? HIGHLIGHT : PASSIVE)
.withFaceTextures(faceTex, faceTex) .withFaceTextures(faceTex, faceTex)
.disableLineNormals() .disableNormals()
.lineWidth(h ? 1 / 16f : 1 / 64f); .lineWidth(h ? 1 / 16f : 1 / 64f);
} }
} }
@ -155,12 +155,12 @@ public class SuperGlueSelectionHandler {
CreateClient.OUTLINER.showAABB(bbOutlineSlot, currentSelectionBox) CreateClient.OUTLINER.showAABB(bbOutlineSlot, currentSelectionBox)
.colored(canReach && canAfford && !cancel ? HIGHLIGHT : FAIL) .colored(canReach && canAfford && !cancel ? HIGHLIGHT : FAIL)
.withFaceTextures(AllSpecialTextures.GLUE, AllSpecialTextures.GLUE) .withFaceTextures(AllSpecialTextures.GLUE, AllSpecialTextures.GLUE)
.disableLineNormals() .disableNormals()
.lineWidth(1 / 16f); .lineWidth(1 / 16f);
CreateClient.OUTLINER.showCluster(clusterOutlineSlot, currentCluster) CreateClient.OUTLINER.showCluster(clusterOutlineSlot, currentCluster)
.colored(0x4D9162) .colored(0x4D9162)
.disableLineNormals() .disableNormals()
.lineWidth(1 / 64f); .lineWidth(1 / 64f);
} }
@ -259,7 +259,7 @@ public class SuperGlueSelectionHandler {
CreateClient.OUTLINER.showCluster(clusterOutlineSlot, currentCluster) CreateClient.OUTLINER.showCluster(clusterOutlineSlot, currentCluster)
.colored(0xB5F2C6) .colored(0xB5F2C6)
.withFaceTextures(AllSpecialTextures.GLUE, AllSpecialTextures.HIGHLIGHT_CHECKERED) .withFaceTextures(AllSpecialTextures.GLUE, AllSpecialTextures.HIGHLIGHT_CHECKERED)
.disableLineNormals() .disableNormals()
.lineWidth(1 / 24f); .lineWidth(1 / 24f);
discard(); discard();

View file

@ -39,7 +39,7 @@ public class ZapperRenderHandler extends ShootableGadgetRenderHandler {
cachedBeams.forEach(beam -> { cachedBeams.forEach(beam -> {
CreateClient.OUTLINER.endChasingLine(beam, beam.start, beam.end, 1 - beam.itensity, false) CreateClient.OUTLINER.endChasingLine(beam, beam.start, beam.end, 1 - beam.itensity, false)
.disableLineNormals() .disableNormals()
.colored(0xffffff) .colored(0xffffff)
.lineWidth(beam.itensity * 1 / 8f); .lineWidth(beam.itensity * 1 / 8f);
}); });

View file

@ -33,7 +33,7 @@ public class WorldshaperRenderHandler {
CreateClient.OUTLINER.showCluster("terrainZapper", renderedPositions.get()) CreateClient.OUTLINER.showCluster("terrainZapper", renderedPositions.get())
.colored(0xbfbfbf) .colored(0xbfbfbf)
.disableLineNormals() .disableNormals()
.lineWidth(1 / 32f) .lineWidth(1 / 32f)
.withFaceTexture(AllSpecialTextures.CHECKERED); .withFaceTexture(AllSpecialTextures.CHECKERED);
} }

View file

@ -124,7 +124,7 @@ public class TrainRelocator {
Vec3 vec2 = toVisualise.get(i + 1).add(offset); Vec3 vec2 = toVisualise.get(i + 1).add(offset);
CreateClient.OUTLINER.showLine(Pair.of(relocating, i), vec1.add(0, -.925f, 0), vec2.add(0, -.925f, 0)) CreateClient.OUTLINER.showLine(Pair.of(relocating, i), vec1.add(0, -.925f, 0), vec2.add(0, -.925f, 0))
.colored(lastHoveredResult || i != toVisualise.size() - 2 ? 0x95CD41 : 0xEA5C2B) .colored(lastHoveredResult || i != toVisualise.size() - 2 ? 0x95CD41 : 0xEA5C2B)
.disableLineNormals() .disableNormals()
.lineWidth(i % 2 == 1 ? 1 / 6f : 1 / 4f); .lineWidth(i % 2 == 1 ? 1 / 6f : 1 / 4f);
} }
} }
@ -272,7 +272,7 @@ public class TrainRelocator {
public static void visualise(Train train, int i, Vec3 v1, Vec3 v2, boolean valid) { public static void visualise(Train train, int i, Vec3 v1, Vec3 v2, boolean valid) {
CreateClient.OUTLINER.showLine(Pair.of(train, i), v1.add(0, -.825f, 0), v2.add(0, -.825f, 0)) CreateClient.OUTLINER.showLine(Pair.of(train, i), v1.add(0, -.825f, 0), v2.add(0, -.825f, 0))
.colored(valid ? 0x95CD41 : 0xEA5C2B) .colored(valid ? 0x95CD41 : 0xEA5C2B)
.disableLineNormals() .disableNormals()
.lineWidth(i % 2 == 1 ? 1 / 6f : 1 / 4f); .lineWidth(i % 2 == 1 ? 1 / 6f : 1 / 4f);
} }

View file

@ -748,13 +748,13 @@ public class TrackPlacement {
.showLine(Pair.of(key, i * 2), VecHelper.lerp(s, middle1, previous1), .showLine(Pair.of(key, i * 2), VecHelper.lerp(s, middle1, previous1),
VecHelper.lerp(s, middle1, rail1)) VecHelper.lerp(s, middle1, rail1))
.colored(railcolor) .colored(railcolor)
.disableLineNormals() .disableNormals()
.lineWidth(lw); .lineWidth(lw);
CreateClient.OUTLINER CreateClient.OUTLINER
.showLine(Pair.of(key, i * 2 + 1), VecHelper.lerp(s, middle2, previous2), .showLine(Pair.of(key, i * 2 + 1), VecHelper.lerp(s, middle2, previous2),
VecHelper.lerp(s, middle2, rail2)) VecHelper.lerp(s, middle2, rail2))
.colored(railcolor) .colored(railcolor)
.disableLineNormals() .disableNormals()
.lineWidth(lw); .lineWidth(lw);
} }
@ -775,7 +775,7 @@ public class TrackPlacement {
int color = Color.mixColors(0xEA5C2B, 0x95CD41, animation.getValue()); int color = Color.mixColors(0xEA5C2B, 0x95CD41, animation.getValue());
CreateClient.OUTLINER.showLine(Pair.of("start", id), v1.subtract(o1), v1.add(ex)) CreateClient.OUTLINER.showLine(Pair.of("start", id), v1.subtract(o1), v1.add(ex))
.lineWidth(1 / 8f) .lineWidth(1 / 8f)
.disableLineNormals() .disableNormals()
.colored(color); .colored(color);
} }

View file

@ -72,7 +72,7 @@ public class FlipTool extends PlacementToolBase {
AllSpecialTextures tex = AllSpecialTextures.CHECKERED; AllSpecialTextures tex = AllSpecialTextures.CHECKERED;
outline.getParams() outline.getParams()
.lineWidth(1 / 16f) .lineWidth(1 / 16f)
.disableLineNormals() .disableNormals()
.colored(0xdddddd) .colored(0xdddddd)
.withFaceTextures(tex, tex); .withFaceTextures(tex, tex);
outline.render(ms, buffer, AnimationTickHolder.getPartialTicks()); outline.render(ms, buffer, AnimationTickHolder.getPartialTicks());

View file

@ -32,7 +32,7 @@ public class RotateTool extends PlacementToolBase {
line.getParams() line.getParams()
.disableCull() .disableCull()
.disableLineNormals() .disableNormals()
.colored(0xdddddd) .colored(0xdddddd)
.lineWidth(1 / 16f); .lineWidth(1 / 16f);
line.set(start, end) line.set(start, end)

View file

@ -398,7 +398,7 @@ public class WorldSectionElement extends AnimatedSceneElement {
aabbOutline.getParams() aabbOutline.getParams()
.lineWidth(1 / 64f) .lineWidth(1 / 64f)
.colored(0xefefef) .colored(0xefefef)
.disableLineNormals(); .disableNormals();
aabbOutline.render(ms, (SuperRenderTypeBuffer) buffer, pt); aabbOutline.render(ms, (SuperRenderTypeBuffer) buffer, pt);
ms.popPose(); ms.popPose();

View file

@ -87,6 +87,9 @@ public class ValueBox extends ChasingAABBOutline {
ms.translate(pos.getX(), pos.getY(), pos.getZ()); ms.translate(pos.getX(), pos.getY(), pos.getZ());
if (hasTransform) if (hasTransform)
transform.transform(blockState, ms); transform.transform(blockState, ms);
transformNormals = ms.last()
.normal()
.copy();
params.colored(isPassive ? passiveColor : highlightColor); params.colored(isPassive ? passiveColor : highlightColor);
super.render(ms, buffer, pt); super.render(ms, buffer, pt);

View file

@ -1,18 +1,15 @@
package com.simibubi.create.foundation.utility.outliner; package com.simibubi.create.foundation.utility.outliner;
import java.util.Optional;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Vector3f;
import com.mojang.math.Vector4f;
import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.foundation.render.RenderTypes; import com.simibubi.create.foundation.render.RenderTypes;
import com.simibubi.create.foundation.render.SuperRenderTypeBuffer; import com.simibubi.create.foundation.render.SuperRenderTypeBuffer;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
@ -20,212 +17,85 @@ public class AABBOutline extends Outline {
protected AABB bb; protected AABB bb;
protected final Vector3f minPosTemp1 = new Vector3f();
protected final Vector3f maxPosTemp1 = new Vector3f();
protected final Vector4f colorTemp1 = new Vector4f();
protected final Vector3f pos0Temp = new Vector3f();
protected final Vector3f pos1Temp = new Vector3f();
protected final Vector3f pos2Temp = new Vector3f();
protected final Vector3f pos3Temp = new Vector3f();
protected final Vector3f normalTemp = new Vector3f();
protected final Vector3f originTemp = new Vector3f();
public AABBOutline(AABB bb) { public AABBOutline(AABB bb) {
setBounds(bb); this.setBounds(bb);
} }
public AABB getBounds() { @Override
return bb; public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) {
renderBB(ms, buffer, bb);
}
public void renderBB(PoseStack ms, SuperRenderTypeBuffer buffer, AABB bb) {
Vec3 projectedView = Minecraft.getInstance().gameRenderer.getMainCamera()
.getPosition();
boolean noCull = bb.contains(projectedView);
bb = bb.inflate(noCull ? -1 / 128d : 1 / 128d);
noCull |= params.disableCull;
Vec3 xyz = new Vec3(bb.minX, bb.minY, bb.minZ);
Vec3 Xyz = new Vec3(bb.maxX, bb.minY, bb.minZ);
Vec3 xYz = new Vec3(bb.minX, bb.maxY, bb.minZ);
Vec3 XYz = new Vec3(bb.maxX, bb.maxY, bb.minZ);
Vec3 xyZ = new Vec3(bb.minX, bb.minY, bb.maxZ);
Vec3 XyZ = new Vec3(bb.maxX, bb.minY, bb.maxZ);
Vec3 xYZ = new Vec3(bb.minX, bb.maxY, bb.maxZ);
Vec3 XYZ = new Vec3(bb.maxX, bb.maxY, bb.maxZ);
Vec3 start = xyz;
renderAACuboidLine(ms, buffer, start, Xyz);
renderAACuboidLine(ms, buffer, start, xYz);
renderAACuboidLine(ms, buffer, start, xyZ);
start = XyZ;
renderAACuboidLine(ms, buffer, start, xyZ);
renderAACuboidLine(ms, buffer, start, XYZ);
renderAACuboidLine(ms, buffer, start, Xyz);
start = XYz;
renderAACuboidLine(ms, buffer, start, xYz);
renderAACuboidLine(ms, buffer, start, Xyz);
renderAACuboidLine(ms, buffer, start, XYZ);
start = xYZ;
renderAACuboidLine(ms, buffer, start, XYZ);
renderAACuboidLine(ms, buffer, start, xyZ);
renderAACuboidLine(ms, buffer, start, xYz);
renderFace(ms, buffer, Direction.NORTH, xYz, XYz, Xyz, xyz, noCull);
renderFace(ms, buffer, Direction.SOUTH, XYZ, xYZ, xyZ, XyZ, noCull);
renderFace(ms, buffer, Direction.EAST, XYz, XYZ, XyZ, Xyz, noCull);
renderFace(ms, buffer, Direction.WEST, xYZ, xYz, xyz, xyZ, noCull);
renderFace(ms, buffer, Direction.UP, xYZ, XYZ, XYz, xYz, noCull);
renderFace(ms, buffer, Direction.DOWN, xyz, Xyz, XyZ, xyZ, noCull);
}
protected void renderFace(PoseStack ms, SuperRenderTypeBuffer buffer, Direction direction, Vec3 p1, Vec3 p2,
Vec3 p3, Vec3 p4, boolean noCull) {
if (!params.faceTexture.isPresent())
return;
ResourceLocation faceTexture = params.faceTexture.get()
.getLocation();
float alphaBefore = params.alpha;
params.alpha =
(direction == params.getHighlightedFace() && params.hightlightedFaceTexture.isPresent()) ? 1 : 0.5f;
RenderType translucentType = RenderTypes.getOutlineTranslucent(faceTexture, !noCull);
VertexConsumer builder = buffer.getLateBuffer(translucentType);
Axis axis = direction.getAxis();
Vec3 uDiff = p2.subtract(p1);
Vec3 vDiff = p4.subtract(p1);
float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x);
float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y);
putQuadUV(ms, builder, p1, p2, p3, p4, 0, 0, maxU, maxV, Direction.UP);
params.alpha = alphaBefore;
} }
public void setBounds(AABB bb) { public void setBounds(AABB bb) {
this.bb = bb; this.bb = bb;
} }
@Override
public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) {
params.loadColor(colorTemp);
Vector4f color = colorTemp;
int lightmap = params.lightmap;
boolean disableLineNormals = params.disableLineNormals;
renderBox(ms, buffer, bb, color, lightmap, disableLineNormals);
}
protected void renderBox(PoseStack ms, SuperRenderTypeBuffer buffer, AABB box, Vector4f color, int lightmap, boolean disableLineNormals) {
Vector3f minPos = minPosTemp1;
Vector3f maxPos = maxPosTemp1;
Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera()
.getPosition();
boolean cameraInside = box.contains(cameraPos);
boolean cull = !cameraInside && !params.disableCull;
float inflate = cameraInside ? -1 / 128f : 1 / 128f;
minPos.set((float) box.minX - inflate, (float) box.minY - inflate, (float) box.minZ - inflate);
maxPos.set((float) box.maxX + inflate, (float) box.maxY + inflate, (float) box.maxZ + inflate);
renderBoxFaces(ms, buffer, cull, params.getHighlightedFace(), minPos, maxPos, color, lightmap);
float lineWidth = params.getLineWidth();
if (lineWidth == 0)
return;
VertexConsumer consumer = buffer.getBuffer(RenderTypes.getOutlineSolid());
renderBoxEdges(ms, consumer, minPos, maxPos, lineWidth, color, lightmap, disableLineNormals);
}
protected void renderBoxFaces(PoseStack ms, SuperRenderTypeBuffer buffer, boolean cull, Direction highlightedFace, Vector3f minPos, Vector3f maxPos, Vector4f color, int lightmap) {
PoseStack.Pose pose = ms.last();
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.DOWN, color, lightmap);
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.UP, color, lightmap);
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.NORTH, color, lightmap);
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.SOUTH, color, lightmap);
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.WEST, color, lightmap);
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.EAST, color, lightmap);
}
protected void renderBoxFace(PoseStack.Pose pose, SuperRenderTypeBuffer buffer, boolean cull, Direction highlightedFace, Vector3f minPos, Vector3f maxPos, Direction face, Vector4f color, int lightmap) {
boolean highlighted = face == highlightedFace;
// TODO: Presumably, the other texture should be used, but this was not noticed before so fixing it may lead to suboptimal visuals.
// Optional<AllSpecialTextures> optionalFaceTexture = highlighted ? params.hightlightedFaceTexture : params.faceTexture;
Optional<AllSpecialTextures> optionalFaceTexture = params.faceTexture;
if (!optionalFaceTexture.isPresent())
return;
AllSpecialTextures faceTexture = optionalFaceTexture.get();
RenderType renderType = RenderTypes.getOutlineTranslucent(faceTexture.getLocation(), cull);
VertexConsumer consumer = buffer.getLateBuffer(renderType);
float alphaMult = highlighted ? 1 : 0.5f;
colorTemp1.set(color.x(), color.y(), color.z(), color.w() * alphaMult);
color = colorTemp1;
renderBoxFace(pose, consumer, minPos, maxPos, face, color, lightmap);
}
protected void renderBoxFace(PoseStack.Pose pose, VertexConsumer consumer, Vector3f minPos, Vector3f maxPos, Direction face, Vector4f color, int lightmap) {
Vector3f pos0 = pos0Temp;
Vector3f pos1 = pos1Temp;
Vector3f pos2 = pos2Temp;
Vector3f pos3 = pos3Temp;
Vector3f normal = normalTemp;
float minX = minPos.x();
float minY = minPos.y();
float minZ = minPos.z();
float maxX = maxPos.x();
float maxY = maxPos.y();
float maxZ = maxPos.z();
float maxU;
float maxV;
switch (face) {
case DOWN -> {
// 0 1 2 3
pos0.set(minX, minY, maxZ);
pos1.set(minX, minY, minZ);
pos2.set(maxX, minY, minZ);
pos3.set(maxX, minY, maxZ);
maxU = maxX - minX;
maxV = maxZ - minZ;
normal.set(0, -1, 0);
}
case UP -> {
// 4 5 6 7
pos0.set(minX, maxY, minZ);
pos1.set(minX, maxY, maxZ);
pos2.set(maxX, maxY, maxZ);
pos3.set(maxX, maxY, minZ);
maxU = maxX - minX;
maxV = maxZ - minZ;
normal.set(0, 1, 0);
}
case NORTH -> {
// 7 2 1 4
pos0.set(maxX, maxY, minZ);
pos1.set(maxX, minY, minZ);
pos2.set(minX, minY, minZ);
pos3.set(minX, maxY, minZ);
maxU = maxX - minX;
maxV = maxY - minY;
normal.set(0, 0, -1);
}
case SOUTH -> {
// 5 0 3 6
pos0.set(minX, maxY, maxZ);
pos1.set(minX, minY, maxZ);
pos2.set(maxX, minY, maxZ);
pos3.set(maxX, maxY, maxZ);
maxU = maxX - minX;
maxV = maxY - minY;
normal.set(0, 0, 1);
}
case WEST -> {
// 4 1 0 5
pos0.set(minX, maxY, minZ);
pos1.set(minX, minY, minZ);
pos2.set(minX, minY, maxZ);
pos3.set(minX, maxY, maxZ);
maxU = maxZ - minZ;
maxV = maxY - minY;
normal.set(-1, 0, 0);
}
case EAST -> {
// 6 3 2 7
pos0.set(maxX, maxY, maxZ);
pos1.set(maxX, minY, maxZ);
pos2.set(maxX, minY, minZ);
pos3.set(maxX, maxY, minZ);
maxU = maxZ - minZ;
maxV = maxY - minY;
normal.set(1, 0, 0);
}
default -> {
maxU = 1;
maxV = 1;
}
}
bufferQuad(pose, consumer, pos0, pos1, pos2, pos3, color, 0, 0, maxU, maxV, lightmap, normal);
}
protected void renderBoxEdges(PoseStack ms, VertexConsumer consumer, Vector3f minPos, Vector3f maxPos, float lineWidth, Vector4f color, int lightmap, boolean disableNormals) {
Vector3f origin = originTemp;
PoseStack.Pose pose = ms.last();
float lineLengthX = maxPos.x() - minPos.x();
float lineLengthY = maxPos.y() - minPos.y();
float lineLengthZ = maxPos.z() - minPos.z();
origin.load(minPos);
bufferCuboidLine(pose, consumer, origin, Direction.EAST, lineLengthX, lineWidth, color, lightmap, disableNormals);
bufferCuboidLine(pose, consumer, origin, Direction.UP, lineLengthY, lineWidth, color, lightmap, disableNormals);
bufferCuboidLine(pose, consumer, origin, Direction.SOUTH, lineLengthZ, lineWidth, color, lightmap, disableNormals);
origin.set(maxPos.x(), minPos.y(), minPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.UP, lineLengthY, lineWidth, color, lightmap, disableNormals);
bufferCuboidLine(pose, consumer, origin, Direction.SOUTH, lineLengthZ, lineWidth, color, lightmap, disableNormals);
origin.set(minPos.x(), maxPos.y(), minPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.EAST, lineLengthX, lineWidth, color, lightmap, disableNormals);
bufferCuboidLine(pose, consumer, origin, Direction.SOUTH, lineLengthZ, lineWidth, color, lightmap, disableNormals);
origin.set(minPos.x(), minPos.y(), maxPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.EAST, lineLengthX, lineWidth, color, lightmap, disableNormals);
bufferCuboidLine(pose, consumer, origin, Direction.UP, lineLengthY, lineWidth, color, lightmap, disableNormals);
origin.set(minPos.x(), maxPos.y(), maxPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.EAST, lineLengthX, lineWidth, color, lightmap, disableNormals);
origin.set(maxPos.x(), minPos.y(), maxPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.UP, lineLengthY, lineWidth, color, lightmap, disableNormals);
origin.set(maxPos.x(), maxPos.y(), minPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.SOUTH, lineLengthZ, lineWidth, color, lightmap, disableNormals);
}
} }

View file

@ -8,156 +8,94 @@ import java.util.Set;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Vector3f;
import com.mojang.math.Vector4f;
import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.foundation.render.RenderTypes; import com.simibubi.create.foundation.render.RenderTypes;
import com.simibubi.create.foundation.render.SuperRenderTypeBuffer; import com.simibubi.create.foundation.render.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection; import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.world.phys.Vec3;
public class BlockClusterOutline extends Outline { public class BlockClusterOutline extends Outline {
private final Cluster cluster; private Cluster cluster;
protected final Vector3f pos0Temp = new Vector3f(); public BlockClusterOutline(Iterable<BlockPos> selection) {
protected final Vector3f pos1Temp = new Vector3f();
protected final Vector3f pos2Temp = new Vector3f();
protected final Vector3f pos3Temp = new Vector3f();
protected final Vector3f normalTemp = new Vector3f();
protected final Vector3f originTemp = new Vector3f();
public BlockClusterOutline(Iterable<BlockPos> positions) {
cluster = new Cluster(); cluster = new Cluster();
positions.forEach(cluster::include); selection.forEach(cluster::include);
} }
@Override @Override
public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) { public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) {
params.loadColor(colorTemp); cluster.visibleEdges.forEach(edge -> {
Vector4f color = colorTemp; Vec3 start = Vec3.atLowerCornerOf(edge.pos);
int lightmap = params.lightmap; Direction direction = Direction.get(AxisDirection.POSITIVE, edge.axis);
boolean disableLineNormals = params.disableLineNormals; renderAACuboidLine(ms, buffer, start, Vec3.atLowerCornerOf(edge.pos.relative(direction)));
});
renderFaces(ms, buffer, pt, color, lightmap); Optional<AllSpecialTextures> faceTexture = params.faceTexture;
renderEdges(ms, buffer, pt, color, lightmap, disableLineNormals); if (!faceTexture.isPresent())
}
protected void renderFaces(PoseStack ms, SuperRenderTypeBuffer buffer, float pt, Vector4f color, int lightmap) {
Optional<AllSpecialTextures> optionalFaceTexture = params.faceTexture;
if (!optionalFaceTexture.isPresent())
return; return;
AllSpecialTextures faceTexture = optionalFaceTexture.get();
PoseStack.Pose pose = ms.last(); RenderType translucentType = RenderTypes.getOutlineTranslucent(faceTexture.get()
RenderType renderType = RenderTypes.getOutlineTranslucent(faceTexture.getLocation(), true); .getLocation(), true);
VertexConsumer consumer = buffer.getLateBuffer(renderType); VertexConsumer builder = buffer.getLateBuffer(translucentType);
cluster.visibleFaces.forEach((face, axisDirection) -> { cluster.visibleFaces.forEach((face, axisDirection) -> {
Direction direction = Direction.get(axisDirection, face.axis); Direction direction = Direction.get(axisDirection, face.axis);
BlockPos pos = face.pos; BlockPos pos = face.pos;
if (axisDirection == AxisDirection.POSITIVE) if (axisDirection == AxisDirection.POSITIVE)
pos = pos.relative(direction.getOpposite()); pos = pos.relative(direction.getOpposite());
bufferBlockFace(pose, consumer, pos, direction, color, lightmap); renderBlockFace(ms, builder, pos, direction);
}); });
} }
protected void renderEdges(PoseStack ms, SuperRenderTypeBuffer buffer, float pt, Vector4f color, int lightmap, boolean disableNormals) { static Vec3 xyz = new Vec3(-.5, -.5, -.5);
float lineWidth = params.getLineWidth(); static Vec3 Xyz = new Vec3(.5, -.5, -.5);
if (lineWidth == 0) static Vec3 xYz = new Vec3(-.5, .5, -.5);
return; static Vec3 XYz = new Vec3(.5, .5, -.5);
static Vec3 xyZ = new Vec3(-.5, -.5, .5);
static Vec3 XyZ = new Vec3(.5, -.5, .5);
static Vec3 xYZ = new Vec3(-.5, .5, .5);
static Vec3 XYZ = new Vec3(.5, .5, .5);
PoseStack.Pose pose = ms.last(); protected void renderBlockFace(PoseStack ms, VertexConsumer builder, BlockPos pos, Direction face) {
VertexConsumer consumer = buffer.getBuffer(RenderTypes.getOutlineSolid()); Vec3 center = VecHelper.getCenterOf(pos);
Vec3 offset = Vec3.atLowerCornerOf(face.getNormal());
offset = offset.scale(1 / 128d);
center = center.add(offset);
cluster.visibleEdges.forEach(edge -> { ms.pushPose();
BlockPos pos = edge.pos; ms.translate(center.x, center.y, center.z);
Vector3f origin = originTemp;
origin.set(pos.getX(), pos.getY(), pos.getZ());
Direction direction = Direction.get(AxisDirection.POSITIVE, edge.axis);
bufferCuboidLine(pose, consumer, origin, direction, 1, lineWidth, color, lightmap, disableNormals);
});
}
public static void loadFaceData(Direction face, Vector3f pos0, Vector3f pos1, Vector3f pos2, Vector3f pos3, Vector3f normal) {
switch (face) { switch (face) {
case DOWN -> { case DOWN:
// 0 1 2 3 putQuad(ms, builder, xyz, Xyz, XyZ, xyZ, face);
pos0.set(0, 0, 1); break;
pos1.set(0, 0, 0); case EAST:
pos2.set(1, 0, 0); putQuad(ms, builder, XYz, XYZ, XyZ, Xyz, face);
pos3.set(1, 0, 1); break;
normal.set(0, -1, 0); case NORTH:
} putQuad(ms, builder, xYz, XYz, Xyz, xyz, face);
case UP -> { break;
// 4 5 6 7 case SOUTH:
pos0.set(0, 1, 0); putQuad(ms, builder, XYZ, xYZ, xyZ, XyZ, face);
pos1.set(0, 1, 1); break;
pos2.set(1, 1, 1); case UP:
pos3.set(1, 1, 0); putQuad(ms, builder, xYZ, XYZ, XYz, xYz, face);
normal.set(0, 1, 0); break;
} case WEST:
case NORTH -> { putQuad(ms, builder, xYZ, xYz, xyz, xyZ, face);
// 7 2 1 4 default:
pos0.set(1, 1, 0); break;
pos1.set(1, 0, 0);
pos2.set(0, 0, 0);
pos3.set(0, 1, 0);
normal.set(0, 0, -1);
}
case SOUTH -> {
// 5 0 3 6
pos0.set(0, 1, 1);
pos1.set(0, 0, 1);
pos2.set(1, 0, 1);
pos3.set(1, 1, 1);
normal.set(0, 0, 1);
}
case WEST -> {
// 4 1 0 5
pos0.set(0, 1, 0);
pos1.set(0, 0, 0);
pos2.set(0, 0, 1);
pos3.set(0, 1, 1);
normal.set(-1, 0, 0);
}
case EAST -> {
// 6 3 2 7
pos0.set(1, 1, 1);
pos1.set(1, 0, 1);
pos2.set(1, 0, 0);
pos3.set(1, 1, 0);
normal.set(1, 0, 0);
}
}
} }
public static void addPos(float x, float y, float z, Vector3f pos0, Vector3f pos1, Vector3f pos2, Vector3f pos3) { ms.popPose();
pos0.add(x, y, z);
pos1.add(x, y, z);
pos2.add(x, y, z);
pos3.add(x, y, z);
}
protected void bufferBlockFace(PoseStack.Pose pose, VertexConsumer consumer, BlockPos pos, Direction face, Vector4f color, int lightmap) {
Vector3f pos0 = pos0Temp;
Vector3f pos1 = pos1Temp;
Vector3f pos2 = pos2Temp;
Vector3f pos3 = pos3Temp;
Vector3f normal = normalTemp;
loadFaceData(face, pos0, pos1, pos2, pos3, normal);
addPos(pos.getX() + face.getStepX() * 1 / 128f,
pos.getY() + face.getStepY() * 1 / 128f,
pos.getZ() + face.getStepZ() * 1 / 128f,
pos0, pos1, pos2, pos3);
bufferQuad(pose, consumer, pos0, pos1, pos2, pos3, color, lightmap, normal);
} }
private static class Cluster { private static class Cluster {

View file

@ -1,7 +1,6 @@
package com.simibubi.create.foundation.utility.outliner; package com.simibubi.create.foundation.utility.outliner;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector4f;
import com.simibubi.create.foundation.render.SuperRenderTypeBuffer; import com.simibubi.create.foundation.render.SuperRenderTypeBuffer;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
@ -30,12 +29,7 @@ public class ChasingAABBOutline extends AABBOutline {
@Override @Override
public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) { public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) {
params.loadColor(colorTemp); renderBB(ms, buffer, interpolateBBs(prevBB, bb, pt));
Vector4f color = colorTemp;
int lightmap = params.lightmap;
boolean disableLineNormals = params.disableLineNormals;
renderBox(ms, buffer, interpolateBBs(prevBB, bb, pt), color, lightmap, disableLineNormals);
} }
private static AABB interpolateBBs(AABB current, AABB target, float pt) { private static AABB interpolateBBs(AABB current, AABB target, float pt) {

View file

@ -1,10 +1,6 @@
package com.simibubi.create.foundation.utility.outliner; package com.simibubi.create.foundation.utility.outliner;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Vector3f;
import com.mojang.math.Vector4f;
import com.simibubi.create.foundation.render.RenderTypes;
import com.simibubi.create.foundation.render.SuperRenderTypeBuffer; import com.simibubi.create.foundation.render.SuperRenderTypeBuffer;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
@ -12,50 +8,33 @@ import net.minecraft.world.phys.Vec3;
public class LineOutline extends Outline { public class LineOutline extends Outline {
protected final Vector3f start = new Vector3f(); protected Vec3 start = Vec3.ZERO;
protected final Vector3f end = new Vector3f(); protected Vec3 end = Vec3.ZERO;
public LineOutline set(Vector3f start, Vector3f end) {
this.start.load(start);
this.start.load(end);
return this;
}
public LineOutline set(Vec3 start, Vec3 end) { public LineOutline set(Vec3 start, Vec3 end) {
this.start.set((float) start.x, (float) start.y, (float) start.z); this.start = start;
this.end.set((float) end.x, (float) end.y, (float) end.z); this.end = end;
return this; return this;
} }
@Override @Override
public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) { public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) {
float width = params.getLineWidth(); renderCuboidLine(ms, buffer, start, end);
if (width == 0)
return;
VertexConsumer consumer = buffer.getBuffer(RenderTypes.getOutlineSolid());
params.loadColor(colorTemp);
Vector4f color = colorTemp;
int lightmap = params.lightmap;
boolean disableLineNormals = params.disableLineNormals;
renderInner(ms, consumer, pt, width, color, lightmap, disableLineNormals);
}
protected void renderInner(PoseStack ms, VertexConsumer consumer, float pt, float width, Vector4f color, int lightmap, boolean disableNormals) {
bufferCuboidLine(ms, consumer, start, end, width, color, lightmap, disableNormals);
} }
public static class EndChasingLineOutline extends LineOutline { public static class EndChasingLineOutline extends LineOutline {
private float progress = 0;
private float prevProgress = 0;
private boolean lockStart;
private final Vector3f startTemp = new Vector3f(); float prevProgress = 0;
float progress = 0;
private boolean lockStart;
public EndChasingLineOutline(boolean lockStart) { public EndChasingLineOutline(boolean lockStart) {
this.lockStart = lockStart; this.lockStart = lockStart;
} }
@Override
public void tick() {}
public EndChasingLineOutline setProgress(float progress) { public EndChasingLineOutline setProgress(float progress) {
prevProgress = this.progress; prevProgress = this.progress;
this.progress = progress; this.progress = progress;
@ -63,24 +42,25 @@ public class LineOutline extends Outline {
} }
@Override @Override
protected void renderInner(PoseStack ms, VertexConsumer consumer, float pt, float width, Vector4f color, int lightmap, boolean disableNormals) { public LineOutline set(Vec3 start, Vec3 end) {
if (!end.equals(this.end))
super.set(start, end);
return this;
}
@Override
public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) {
float distanceToTarget = Mth.lerp(pt, prevProgress, progress); float distanceToTarget = Mth.lerp(pt, prevProgress, progress);
Vector3f end; if (!lockStart)
if (lockStart) {
end = this.start;
} else {
end = this.end;
distanceToTarget = 1 - distanceToTarget; distanceToTarget = 1 - distanceToTarget;
} Vec3 start = lockStart ? this.end : this.start;
Vec3 end = lockStart ? this.start : this.end;
start = end.add(this.start.subtract(end)
.scale(distanceToTarget));
renderCuboidLine(ms, buffer, start, end);
}
Vector3f start = this.startTemp;
start.load(this.start);
start.sub(end);
start.mul(distanceToTarget);
start.add(end);
bufferCuboidLine(ms, consumer, start, end, width, color, lightmap, disableNormals);
}
} }
} }

View file

@ -8,497 +8,156 @@ import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Matrix3f; import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
import com.mojang.math.Vector3f;
import com.mojang.math.Vector4f;
import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.foundation.render.RenderTypes;
import com.simibubi.create.foundation.render.SuperRenderTypeBuffer; import com.simibubi.create.foundation.render.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Color; import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3;
public abstract class Outline { public abstract class Outline {
protected final OutlineParams params; protected OutlineParams params;
protected Matrix3f transformNormals; // TODO: not used?
protected final Vector4f colorTemp = new Vector4f();
protected final Vector3f diffPosTemp = new Vector3f();
protected final Vector3f minPosTemp = new Vector3f();
protected final Vector3f maxPosTemp = new Vector3f();
protected final Vector4f posTransformTemp = new Vector4f();
protected final Vector3f normalTransformTemp = new Vector3f();
public Outline() { public Outline() {
params = new OutlineParams(); params = new OutlineParams();
} }
public OutlineParams getParams() {
return params;
}
public abstract void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt); public abstract void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt);
public void tick() {} public void tick() {}
public void bufferCuboidLine(PoseStack poseStack, VertexConsumer consumer, Vector3f start, Vector3f end, float width, Vector4f color, int lightmap, boolean disableNormals) { public OutlineParams getParams() {
Vector3f diff = this.diffPosTemp; return params;
diff.load(end);
diff.sub(start);
float length = Mth.sqrt(diff.x() * diff.x() + diff.y() * diff.y() + diff.z() * diff.z());
float hAngle = AngleHelper.deg(Mth.atan2(diff.x(), diff.z()));
float hDistance = Mth.sqrt(diff.x() * diff.x() + diff.z() * diff.z());
float vAngle = AngleHelper.deg(Mth.atan2(hDistance, diff.y())) - 90;
poseStack.pushPose();
TransformStack.cast(poseStack)
.rotateY(hAngle)
.rotateX(vAngle);
bufferCuboidLine(poseStack.last(), consumer, start, Direction.NORTH, length, width, color, lightmap, disableNormals);
poseStack.popPose();
} }
public void bufferCuboidLine(PoseStack.Pose pose, VertexConsumer consumer, Vector3f origin, Direction direction, float length, float width, Vector4f color, int lightmap, boolean disableNormals) { public void renderCuboidLine(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 start, Vec3 end) {
Vector3f minPos = minPosTemp; Vec3 diff = end.subtract(start);
Vector3f maxPos = maxPosTemp; float hAngle = AngleHelper.deg(Mth.atan2(diff.x, diff.z));
float hDistance = (float) diff.multiply(1, 0, 1)
float halfWidth = width / 2; .length();
minPos.set(origin.x() - halfWidth, origin.y() - halfWidth, origin.z() - halfWidth); float vAngle = AngleHelper.deg(Mth.atan2(hDistance, diff.y)) - 90;
maxPos.set(origin.x() + halfWidth, origin.y() + halfWidth, origin.z() + halfWidth); ms.pushPose();
TransformStack.cast(ms)
switch (direction) { .translate(start)
case DOWN -> { .rotateY(hAngle).rotateX(vAngle);
minPos.add(0, -length, 0); renderAACuboidLine(ms, buffer, Vec3.ZERO, new Vec3(0, 0, diff.length()));
} ms.popPose();
case UP -> {
maxPos.add(0, length, 0);
}
case NORTH -> {
minPos.add(0, 0, -length);
}
case SOUTH -> {
maxPos.add(0, 0, length);
}
case WEST -> {
minPos.add(-length, 0, 0);
}
case EAST -> {
maxPos.add(length, 0, 0);
}
} }
bufferCuboid(pose, consumer, minPos, maxPos, color, lightmap, disableNormals); public void renderAACuboidLine(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 start, Vec3 end) {
float lineWidth = params.getLineWidth();
if (lineWidth == 0)
return;
VertexConsumer builder = buffer.getBuffer(RenderTypes.getOutlineSolid());
Vec3 diff = end.subtract(start);
if (diff.x + diff.y + diff.z < 0) {
Vec3 temp = start;
start = end;
end = temp;
diff = diff.scale(-1);
} }
public void bufferCuboid(PoseStack.Pose pose, VertexConsumer consumer, Vector3f minPos, Vector3f maxPos, Vector4f color, int lightmap, boolean disableNormals) { Vec3 extension = diff.normalize()
Vector4f posTransformTemp = this.posTransformTemp; .scale(lineWidth / 2);
Vector3f normalTransformTemp = this.normalTransformTemp; Vec3 plane = VecHelper.axisAlingedPlaneOf(diff);
Direction face = Direction.getNearest(diff.x, diff.y, diff.z);
Axis axis = face.getAxis();
float minX = minPos.x(); start = start.subtract(extension);
float minY = minPos.y(); end = end.add(extension);
float minZ = minPos.z(); plane = plane.scale(lineWidth / 2);
float maxX = maxPos.x();
float maxY = maxPos.y();
float maxZ = maxPos.z();
Matrix4f posMatrix = pose.pose(); Vec3 a1 = plane.add(start);
Vec3 b1 = plane.add(end);
plane = VecHelper.rotate(plane, -90, axis);
Vec3 a2 = plane.add(start);
Vec3 b2 = plane.add(end);
plane = VecHelper.rotate(plane, -90, axis);
Vec3 a3 = plane.add(start);
Vec3 b3 = plane.add(end);
plane = VecHelper.rotate(plane, -90, axis);
Vec3 a4 = plane.add(start);
Vec3 b4 = plane.add(end);
posTransformTemp.set(minX, minY, maxZ, 1); if (params.disableNormals) {
posTransformTemp.transform(posMatrix); face = Direction.UP;
double x0 = posTransformTemp.x(); putQuad(ms, builder, b4, b3, b2, b1, face);
double y0 = posTransformTemp.y(); putQuad(ms, builder, a1, a2, a3, a4, face);
double z0 = posTransformTemp.z(); putQuad(ms, builder, a1, b1, b2, a2, face);
putQuad(ms, builder, a2, b2, b3, a3, face);
posTransformTemp.set(minX, minY, minZ, 1); putQuad(ms, builder, a3, b3, b4, a4, face);
posTransformTemp.transform(posMatrix); putQuad(ms, builder, a4, b4, b1, a1, face);
double x1 = posTransformTemp.x(); return;
double y1 = posTransformTemp.y();
double z1 = posTransformTemp.z();
posTransformTemp.set(maxX, minY, minZ, 1);
posTransformTemp.transform(posMatrix);
double x2 = posTransformTemp.x();
double y2 = posTransformTemp.y();
double z2 = posTransformTemp.z();
posTransformTemp.set(maxX, minY, maxZ, 1);
posTransformTemp.transform(posMatrix);
double x3 = posTransformTemp.x();
double y3 = posTransformTemp.y();
double z3 = posTransformTemp.z();
posTransformTemp.set(minX, maxY, minZ, 1);
posTransformTemp.transform(posMatrix);
double x4 = posTransformTemp.x();
double y4 = posTransformTemp.y();
double z4 = posTransformTemp.z();
posTransformTemp.set(minX, maxY, maxZ, 1);
posTransformTemp.transform(posMatrix);
double x5 = posTransformTemp.x();
double y5 = posTransformTemp.y();
double z5 = posTransformTemp.z();
posTransformTemp.set(maxX, maxY, maxZ, 1);
posTransformTemp.transform(posMatrix);
double x6 = posTransformTemp.x();
double y6 = posTransformTemp.y();
double z6 = posTransformTemp.z();
posTransformTemp.set(maxX, maxY, minZ, 1);
posTransformTemp.transform(posMatrix);
double x7 = posTransformTemp.x();
double y7 = posTransformTemp.y();
double z7 = posTransformTemp.z();
float r = color.x();
float g = color.y();
float b = color.z();
float a = color.w();
Matrix3f normalMatrix = pose.normal();
// down
if (disableNormals) {
normalTransformTemp.set(0, 1, 0);
} else {
normalTransformTemp.set(0, -1, 0);
}
normalTransformTemp.transform(normalMatrix);
float nx0 = normalTransformTemp.x();
float ny0 = normalTransformTemp.y();
float nz0 = normalTransformTemp.z();
consumer.vertex(x0, y0, z0)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx0, ny0, nz0)
.endVertex();
consumer.vertex(x1, y1, z1)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx0, ny0, nz0)
.endVertex();
consumer.vertex(x2, y2, z2)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx0, ny0, nz0)
.endVertex();
consumer.vertex(x3, y3, z3)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx0, ny0, nz0)
.endVertex();
// up
normalTransformTemp.set(0, 1, 0);
normalTransformTemp.transform(normalMatrix);
float nx1 = normalTransformTemp.x();
float ny1 = normalTransformTemp.y();
float nz1 = normalTransformTemp.z();
consumer.vertex(x4, y4, z4)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx1, ny1, nz1)
.endVertex();
consumer.vertex(x5, y5, z5)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx1, ny1, nz1)
.endVertex();
consumer.vertex(x6, y6, z6)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx1, ny1, nz1)
.endVertex();
consumer.vertex(x7, y7, z7)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx1, ny1, nz1)
.endVertex();
// north
if (disableNormals) {
normalTransformTemp.set(0, 1, 0);
} else {
normalTransformTemp.set(0, 0, -1);
}
normalTransformTemp.transform(normalMatrix);
float nx2 = normalTransformTemp.x();
float ny2 = normalTransformTemp.y();
float nz2 = normalTransformTemp.z();
consumer.vertex(x7, y7, z7)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx2, ny2, nz2)
.endVertex();
consumer.vertex(x2, y2, z2)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx2, ny2, nz2)
.endVertex();
consumer.vertex(x1, y1, z1)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx2, ny2, nz2)
.endVertex();
consumer.vertex(x4, y4, z4)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx2, ny2, nz2)
.endVertex();
// south
if (disableNormals) {
normalTransformTemp.set(0, 1, 0);
} else {
normalTransformTemp.set(0, 0, 1);
}
normalTransformTemp.transform(normalMatrix);
float nx3 = normalTransformTemp.x();
float ny3 = normalTransformTemp.y();
float nz3 = normalTransformTemp.z();
consumer.vertex(x5, y5, z5)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx3, ny3, nz3)
.endVertex();
consumer.vertex(x0, y0, z0)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx3, ny3, nz3)
.endVertex();
consumer.vertex(x3, y3, z3)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx3, ny3, nz3)
.endVertex();
consumer.vertex(x6, y6, z6)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx3, ny3, nz3)
.endVertex();
// west
if (disableNormals) {
normalTransformTemp.set(0, 1, 0);
} else {
normalTransformTemp.set(-1, 0, 0);
}
normalTransformTemp.transform(normalMatrix);
float nx4 = normalTransformTemp.x();
float ny4 = normalTransformTemp.y();
float nz4 = normalTransformTemp.z();
consumer.vertex(x4, y4, z4)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx4, ny4, nz4)
.endVertex();
consumer.vertex(x1, y1, z1)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx4, ny4, nz4)
.endVertex();
consumer.vertex(x0, y0, z0)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx4, ny4, nz4)
.endVertex();
consumer.vertex(x5, y5, z5)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx4, ny4, nz4)
.endVertex();
// east
if (disableNormals) {
normalTransformTemp.set(0, 1, 0);
} else {
normalTransformTemp.set(1, 0, 0);
}
normalTransformTemp.transform(normalMatrix);
float nx5 = normalTransformTemp.x();
float ny5 = normalTransformTemp.y();
float nz5 = normalTransformTemp.z();
consumer.vertex(x6, y6, z6)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx5, ny5, nz5)
.endVertex();
consumer.vertex(x3, y3, z3)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx5, ny5, nz5)
.endVertex();
consumer.vertex(x2, y2, z2)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx5, ny5, nz5)
.endVertex();
consumer.vertex(x7, y7, z7)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx5, ny5, nz5)
.endVertex();
} }
public void bufferQuad(PoseStack.Pose pose, VertexConsumer consumer, Vector3f pos0, Vector3f pos1, Vector3f pos2, Vector3f pos3, Vector4f color, int lightmap, Vector3f normal) { putQuad(ms, builder, b4, b3, b2, b1, face);
bufferQuad(pose, consumer, pos0, pos1, pos2, pos3, color, 0, 0, 1, 1, lightmap, normal); putQuad(ms, builder, a1, a2, a3, a4, face.getOpposite());
Vec3 vec = a1.subtract(a4);
face = Direction.getNearest(vec.x, vec.y, vec.z);
putQuad(ms, builder, a1, b1, b2, a2, face);
vec = VecHelper.rotate(vec, -90, axis);
face = Direction.getNearest(vec.x, vec.y, vec.z);
putQuad(ms, builder, a2, b2, b3, a3, face);
vec = VecHelper.rotate(vec, -90, axis);
face = Direction.getNearest(vec.x, vec.y, vec.z);
putQuad(ms, builder, a3, b3, b4, a4, face);
vec = VecHelper.rotate(vec, -90, axis);
face = Direction.getNearest(vec.x, vec.y, vec.z);
putQuad(ms, builder, a4, b4, b1, a1, face);
} }
public void bufferQuad(PoseStack.Pose pose, VertexConsumer consumer, Vector3f pos0, Vector3f pos1, Vector3f pos2, Vector3f pos3, Vector4f color, float minU, float minV, float maxU, float maxV, int lightmap, Vector3f normal) { public void putQuad(PoseStack ms, VertexConsumer builder, Vec3 v1, Vec3 v2, Vec3 v3, Vec3 v4,
Vector4f posTransformTemp = this.posTransformTemp; Direction normal) {
Vector3f normalTransformTemp = this.normalTransformTemp; putQuadUV(ms, builder, v1, v2, v3, v4, 0, 0, 1, 1, normal);
}
Matrix4f posMatrix = pose.pose(); public void putQuadUV(PoseStack ms, VertexConsumer builder, Vec3 v1, Vec3 v2, Vec3 v3, Vec3 v4, float minU,
float minV, float maxU, float maxV, Direction normal) {
putVertex(ms, builder, v1, minU, minV, normal);
putVertex(ms, builder, v2, maxU, minV, normal);
putVertex(ms, builder, v3, maxU, maxV, normal);
putVertex(ms, builder, v4, minU, maxV, normal);
}
posTransformTemp.set(pos0.x(), pos0.y(), pos0.z(), 1); protected void putVertex(PoseStack ms, VertexConsumer builder, Vec3 pos, float u, float v, Direction normal) {
posTransformTemp.transform(posMatrix); putVertex(ms.last(), builder, (float) pos.x, (float) pos.y, (float) pos.z, u, v, normal);
double x0 = posTransformTemp.x(); }
double y0 = posTransformTemp.y();
double z0 = posTransformTemp.z();
posTransformTemp.set(pos1.x(), pos1.y(), pos1.z(), 1); protected void putVertex(PoseStack.Pose pose, VertexConsumer builder, float x, float y, float z, float u, float v, Direction normal) {
posTransformTemp.transform(posMatrix); Color rgb = params.rgb;
double x1 = posTransformTemp.x(); if (transformNormals == null)
double y1 = posTransformTemp.y(); transformNormals = pose.normal();
double z1 = posTransformTemp.z();
posTransformTemp.set(pos2.x(), pos2.y(), pos2.z(), 1); int xOffset = 0;
posTransformTemp.transform(posMatrix); int yOffset = 0;
double x2 = posTransformTemp.x(); int zOffset = 0;
double y2 = posTransformTemp.y();
double z2 = posTransformTemp.z();
posTransformTemp.set(pos3.x(), pos3.y(), pos3.z(), 1); if (normal != null) {
posTransformTemp.transform(posMatrix); xOffset = normal.getStepX();
double x3 = posTransformTemp.x(); yOffset = normal.getStepY();
double y3 = posTransformTemp.y(); zOffset = normal.getStepZ();
double z3 = posTransformTemp.z(); }
float r = color.x(); builder.vertex(pose.pose(), x, y, z)
float g = color.y(); .color(rgb.getRedAsFloat(), rgb.getGreenAsFloat(), rgb.getBlueAsFloat(), rgb.getAlphaAsFloat() * params.alpha)
float b = color.z(); .uv(u, v)
float a = color.w();
normalTransformTemp.load(normal);
normalTransformTemp.transform(pose.normal());
float nx = normalTransformTemp.x();
float ny = normalTransformTemp.y();
float nz = normalTransformTemp.z();
consumer.vertex(x0, y0, z0)
.color(r, g, b, a)
.uv(minU, minV)
.overlayCoords(OverlayTexture.NO_OVERLAY) .overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap) .uv2(params.lightMap)
.normal(nx, ny, nz) .normal(pose.normal(), xOffset, yOffset, zOffset)
.endVertex(); .endVertex();
consumer.vertex(x1, y1, z1) transformNormals = null;
.color(r, g, b, a)
.uv(minU, maxV)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx, ny, nz)
.endVertex();
consumer.vertex(x2, y2, z2)
.color(r, g, b, a)
.uv(maxU, maxV)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx, ny, nz)
.endVertex();
consumer.vertex(x3, y3, z3)
.color(r, g, b, a)
.uv(maxU, minV)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx, ny, nz)
.endVertex();
} }
public static class OutlineParams { public static class OutlineParams {
@ -507,9 +166,9 @@ public abstract class Outline {
protected Direction highlightedFace; protected Direction highlightedFace;
protected boolean fadeLineWidth; protected boolean fadeLineWidth;
protected boolean disableCull; protected boolean disableCull;
protected boolean disableLineNormals; protected boolean disableNormals;
protected float alpha; protected float alpha;
protected int lightmap; protected int lightMap;
protected Color rgb; protected Color rgb;
private float lineWidth; private float lineWidth;
@ -519,7 +178,7 @@ public abstract class Outline {
lineWidth = 1 / 32f; lineWidth = 1 / 32f;
fadeLineWidth = true; fadeLineWidth = true;
rgb = Color.WHITE; rgb = Color.WHITE;
lightmap = LightTexture.FULL_BRIGHT; lightMap = LightTexture.FULL_BRIGHT;
} }
// builder // builder
@ -534,8 +193,8 @@ public abstract class Outline {
return this; return this;
} }
public OutlineParams lightmap(int light) { public OutlineParams lightMap(int light) {
lightmap = light; lightMap = light;
return this; return this;
} }
@ -564,8 +223,8 @@ public abstract class Outline {
return this; return this;
} }
public OutlineParams disableLineNormals() { public OutlineParams disableNormals() {
disableLineNormals = true; disableNormals = true;
return this; return this;
} }
@ -584,9 +243,6 @@ public abstract class Outline {
return highlightedFace; return highlightedFace;
} }
public void loadColor(Vector4f vec) {
vec.set(rgb.getRedAsFloat(), rgb.getGreenAsFloat(), rgb.getBlueAsFloat(), rgb.getAlphaAsFloat() * alpha);
}
} }
} }

View file

@ -32,7 +32,7 @@ public class Outliner {
public OutlineParams showLine(Object slot, Vec3 start, Vec3 end) { public OutlineParams showLine(Object slot, Vec3 start, Vec3 end) {
if (!outlines.containsKey(slot)) { if (!outlines.containsKey(slot)) {
LineOutline outline = new LineOutline(); LineOutline outline = new LineOutline();
addOutline(slot, outline); outlines.put(slot, new OutlineEntry(outline));
} }
OutlineEntry entry = outlines.get(slot); OutlineEntry entry = outlines.get(slot);
entry.ticksTillRemoval = 1; entry.ticksTillRemoval = 1;
@ -43,7 +43,7 @@ public class Outliner {
public OutlineParams endChasingLine(Object slot, Vec3 start, Vec3 end, float chasingProgress, boolean lockStart) { public OutlineParams endChasingLine(Object slot, Vec3 start, Vec3 end, float chasingProgress, boolean lockStart) {
if (!outlines.containsKey(slot)) { if (!outlines.containsKey(slot)) {
EndChasingLineOutline outline = new EndChasingLineOutline(lockStart); EndChasingLineOutline outline = new EndChasingLineOutline(lockStart);
addOutline(slot, outline); outlines.put(slot, new OutlineEntry(outline));
} }
OutlineEntry entry = outlines.get(slot); OutlineEntry entry = outlines.get(slot);
entry.ticksTillRemoval = 1; entry.ticksTillRemoval = 1;
@ -75,12 +75,12 @@ public class Outliner {
public OutlineParams showCluster(Object slot, Iterable<BlockPos> selection) { public OutlineParams showCluster(Object slot, Iterable<BlockPos> selection) {
BlockClusterOutline outline = new BlockClusterOutline(selection); BlockClusterOutline outline = new BlockClusterOutline(selection);
addOutline(slot, outline); OutlineEntry entry = new OutlineEntry(outline);
return outline.getParams(); outlines.put(slot, entry);
return entry.getOutline()
.getParams();
} }
//
public void keep(Object slot) { public void keep(Object slot) {
if (outlines.containsKey(slot)) if (outlines.containsKey(slot))
outlines.get(slot).ticksTillRemoval = 1; outlines.get(slot).ticksTillRemoval = 1;
@ -105,19 +105,17 @@ public class Outliner {
// Utility // Utility
private void addOutline(Object slot, Outline outline) {
outlines.put(slot, new OutlineEntry(outline));
}
private void createAABBOutlineIfMissing(Object slot, AABB bb) { private void createAABBOutlineIfMissing(Object slot, AABB bb) {
if (!outlines.containsKey(slot) || !(outlines.get(slot).outline instanceof AABBOutline)) { if (!outlines.containsKey(slot) || !(outlines.get(slot).outline instanceof AABBOutline)) {
ChasingAABBOutline outline = new ChasingAABBOutline(bb); ChasingAABBOutline outline = new ChasingAABBOutline(bb);
addOutline(slot, outline); outlines.put(slot, new OutlineEntry(outline));
} }
} }
private ChasingAABBOutline getAndRefreshAABB(Object slot) { private ChasingAABBOutline getAndRefreshAABB(Object slot) {
return getAndRefreshAABB(slot, 1); OutlineEntry entry = outlines.get(slot);
entry.ticksTillRemoval = 1;
return (ChasingAABBOutline) entry.getOutline();
} }
private ChasingAABBOutline getAndRefreshAABB(Object slot, int ttl) { private ChasingAABBOutline getAndRefreshAABB(Object slot, int ttl) {
@ -146,7 +144,7 @@ public class Outliner {
params.alpha = 1; params.alpha = 1;
if (entry.isFading()) { if (entry.isFading()) {
int prevTicks = entry.ticksTillRemoval + 1; int prevTicks = entry.ticksTillRemoval + 1;
float fadeticks = OutlineEntry.FADE_TICKS; float fadeticks = OutlineEntry.fadeTicks;
float lastAlpha = prevTicks >= 0 ? 1 : 1 + (prevTicks / fadeticks); float lastAlpha = prevTicks >= 0 ? 1 : 1 + (prevTicks / fadeticks);
float currentAlpha = 1 + (entry.ticksTillRemoval / fadeticks); float currentAlpha = 1 + (entry.ticksTillRemoval / fadeticks);
float alpha = Mth.lerp(pt, lastAlpha, currentAlpha); float alpha = Mth.lerp(pt, lastAlpha, currentAlpha);
@ -160,35 +158,33 @@ public class Outliner {
} }
public static class OutlineEntry { public static class OutlineEntry {
public static final int FADE_TICKS = 8;
private final Outline outline; static final int fadeTicks = 8;
private int ticksTillRemoval = 1; private Outline outline;
private int ticksTillRemoval;
public OutlineEntry(Outline outline) { public OutlineEntry(Outline outline) {
this.outline = outline; this.outline = outline;
} ticksTillRemoval = 1;
public Outline getOutline() {
return outline;
}
public int getTicksTillRemoval() {
return ticksTillRemoval;
}
public boolean isAlive() {
return ticksTillRemoval >= -FADE_TICKS;
}
public boolean isFading() {
return ticksTillRemoval < 0;
} }
public void tick() { public void tick() {
ticksTillRemoval--; ticksTillRemoval--;
outline.tick(); outline.tick();
} }
public boolean isAlive() {
return ticksTillRemoval >= -fadeTicks;
}
public boolean isFading() {
return ticksTillRemoval < 0;
}
public Outline getOutline() {
return outline;
}
} }
} }