This commit is contained in:
2026-01-02 17:19:45 +01:00
parent 999e5fb752
commit 8163dabf2d
4 changed files with 77 additions and 2 deletions

BIN
no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@@ -1,5 +1,6 @@
package com.straice.smoothdoors.client.anim;
import it.unimi.dsi.fastutil.longs.Long2FloatOpenHashMap;
import net.minecraft.block.BlockState;
import net.minecraft.block.FenceGateBlock;
import net.minecraft.client.MinecraftClient;
@@ -12,8 +13,10 @@ import net.minecraft.client.render.model.BlockModelPart;
import net.minecraft.client.render.model.BlockStateModel;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.RotationAxis;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.random.Random;
import java.util.ArrayList;
@@ -24,6 +27,10 @@ final class FenceGateAnimation {
private static final float POST_EDGE = 2.0f / 16.0f;
private static final float EDGE_EPS = 1.0e-4f;
private static final float ANGLE_EPS = 1.0e-3f;
private static final Long2FloatOpenHashMap GATE_SIGNS = new Long2FloatOpenHashMap();
private static final Long2FloatOpenHashMap LAST_ANGLES = new Long2FloatOpenHashMap();
private FenceGateAnimation() {}
@@ -55,10 +62,13 @@ final class FenceGateAnimation {
float rightPivotX = leftRightIsX ? (15.0f / 16.0f) : 0.5f;
float rightPivotZ = leftRightIsX ? 0.5f : (15.0f / 16.0f);
long key = blockKey(mc, matrices);
float signedAngle = angleDeg * resolveSign(mc, key, facing, leftRightIsX, angleDeg);
if (models.left != null) {
matrices.push();
matrices.translate(leftPivotX, 0.0f, leftPivotZ);
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-angleDeg));
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-signedAngle));
matrices.translate(-leftPivotX, 0.0f, -leftPivotZ);
BlockModelRenderer.render(matrices.peek(), consumer, models.left, r, g, b, light, overlay);
matrices.pop();
@@ -67,13 +77,78 @@ final class FenceGateAnimation {
if (models.right != null) {
matrices.push();
matrices.translate(rightPivotX, 0.0f, rightPivotZ);
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angleDeg));
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(signedAngle));
matrices.translate(-rightPivotX, 0.0f, -rightPivotZ);
BlockModelRenderer.render(matrices.peek(), consumer, models.right, r, g, b, light, overlay);
matrices.pop();
}
}
private static long blockKey(MinecraftClient mc, MatrixStack matrices) {
Vec3d camPos = mc.gameRenderer.getCamera().getPos();
var posMat = matrices.peek().getPositionMatrix();
double worldX = camPos.x + posMat.m30();
double worldY = camPos.y + posMat.m31();
double worldZ = camPos.z + posMat.m32();
int blockX = (int) Math.round(worldX);
int blockY = (int) Math.round(worldY);
int blockZ = (int) Math.round(worldZ);
return BlockPos.asLong(blockX, blockY, blockZ);
}
private static float resolveSign(MinecraftClient mc, long key, Direction facing,
boolean leftRightIsX, float angleDeg) {
float prevAngle = LAST_ANGLES.containsKey(key) ? LAST_ANGLES.get(key) : angleDeg;
float sign = GATE_SIGNS.containsKey(key) ? GATE_SIGNS.get(key) : 0.0f;
boolean opening = angleDeg > prevAngle + ANGLE_EPS;
boolean closing = angleDeg < prevAngle - ANGLE_EPS;
if (sign == 0.0f && opening && mc.player != null) {
sign = computeSign(mc, key, facing, leftRightIsX);
GATE_SIGNS.put(key, sign);
}
if (sign == 0.0f && angleDeg > ANGLE_EPS && mc.player != null) {
sign = computeSign(mc, key, facing, leftRightIsX);
GATE_SIGNS.put(key, sign);
}
if (closing && angleDeg <= ANGLE_EPS) {
GATE_SIGNS.remove(key);
LAST_ANGLES.remove(key);
return 1.0f;
}
LAST_ANGLES.put(key, angleDeg);
return (sign == 0.0f) ? 1.0f : sign;
}
private static float computeSign(MinecraftClient mc, long key, Direction facing, boolean leftRightIsX) {
if (mc.player == null) return 1.0f;
BlockPos pos = BlockPos.fromLong(key);
double centerX = pos.getX() + 0.5;
double centerZ = pos.getZ() + 0.5;
double dx = mc.player.getX() - centerX;
double dz = mc.player.getZ() - centerZ;
int facingX = facing.getOffsetX();
int facingZ = facing.getOffsetZ();
double dot = dx * facingX + dz * facingZ;
float side;
if (dot > 0.0) {
side = 1.0f;
} else if (dot < 0.0) {
side = -1.0f;
} else {
Direction playerFacing = mc.player.getHorizontalFacing();
int facingDot = playerFacing.getOffsetX() * facingX + playerFacing.getOffsetZ() * facingZ;
side = (facingDot >= 0) ? 1.0f : -1.0f;
}
return leftRightIsX ? -side * facingZ : side * facingX;
}
private static FenceGateModels splitFenceGateModels(BlockStateModel model, boolean leftRightIsX) {
List<BlockModelPart> parts = model.getParts(Random.create(42L));
List<BlockModelPart> posts = new ArrayList<>();

BIN
tex.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
vacio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB