Skip to content

Commit 262d41f

Browse files
committed
Fix sneaking offset in <=1.7.x
1 parent 07d3b0a commit 262d41f

File tree

6 files changed

+267
-238
lines changed

6 files changed

+267
-238
lines changed

src/main/java/org/visuals/legacy/animatium/mixins/v1/entity/MixinLivingEntityRenderer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public abstract class MixinLivingEntityRenderer<S extends LivingEntityRenderStat
5858
final CameraUtilityRenderState cameraUtilityRenderState = (CameraUtilityRenderState) cameraRenderState;
5959
if (Animatium.isEnabled() && AnimatiumConfig.instance().movement.sneakAnimation == SneakAnimationSetting.V1_7 && livingEntityRenderState instanceof AvatarRenderState avatarRenderState && cameraUtilityRenderState.animatium$getId() == avatarRenderState.id) {
6060
final float cameraLerpValue = Utils.lerpCameraPosition(cameraUtilityRenderState);
61-
poseStack.translate(0.0F, (livingEntityRenderState.eyeHeight * livingEntityRenderState.scale) - cameraLerpValue, 0.0F);
61+
final UtilityRenderState utilityRenderState = (UtilityRenderState) avatarRenderState;
62+
poseStack.translate(0.0F, (utilityRenderState.animatium$getStandingDimensions().eyeHeight() * avatarRenderState.scale) - cameraLerpValue, 0.0F);
6263
}
6364
}
6465

src/main/java/org/visuals/legacy/animatium/mixins/v1/gui/screen_tweaks/MixinPanoramaRenderer_LegacyRendering.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@
3838
import org.spongepowered.asm.mixin.injection.At;
3939
import org.visuals.legacy.animatium.Animatium;
4040
import org.visuals.legacy.animatium.config.AnimatiumConfig;
41-
import org.visuals.legacy.animatium.util.rendering.PanoramaRendererUtility;
41+
import org.visuals.legacy.animatium.util.rendering.LegacyPanoramaRenderer;
4242

4343
@Mixin(PanoramaRenderer.class)
4444
public abstract class MixinPanoramaRenderer_LegacyRendering {
4545
@WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/CubeMap;render(Lnet/minecraft/client/Minecraft;FF)V", ordinal = 0))
4646
private void animatium$panoramaRendering(CubeMap instance, Minecraft minecraft, float xRot, float yRot, Operation<Void> original, @Local(argsOnly = true) GuiGraphics guiGraphics, @Local(argsOnly = true, ordinal = 0) int width, @Local(argsOnly = true, ordinal = 1) int height) {
4747
if (Animatium.isEnabled() && AnimatiumConfig.instance().screen.panoramaRendering) {
48-
PanoramaRendererUtility.update(minecraft.getDeltaTracker().getGameTimeDeltaTicks());
49-
PanoramaRendererUtility.render(guiGraphics, width, height);
48+
LegacyPanoramaRenderer.update(minecraft.getDeltaTracker().getGameTimeDeltaTicks());
49+
LegacyPanoramaRenderer.render(guiGraphics, width, height);
5050
} else {
5151
original.call(instance, minecraft, xRot, yRot);
5252
}

src/main/java/org/visuals/legacy/animatium/mixins/v1/rendering/states/MixinArmedEntityRenderState.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727

2828
import net.minecraft.client.renderer.entity.state.ArmedEntityRenderState;
2929
import net.minecraft.client.renderer.item.ItemModelResolver;
30-
import net.minecraft.world.entity.HumanoidArm;
31-
import net.minecraft.world.entity.LivingEntity;
30+
import net.minecraft.world.entity.*;
3231
import net.minecraft.world.entity.player.Player;
3332
import net.minecraft.world.item.ItemStack;
3433
import org.spongepowered.asm.mixin.Mixin;
@@ -53,8 +52,11 @@ public abstract class MixinArmedEntityRenderState implements UtilityRenderState
5352
@Unique
5453
private boolean animatium$isSleeping = false;
5554

55+
@Unique
56+
private EntityDimensions animatium$standingDimensions = null;
57+
5658
@Inject(method = "extractArmedEntityRenderState", at = @At("TAIL"))
57-
private static void animatium$storeStacks(LivingEntity livingEntity, ArmedEntityRenderState armedEntityRenderState, ItemModelResolver itemModelResolver, CallbackInfo ci) {
59+
private static void animatium$storeData(LivingEntity livingEntity, ArmedEntityRenderState armedEntityRenderState, ItemModelResolver itemModelResolver, CallbackInfo ci) {
5860
UtilityRenderState utilityRenderState = (UtilityRenderState) armedEntityRenderState;
5961
utilityRenderState.animatium$setItemHeldByArm(HumanoidArm.LEFT, livingEntity.getItemHeldByArm(HumanoidArm.LEFT));
6062
utilityRenderState.animatium$setItemHeldByArm(HumanoidArm.RIGHT, livingEntity.getItemHeldByArm(HumanoidArm.RIGHT));
@@ -65,6 +67,10 @@ public abstract class MixinArmedEntityRenderState implements UtilityRenderState
6567
if (livingEntity.isSleeping()) {
6668
utilityRenderState.animatium$setSleeping();
6769
}
70+
71+
if (livingEntity instanceof Avatar avatar) {
72+
utilityRenderState.animatium$setStandingDimensions(avatar.getDefaultDimensions(Pose.STANDING));
73+
}
6874
}
6975

7076
@Override
@@ -108,4 +114,14 @@ public abstract class MixinArmedEntityRenderState implements UtilityRenderState
108114
public void animatium$setSleeping() {
109115
animatium$isSleeping = true;
110116
}
117+
118+
@Override
119+
public EntityDimensions animatium$getStandingDimensions() {
120+
return animatium$standingDimensions;
121+
}
122+
123+
@Override
124+
public void animatium$setStandingDimensions(EntityDimensions entityDimensions) {
125+
animatium$standingDimensions = entityDimensions;
126+
}
111127
}
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/**
2+
* Animatium
3+
* The all-you-could-want legacy animations mod for modern minecraft versions.
4+
* Brings back animations from the 1.7/1.8 era and more.
5+
* <p>
6+
* Copyright (C) 2024-2025 lowercasebtw
7+
* Copyright (C) 2024-2025 mixces
8+
* Copyright (C) 2024-2025 Contributors to the project retain their copyright
9+
* <p>
10+
* This program is free software: you can redistribute it and/or modify
11+
* it under the terms of the GNU General Public License as published by
12+
* the Free Software Foundation, either version 3 of the License, or
13+
* (at your option) any later version.
14+
* <p>
15+
* This program is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
* GNU General Public License for more details.
19+
* <p>
20+
* You should have received a copy of the GNU General Public License
21+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
* <p>
23+
* "MINECRAFT" LINKING EXCEPTION TO THE GPL
24+
*/
25+
26+
package org.visuals.legacy.animatium.util.rendering;
27+
28+
import com.mojang.blaze3d.ProjectionType;
29+
import com.mojang.blaze3d.pipeline.BlendFunction;
30+
import com.mojang.blaze3d.pipeline.MainTarget;
31+
import com.mojang.blaze3d.pipeline.RenderPipeline;
32+
import com.mojang.blaze3d.platform.DestFactor;
33+
import com.mojang.blaze3d.platform.SourceFactor;
34+
import com.mojang.blaze3d.systems.RenderSystem;
35+
import com.mojang.blaze3d.textures.FilterMode;
36+
import com.mojang.blaze3d.textures.GpuTexture;
37+
import com.mojang.blaze3d.textures.GpuTextureView;
38+
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
39+
import com.mojang.blaze3d.vertex.VertexConsumer;
40+
import com.mojang.blaze3d.vertex.VertexFormat;
41+
import lombok.experimental.UtilityClass;
42+
import net.minecraft.client.gui.GuiGraphics;
43+
import net.minecraft.client.gui.navigation.ScreenRectangle;
44+
import net.minecraft.client.gui.render.TextureSetup;
45+
import net.minecraft.client.gui.render.state.GuiElementRenderState;
46+
import net.minecraft.client.renderer.CachedPerspectiveProjectionMatrixBuffer;
47+
import net.minecraft.client.renderer.RenderPipelines;
48+
import net.minecraft.client.renderer.texture.DynamicTexture;
49+
import net.minecraft.resources.ResourceLocation;
50+
import net.minecraft.util.ARGB;
51+
import net.minecraft.util.Mth;
52+
import org.jetbrains.annotations.NotNull;
53+
import org.jetbrains.annotations.Nullable;
54+
import org.joml.Matrix3x2f;
55+
import org.joml.Matrix4f;
56+
import org.joml.Vector4i;
57+
import org.visuals.legacy.animatium.Animatium;
58+
import org.visuals.legacy.animatium.util.Utils;
59+
60+
@UtilityClass
61+
// Ported code of the old <=1.12.2 panorama renderer (w/ blur)
62+
public class LegacyPanoramaRenderer {
63+
private final BlendFunction PANORAMA_BLEND = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO);
64+
65+
private final RenderPipeline LEGACY_PANORAMA =
66+
RenderPipeline.builder(RenderPipelines.MATRICES_PROJECTION_SNIPPET)
67+
.withLocation(Animatium.location("pipeline/legacy_panorama"))
68+
.withVertexShader(Animatium.location("core/legacy_panorama"))
69+
.withFragmentShader(Animatium.location("core/legacy_panorama"))
70+
.withCull(false)
71+
.withDepthWrite(false)
72+
.withBlend(PANORAMA_BLEND)
73+
// .withColorWrite(true, false) // TODO/NOTE: Causes it to not render (alpha becomes 0.0?!??!?!)
74+
.withSampler("Sampler0")
75+
.withVertexFormat(DefaultVertexFormat.POSITION_TEX_COLOR, VertexFormat.Mode.QUADS)
76+
.build();
77+
78+
private final RenderPipeline LEGACY_PANORAMA_BLUR =
79+
RenderPipeline.builder(RenderPipelines.GUI_TEXTURED_SNIPPET)
80+
.withLocation(Animatium.location("pipeline/legacy_panorama_blur"))
81+
.withVertexShader(Animatium.location("core/legacy_panorama_blur"))
82+
.withFragmentShader(Animatium.location("core/legacy_panorama_blur"))
83+
.withBlend(PANORAMA_BLEND)
84+
.withColorWrite(true, false)
85+
.build();
86+
87+
private final Vector4i VIEWPORT = new Vector4i(0, 0, 256, 256);
88+
89+
private final CachedPerspectiveProjectionMatrixBuffer projectionMatrixBuffer = new CachedPerspectiveProjectionMatrixBuffer("panorama", 0.05F, 10.0F);
90+
private final MainTarget panoramaTarget = new MainTarget(256, 256);
91+
private final GpuTextureView backgroundTextureView;
92+
private float spin = 0.0F;
93+
94+
static {
95+
final DynamicTexture dynamicTexture = new DynamicTexture(() -> "background", 256, 256, true);
96+
backgroundTextureView = dynamicTexture.getTextureView();
97+
RenderSystem.getDevice().createCommandEncoder().clearDepthTexture(panoramaTarget.getDepthTexture(), 1.0F);
98+
}
99+
100+
public void render(final GuiGraphics guiGraphics, final int width, final int height) {
101+
renderPanorama(width, height);
102+
for (int pass = 0; pass < 7; ++pass) {
103+
panoramaBlurPass(guiGraphics.pose(), width, height);
104+
}
105+
106+
guiGraphics.guiRenderState.submitGuiElement(new BlitFinalTexture(guiGraphics.pose(), backgroundTextureView, width, height, ARGB.white(1.0F)));
107+
}
108+
109+
private void renderPanorama(final int width, final int height) {
110+
RenderSystem.setProjectionMatrix(projectionMatrixBuffer.getBuffer(width, height, 120.0F), ProjectionType.PERSPECTIVE);
111+
final Matrix4f rootMatrix = new Matrix4f().identity().rotateX(Utils.toRadians(180.0F)).rotateZ(Utils.toRadians(90.0F));
112+
for (int layer = 0; layer < 64; layer++) {
113+
float x = (layer % 8 / 8.0F - 0.5F) / 64.0F;
114+
float y = ((float) layer / 8 / 8.0F - 0.5F) / 64.0F;
115+
final Matrix4f layerMatrix = new Matrix4f(rootMatrix).translate(x, y, 0.0F).rotateX(Utils.toRadians(getXRot())).rotateY(Utils.toRadians(getYRot()));
116+
for (int panoramaIdx = 0; panoramaIdx < 6; panoramaIdx++) {
117+
final Matrix4f faceMatrix = new Matrix4f(layerMatrix);
118+
if (panoramaIdx == 1) {
119+
faceMatrix.rotateY(Utils.toRadians(90.0F));
120+
} else if (panoramaIdx == 2) {
121+
faceMatrix.rotateY(Utils.toRadians(180.0F));
122+
} else if (panoramaIdx == 3) {
123+
faceMatrix.rotateY(Utils.toRadians(-90.0F));
124+
} else if (panoramaIdx == 4) {
125+
faceMatrix.rotateX(Utils.toRadians(90.0F));
126+
} else if (panoramaIdx == 5) {
127+
faceMatrix.rotateX(Utils.toRadians(-90.0F));
128+
}
129+
130+
try (final Renderer renderer = Renderer.of("Panorama")) {
131+
renderer.setPipeline(LEGACY_PANORAMA);
132+
renderer.setViewport(VIEWPORT);
133+
renderer.setFramebuffer(panoramaTarget);
134+
renderer.setDynamicTransforms(renderer.getDynamicTransforms().withModelViewMatrix(faceMatrix));
135+
136+
final int currentLayer = layer;
137+
renderer.setup((vertexConsumer) -> {
138+
final int color = ARGB.white(255.0F / (currentLayer + 1.0F));
139+
vertexConsumer.addVertex(-1.0F, -1.0F, 1.0F).setUv(0.0F, 0.0F).setColor(color);
140+
vertexConsumer.addVertex(1.0F, -1.0F, 1.0F).setUv(1.0F, 0.0F).setColor(color);
141+
vertexConsumer.addVertex(1.0F, 1.0F, 1.0F).setUv(1.0F, 1.0F).setColor(color);
142+
vertexConsumer.addVertex(-1.0F, 1.0F, 1.0F).setUv(0.0F, 1.0F).setColor(color);
143+
}, 4);
144+
145+
renderer.setTexture(0, getPanoramaTexture(panoramaIdx));
146+
renderer.draw();
147+
}
148+
}
149+
}
150+
}
151+
152+
private void panoramaBlurPass(final Matrix3x2f pose, final int width, final int height) {
153+
final GpuTexture texture = backgroundTextureView.texture();
154+
texture.setTextureFilter(FilterMode.LINEAR, FilterMode.LINEAR, false);
155+
RenderSystem.getDevice().createCommandEncoder().copyTextureToTexture(
156+
panoramaTarget.getColorTexture(), // source
157+
texture, // destination
158+
0, // mipLevel
159+
0, // destX
160+
0, // destY
161+
0, // srcX
162+
0, // srcY
163+
256, // width
164+
256 // height
165+
);
166+
try (final Renderer renderer = Renderer.of("Panorama Blur Pass")) {
167+
renderer.setPipeline(LEGACY_PANORAMA_BLUR);
168+
renderer.setViewport(VIEWPORT);
169+
renderer.setFramebuffer(panoramaTarget);
170+
renderer.setup((vertexConsumer) -> {
171+
for (int cycle = 0; cycle < 3; cycle++) {
172+
final int color = ARGB.white(1.0F / (cycle + 1.0F));
173+
final float growth = (cycle - 1.0F) / 256.0F;
174+
vertexConsumer.addVertexWith2DPose(pose, width, height).setUv(0.0F + growth, 1.0F).setColor(color);
175+
vertexConsumer.addVertexWith2DPose(pose, width, 0.0F).setUv(1.0F + growth, 1.0F).setColor(color);
176+
vertexConsumer.addVertexWith2DPose(pose, 0.0F, 0.0F).setUv(1.0F + growth, 0.0F).setColor(color);
177+
vertexConsumer.addVertexWith2DPose(pose, 0.0F, height).setUv(0.0F + growth, 0.0F).setColor(color);
178+
}
179+
}, 12);
180+
renderer.setTexture(0, backgroundTextureView);
181+
renderer.drawInGui();
182+
}
183+
}
184+
185+
public void update(float tickDelta) {
186+
spin += tickDelta;
187+
}
188+
189+
public float getXRot() {
190+
return Mth.sin(spin / 400.0F) * 25.0F + 20.0F;
191+
}
192+
193+
public float getYRot() {
194+
return -spin * 0.1F;
195+
}
196+
197+
public ResourceLocation getPanoramaTexture(int side) {
198+
return ResourceLocation.withDefaultNamespace("textures/gui/title/background/panorama_" + side + ".png");
199+
}
200+
201+
private record BlitFinalTexture(
202+
Matrix3x2f pose,
203+
GpuTextureView texture,
204+
int width, int height,
205+
int color
206+
) implements GuiElementRenderState {
207+
@Override
208+
public void buildVertices(VertexConsumer consumer) {
209+
final float aspect = 120.0F / Math.max(this.width, this.height);
210+
final float sw = this.width * aspect / 256.0F;
211+
final float sh = this.height * aspect / 256.0F;
212+
consumer.addVertexWith2DPose(this.pose, 0.0F, this.height).setUv(0.5F - sh, 0.5F + sw).setColor(this.color);
213+
consumer.addVertexWith2DPose(this.pose, this.width, this.height).setUv(0.5F - sh, 0.5F - sw).setColor(this.color);
214+
consumer.addVertexWith2DPose(this.pose, this.width, 0.0F).setUv(0.5F + sh, 0.5F - sw).setColor(this.color);
215+
consumer.addVertexWith2DPose(this.pose, 0.0F, 0.0F).setUv(0.5F + sh, 0.5F + sw).setColor(this.color);
216+
}
217+
218+
@Override
219+
public @NotNull RenderPipeline pipeline() {
220+
return RenderPipelines.GUI_TEXTURED;
221+
}
222+
223+
@Override
224+
public @NotNull TextureSetup textureSetup() {
225+
return TextureSetup.singleTexture(this.texture);
226+
}
227+
228+
@Override
229+
public @Nullable ScreenRectangle scissorArea() {
230+
return null;
231+
}
232+
233+
@Override
234+
public @NotNull ScreenRectangle bounds() {
235+
return new ScreenRectangle(0, 0, this.width, this.height).transformMaxBounds(this.pose);
236+
}
237+
}
238+
}

0 commit comments

Comments
 (0)