From f9eb4dd2e7546d14480861e2dd02645b3e33cee2 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Thu, 11 Mar 2021 15:59:26 -0800 Subject: [PATCH] Pondering back and forth. - Only about gantries so far. - Reduce Backend log spam. --- .../foundation/ponder/PonderProgressBar.java | 150 ++++++++++++++++++ .../create/foundation/ponder/PonderScene.java | 21 +++ .../create/foundation/ponder/PonderUI.java | 36 ++--- .../foundation/ponder/SceneBuilder.java | 24 +-- .../ponder/content/GantryScenes.java | 11 ++ .../instructions/KeyframeInstruction.java | 24 +++ .../foundation/render/backend/Backend.java | 4 +- .../render/backend/gl/shader/GlProgram.java | 6 +- .../render/backend/gl/shader/GlShader.java | 6 +- 9 files changed, 238 insertions(+), 44 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java create mode 100644 src/main/java/com/simibubi/create/foundation/ponder/instructions/KeyframeInstruction.java diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java new file mode 100644 index 000000000..357b82820 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java @@ -0,0 +1,150 @@ +package com.simibubi.create.foundation.ponder; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.LerpedFloat; +import net.minecraft.client.audio.SoundHandler; +import net.minecraftforge.fml.client.gui.GuiUtils; +import org.antlr.v4.runtime.misc.IntegerList; + +public class PonderProgressBar extends AbstractSimiWidget { + + LerpedFloat progress; + LerpedFloat flash; + + PonderUI ponder; + + public PonderProgressBar(PonderUI ponder, int xIn, int yIn, int widthIn, int heightIn) { + super(xIn, yIn, widthIn, heightIn); + + this.ponder = ponder; + progress = LerpedFloat.linear() + .startWithValue(0); + flash = LerpedFloat.linear() + .startWithValue(0); + } + + public void tick() { + progress.chase(ponder.getActiveScene().getSceneProgress(), .5f, LerpedFloat.Chaser.EXP); + progress.tickChaser(); + + if (isHovered) + flash(); + } + + public void flash() { + float value = flash.getValue(); + flash.setValue(value + (1 - value) * .2f); + } + + public void dim() { + float value = flash.getValue(); + flash.setValue(value * .5f); + } + + @Override + protected boolean clicked(double mouseX, double mouseY) { + return this.active && this.visible && + !ponder.getActiveScene().keyframeTimes.isEmpty() && + mouseX >= (double)this.x && + mouseX < (double)(this.x + this.width) && + mouseY >= (double)this.y - 3 && + mouseY < (double)(this.y + this.height + 3); + } + + @Override + public void onClick(double mouseX, double mouseY) { + PonderScene activeScene = ponder.getActiveScene(); + int clickedAtTime = (int) ((mouseX - x) / ((double) width) * activeScene.totalTime); + + int seekTime = 0; + + IntegerList keyframeTimes = activeScene.keyframeTimes; + for (int i = 0; i < keyframeTimes.size(); i++) { + int keyframeTime = keyframeTimes.get(i); + + if (keyframeTime > clickedAtTime) + break; + + seekTime = keyframeTime; + } + ponder.seekToTime(seekTime); + } + + public int getHoveredKeyframeIndex(double mouseX) { + PonderScene activeScene = ponder.getActiveScene(); + int clickedAtTime = (int) ((mouseX - x) / ((double) width) * activeScene.totalTime); + + int index = -1; + + IntegerList keyframeTimes = activeScene.keyframeTimes; + for (int i = 0; i < keyframeTimes.size(); i++) { + int keyframeTime = keyframeTimes.get(i); + + if (keyframeTime > clickedAtTime) + break; + + index = i; + } + + return index; + } + + @Override + public void renderButton(int mouseX, int mouseY, float partialTicks) { + + isHovered = clicked(mouseX, mouseY); + + PonderUI.renderBox(x, y, width, height, false); + RenderSystem.pushMatrix(); + RenderSystem.translated(x - 2, y - 2, 0); + + RenderSystem.pushMatrix(); + RenderSystem.scaled((width + 4) * progress.getValue(partialTicks), 1, 1); + GuiUtils.drawGradientRect(200, 0, 3, 1, 4, 0x60ffeedd, 0x60ffeedd); + RenderSystem.popMatrix(); + + renderKeyframes(mouseX, partialTicks); + + RenderSystem.popMatrix(); + } + + private void renderKeyframes(int mouseX, float partialTicks) { + PonderScene activeScene = ponder.getActiveScene(); + + int hoverStartColor; + int hoverEndColor; + int hoverIndex; + if (isHovered) { + hoverIndex = getHoveredKeyframeIndex(mouseX); + + float flashValue = flash.getValue(partialTicks) * 3 + (float) Math.sin((AnimationTickHolder.getTicks() + partialTicks) / 6); + + hoverEndColor = ColorHelper.applyAlpha(0x70ffffff, flashValue); + hoverStartColor = ColorHelper.applyAlpha(0x30ffffff, flashValue); + } + else { + hoverIndex = -1; + hoverEndColor = 0; + hoverStartColor = 0; + } + + IntegerList keyframeTimes = activeScene.keyframeTimes; + for (int i = 0; i < keyframeTimes.size(); i++) { + int keyframeTime = keyframeTimes.get(i); + + int startColor = i == hoverIndex ? hoverStartColor : 0x60ffeedd; + int endColor = i == hoverIndex ? hoverEndColor : 0x60ffeedd; + + int keyframePos = (int) (((float) keyframeTime) / ((float) activeScene.totalTime) * (width + 4)); + GuiUtils.drawGradientRect(200, keyframePos, 1, keyframePos + 1, 4, startColor, endColor); + } + } + + @Override + public void playDownSound(SoundHandler handler) { + + } +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java index a622c8b8d..db47f742e 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java @@ -13,6 +13,8 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import com.simibubi.create.foundation.ponder.instructions.KeyframeInstruction; +import org.antlr.v4.runtime.misc.IntegerList; import org.apache.commons.lang3.mutable.MutableDouble; import org.apache.commons.lang3.mutable.MutableObject; @@ -59,6 +61,8 @@ public class PonderScene { int textIndex; String sceneId; + IntegerList keyframeTimes; + List schedule, activeSchedule; Map linkedElements; Set elements; @@ -102,6 +106,7 @@ public class PonderScene { info = new SceneRenderInfo(); baseWorldSection = new WorldSectionElement(); renderViewEntity = new ArmorStandEntity(world, 0, 0, 0); + keyframeTimes = new IntegerList(4); setPointOfInterest(new Vec3d(0, 4, 0)); } @@ -180,6 +185,7 @@ public class PonderScene { world.restore(); elements.clear(); linkedElements.clear(); + keyframeTimes.clear(); transform = new SceneTransform(); finished = false; @@ -270,6 +276,15 @@ public class PonderScene { finished = true; } + public void seekToTime(int time) { + if (time < currentTime) + throw new IllegalStateException("Cannot seek backwards. Rewind first."); + + while (currentTime < time && !finished) { + tick(); + } + } + public void addToSceneTime(int time) { if (!stoppedCounting) totalTime += time; @@ -279,6 +294,12 @@ public class PonderScene { stoppedCounting = true; } + public void markKeyframe() { + if (!stoppedCounting) { + keyframeTimes.add(totalTime); + } + } + public void addElement(PonderElement e) { elements.add(e); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java index f9ac2c8a6..cc7bbcde4 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java @@ -64,7 +64,6 @@ public class PonderUI extends AbstractSimiScreen { private List tagButtons; private List tagFades; private LerpedFloat fadeIn; - private LerpedFloat sceneProgress; ItemStack stack; PonderChapter chapter = null; @@ -80,6 +79,7 @@ public class PonderUI extends AbstractSimiScreen { private PonderTag referredToByTag; private PonderButton left, right, scan, chap; + private PonderProgressBar progressBar; public static PonderUI of(ItemStack item) { return new PonderUI(PonderRegistry.compile(item.getItem() @@ -115,8 +115,6 @@ public class PonderUI extends AbstractSimiScreen { } lazyIndex = LerpedFloat.linear() .startWithValue(index); - sceneProgress = LerpedFloat.linear() - .startWithValue(0); fadeIn = LerpedFloat.linear() .startWithValue(0) .chase(1, .1f, Chaser.EXP); @@ -160,6 +158,11 @@ public class PonderUI extends AbstractSimiScreen { int bX = (width - 20) / 2 - (70 + 2 * spacing); int bY = height - 20 - 31; + int pX = (width / 2) - 110; + int pY = bY + PonderButton.SIZE + 4; + int pW = width - 2 * pX; + widgets.add(progressBar = new PonderProgressBar(this, pX, pY, pW, 1)); + widgets.add(scan = new PonderButton(bX, bY, () -> { identifyMode = !identifyMode; if (!identifyMode) @@ -188,7 +191,6 @@ public class PonderUI extends AbstractSimiScreen { widgets.add(new PonderButton(bX, bY, this::replay).showing(AllIcons.I_MTD_REPLAY) .shortcut(bindings.keyBindBack) .fade(0, -1)); - } @Override @@ -217,10 +219,9 @@ public class PonderUI extends AbstractSimiScreen { PonderScene activeScene = scenes.get(index); if (!identifyMode) activeScene.tick(); - sceneProgress.chase(activeScene.getSceneProgress(), .5f, Chaser.EXP); lazyIndex.tickChaser(); fadeIn.tickChaser(); - sceneProgress.tickChaser(); + progressBar.tick(); if (!identifyMode) { float lazyIndexValue = lazyIndex.getValue(); @@ -232,6 +233,17 @@ public class PonderUI extends AbstractSimiScreen { updateIdentifiedItem(activeScene); } + public PonderScene getActiveScene() { + return scenes.get(index); + } + + public void seekToTime(int time) { + if (getActiveScene().currentTime > time) + replay(); + + getActiveScene().seekToTime(time); + } + public void updateIdentifiedItem(PonderScene activeScene) { hoveredTooltipItem = ItemStack.EMPTY; hoveredBlockPos = null; @@ -490,18 +502,6 @@ public class PonderUI extends AbstractSimiScreen { else right.dim(); - { - int x = (width / 2) - 110; - int y = right.y + right.getHeight() + 4; - int w = width - 2 * x; - renderBox(x, y, w, 1, false); - RenderSystem.pushMatrix(); - RenderSystem.translated(x - 2, y - 2, 0); - RenderSystem.scaled((w + 4) * sceneProgress.getValue(partialTicks), 1, 1); - GuiUtils.drawGradientRect(200, 0, 3, 1, 4, 0x60ffeedd, 0x60ffeedd); - RenderSystem.popMatrix(); - } - // Tags List sceneTags = activeScene.tags; boolean highlightAll = sceneTags.contains(PonderTag.Highlight.ALL); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java index 5bfe87504..13fe61832 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java @@ -24,26 +24,8 @@ import com.simibubi.create.foundation.ponder.elements.ParrotElement.ParrotPose; import com.simibubi.create.foundation.ponder.elements.ParrotElement.SpinOnComponentPose; import com.simibubi.create.foundation.ponder.elements.TextWindowElement; import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; -import com.simibubi.create.foundation.ponder.instructions.AnimateParrotInstruction; -import com.simibubi.create.foundation.ponder.instructions.AnimateTileEntityInstruction; -import com.simibubi.create.foundation.ponder.instructions.AnimateWorldSectionInstruction; -import com.simibubi.create.foundation.ponder.instructions.ChaseAABBInstruction; -import com.simibubi.create.foundation.ponder.instructions.CreateParrotInstruction; -import com.simibubi.create.foundation.ponder.instructions.DelayInstruction; -import com.simibubi.create.foundation.ponder.instructions.DisplayWorldSectionInstruction; -import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction; +import com.simibubi.create.foundation.ponder.instructions.*; import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction.Emitter; -import com.simibubi.create.foundation.ponder.instructions.FadeOutOfSceneInstruction; -import com.simibubi.create.foundation.ponder.instructions.HighlightValueBoxInstruction; -import com.simibubi.create.foundation.ponder.instructions.LineInstruction; -import com.simibubi.create.foundation.ponder.instructions.MarkAsFinishedInstruction; -import com.simibubi.create.foundation.ponder.instructions.MovePoiInstruction; -import com.simibubi.create.foundation.ponder.instructions.OutlineSelectionInstruction; -import com.simibubi.create.foundation.ponder.instructions.ReplaceBlocksInstruction; -import com.simibubi.create.foundation.ponder.instructions.RotateSceneInstruction; -import com.simibubi.create.foundation.ponder.instructions.ShowInputInstruction; -import com.simibubi.create.foundation.ponder.instructions.TextInstruction; -import com.simibubi.create.foundation.ponder.instructions.TileEntityDataInstruction; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour; @@ -345,6 +327,10 @@ public class SceneBuilder { addInstruction(AnimateParrotInstruction.move(link, offset, duration)); } + public void addKeyframe() { + addInstruction(KeyframeInstruction.INSTANCE); + } + } public class WorldInstructions { diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/GantryScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/GantryScenes.java index 152d7c781..f1487a4e5 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/GantryScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/GantryScenes.java @@ -48,6 +48,8 @@ public class GantryScenes { scene.overlay.showText(80) .text(text) .pointAt(util.vector.centerOf(centralShaft)); + + scene.special.addKeyframe(); scene.idle(80); scene.world.hideIndependentSection(gantry, Direction.UP); @@ -59,6 +61,7 @@ public class GantryScenes { .text("Gantry setups can move attached Blocks.") .pointAt(gantryTop) .placeNearTarget(); + scene.special.addKeyframe(); scene.idle(30); Selection planks = util.select.position(5, 3, 1); @@ -75,6 +78,7 @@ public class GantryScenes { .sharedText("movement_anchors") .pointAt(gantryTop) .placeNearTarget(); + scene.special.addKeyframe(); scene.idle(80); scene.world.modifyKineticSpeed(util.select.layer(0), f -> 32f); @@ -107,6 +111,7 @@ public class GantryScenes { scene.idle(15); scene.world.moveSection(gantry, util.vector.of(-3, 0, 0), 40); scene.idle(40); + scene.special.addKeyframe(); scene.world.toggleRedstonePower(shaft); scene.world.toggleRedstonePower(util.select.position(3, 1, 0)); @@ -122,6 +127,7 @@ public class GantryScenes { .south())) .text("Redstone-powered gantry shafts stop moving their carriages") .placeNearTarget(); + scene.special.addKeyframe(); scene.idle(70); Selection cogSelection = util.select.position(cogPos); @@ -168,6 +174,7 @@ public class GantryScenes { .text("The movement direction of carriages depend on their shafts' orientation") .pointAt(util.vector.topOf(1, 1, 3)) .placeNearTarget(); + scene.special.addKeyframe(); scene.idle(80); BlockPos lastShaft = util.grid.at(0, 1, 2); @@ -188,6 +195,7 @@ public class GantryScenes { .text("...as well as the rotation direction of the shaft") .pointAt(util.vector.blockSurface(lastShaft, Direction.WEST)) .placeNearTarget(); + scene.special.addKeyframe(); } scene.idle(30); @@ -216,6 +224,7 @@ public class GantryScenes { .text("Same rules apply for the propagated rotation") .pointAt(util.vector.topOf(0, 3, 3)) .placeNearTarget(); + scene.special.addKeyframe(); scene.idle(20); for (boolean flip2 : Iterate.trueAndFalse) { @@ -260,6 +269,7 @@ public class GantryScenes { scene.overlay.showText(60) .text("Gantry shafts attach to a carriage without the need of super glue") .independent(20); + scene.special.addKeyframe(); scene.idle(40); scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -f); @@ -272,6 +282,7 @@ public class GantryScenes { scene.overlay.showText(60) .text("Same applies for carriages on moved Gantry Shafts") .independent(20); + scene.special.addKeyframe(); scene.idle(15); scene.world.moveSection(gantry, util.vector.of(0, 2, 0), 40); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/KeyframeInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/KeyframeInstruction.java new file mode 100644 index 000000000..1330c0fdb --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/KeyframeInstruction.java @@ -0,0 +1,24 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderInstruction; +import com.simibubi.create.foundation.ponder.PonderScene; + +public class KeyframeInstruction extends PonderInstruction { + + public static final KeyframeInstruction INSTANCE = new KeyframeInstruction(); + + private KeyframeInstruction() { } + + @Override + public boolean isComplete() { + return true; + } + + @Override + public void tick(PonderScene scene) { } + + @Override + public void onScheduled(PonderScene scene) { + scene.markKeyframe(); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java b/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java index b2a50382f..9d718384e 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java @@ -122,6 +122,8 @@ public class Backend { for (ProgramSpec shader : registry.values()) { loadProgram(manager, shader); } + + log.info("Loaded all shader programs."); } } } @@ -140,7 +142,7 @@ public class Backend { programs.put(programSpec, new ProgramGroup<>(programGroup)); - log.info("Loaded program {}", programSpec.name); + log.debug("Loaded program {}", programSpec.name); } catch (IOException ex) { log.error("Failed to load program {}", programSpec.name, ex); return; diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlProgram.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlProgram.java index 09fdde86d..0b550b448 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlProgram.java @@ -39,7 +39,7 @@ public abstract class GlProgram extends GlObject { int index = GL20.glGetUniformLocation(this.handle(), uniform); if (index < 0 && Backend.SHADER_DEBUG_OUTPUT) { - Backend.log.warn("No active uniform '{}' exists in program '{}'. Could be unused.", uniform, this.name); + Backend.log.debug("No active uniform '{}' exists in program '{}'. Could be unused.", uniform, this.name); } return index; @@ -106,8 +106,8 @@ public abstract class GlProgram extends GlObject { String log = GL20.glGetProgramInfoLog(this.program); - if (!log.isEmpty()) { - Backend.log.warn("Program link log for " + this.name + ": " + log); + if (!log.isEmpty() && Backend.SHADER_DEBUG_OUTPUT) { + Backend.log.debug("Program link log for " + this.name + ": " + log); } int result = GL20.glGetProgrami(this.program, GL20.GL_LINK_STATUS); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlShader.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlShader.java index 6f7076a18..dae037bdb 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlShader.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlShader.java @@ -21,7 +21,7 @@ public class GlShader extends GlObject { source = preProcessor.process(source); if (Backend.SHADER_DEBUG_OUTPUT) - Backend.log.info("Preprocessor run on " + name);// + ":\n" + source); + Backend.log.debug("Preprocessor run on " + name);// + ":\n" + source); } GL20.glShaderSource(handle, source); @@ -30,11 +30,11 @@ public class GlShader extends GlObject { String log = GL20.glGetShaderInfoLog(handle); if (!log.isEmpty()) { - Backend.log.warn("Shader compilation log for " + name + ": " + log); + Backend.log.error("Shader compilation log for " + name + ": " + log); } if (GL20.glGetShaderi(handle, GL20.GL_COMPILE_STATUS) != GL20.GL_TRUE) { - throw new RuntimeException("Could not compile shader"); + throw new RuntimeException("Could not compile shader. See log for details."); } setHandle(handle);