Compare commits

..

No commits in common. "TopchetoEU/reprogramming-shaders" and "1.19.2" have entirely different histories.

15 changed files with 136 additions and 119 deletions

View File

@ -107,12 +107,12 @@ public final class AnimatedChunks implements ClientModInitializer, ModMenuApi {
} }
public AnimatedChunks() { public AnimatedChunks() {
var eases = new Manager<>(new Descriptor<Ease>(() -> "t = 1;", "default") var eases = new Manager<>(new Descriptor<Ease>(x -> 1, "default")
.author("TopchetoEU") .author("TopchetoEU")
.description("Ends the animation as soon as it has started.") .description("Ends the animation as soon as it has started.")
.displayName("No animation") .displayName("No animation")
); );
var animations = new Manager<>(new Descriptor<Animation>(() -> ";", "default") var animations = new Manager<>(new Descriptor<Animation>((a, b, c, d, e, f, g, h) -> {}, "default")
.author("TopchetoEU") .author("TopchetoEU")
.description("Does nothing.") .description("Does nothing.")
.displayName("No animation") .displayName("No animation")

View File

@ -1,26 +0,0 @@
package me.topchetoeu.animatedchunks;
import java.util.Map;
public interface StatementFactory {
/**
* Returns a GLSL statement, with access to at least the following variables:
* <ul>
* <li>playerPos - vec3, the position of the player</li>
* <li>chunkPos - vec3, the position of the current chunk</li>
* <li>pos - vec3, the position of the current vertex</li>
* <li>x - the raw stage of the animation, from 0 to 1</li>
* <li>t - the eased stage of the animation, from 0 to 1</li>
* <li>tmp0 - tmp7 - temporary float variables</li>
* <li>tmp8 - tmp11 - temporary vec3 variables</li>
* <li>tmp12 - tmp15 - temporary vec4 variables</li>
* </ul>
*/
String statement();
/**
* Returns all uniforms that are used by the statement
*/
public default Map<String, Float> uniforms() {
return Map.of();
}
}

View File

@ -1,5 +1,18 @@
package me.topchetoeu.animatedchunks.animation; package me.topchetoeu.animatedchunks.animation;
import me.topchetoeu.animatedchunks.StatementFactory; import net.minecraft.client.util.math.MatrixStack;
public interface Animation extends StatementFactory { } public interface Animation {
/**
* Animations using the currently set ease
* @param progress The point at which the animation currently is (a value between 0 and 1)
* @param matrices The matrix stack used for rendering
* @param chunkX The current chunk's x (in blocks) which is animated
* @param chunkY The current chunk's y (in blocks) which is animated
* @param chunkZ The current chunk's z (in blocks) which is animated
* @param playerX The player's x (in blocks)
* @param playerY The player's y (in blocks)
* @param playerZ The player's z (in blocks)
*/
void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ);
}

View File

@ -6,6 +6,9 @@ import java.util.Hashtable;
import me.topchetoeu.animatedchunks.Manager; import me.topchetoeu.animatedchunks.Manager;
import me.topchetoeu.animatedchunks.easing.Ease; import me.topchetoeu.animatedchunks.easing.Ease;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.util.math.Vector3d;
import net.minecraft.util.math.BlockPos;
public final class Animator { public final class Animator {
public static class ChunkLoc { public static class ChunkLoc {
@ -149,4 +152,33 @@ public final class Animator {
if (!chunkToStage.containsKey(new ChunkLoc(x, y, z))) return 1f; if (!chunkToStage.containsKey(new ChunkLoc(x, y, z))) return 1f;
return chunkToStage.get(new ChunkLoc(x, y, z)); return chunkToStage.get(new ChunkLoc(x, y, z));
} }
public void animate(MatrixStack matrices, float progress, BlockPos chunkPos, Vector3d playerPos) {
if (progress < 0) progress = 0;
if (progress > 1) progress = 1;
if (progress < 0.999) {
float _progress = EASES.getValue().ease(progress);
ANIMATIONS.getValue().animate(
_progress, matrices,
chunkPos.getX() * 16, chunkPos.getY() * 16, chunkPos.getZ() * 16,
(float)playerPos.x, (float)playerPos.y, (float)playerPos.z
);
// matrices.translate(0, 0, 16);
}
}
public void animate(MatrixStack matrices, BlockPos chunkPos, Vector3d playerPos) {
if (!isChunkLoaded(chunkPos.getX(), chunkPos.getY(), chunkPos.getZ())) {
matrices.scale(0, 0, 0);
}
else {
animate(matrices, getChunkProgress(chunkPos.getX(), chunkPos.getY(), chunkPos.getZ()), chunkPos, playerPos);
}
}
public void animate(MatrixStack matrices, BlockPos chunkPos) {
animate(matrices, chunkPos, new Vector3d(0, 0, 0));
}
public void animate(MatrixStack matrices, float progress, BlockPos chunkPos) {
animate(matrices, progress, chunkPos, new Vector3d(0, 0, 0));
}
} }

View File

@ -1,6 +1,6 @@
package me.topchetoeu.animatedchunks.animation; package me.topchetoeu.animatedchunks.animation;
import java.util.Map; import net.minecraft.client.util.math.MatrixStack;
public class FallAnimation implements Animation { public class FallAnimation implements Animation {
private float offset; private float offset;
@ -12,11 +12,12 @@ public class FallAnimation implements Animation {
this.offset = offset; this.offset = offset;
} }
public Map<String, Float> uniforms() { @Override
return Map.of("animation_f", offset); public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
animate(progress, matrices);
} }
public String statement() { public void animate(float progress, MatrixStack matrices) {
return "pos += vec3(0, animation_f * (1 - t));"; matrices.translate(0, offset * (1 - progress), 0);
} }
public FallAnimation(float offset) { public FallAnimation(float offset) {

View File

@ -1,6 +1,7 @@
package me.topchetoeu.animatedchunks.animation; package me.topchetoeu.animatedchunks.animation;
import java.util.Map; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Vec2f;
public class FlyInAnimation implements Animation { public class FlyInAnimation implements Animation {
private float offset; private float offset;
@ -12,22 +13,14 @@ public class FlyInAnimation implements Animation {
this.offset = offset; this.offset = offset;
} }
public Map<String, Float> uniforms() {
return Map.of("animation_f", offset);
}
@Override @Override
public String statement() { public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
return "tmp8 = normalize(chunkPos.xz - playerPos.xz) * animation_f; tmp8 *= (1 - t); pos += tmp8;"; Vec2f direction = new Vec2f(playerX, playerZ).add(new Vec2f(-chunkX, -chunkZ)).normalize().multiply(-offset);
matrices.translate(direction.x * (1 - progress), 0, direction.y * (1 - progress));
} }
// @Override
// public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
// Vec2f direction = new Vec2f(playerX, playerZ).add(new Vec2f(-chunkX, -chunkZ)).normalize().multiply(-offset);
// matrices.translate(direction.x * (1 - progress), 0, direction.y * (1 - progress));
// }
public FlyInAnimation() { public FlyInAnimation() {
offset = 50; offset = 50;
} }

View File

@ -1,6 +1,6 @@
package me.topchetoeu.animatedchunks.animation; package me.topchetoeu.animatedchunks.animation;
import java.util.Map; import net.minecraft.client.util.math.MatrixStack;
public final class RiseAnimation implements Animation { public final class RiseAnimation implements Animation {
private float offset; private float offset;
@ -12,11 +12,12 @@ public final class RiseAnimation implements Animation {
this.offset = offset; this.offset = offset;
} }
public Map<String, Float> uniforms() { @Override
return Map.of("animation_f", offset); public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
animate(progress, matrices);
} }
public String statement() { public void animate(float progress, MatrixStack matrices) {
return "pos += vec3(0, animation_f * (t - 1));"; matrices.translate(0, offset * (progress - 1), 0);
} }
public RiseAnimation(float offset) { public RiseAnimation(float offset) {

View File

@ -1,11 +1,10 @@
package me.topchetoeu.animatedchunks.animation; package me.topchetoeu.animatedchunks.animation;
import java.util.Map; import net.minecraft.client.util.math.MatrixStack;
public class ScaleAnimation implements Animation { public class ScaleAnimation implements Animation {
public static float xOffset = 8, yOffset = 8, zOffset = 8;
private boolean scaleY = true; private boolean scaleY = true;
private float xOffset = 8, yOffset = 8, zOffset = 8;
public boolean isScalingY() { public boolean isScalingY() {
return scaleY; return scaleY;
@ -14,31 +13,38 @@ public class ScaleAnimation implements Animation {
this.scaleY = scaleY; this.scaleY = scaleY;
} }
@Override public float getXOffset() {
public Map<String, Float> uniforms() { return xOffset;
return Map.of("animation_ox", xOffset, "animation_oy", yOffset, "animation_oz", zOffset, "animation_sy", scaleY ? 1f : 0f); }
public void setXOffset(float xOffset) {
this.xOffset = xOffset;
}
public float getYOffset() {
return yOffset;
}
public void setYOffset(float yOffset) {
this.yOffset = yOffset;
}
public float getZOffset() {
return zOffset;
}
public void setZOffset(float zOffset) {
this.zOffset = zOffset;
} }
@Override @Override
public String statement() { public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
return float scaleX = progress;
"tmp8 = vec3(animation_ox, animation_oy, animation_oz);" + float scaleZ = progress;
"tmp9 = vec3(t);" +
"if (animation_sy < .5f) tmp9.y = 0;" + matrices.translate(xOffset, yOffset, zOffset);
"pos += tmp8;" + matrices.scale(scaleX, 1, scaleZ);
"pos *= tmp9;" + matrices.translate(-xOffset, -yOffset, -zOffset);
"pos -= tmp8;";
} }
// @Override public ScaleAnimation() {
// public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
// float scaleX = progress;
// float scaleZ = progress;
// matrices.translate(xOffset, yOffset, zOffset); }
// matrices.scale(scaleX, 1, scaleZ);
// matrices.translate(-xOffset, -yOffset, -zOffset);
// }
public ScaleAnimation() { }
} }

View File

@ -1,30 +1,34 @@
package me.topchetoeu.animatedchunks.easing; package me.topchetoeu.animatedchunks.easing;
import me.topchetoeu.animatedchunks.StatementFactory; public interface Ease {
public interface Ease extends StatementFactory {
/** /**
* Converts a ease-in statement to an ease-out statement * Converts the linear progress of an animation to an eased progress
* @param x The progress of the animation being eased
* @return The new, eased progress
*/
float ease(float x);
/**
* Converts a function to an ease out version of itself.
* Mathematically, the function is being "rotated" 180 degrees * Mathematically, the function is being "rotated" 180 degrees
* @param func The ease statement to convert * @param func The function to convert
* @return The ease out version of the function
*/ */
public static Ease easeOut(Ease func) { public static Ease easeOut(Ease func) {
return () -> "x = 1 - x; " + func.statement() + "x = 1 - x; t = 1 - t;"; return x -> 1 - func.ease(1 - x);
// return x -> 1 - func.ease(1 - x);
} }
/** /**
* Converts a ease statement to an ease in-out statement * Converts a function to an ease in-out version of itself.
* Mathematically, the function is being split into two, where in the interval [0; 0.5), the ease-in function is being used, and in the other interval [0.5; 1], the ease-out function is being used * Mathematically, the function is being split into two, where in the interval [0; 0.5], the ease-out function is being used, and in the other interval [0.5; 1], the ease-in function is being used
* @param func The ease statement to convert * @param func The function to convert
* @return The ease in-out statement * @return The ease in-out version of the function
*/ */
public static Ease easeInOut(Ease func) { public static Ease easeInOut(Ease func) {
return () -> "x *= 2; if (x < 1f) { " + easeOut(func) + "} else { x -= 1; " + func.statement() + " } x /= 2;"; return x -> {
// return x -> { float x2 = 2 * x;
// float x2 = 2 * x;
// if (x < 0.5f) return (1 - func.ease(1 - x2)) / 2; if (x < 0.5f) return (1 - func.ease(1 - x2)) / 2;
// else return (1 + func.ease(x2 - 1)) / 2; else return (1 + func.ease(x2 - 1)) / 2;
// }; };
} }
} }

View File

@ -1,7 +1,5 @@
package me.topchetoeu.animatedchunks.easing; package me.topchetoeu.animatedchunks.easing;
import java.util.Map;
public class ElasticEase implements Ease { public class ElasticEase implements Ease {
private float steepness = 1; private float steepness = 1;
private int periods = 3; private int periods = 3;
@ -21,21 +19,11 @@ public class ElasticEase implements Ease {
} }
@Override @Override
public Map<String, Float> uniforms() { public float ease(float x) {
return Map.of("ease_s", steepness, "ease_p", (float)periods); float amplitude = (float)Math.pow(2, -steepness * x) * (1 - x);
} float wave = (float)Math.sin(2 * Math.PI * periods * x - Math.PI / 2);
@Override return amplitude * wave + 1;
public String statement() {
return
"tmp0 = pow(2, -ease_s * x) * (1 - x);" +
"tmp1 = sin(6.28 * ease_p * x - 1.57);" +
"t = tmp0 * tmp1 + 1;";
// float amplitude = (float)Math.pow(2, -steepness * x) * (1 - x);
// float wave = (float)Math.sin(2 * Math.PI * periods * x - Math.PI / 2);
// return amplitude * wave + 1;
} }
} }

View File

@ -1,7 +1,7 @@
package me.topchetoeu.animatedchunks.easing; package me.topchetoeu.animatedchunks.easing;
public class LinearEase implements Ease { public class LinearEase implements Ease {
public String statement() { public float ease(float x) {
return "t = x;"; return x;
} }
} }

View File

@ -1,7 +1,8 @@
package me.topchetoeu.animatedchunks.easing; package me.topchetoeu.animatedchunks.easing;
public class QuadraticEase implements Ease { public class QuadraticEase implements Ease {
public String statement() { @Override
return "t = x * x;"; public float ease(float x) {
return x * x;
} }
} }

View File

@ -1,7 +1,8 @@
package me.topchetoeu.animatedchunks.easing; package me.topchetoeu.animatedchunks.easing;
public class SineEase implements Ease { public class SineEase implements Ease {
public String statement() { @Override
return "t = sin(x * 1.57);"; public float ease(float x) {
return (float)Math.sin(x * Math.PI / 2);
} }
} }

View File

@ -20,6 +20,7 @@ import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat; import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats; import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.math.Quaternion; import net.minecraft.util.math.Quaternion;
import net.minecraft.util.math.Vec3f; import net.minecraft.util.math.Vec3f;
@ -172,7 +173,7 @@ public class ChunkPreview extends DrawableHelper implements Drawable, Element, S
// x += n; // x += n;
// y += n; // y += n;
// animator.animate(matrices, progress, new BlockPos(x * 16, 0, y * 16)); animator.animate(matrices, progress, new BlockPos(x * 16, 0, y * 16));
// if (progress < 0) progress = 0; // if (progress < 0) progress = 0;
// if (progress > 1) progress = 1; // if (progress > 1) progress = 1;

View File

@ -11,6 +11,8 @@ import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.render.WorldRenderer.ChunkInfo; import net.minecraft.client.render.WorldRenderer.ChunkInfo;
import net.minecraft.client.render.chunk.ChunkBuilder.BuiltChunk; import net.minecraft.client.render.chunk.ChunkBuilder.BuiltChunk;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.util.math.Vector3d;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Matrix4f;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@ -54,7 +56,7 @@ public abstract class WorldRendererMixin {
matrices.push(); matrices.push();
// AnimatedChunks.getInstance().animator.animate(matrices, new BlockPos(chunk.getOrigin().getX(), 0, chunk.getOrigin().getZ()), new Vector3d(playerX, playerY, playerZ)); AnimatedChunks.getInstance().animator.animate(matrices, new BlockPos(chunk.getOrigin().getX(), 0, chunk.getOrigin().getZ()), new Vector3d(playerX, playerY, playerZ));
// if (getProgressManager().isChunkLoaded(x, 0, z)) { // if (getProgressManager().isChunkLoaded(x, 0, z)) {
// float progress = getProgressManager().getChunkProgress(x, 0, z); // float progress = getProgressManager().getChunkProgress(x, 0, z);