From 1091a478e15a502002811e85f2ffd1a4452fe200 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Wed, 9 Oct 2024 21:59:52 -0700 Subject: [PATCH] Pair down parameters per Pepper's pondering - Flatten TextVisual API to be less of a parameter container - This is mostly a surface change - Do not accept x and y positions, instead force the user to translate in their matrix - Track light from light updates to apply when setting up text - Add (unoptimized) updateLight, backgroundColor, and updateObfuscated methods to TextVisual --- .../flywheel/lib/visual/text/TextVisual.java | 104 ++++++------------ .../flywheel/vanilla/SignVisual.java | 28 ++--- 2 files changed, 45 insertions(+), 87 deletions(-) diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/text/TextVisual.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/text/TextVisual.java index e11b6683a..cac40b934 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/text/TextVisual.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/text/TextVisual.java @@ -1,7 +1,6 @@ package dev.engine_room.flywheel.lib.visual.text; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import org.jetbrains.annotations.Nullable; @@ -53,8 +52,6 @@ public final class TextVisual { private final Matrix4f pose = new Matrix4f(); private FormattedCharSequence text = FormattedCharSequence.EMPTY; - private float x; - private float y; private int backgroundColor = 0; private int light; @@ -63,91 +60,60 @@ public TextVisual(InstancerProvider provider) { .createInstance()); } - public TextVisual addLayer(TextLayer layer) { - layers.add(layer); - return this; - } - - public TextVisual addLayers(Collection layers) { - this.layers.addAll(layers); - return this; - } - - public TextVisual layers(Collection layers) { + public void setup(FormattedCharSequence textLine, List layers, Matrix4f pose, int light) { + // TODO: probably don't store everything + this.text = textLine; this.layers.clear(); this.layers.addAll(layers); - return this; - } + this.pose.set(pose); + this.light = light; - public TextVisual clearLayers() { - layers.clear(); - return this; + setup(); } - public Matrix4f pose() { - return pose; + public void updateObfuscated() { + // TODO: track obfuscated glyphs and update here + setup(); } - public TextVisual text(FormattedCharSequence text) { - this.text = text; - return this; + public void backgroundColor(int backgroundColor) { + // TODO: don't setup the whole thing + this.backgroundColor = backgroundColor; + setup(); } - public TextVisual x(float x) { - this.x = x; - return this; + public void updateLight(int packedLight) { + // TODO: just iterate over instances and update light + light = packedLight; + setup(); } - public TextVisual y(float y) { - this.y = y; - return this; - } + private void setup() { + recycler.resetCount(); - public TextVisual pos(float x, float y) { - this.x = x; - this.y = y; - return this; - } + var sink = SINKS.get(); + sink.prepare(recycler, layers, pose, light); - public TextVisual backgroundColor(int backgroundColor) { - this.backgroundColor = backgroundColor; - return this; - } + text.accept(sink); - public TextVisual light(int light) { - this.light = light; - return this; + sink.addBackground(backgroundColor, 0, sink.x); + sink.clear(); + + recycler.discardExtra(); } - public TextVisual reset() { + private TextVisual reset() { + // TODO: should this be public? what should it do? layers.clear(); pose.identity(); text = FormattedCharSequence.EMPTY; - x = 0; - y = 0; backgroundColor = 0; light = 0; return this; } - // TODO: track glyph instances and add method to update only UVs of obfuscated glyphs, method to update only - // background color, and method to only update light - public void setup() { - recycler.resetCount(); - - var sink = SINKS.get(); - sink.prepare(recycler, layers, pose, light, x, y); - - text.accept(sink); - - sink.addBackground(backgroundColor, x, sink.x); - sink.clear(); - - recycler.discardExtra(); - } - public void delete() { recycler.delete(); } @@ -196,15 +162,13 @@ private static class Sink implements FormattedCharSink { private int light; private float x; - private float y; - public void prepare(SmartRecycler recycler, List layers, Matrix4f pose, int light, float x, float y) { + public void prepare(SmartRecycler recycler, List layers, Matrix4f pose, int light) { this.recycler = recycler; this.layers = layers; this.pose = pose; this.light = light; - this.x = x; - this.y = y; + this.x = 0; } public void clear() { @@ -233,7 +197,7 @@ public boolean accept(int index, Style style, int codePoint) { if (!(glyph instanceof EmptyGlyph)) { GlyphInstance instance = recycler.get(key(layer, glyphInfo, glyph, bold)); float shadowOffset = glyphInfo.getShadowOffset(); - instance.setGlyph(glyph, pose, x + offset.x() * shadowOffset, y + offset.y() * shadowOffset, style.isItalic()); + instance.setGlyph(glyph, pose, x + offset.x() * shadowOffset, offset.y() * shadowOffset, style.isItalic()); instance.colorArgb(color); instance.light(light); instance.setChanged(); @@ -241,10 +205,10 @@ public boolean accept(int index, Style style, int codePoint) { // SpecialGlyphs.WHITE, which effects use, has a shadowOffset of 1, so don't modify the offset returned by the layer. if (style.isStrikethrough()) { - addEffect(layer, x + offset.x() - 1.0f, y + offset.y() + 4.5f, x + offset.x() + advance, y + offset.y() + 4.5f - 1.0f, 0.01f, color); + addEffect(layer, x + offset.x() - 1.0f, offset.y() + 4.5f, x + offset.x() + advance, offset.y() + 4.5f - 1.0f, 0.01f, color); } if (style.isUnderlined()) { - addEffect(layer, x + offset.x() - 1.0f, y + offset.y() + 9.0f, x + offset.x() + advance, y + offset.y() + 9.0f - 1.0f, 0.01f, color); + addEffect(layer, x + offset.x() - 1.0f, offset.y() + 9.0f, x + offset.x() + advance, offset.y() + 9.0f - 1.0f, 0.01f, color); } } @@ -260,7 +224,7 @@ public void addBackground(int backgroundColor, float startX, float endX) { var glyphExtension = FlwLibLink.INSTANCE.getBakedGlyphExtension(glyph); GlyphInstance instance = recycler.get(effectKey(glyphExtension.flywheel$texture(), TextLayer.GlyphMaterial.SEE_THROUGH, 0)); - instance.setEffect(glyph, pose, startX - 1.0f, y + 9.0f, endX + 1.0f, y - 1.0f, 0.01f); + instance.setEffect(glyph, pose, startX - 1.0f, 9.0f, endX + 1.0f, 1.0f, 0.01f); instance.colorArgb(backgroundColor); instance.light(light); instance.setChanged(); diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/SignVisual.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/SignVisual.java index b4dc3e192..c772bb425 100644 --- a/common/src/main/java/dev/engine_room/flywheel/vanilla/SignVisual.java +++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/SignVisual.java @@ -60,6 +60,8 @@ public class SignVisual extends AbstractBlockEntityVisual imple // Most of the time this will be empty. private final List obfuscated = new ArrayList<>(); + private int packedLight = 0; + private SignText lastFrontText; private SignText lastBackText; @@ -127,14 +129,14 @@ public void beginFrame(Context ctx) { // The is visible check is relatively expensive compared to the boolean checks above, // so only do it when it'll actually save some work in obfuscating. if (isVisible(ctx.frustum())) { - obfuscated.forEach(TextVisual::setup); + obfuscated.forEach(TextVisual::updateObfuscated); } } } @Override public void updateLight(float partialTick) { - int packedLight = computePackedLight(); + packedLight = computePackedLight(); instances.traverse(instance -> { instance.light(packedLight) .setChanged(); @@ -142,15 +144,13 @@ public void updateLight(float partialTick) { if (!lastFrontText.hasGlowingText()) { for (var text : frontTextVisuals) { - text.light(packedLight); - text.setup(); + text.updateLight(packedLight); } } if (!lastBackText.hasGlowingText()) { for (var text : backTextVisuals) { - text.light(packedLight); - text.setup(); + text.updateLight(packedLight); } } } @@ -216,12 +216,7 @@ private void setupText(SignText text, boolean isFrontText) { float x = (float) (-FONT.width(textLine) / 2); float y = i * lineHeight - lineDelta; - var textVisual = textVisuals[i].layers(layers) - .text(textLine) - .pos(x, y) - .backgroundColor(0); - - var pose = textVisual.pose().set(initialPose); + var pose = new Matrix4f(initialPose); if (!isFrontText) { pose.rotateY(Mth.PI); } @@ -229,13 +224,12 @@ private void setupText(SignText text, boolean isFrontText) { var textOffset = getTextOffset(); pose.translate((float) textOffset.x, (float) textOffset.y, (float) textOffset.z); pose.scale(scale, -scale, scale); + pose.translate(x, y, 0.0f); - if (text.hasGlowingText()) { - textVisual.light(LightTexture.FULL_BRIGHT); - } - // FIXME: incorrect light when going from glowing to non-glowing - textVisual.setup(); + var textVisual = textVisuals[i]; + int light = text.hasGlowingText() ? LightTexture.FULL_BRIGHT : packedLight; + textVisual.setup(textLine, layers, pose, light); if (hasObfuscation(textLine)) { obfuscated.add(textVisual);