From 115c74b1c3a13112a60105279497c32a4c314623 Mon Sep 17 00:00:00 2001 From: Aram Date: Mon, 5 Jan 2026 12:52:22 +0100 Subject: [PATCH 1/6] Bunch of Cleanup --- .gitignore | 1 + changelog.md | 46 +++++- .../software/bluelib/config/LoggerConfig.java | 2 +- .../bluelib/loader/animation/Animation.java | 87 +++++++----- .../loader/animation/AnimationController.java | 20 +-- .../loader/animation/AnimationExtraData.java | 53 +++++++ .../loader/animation/AnimationProcessor.java | 38 ++--- .../loader/animation/AnimationSnapshot.java | 21 +++ .../loader/animation/AnimationState.java | 132 ++++++++++-------- .../animation/keyframe/AnimationPoint.java | 22 --- .../keyframe/BoneAnimationFrame.java | 113 +++++---------- .../animation/keyframe/InterpolationData.java | 59 ++++++++ .../AnimationFrame.java} | 6 +- .../keyframe/frame/AnimationFrameVector.java | 30 ++++ .../bluelib/loader/animation/math/Easing.java | 36 ++--- .../cache/animations/AnimationCache.java | 2 +- .../bluelib/loader/model/BlueModel.java | 2 +- 17 files changed, 426 insertions(+), 244 deletions(-) create mode 100644 common/src/main/java/software/bluelib/loader/animation/AnimationExtraData.java create mode 100644 common/src/main/java/software/bluelib/loader/animation/AnimationSnapshot.java delete mode 100644 common/src/main/java/software/bluelib/loader/animation/keyframe/AnimationPoint.java create mode 100644 common/src/main/java/software/bluelib/loader/animation/keyframe/InterpolationData.java rename common/src/main/java/software/bluelib/loader/animation/keyframe/{AnimationPointFrame.java => frame/AnimationFrame.java} (65%) create mode 100644 common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrameVector.java diff --git a/.gitignore b/.gitignore index 723f856d..1b4a7a63 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,4 @@ common/src/main/resources/data/bluelib/controller/* common/src/main/resources/assets/bluelib/textures/* /.env /neoforge +/fabric/out diff --git a/changelog.md b/changelog.md index 6dc59269..37886e6a 100644 --- a/changelog.md +++ b/changelog.md @@ -1,12 +1,46 @@ -# 2.4.3 +# 2.4.4 + +## Added + +- New `AnimationExtraData` class for managing animation-related data with type-safe `DataTicket` support +- New `AnimationSnapshot` record to encapsulate immutable animation state (limbSwing, limbSwingAmount, partialTick, + isMoving) +- New `InterpolationData` record replacing `AnimationPoint` with added `getProgress()` method for calculating normalized + interpolation progress +- New `AnimationFrameVector` record to group X, Y, Z animation frames together +- Utility methods `isEmpty()` and `size()` added to `Animation` class +- `isWait()` helper method added to `Animation.Frame` record +- `toString()` method added to `Animation` and `AnimationState` for better debugging +- Input validation with `IllegalArgumentException` for negative ticks, non-positive play counts, and NaN animation + values ## Changed -* Massive cleanup in the way we register Codecs and Data ComponentTypes. +- Renamed `Animation.Stage` to `Animation.Frame` for clearer semantics +- Renamed `AnimationPoint` to `InterpolationData` with updated field names (`animationStartValue` → `startValue`, + `animationEndValue` → `endValue`) +- Renamed `AnimationPointFrame` to `AnimationFrame` and moved to `frame` subpackage +- Renamed `getAnimationStages()` to `getAnimationFrames()` in `Animation` class +- Refactored `BoneAnimationFrame` to use `AnimationFrameVector` instead of individual X/Y/Z queues +- Renamed methods in `BoneAnimationFrame`: `addRotations` → `addNextRotation`, `addPositions` → `addNextPosition`, + `addScales` → `addNextScale` +- `AnimationState` now uses composition with `AnimationSnapshot` and `AnimationExtraData` instead of individual fields +- `getAnimationFrames()` now returns an unmodifiable list +- `getController()` in `AnimationState` now throws `IllegalStateException` if controller is not set +- `setControllerSpeed()` parameter changed from `Double` to primitive `double` +- `animationTick` field in `AnimationState` is now private with getter/setter methods +- Improved `equals()` and `hashCode()` implementations for `Animation` and `Animation.Frame` +- Added `/fabric/out` to `.gitignore` +- Enabled example logging (`isExampleEnabled = true`) + +## Deleted + +- Removed `AnimationPoint` class (replaced by `InterpolationData`) +- Removed individual rotation/position/scale queue fields from `BoneAnimationFrame` (consolidated into + `AnimationFrameVector`) +- Removed individual `addRotationXPoint`, `addRotationYPoint`, etc. methods (replaced with vector-based methods) ## Bug Fixes -* Fixed a critical issue where Fabric Server where enable to be started due to trying to load Client sided Code on the - Server. -* Fixed a critical issue where Clients would crash when trying to send a Packet. -* Fixed a crash where the Client was looking for the Controller file. \ No newline at end of file +- Fixed `equals()` method in `Animation` and `Animation.Frame` to properly compare field values instead of just hashCode +- Added proper null handling in `AnimationExtraData.set()` method \ No newline at end of file diff --git a/common/src/main/java/software/bluelib/config/LoggerConfig.java b/common/src/main/java/software/bluelib/config/LoggerConfig.java index 7006e7c0..c6203f38 100644 --- a/common/src/main/java/software/bluelib/config/LoggerConfig.java +++ b/common/src/main/java/software/bluelib/config/LoggerConfig.java @@ -15,5 +15,5 @@ public class LoggerConfig { public static boolean isBlueLibLoggingEnabled = false; public static boolean isLoggingEnabled = false; @ApiStatus.Internal - public static final boolean isExampleEnabled = false; + public static final boolean isExampleEnabled = true; } diff --git a/common/src/main/java/software/bluelib/loader/animation/Animation.java b/common/src/main/java/software/bluelib/loader/animation/Animation.java index 5a3ebe9a..34fedfb4 100644 --- a/common/src/main/java/software/bluelib/loader/animation/Animation.java +++ b/common/src/main/java/software/bluelib/loader/animation/Animation.java @@ -8,8 +8,11 @@ package software.bluelib.loader.animation; import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +import java.util.Collections; import java.util.List; import java.util.Objects; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bluelib.loader.cache.animations.AnimationCache; @@ -17,10 +20,10 @@ public final class Animation { @NotNull - private final List animationList = new ObjectArrayList<>(); + private final List animationList = new ObjectArrayList<>(); - // Private constructor to force usage of factory for logical operations - private Animation() {} + private Animation() { + } @NotNull public static Animation begin() { @@ -39,55 +42,61 @@ public Animation thenLoop(@NotNull String pAnimationName) { @NotNull public Animation thenWait(int pTicks) { - this.animationList.add(new Stage(Stage.WAIT, AnimationCache.LoopType.PLAY_ONCE, pTicks)); - + if (pTicks < 0) { + throw new IllegalArgumentException("Ticks cannot be negative"); + } + this.animationList.add(new Frame(Frame.WAIT, AnimationCache.LoopType.PLAY_ONCE, pTicks)); return this; } @NotNull - public Animation thenPlayAndHold(@NotNull String pAnimation) { - return then(pAnimation, AnimationCache.LoopType.HOLD_ON_LAST_FRAME); + public Animation thenPlayAndHold(@NotNull String pAnimationName) { + return then(pAnimationName, AnimationCache.LoopType.HOLD_ON_LAST_FRAME); } @NotNull public Animation thenPlayXTimes(@NotNull String pAnimationName, int pPlayCount) { + if (pPlayCount <= 0) { + throw new IllegalArgumentException("Play count must be positive"); + } for (int i = 0; i < pPlayCount; i++) { then(pAnimationName, i == pPlayCount - 1 ? AnimationCache.LoopType.DEFAULT : AnimationCache.LoopType.PLAY_ONCE); } - return this; } @NotNull public Animation then(@NotNull String pAnimationName, @NotNull AnimationCache.LoopType pLoopType) { - this.animationList.add(new Stage(pAnimationName, pLoopType)); - + this.animationList.add(new Frame(pAnimationName, pLoopType)); return this; } @NotNull - public List getAnimationStages() { - return this.animationList; + public List getAnimationFrames() { + return Collections.unmodifiableList(this.animationList); } @NotNull public static Animation copyOf(@NotNull Animation pOther) { Animation newInstance = Animation.begin(); - newInstance.animationList.addAll(pOther.animationList); - return newInstance; } - @Override - public boolean equals(@Nullable Object pObj) { - if (this == pObj) - return true; + public boolean isEmpty() { + return this.animationList.isEmpty(); + } - if (pObj == null || getClass() != pObj.getClass()) - return false; + public int size() { + return this.animationList.size(); + } - return hashCode() == pObj.hashCode(); + @Override + public boolean equals(@Nullable Object pObj) { + if (this == pObj) return true; + if (pObj == null || getClass() != pObj.getClass()) return false; + Animation animation = (Animation) pObj; + return Objects.equals(this.animationList, animation.animationList); } @Override @@ -95,29 +104,43 @@ public int hashCode() { return Objects.hash(this.animationList); } - public record Stage(@NotNull String animationName, @NotNull AnimationCache.LoopType loopType, int additionalTicks) { + @Override + public String toString() { + return "Animation{stages=" + this.animationList + "}"; + } + + public record Frame(@NotNull String animationName, @NotNull AnimationCache.LoopType loopType, int additionalTicks) { @NotNull public static final String WAIT = "internal.wait"; - public Stage(@NotNull String pAnimationName, @NotNull AnimationCache.LoopType pLoopType) { + public Frame { + if (additionalTicks < 0) { + throw new IllegalArgumentException("Additional ticks cannot be negative"); + } + } + + public Frame(@NotNull String pAnimationName, @NotNull AnimationCache.LoopType pLoopType) { this(pAnimationName, pLoopType, 0); } + public boolean isWait() { + return WAIT.equals(this.animationName); + } + @Override public boolean equals(@Nullable Object pObj) { - if (this == pObj) - return true; - - if (pObj == null || getClass() != pObj.getClass()) - return false; - - return hashCode() == pObj.hashCode(); + if (this == pObj) return true; + if (pObj == null || getClass() != pObj.getClass()) return false; + Frame frame = (Frame) pObj; + return this.additionalTicks == frame.additionalTicks + && Objects.equals(this.animationName, frame.animationName) + && this.loopType == frame.loopType; } @Override public int hashCode() { - return Objects.hash(this.animationName, this.loopType); + return Objects.hash(this.animationName, this.loopType, this.additionalTicks); } } -} +} \ No newline at end of file diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationController.java b/common/src/main/java/software/bluelib/loader/animation/AnimationController.java index 138ce7bc..a9f32a79 100644 --- a/common/src/main/java/software/bluelib/loader/animation/AnimationController.java +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationController.java @@ -9,8 +9,10 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; + import java.util.*; import java.util.function.Function; + import net.minecraft.core.Direction.Axis; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,7 +20,7 @@ import software.bluelib.api.utils.logging.BaseLogger; import software.bluelib.loader.animatable.base.BlueAnimatable; import software.bluelib.loader.animation.bone.BoneSnapshot; -import software.bluelib.loader.animation.keyframe.AnimationPoint; +import software.bluelib.loader.animation.keyframe.InterpolationData; import software.bluelib.loader.animation.keyframe.BoneAnimationFrame; import software.bluelib.loader.animation.keyframe.KeyframeLocation; import software.bluelib.loader.animation.keyframe.data.CustomInstructionKeyframeData; @@ -230,7 +232,7 @@ public boolean isPlayingTriggeredAnimation() { } public void setAnimation(@NotNull Animation pAnimation) { - if (pAnimation.getAnimationStages().isEmpty()) { + if (pAnimation.getAnimationFrames().isEmpty()) { stop(); return; @@ -454,21 +456,21 @@ private void processCurrentAnimation(double pAdjustedTick, double pSeekTime, boo KeyframeStackCache> scaleKeyFrames = boneAnimationCache.scaleKeyFrames(); if (!rotationKeyFrames.xKeyframes().isEmpty()) { - boneAnimationFrame.addRotations( + boneAnimationFrame.addNextRotation( getAnimationPointAtTick(rotationKeyFrames.xKeyframes(), pAdjustedTick, true, Axis.X), getAnimationPointAtTick(rotationKeyFrames.yKeyframes(), pAdjustedTick, true, Axis.Y), getAnimationPointAtTick(rotationKeyFrames.zKeyframes(), pAdjustedTick, true, Axis.Z)); } if (!positionKeyFrames.xKeyframes().isEmpty()) { - boneAnimationFrame.addPositions( + boneAnimationFrame.addNextPosition( getAnimationPointAtTick(positionKeyFrames.xKeyframes(), pAdjustedTick, false, Axis.X), getAnimationPointAtTick(positionKeyFrames.yKeyframes(), pAdjustedTick, false, Axis.Y), getAnimationPointAtTick(positionKeyFrames.zKeyframes(), pAdjustedTick, false, Axis.Z)); } if (!scaleKeyFrames.xKeyframes().isEmpty()) { - boneAnimationFrame.addScales( + boneAnimationFrame.addNextScale( getAnimationPointAtTick(scaleKeyFrames.xKeyframes(), pAdjustedTick, false, Axis.X), getAnimationPointAtTick(scaleKeyFrames.yKeyframes(), pAdjustedTick, false, Axis.Y), getAnimationPointAtTick(scaleKeyFrames.zKeyframes(), pAdjustedTick, false, Axis.Z)); @@ -553,8 +555,8 @@ protected double adjustTick(double pTick) { } @NotNull - private AnimationPoint getAnimationPointAtTick(@NotNull List> pFrames, double pTick, boolean pIsRotation, - @NotNull Axis pAxis) { + private InterpolationData getAnimationPointAtTick(@NotNull List> pFrames, double pTick, boolean pIsRotation, + @NotNull Axis pAxis) { KeyframeLocation> location = getCurrentKeyFrameLocation(pFrames, pTick); KeyframeCache currentFrame = location.keyframe(); double startValue = currentFrame.startValue().get(); @@ -576,12 +578,12 @@ private AnimationPoint getAnimationPointAtTick(@NotNull List> getCurrentKeyFrameLocation(@NotNull List> pFrames, - double pAgeInTicks) { + double pAgeInTicks) { double totalFrameTime = 0; for (KeyframeCache frame : pFrames) { diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationExtraData.java b/common/src/main/java/software/bluelib/loader/animation/AnimationExtraData.java new file mode 100644 index 00000000..3cedf10c --- /dev/null +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationExtraData.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024 BlueLib Contributors + * + * This Source Code Form is subject to the terms of the MIT License. + * If a copy of the MIT License was not distributed with this file, + * You can obtain one at https://opensource.org/licenses/MIT. + */ +package software.bluelib.loader.animation; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; + +import java.util.Collections; +import java.util.Map; +import java.util.Objects; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import software.bluelib.loader.geckolib.constant.dataticket.DataTicket; + +public final class AnimationExtraData { + + @NotNull + private final Map, Object> data = new Object2ObjectOpenHashMap<>(); + + @Nullable + public D get(@NotNull DataTicket pTicket) { + Objects.requireNonNull(pTicket, "Data ticket cannot be null"); + return pTicket.getData(this.data); + } + + public void set(@NotNull DataTicket pTicket, @Nullable D pValue) { + Objects.requireNonNull(pTicket, "Data ticket cannot be null"); + if (pValue == null) { + this.data.remove(pTicket); + } else { + this.data.put(pTicket, pValue); + } + } + + public boolean has(@NotNull DataTicket pTicket) { + Objects.requireNonNull(pTicket, "Data ticket cannot be null"); + return this.data.containsKey(pTicket); + } + + public void clear() { + this.data.clear(); + } + + @NotNull + public Map, ?> asUnmodifiableMap() { + return Collections.unmodifiableMap(this.data); + } +} \ No newline at end of file diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java b/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java index 8cf9b7ef..bca4ce01 100644 --- a/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java @@ -8,10 +8,12 @@ package software.bluelib.loader.animation; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; + import java.util.Collection; import java.util.LinkedList; import java.util.Map; import java.util.Queue; + import net.minecraft.util.Mth; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -20,7 +22,7 @@ import software.bluelib.loader.animatable.base.AnimatableManager; import software.bluelib.loader.animatable.base.BlueAnimatable; import software.bluelib.loader.animation.bone.BoneSnapshot; -import software.bluelib.loader.animation.keyframe.AnimationPoint; +import software.bluelib.loader.animation.keyframe.InterpolationData; import software.bluelib.loader.animation.keyframe.BoneAnimationFrame; import software.bluelib.loader.animation.math.Easing; import software.bluelib.loader.cache.animations.AnimationCache; @@ -48,22 +50,22 @@ public Queue buildAnimationQueue(@NotNull T pAnimatable, @NotNu LinkedList animations = new LinkedList<>(); boolean error = false; - for (Animation.Stage stage : pAnimation.getAnimationStages()) { + for (Animation.Frame frame : pAnimation.getAnimationFrames()) { AnimationCache animationCache = null; - if (stage.animationName() == Animation.Stage.WAIT) { - animationCache = AnimationCache.generateWaitAnimation(stage.additionalTicks()); + if (frame.animationName() == Animation.Frame.WAIT) { + animationCache = AnimationCache.generateWaitAnimation(frame.additionalTicks()); } else { try { - animationCache = this.model.getAnimation(pAnimatable, stage.animationName()); + animationCache = this.model.getAnimation(pAnimatable, frame.animationName()); } catch (RuntimeException ex) { - BaseLogger.log(BaseLogLevel.ERROR, "Unable to find animation: " + stage.animationName() + " for " + pAnimatable.getClass().getSimpleName(), ex); + BaseLogger.log(BaseLogLevel.ERROR, "Unable to find animation: " + frame.animationName() + " for " + pAnimatable.getClass().getSimpleName(), ex); error = true; } } if (animationCache != null) - animations.add(new QueuedAnimation(animationCache, stage.loopType())); + animations.add(new QueuedAnimation(animationCache, frame.loopType())); } return error ? null : animations; @@ -81,7 +83,6 @@ public void tickAnimation(@NotNull T pAnimatable, @NotNull BlueModel pModel, controller.isJustStarting = pAnimatableManager.isFirstTick(); pState.withController(controller); - // TODO: REMOVE!!!! MathParser.setVariable(MoLangQueries.ANIM_TIME, () -> pState.getController() != null ? pState.getController().getAnimTime() : 0d); controller.process(pModel, pState, this.bones, boneSnapshots, pAnimTime, pCrashWhenCantFindBone); @@ -90,15 +91,15 @@ public void tickAnimation(@NotNull T pAnimatable, @NotNull BlueModel pModel, BoneSnapshot snapshot = boneSnapshots.get(bone.getName()); BoneSnapshot initialSnapshot = bone.getInitialSnapshot(); - AnimationPoint rotXPoint = boneAnimation.rotationXQueue().poll(); - AnimationPoint rotYPoint = boneAnimation.rotationYQueue().poll(); - AnimationPoint rotZPoint = boneAnimation.rotationZQueue().poll(); - AnimationPoint posXPoint = boneAnimation.positionXQueue().poll(); - AnimationPoint posYPoint = boneAnimation.positionYQueue().poll(); - AnimationPoint posZPoint = boneAnimation.positionZQueue().poll(); - AnimationPoint scaleXPoint = boneAnimation.scaleXQueue().poll(); - AnimationPoint scaleYPoint = boneAnimation.scaleYQueue().poll(); - AnimationPoint scaleZPoint = boneAnimation.scaleZQueue().poll(); + InterpolationData rotXPoint = boneAnimation.rotation().x().poll(); + InterpolationData rotYPoint = boneAnimation.rotation().y().poll(); + InterpolationData rotZPoint = boneAnimation.rotation().z().poll(); + InterpolationData posXPoint = boneAnimation.position().x().poll(); + InterpolationData posYPoint = boneAnimation.position().y().poll(); + InterpolationData posZPoint = boneAnimation.position().z().poll(); + InterpolationData scaleXPoint = boneAnimation.scale().x().poll(); + InterpolationData scaleYPoint = boneAnimation.scale().y().poll(); + InterpolationData scaleZPoint = boneAnimation.scale().z().poll(); Easing easing = controller.overrideEasingTypeFunction.apply(pAnimatable); if (rotXPoint != null && rotYPoint != null && rotZPoint != null) { @@ -268,5 +269,6 @@ public void preAnimationSetup(@NotNull AnimationState pAnimationState, double this.model.applyMolangQueries(pAnimationState, pAnimTime); } - public record QueuedAnimation(@NotNull AnimationCache animationCache, @NotNull AnimationCache.LoopType loopType) {} + public record QueuedAnimation(@NotNull AnimationCache animationCache, @NotNull AnimationCache.LoopType loopType) { + } } diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationSnapshot.java b/common/src/main/java/software/bluelib/loader/animation/AnimationSnapshot.java new file mode 100644 index 00000000..59b42b9c --- /dev/null +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationSnapshot.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 BlueLib Contributors + * + * This Source Code Form is subject to the terms of the MIT License. + * If a copy of the MIT License was not distributed with this file, + * You can obtain one at https://opensource.org/licenses/MIT. + */ +package software.bluelib.loader.animation; + +public record AnimationSnapshot( + float limbSwing, + float limbSwingAmount, + float partialTick, + boolean isMoving +) { + public AnimationSnapshot { + if (Float.isNaN(limbSwing) || Float.isNaN(limbSwingAmount) || Float.isNaN(partialTick)) { + throw new IllegalArgumentException("Animation values cannot be NaN"); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationState.java b/common/src/main/java/software/bluelib/loader/animation/AnimationState.java index 735a1757..b958aced 100644 --- a/common/src/main/java/software/bluelib/loader/animation/AnimationState.java +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationState.java @@ -7,40 +7,44 @@ */ package software.bluelib.loader.animation; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import java.util.Map; -import java.util.Objects; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bluelib.loader.animatable.base.BlueAnimatable; import software.bluelib.loader.animation.state.PlayState; import software.bluelib.loader.geckolib.constant.dataticket.DataTicket; -public class AnimationState { +import java.util.Map; +import java.util.Objects; + +/** + * Represents the current state of an animation for an animatable entity. + * Combines immutable snapshot data with mutable controller interaction. + * + * @param the type of animatable entity + */ +public final class AnimationState { @NotNull private final T animatable; - private final float limbSwing; - private final float limbSwingAmount; - private final float partialTick; - private final boolean isMoving; @NotNull - private final Map, Object> extraData = new Object2ObjectOpenHashMap<>(); + private final AnimationSnapshot snapshot; + @NotNull + private final AnimationExtraData extraData; @Nullable - protected AnimationController controller; - public double animationTick; - - public AnimationState(@NotNull T pAnimatable, float pLimbSwing, float pLimbSwingAmount, float pPartialTick, boolean pIsMoving) { + private AnimationController controller; + private double animationTick; + + public AnimationState( + @NotNull T pAnimatable, + float pLimbSwing, + float pLimbSwingAmount, + float pPartialTick, + boolean pIsMoving + ) { this.animatable = pAnimatable; - this.limbSwing = pLimbSwing; - this.limbSwingAmount = pLimbSwingAmount; - this.partialTick = pPartialTick; - this.isMoving = pIsMoving; - } - - public double getAnimationTick() { - return this.animationTick; + this.snapshot = new AnimationSnapshot(pLimbSwing, pLimbSwingAmount, pPartialTick, pIsMoving); + this.extraData = new AnimationExtraData(); } @NotNull @@ -49,88 +53,106 @@ public T getAnimatable() { } public float getLimbSwing() { - return this.limbSwing; + return this.snapshot.limbSwing(); } public float getLimbSwingAmount() { - return this.limbSwingAmount; + return this.snapshot.limbSwingAmount(); } public float getPartialTick() { - return this.partialTick; + return this.snapshot.partialTick(); } public boolean isMoving() { - return this.isMoving; + return this.snapshot.isMoving(); } - public @Nullable AnimationController getController() { + @NotNull + public AnimationSnapshot getSnapshot() { + return this.snapshot; + } + + public double getAnimationTick() { + return this.animationTick; + } + + public void setAnimationTick(double pTick) { + if (pTick < 0) { + throw new IllegalArgumentException("Animation tick cannot be negative"); + } + this.animationTick = pTick; + } + + @NotNull + public AnimationController getController() { + if (this.controller == null) { + throw new IllegalStateException("AnimationController has not been set"); + } return this.controller; } + public boolean hasController() { + return this.controller != null; + } + @NotNull public AnimationState withController(@NotNull AnimationController pController) { - this.controller = pController; - + this.controller = Objects.requireNonNull(pController, "Controller cannot be null"); return this; } @NotNull public Map, ?> getExtraData() { - return this.extraData; + return this.extraData.asUnmodifiableMap(); } @Nullable - public D getData(@NotNull DataTicket pDataTicket) { - return pDataTicket.getData(this.extraData); + public D getData(@NotNull DataTicket pTicket) { + return this.extraData.get(pTicket); } - public void setData(@NotNull DataTicket pDataTicket, D pData) { - this.extraData.put(pDataTicket, pData); + public void setData(@NotNull DataTicket pTicket, @Nullable D pData) { + this.extraData.set(pTicket, pData); } public void setAnimation(@NotNull Animation pAnimation) { - if (getController() == null) { - throw new IllegalStateException("AnimationController is not set for this AnimationState."); - } getController().setAnimation(pAnimation); } @NotNull public PlayState setAndContinue(@NotNull Animation pAnimation) { - if (getController() == null) { - throw new IllegalStateException("AnimationController is not set for this AnimationState."); - } - getController().setAnimation(pAnimation); - + setAnimation(pAnimation); return PlayState.PLAY; } public boolean isCurrentAnimation(@NotNull Animation pAnimation) { - if (getController() == null) { - throw new IllegalStateException("AnimationController is not set for this AnimationState."); - } return Objects.equals(getController().currentRawAnimation, pAnimation); } public boolean isCurrentAnimationStage(@NotNull String pName) { - if (getController() == null) { - throw new IllegalStateException("AnimationController is not set for this AnimationState."); - } - return getController().getCurrentAnimation() != null && getController().getCurrentAnimation().animationCache().name().equals(pName); + var currentAnim = getController().getCurrentAnimation(); + return currentAnim != null && pName.equals(currentAnim.animationCache().name()); } public void resetCurrentAnimation() { - if (getController() == null) { - throw new IllegalStateException("AnimationController is not set for this AnimationState."); - } getController().forceAnimationReset(); } - public void setControllerSpeed(@NotNull Double pSpeed) { - if (getController() == null) { - throw new IllegalStateException("AnimationController is not set for this AnimationState."); + public void setControllerSpeed(double pSpeed) { + if (pSpeed < 0) { + throw new IllegalArgumentException("Speed cannot be negative"); } getController().setAnimationSpeed(pSpeed); } -} + + @Override + public String toString() { + return "AnimationState{" + + "animatable=" + this.animatable.getClass().getSimpleName() + + ", tick=" + this.animationTick + + ", moving=" + this.snapshot.isMoving() + + ", hasController=" + (this.controller != null) + + '}'; + } +} \ No newline at end of file diff --git a/common/src/main/java/software/bluelib/loader/animation/keyframe/AnimationPoint.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/AnimationPoint.java deleted file mode 100644 index 9cc1d9aa..00000000 --- a/common/src/main/java/software/bluelib/loader/animation/keyframe/AnimationPoint.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2024 BlueLib Contributors - * - * This Source Code Form is subject to the terms of the MIT License. - * If a copy of the MIT License was not distributed with this file, - * You can obtain one at https://opensource.org/licenses/MIT. - */ -package software.bluelib.loader.animation.keyframe; - -import org.jetbrains.annotations.NotNull; -import software.bluelib.loader.cache.animations.keyframe.KeyframeCache; - -public record AnimationPoint(KeyframeCache keyFrame, double currentTick, double transitionLength, double animationStartValue, double animationEndValue) { - - @Override - public @NotNull String toString() { - return "Tick: " + this.currentTick + - " | Transition Length: " + this.transitionLength + - " | Start Value: " + this.animationStartValue + - " | End Value: " + this.animationEndValue; - } -} diff --git a/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java index c40a3cab..00728344 100644 --- a/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java +++ b/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java @@ -1,102 +1,57 @@ -/* - * Copyright (C) 2024 BlueLib Contributors - * - * This Source Code Form is subject to the terms of the MIT License. - * If a copy of the MIT License was not distributed with this file, - * You can obtain one at https://opensource.org/licenses/MIT. - */ package software.bluelib.loader.animation.keyframe; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bluelib.loader.animation.bone.BoneSnapshot; +import software.bluelib.loader.animation.keyframe.frame.AnimationFrameVector; import software.bluelib.loader.cache.animations.keyframe.KeyframeCache; import software.bluelib.loader.cache.model.BoneCache; -public record BoneAnimationFrame(@NotNull BoneCache bone, @NotNull AnimationPointFrame rotationXQueue, - @NotNull AnimationPointFrame rotationYQueue, - @NotNull AnimationPointFrame rotationZQueue, - @NotNull AnimationPointFrame positionXQueue, - @NotNull AnimationPointFrame positionYQueue, - @NotNull AnimationPointFrame positionZQueue, @NotNull AnimationPointFrame scaleXQueue, - @NotNull AnimationPointFrame scaleYQueue, - @NotNull AnimationPointFrame scaleZQueue) { +public record BoneAnimationFrame(@NotNull BoneCache bone, + @NotNull AnimationFrameVector rotation, + @NotNull AnimationFrameVector position, + @NotNull AnimationFrameVector scale) { public BoneAnimationFrame(@NotNull BoneCache pBone) { - this(pBone, new AnimationPointFrame(), new AnimationPointFrame(), new AnimationPointFrame(), - new AnimationPointFrame(), new AnimationPointFrame(), new AnimationPointFrame(), - new AnimationPointFrame(), new AnimationPointFrame(), new AnimationPointFrame()); + this(pBone, new AnimationFrameVector(), new AnimationFrameVector(), new AnimationFrameVector()); } - public void addPosXPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, double pStartValue, double pEndValue) { - this.positionXQueue.add(new AnimationPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartValue, pEndValue)); + public void addNextPosition(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, + @NotNull BoneSnapshot pStartSnapshot, + @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { + position.addPoint(pKeyFrame, pLerpedTick, pTransitionLength, + pStartSnapshot.getOffsetX(), pNextX.startValue(), + pStartSnapshot.getOffsetY(), pNextY.startValue(), + pStartSnapshot.getOffsetZ(), pNextZ.startValue()); } - public void addPosYPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, double pStartValue, double pEndValue) { - this.positionYQueue.add(new AnimationPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartValue, pEndValue)); + public void addNextScale(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, + @NotNull BoneSnapshot pStartSnapshot, + @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { + scale.addPoint(pKeyFrame, pLerpedTick, pTransitionLength, + pStartSnapshot.getScaleX(), pNextX.startValue(), + pStartSnapshot.getScaleY(), pNextY.startValue(), + pStartSnapshot.getScaleZ(), pNextZ.startValue()); } - public void addPosZPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, double pStartValue, double pEndValue) { - this.positionZQueue.add(new AnimationPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartValue, pEndValue)); + public void addNextRotation(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, + @NotNull BoneSnapshot pStartSnapshot, @NotNull BoneSnapshot pInitialSnapshot, + @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { + rotation.addPoint(pKeyFrame, pLerpedTick, pTransitionLength, + pStartSnapshot.getRotX() - pInitialSnapshot.getRotX(), pNextX.startValue(), + pStartSnapshot.getRotY() - pInitialSnapshot.getRotY(), pNextY.startValue(), + pStartSnapshot.getRotZ() - pInitialSnapshot.getRotZ(), pNextZ.startValue()); } - public void addNextPosition(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, @NotNull BoneSnapshot pStartSnapshot, @NotNull AnimationPoint pNextXPoint, @NotNull AnimationPoint pNextYPoint, @NotNull AnimationPoint pNextZPoint) { - addPosXPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getOffsetX(), pNextXPoint.animationStartValue()); - addPosYPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getOffsetY(), pNextYPoint.animationStartValue()); - addPosZPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getOffsetZ(), pNextZPoint.animationStartValue()); + public void addNextRotation(@NotNull InterpolationData pX, @NotNull InterpolationData pY, @NotNull InterpolationData pZ) { + rotation.add(pX, pY, pZ); } - public void addScaleXPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, double pStartValue, double pEndValue) { - this.scaleXQueue.add(new AnimationPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartValue, pEndValue)); + public void addNextPosition(@NotNull InterpolationData pX, @NotNull InterpolationData pY, @NotNull InterpolationData pZ) { + position.add(pX, pY, pZ); } - public void addScaleYPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, double pStartValue, double pEndValue) { - this.scaleYQueue.add(new AnimationPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartValue, pEndValue)); + public void addNextScale(@NotNull InterpolationData pX, @NotNull InterpolationData pY, @NotNull InterpolationData pZ) { + scale.add(pX, pY, pZ); } - - public void addScaleZPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, double pStartValue, double pEndValue) { - this.scaleZQueue.add(new AnimationPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartValue, pEndValue)); - } - - public void addNextScale(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, @NotNull BoneSnapshot pStartSnapshot, @NotNull AnimationPoint pNextXPoint, @NotNull AnimationPoint pNextYPoint, @NotNull AnimationPoint pNextZPoint) { - addScaleXPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getScaleX(), pNextXPoint.animationStartValue()); - addScaleYPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getScaleY(), pNextYPoint.animationStartValue()); - addScaleZPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getScaleZ(), pNextZPoint.animationStartValue()); - } - - public void addRotationXPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, double pStartValue, double pEndValue) { - this.rotationXQueue.add(new AnimationPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartValue, pEndValue)); - } - - public void addRotationYPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, double pStartValue, double pEndValue) { - this.rotationYQueue.add(new AnimationPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartValue, pEndValue)); - } - - public void addRotationZPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, double pStartValue, double pEndValue) { - this.rotationZQueue.add(new AnimationPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartValue, pEndValue)); - } - - public void addNextRotation(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, @NotNull BoneSnapshot pStartSnapshot, @NotNull BoneSnapshot pInitialSnapshot, @NotNull AnimationPoint pNextXPoint, @NotNull AnimationPoint pNextYPoint, @NotNull AnimationPoint pNextZPoint) { - addRotationXPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getRotX() - pInitialSnapshot.getRotX(), pNextXPoint.animationStartValue()); - addRotationYPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getRotY() - pInitialSnapshot.getRotY(), pNextYPoint.animationStartValue()); - addRotationZPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getRotZ() - pInitialSnapshot.getRotZ(), pNextZPoint.animationStartValue()); - } - - public void addPositions(@NotNull AnimationPoint pXPoint, @NotNull AnimationPoint pYPoint, @NotNull AnimationPoint pZPoint) { - this.positionXQueue.add(pXPoint); - this.positionYQueue.add(pYPoint); - this.positionZQueue.add(pZPoint); - } - - public void addScales(@NotNull AnimationPoint pXPoint, @NotNull AnimationPoint pYPoint, @NotNull AnimationPoint pZPoint) { - this.scaleXQueue.add(pXPoint); - this.scaleYQueue.add(pYPoint); - this.scaleZQueue.add(pZPoint); - } - - public void addRotations(@NotNull AnimationPoint pXPoint, @NotNull AnimationPoint pYPoint, @NotNull AnimationPoint pZPoint) { - this.rotationXQueue.add(pXPoint); - this.rotationYQueue.add(pYPoint); - this.rotationZQueue.add(pZPoint); - } -} +} \ No newline at end of file diff --git a/common/src/main/java/software/bluelib/loader/animation/keyframe/InterpolationData.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/InterpolationData.java new file mode 100644 index 00000000..891582bb --- /dev/null +++ b/common/src/main/java/software/bluelib/loader/animation/keyframe/InterpolationData.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2024 BlueLib Contributors + * + * This Source Code Form is subject to the terms of the MIT License. + * If a copy of the MIT License was not distributed with this file, + * You can obtain one at https://opensource.org/licenses/MIT. + */ +package software.bluelib.loader.animation.keyframe; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import software.bluelib.loader.animation.AnimationProcessor; +import software.bluelib.loader.animation.math.Easing; +import software.bluelib.loader.cache.animations.keyframe.KeyframeCache; + +/** + * A data container holding interpolation parameters for bone animation between two keyframes. + * + *

This record is a passive data carrier that stores the start/end values, timing, + * and keyframe metadata needed to compute interpolated transform values.

+ * + * @param keyframe The source keyframe cache containing easing type. May be null during transitions. + * @param currentTick Current position within this interpolation segment. + * @param transitionLength Total duration of this interpolation in ticks. + * @param startValue The transform value at the beginning of interpolation. + * @param endValue The transform value at the end of interpolation. + * @see BoneAnimationFrame + * @see AnimationProcessor#tickAnimation + * @see Easing#lerpWithOverride + */ +public record InterpolationData( + @Nullable KeyframeCache keyframe, + double currentTick, + double transitionLength, + double startValue, + double endValue +) { + + /** + * Calculates the normalized progress (0.0 to 1.0) through this interpolation. + * + * @return Progress ratio, clamped between 0 and 1 + */ + public double getProgress() { + if (transitionLength <= 0) return 1.0; + return Math.min(1.0, Math.max(0.0, currentTick / transitionLength)); + } + + @Override + public @NotNull String toString() { + return "InterpolationData{" + + "tick=" + this.currentTick + + ", length=" + this.transitionLength + + ", start=" + this.startValue + + ", end=" + this.endValue + + ", progress=" + String.format("%.2f", getProgress()) + + '}'; + } +} \ No newline at end of file diff --git a/common/src/main/java/software/bluelib/loader/animation/keyframe/AnimationPointFrame.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrame.java similarity index 65% rename from common/src/main/java/software/bluelib/loader/animation/keyframe/AnimationPointFrame.java rename to common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrame.java index 899cb8b6..b766758d 100644 --- a/common/src/main/java/software/bluelib/loader/animation/keyframe/AnimationPointFrame.java +++ b/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrame.java @@ -5,12 +5,14 @@ * If a copy of the MIT License was not distributed with this file, * You can obtain one at https://opensource.org/licenses/MIT. */ -package software.bluelib.loader.animation.keyframe; +package software.bluelib.loader.animation.keyframe.frame; + +import software.bluelib.loader.animation.keyframe.InterpolationData; import java.io.Serial; import java.util.LinkedList; -public final class AnimationPointFrame extends LinkedList { +public final class AnimationFrame extends LinkedList { @Serial private static final long serialVersionUID = 5472797438476621193L; diff --git a/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrameVector.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrameVector.java new file mode 100644 index 00000000..c15efee0 --- /dev/null +++ b/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrameVector.java @@ -0,0 +1,30 @@ +package software.bluelib.loader.animation.keyframe.frame; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import software.bluelib.loader.animation.keyframe.InterpolationData; +import software.bluelib.loader.cache.animations.keyframe.KeyframeCache; + +public record AnimationFrameVector(@NotNull AnimationFrame x, + @NotNull AnimationFrame y, + @NotNull AnimationFrame z) { + + public AnimationFrameVector() { + this(new AnimationFrame(), new AnimationFrame(), new AnimationFrame()); + } + + public void addPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, + double pStartX, double pEndX, + double pStartY, double pEndY, + double pStartZ, double pEndZ) { + x.add(new InterpolationData(pKeyFrame, pLerpedTick, pTransitionLength, pStartX, pEndX)); + y.add(new InterpolationData(pKeyFrame, pLerpedTick, pTransitionLength, pStartY, pEndY)); + z.add(new InterpolationData(pKeyFrame, pLerpedTick, pTransitionLength, pStartZ, pEndZ)); + } + + public void add(@NotNull InterpolationData pXPoint, @NotNull InterpolationData pYPoint, @NotNull InterpolationData pZPoint) { + x.add(pXPoint); + y.add(pYPoint); + z.add(pZPoint); + } +} \ No newline at end of file diff --git a/common/src/main/java/software/bluelib/loader/animation/math/Easing.java b/common/src/main/java/software/bluelib/loader/animation/math/Easing.java index bae17c72..55454439 100644 --- a/common/src/main/java/software/bluelib/loader/animation/math/Easing.java +++ b/common/src/main/java/software/bluelib/loader/animation/math/Easing.java @@ -17,7 +17,7 @@ import net.minecraft.util.Mth; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import software.bluelib.loader.animation.keyframe.AnimationPoint; +import software.bluelib.loader.animation.keyframe.InterpolationData; import software.bluelib.loader.geckolib.math.MathValue; @SuppressWarnings("unused") @@ -97,29 +97,29 @@ public interface Easing { @NotNull Double2DoubleFunction buildTransformer(@Nullable Double pValue); - static double lerpWithOverride(@NotNull AnimationPoint pAnimationPoint, @Nullable Easing pOverride) { + static double lerpWithOverride(@NotNull InterpolationData pInterpolationData, @Nullable Easing pOverride) { Easing easing = pOverride; if (pOverride == null) - easing = pAnimationPoint.keyFrame() == null ? LINEAR : pAnimationPoint.keyFrame().easing(); + easing = pInterpolationData.keyframe() == null ? LINEAR : pInterpolationData.keyframe().easing(); - return easing.apply(pAnimationPoint); + return easing.apply(pInterpolationData); } - default double apply(@NotNull AnimationPoint pAnimationPoint) { + default double apply(@NotNull InterpolationData pInterpolationData) { Double easingVariable = null; - if (pAnimationPoint.keyFrame() != null && !pAnimationPoint.keyFrame().easingArgs().isEmpty()) - easingVariable = pAnimationPoint.keyFrame().easingArgs().getFirst().get(); + if (pInterpolationData.keyframe() != null && !pInterpolationData.keyframe().easingArgs().isEmpty()) + easingVariable = pInterpolationData.keyframe().easingArgs().getFirst().get(); - return apply(pAnimationPoint, easingVariable, pAnimationPoint.currentTick() / pAnimationPoint.transitionLength()); + return apply(pInterpolationData, easingVariable, pInterpolationData.currentTick() / pInterpolationData.transitionLength()); } - default double apply(@NotNull AnimationPoint pAnimationPoint, @Nullable Double pEasingValue, Double pLerpValue) { - if (pAnimationPoint.currentTick() >= pAnimationPoint.transitionLength()) - return (float) pAnimationPoint.animationEndValue(); + default double apply(@NotNull InterpolationData pInterpolationData, @Nullable Double pEasingValue, Double pLerpValue) { + if (pInterpolationData.currentTick() >= pInterpolationData.transitionLength()) + return (float) pInterpolationData.endValue(); - return Mth.lerp(buildTransformer(pEasingValue).apply(pLerpValue), pAnimationPoint.animationStartValue(), pAnimationPoint.animationEndValue()); + return Mth.lerp(buildTransformer(pEasingValue).apply(pLerpValue), pInterpolationData.startValue(), pInterpolationData.endValue()); } @NotNull @@ -299,16 +299,16 @@ public static double getPointOnSpline(double pDelta, double pP0, double pP1, dou } @Override - public double apply(@NotNull AnimationPoint pAnimationPoint, @Nullable Double pEasingValue, @NotNull Double pLerpValue) { - if (pAnimationPoint.currentTick() >= pAnimationPoint.transitionLength()) - return pAnimationPoint.animationEndValue(); + public double apply(@NotNull InterpolationData pInterpolationData, @Nullable Double pEasingValue, @NotNull Double pLerpValue) { + if (pInterpolationData.currentTick() >= pInterpolationData.transitionLength()) + return pInterpolationData.endValue(); - List easingArgs = pAnimationPoint.keyFrame().easingArgs(); + List easingArgs = pInterpolationData.keyframe().easingArgs(); if (easingArgs.size() < 2) - return Mth.lerp(buildTransformer(pEasingValue).apply(pLerpValue), pAnimationPoint.animationStartValue(), pAnimationPoint.animationEndValue()); + return Mth.lerp(buildTransformer(pEasingValue).apply(pLerpValue), pInterpolationData.startValue(), pInterpolationData.endValue()); - return getPointOnSpline(pLerpValue, easingArgs.get(0).get(), pAnimationPoint.animationStartValue(), pAnimationPoint.animationEndValue(), easingArgs.get(1).get()); + return getPointOnSpline(pLerpValue, easingArgs.get(0).get(), pInterpolationData.startValue(), pInterpolationData.endValue(), easingArgs.get(1).get()); } } } diff --git a/common/src/main/java/software/bluelib/loader/cache/animations/AnimationCache.java b/common/src/main/java/software/bluelib/loader/cache/animations/AnimationCache.java index 28c1170b..da70cf17 100644 --- a/common/src/main/java/software/bluelib/loader/cache/animations/AnimationCache.java +++ b/common/src/main/java/software/bluelib/loader/cache/animations/AnimationCache.java @@ -31,7 +31,7 @@ public record AnimationCache( @NotNull public static AnimationCache generateWaitAnimation(double pLength) { - return new AnimationCache(Animation.Stage.WAIT, pLength, LoopType.PLAY_ONCE, new BoneAnimationCache[0], + return new AnimationCache(Animation.Frame.WAIT, pLength, LoopType.PLAY_ONCE, new BoneAnimationCache[0], new KeyframeLibraryCache(new SoundKeyframeData[0], new ParticleKeyframeData[0], new CustomInstructionKeyframeData[0])); } diff --git a/common/src/main/java/software/bluelib/loader/model/BlueModel.java b/common/src/main/java/software/bluelib/loader/model/BlueModel.java index bc0fc1c4..0b273aeb 100644 --- a/common/src/main/java/software/bluelib/loader/model/BlueModel.java +++ b/common/src/main/java/software/bluelib/loader/model/BlueModel.java @@ -194,7 +194,7 @@ public void handleAnimations(@NotNull T pAnimatable, long pInstanceId, @NotNull this.lastGameTickTime = lastUpdateTime; } - pAnimationState.animationTick = this.animTime; + pAnimationState.setAnimationTick(this.animTime); this.lastRenderedInstance = pInstanceId; AnimationProcessor processor = getAnimationProcessor(); From 264dce6f2c1ff3ce526c10e5ca2d1b7638669226 Mon Sep 17 00:00:00 2001 From: Aram Date: Mon, 5 Jan 2026 12:58:59 +0100 Subject: [PATCH 2/6] Renames --- changelog.md | 2 + .../animatable/base/AnimatableManager.java | 6 +-- .../base/ContextAwareAnimatableManager.java | 4 +- .../loader/animation/AnimationController.java | 22 ++++----- .../loader/animation/AnimationProcessor.java | 46 +++++++++---------- .../keyframe/BoneAnimationFrame.java | 38 +++++++++++---- .../BoneFrame.java} | 10 ++-- .../bluelib/loader/cache/model/BoneCache.java | 10 ++-- 8 files changed, 80 insertions(+), 58 deletions(-) rename common/src/main/java/software/bluelib/loader/animation/{bone/BoneSnapshot.java => keyframe/BoneFrame.java} (94%) diff --git a/changelog.md b/changelog.md index 37886e6a..e06272e7 100644 --- a/changelog.md +++ b/changelog.md @@ -21,6 +21,8 @@ `animationEndValue` → `endValue`) - Renamed `AnimationPointFrame` to `AnimationFrame` and moved to `frame` subpackage - Renamed `getAnimationStages()` to `getAnimationFrames()` in `Animation` class +- Renamed `BoneSnapshot` to `BoneFrame` for consistency +- Refactored `BoneAnimationFrame` to be a final class instead of record to avoid a misleading immutable structure. - Refactored `BoneAnimationFrame` to use `AnimationFrameVector` instead of individual X/Y/Z queues - Renamed methods in `BoneAnimationFrame`: `addRotations` → `addNextRotation`, `addPositions` → `addNextPosition`, `addScales` → `addNextScale` diff --git a/common/src/main/java/software/bluelib/loader/animatable/base/AnimatableManager.java b/common/src/main/java/software/bluelib/loader/animatable/base/AnimatableManager.java index b42648f8..ead61ec5 100644 --- a/common/src/main/java/software/bluelib/loader/animatable/base/AnimatableManager.java +++ b/common/src/main/java/software/bluelib/loader/animatable/base/AnimatableManager.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bluelib.loader.animation.AnimationController; -import software.bluelib.loader.animation.bone.BoneSnapshot; +import software.bluelib.loader.animation.keyframe.BoneFrame; import software.bluelib.loader.cache.controller.ControllerCache; import software.bluelib.loader.controller.ControllerManager; import software.bluelib.loader.geckolib.constant.dataticket.DataTicket; @@ -25,7 +25,7 @@ public class AnimatableManager { @NotNull - private final Map boneSnapshotCollection = new Object2ObjectOpenHashMap<>(); + private final Map boneSnapshotCollection = new Object2ObjectOpenHashMap<>(); @NotNull private final Map> animationControllers; @Nullable @@ -60,7 +60,7 @@ public Map> getAnimationControllers() { } @NotNull - public Map getBoneSnapshotCollection() { + public Map getBoneSnapshotCollection() { return this.boneSnapshotCollection; } diff --git a/common/src/main/java/software/bluelib/loader/animatable/base/ContextAwareAnimatableManager.java b/common/src/main/java/software/bluelib/loader/animatable/base/ContextAwareAnimatableManager.java index c7c9a601..7de16101 100644 --- a/common/src/main/java/software/bluelib/loader/animatable/base/ContextAwareAnimatableManager.java +++ b/common/src/main/java/software/bluelib/loader/animatable/base/ContextAwareAnimatableManager.java @@ -11,7 +11,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bluelib.loader.animation.AnimationController; -import software.bluelib.loader.animation.bone.BoneSnapshot; +import software.bluelib.loader.animation.keyframe.BoneFrame; import software.bluelib.loader.geckolib.constant.dataticket.DataTicket; public abstract class ContextAwareAnimatableManager extends AnimatableManager { @@ -48,7 +48,7 @@ public void removeController(@NotNull String pName) { return getManagerForContext(getCurrentContext()).getAnimationControllers(); } - public @NotNull Map getBoneSnapshotCollection() { + public @NotNull Map getBoneSnapshotCollection() { return getManagerForContext(getCurrentContext()).getBoneSnapshotCollection(); } diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationController.java b/common/src/main/java/software/bluelib/loader/animation/AnimationController.java index a9f32a79..b313b5c5 100644 --- a/common/src/main/java/software/bluelib/loader/animation/AnimationController.java +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationController.java @@ -19,7 +19,7 @@ import software.bluelib.api.utils.logging.BaseLogLevel; import software.bluelib.api.utils.logging.BaseLogger; import software.bluelib.loader.animatable.base.BlueAnimatable; -import software.bluelib.loader.animation.bone.BoneSnapshot; +import software.bluelib.loader.animation.keyframe.BoneFrame; import software.bluelib.loader.animation.keyframe.InterpolationData; import software.bluelib.loader.animation.keyframe.BoneAnimationFrame; import software.bluelib.loader.animation.keyframe.KeyframeLocation; @@ -53,7 +53,7 @@ public class AnimationController { @NotNull protected final Map boneAnimationQueues = new Object2ObjectOpenHashMap<>(); @NotNull - protected final Map boneSnapshots = new Object2ObjectOpenHashMap<>(); + protected final Map boneSnapshots = new Object2ObjectOpenHashMap<>(); @NotNull protected Queue animationQueue = new LinkedList<>(); @@ -308,7 +308,7 @@ protected PlayState handleAnimationState(@NotNull AnimationState pState) { return this.stateHandler.handle(pState); } - public void process(@NotNull BlueModel pModel, @NotNull AnimationState pState, @NotNull Map pBones, @NotNull Map pSnapshots, final double pSeekTime, boolean pCrashWhenCantFindBone) { + public void process(@NotNull BlueModel pModel, @NotNull AnimationState pState, @NotNull Map pBones, @NotNull Map pSnapshots, final double pSeekTime, boolean pCrashWhenCantFindBone) { double adjustedTick = adjustTick(pSeekTime); this.lastModel = pModel; @@ -367,10 +367,10 @@ public void process(@NotNull BlueModel pModel, @NotNull AnimationState pSt for (BoneAnimationCache boneAnimationCache : this.currentAnimation.animationCache().boneAnimationCaches()) { BoneAnimationFrame boneAnimationFrame = this.boneAnimationQueues.get(boneAnimationCache.boneName()); - BoneSnapshot boneSnapshot = this.boneSnapshots.get(boneAnimationCache.boneName()); + BoneFrame boneFrame = this.boneSnapshots.get(boneAnimationCache.boneName()); BoneCache bone = pBones.get(boneAnimationCache.boneName()); - if (boneSnapshot == null) + if (boneFrame == null) continue; if (bone == null) { @@ -385,21 +385,21 @@ public void process(@NotNull BlueModel pModel, @NotNull AnimationState pSt KeyframeStackCache> scaleKeyFrames = boneAnimationCache.scaleKeyFrames(); if (!rotationKeyFrames.xKeyframes().isEmpty()) { - boneAnimationFrame.addNextRotation(null, adjustedTick, this.transitionLength, boneSnapshot, bone.getInitialSnapshot(), + boneAnimationFrame.addNextRotation(null, adjustedTick, this.transitionLength, boneFrame, bone.getInitialSnapshot(), getAnimationPointAtTick(rotationKeyFrames.xKeyframes(), 0, true, Axis.X), getAnimationPointAtTick(rotationKeyFrames.yKeyframes(), 0, true, Axis.Y), getAnimationPointAtTick(rotationKeyFrames.zKeyframes(), 0, true, Axis.Z)); } if (!positionKeyFrames.xKeyframes().isEmpty()) { - boneAnimationFrame.addNextPosition(null, adjustedTick, this.transitionLength, boneSnapshot, + boneAnimationFrame.addNextPosition(null, adjustedTick, this.transitionLength, boneFrame, getAnimationPointAtTick(positionKeyFrames.xKeyframes(), 0, false, Axis.X), getAnimationPointAtTick(positionKeyFrames.yKeyframes(), 0, false, Axis.Y), getAnimationPointAtTick(positionKeyFrames.zKeyframes(), 0, false, Axis.Z)); } if (!scaleKeyFrames.xKeyframes().isEmpty()) { - boneAnimationFrame.addNextScale(null, adjustedTick, this.transitionLength, boneSnapshot, + boneAnimationFrame.addNextScale(null, adjustedTick, this.transitionLength, boneFrame, getAnimationPointAtTick(scaleKeyFrames.xKeyframes(), 0, false, Axis.X), getAnimationPointAtTick(scaleKeyFrames.yKeyframes(), 0, false, Axis.Y), getAnimationPointAtTick(scaleKeyFrames.zKeyframes(), 0, false, Axis.Z)); @@ -528,12 +528,12 @@ private void createInitialQueues(@NotNull Collection pModelRendererLi } } - private void saveSnapshotsForAnimation(@NotNull AnimationProcessor.QueuedAnimation pAnimation, @NotNull Map pSnapshots) { - for (BoneSnapshot snapshot : pSnapshots.values()) { + private void saveSnapshotsForAnimation(@NotNull AnimationProcessor.QueuedAnimation pAnimation, @NotNull Map pSnapshots) { + for (BoneFrame snapshot : pSnapshots.values()) { if (pAnimation.animationCache().boneAnimationCaches() != null) { for (BoneAnimationCache boneAnimationCache : pAnimation.animationCache().boneAnimationCaches()) { if (boneAnimationCache.boneName().equals(snapshot.getBone().getName())) { - this.boneSnapshots.put(boneAnimationCache.boneName(), BoneSnapshot.copy(snapshot)); + this.boneSnapshots.put(boneAnimationCache.boneName(), BoneFrame.copy(snapshot)); break; } diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java b/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java index bca4ce01..7defe4b3 100644 --- a/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java @@ -21,7 +21,7 @@ import software.bluelib.api.utils.logging.BaseLogger; import software.bluelib.loader.animatable.base.AnimatableManager; import software.bluelib.loader.animatable.base.BlueAnimatable; -import software.bluelib.loader.animation.bone.BoneSnapshot; +import software.bluelib.loader.animation.keyframe.BoneFrame; import software.bluelib.loader.animation.keyframe.InterpolationData; import software.bluelib.loader.animation.keyframe.BoneAnimationFrame; import software.bluelib.loader.animation.math.Easing; @@ -72,7 +72,7 @@ public Queue buildAnimationQueue(@NotNull T pAnimatable, @NotNu } public void tickAnimation(@NotNull T pAnimatable, @NotNull BlueModel pModel, @NotNull AnimatableManager pAnimatableManager, double pAnimTime, @NotNull AnimationState pState, boolean pCrashWhenCantFindBone) { - Map boneSnapshots = updateBoneSnapshots(pAnimatableManager.getBoneSnapshotCollection()); + Map boneSnapshots = updateBoneSnapshots(pAnimatableManager.getBoneSnapshotCollection()); for (AnimationController controller : pAnimatableManager.getAnimationControllers().values()) { if (this.reloadAnimations) { @@ -87,19 +87,19 @@ public void tickAnimation(@NotNull T pAnimatable, @NotNull BlueModel pModel, controller.process(pModel, pState, this.bones, boneSnapshots, pAnimTime, pCrashWhenCantFindBone); for (BoneAnimationFrame boneAnimation : controller.getBoneAnimationQueues().values()) { - BoneCache bone = boneAnimation.bone(); - BoneSnapshot snapshot = boneSnapshots.get(bone.getName()); - BoneSnapshot initialSnapshot = bone.getInitialSnapshot(); - - InterpolationData rotXPoint = boneAnimation.rotation().x().poll(); - InterpolationData rotYPoint = boneAnimation.rotation().y().poll(); - InterpolationData rotZPoint = boneAnimation.rotation().z().poll(); - InterpolationData posXPoint = boneAnimation.position().x().poll(); - InterpolationData posYPoint = boneAnimation.position().y().poll(); - InterpolationData posZPoint = boneAnimation.position().z().poll(); - InterpolationData scaleXPoint = boneAnimation.scale().x().poll(); - InterpolationData scaleYPoint = boneAnimation.scale().y().poll(); - InterpolationData scaleZPoint = boneAnimation.scale().z().poll(); + BoneCache bone = boneAnimation.getBone(); + BoneFrame snapshot = boneSnapshots.get(bone.getName()); + BoneFrame initialSnapshot = bone.getInitialSnapshot(); + + InterpolationData rotXPoint = boneAnimation.getRotation().x().poll(); + InterpolationData rotYPoint = boneAnimation.getRotation().y().poll(); + InterpolationData rotZPoint = boneAnimation.getRotation().z().poll(); + InterpolationData posXPoint = boneAnimation.getPosition().x().poll(); + InterpolationData posYPoint = boneAnimation.getPosition().y().poll(); + InterpolationData posZPoint = boneAnimation.getPosition().z().poll(); + InterpolationData scaleXPoint = boneAnimation.getScale().x().poll(); + InterpolationData scaleYPoint = boneAnimation.getScale().y().poll(); + InterpolationData scaleZPoint = boneAnimation.getScale().z().poll(); Easing easing = controller.overrideEasingTypeFunction.apply(pAnimatable); if (rotXPoint != null && rotYPoint != null && rotZPoint != null) { @@ -136,8 +136,8 @@ public void tickAnimation(@NotNull T pAnimatable, @NotNull BlueModel pModel, for (BoneCache bone : getRegisteredBones()) { if (!bone.hasRotationChanged()) { - BoneSnapshot initialSnapshot = bone.getInitialSnapshot(); - BoneSnapshot saveSnapshot = boneSnapshots.get(bone.getName()); + BoneFrame initialSnapshot = bone.getInitialSnapshot(); + BoneFrame saveSnapshot = boneSnapshots.get(bone.getName()); if (saveSnapshot.isRotAnimInProgress()) saveSnapshot.stopRotAnim(pAnimTime); @@ -178,8 +178,8 @@ public void tickAnimation(@NotNull T pAnimatable, @NotNull BlueModel pModel, } if (!bone.hasPositionChanged()) { - BoneSnapshot initialSnapshot = bone.getInitialSnapshot(); - BoneSnapshot saveSnapshot = boneSnapshots.get(bone.getName()); + BoneFrame initialSnapshot = bone.getInitialSnapshot(); + BoneFrame saveSnapshot = boneSnapshots.get(bone.getName()); if (saveSnapshot.isPosAnimInProgress()) saveSnapshot.stopPosAnim(pAnimTime); @@ -195,8 +195,8 @@ public void tickAnimation(@NotNull T pAnimatable, @NotNull BlueModel pModel, } if (!bone.hasScaleChanged()) { - BoneSnapshot initialSnapshot = bone.getInitialSnapshot(); - BoneSnapshot saveSnapshot = boneSnapshots.get(bone.getName()); + BoneFrame initialSnapshot = bone.getInitialSnapshot(); + BoneFrame saveSnapshot = boneSnapshots.get(bone.getName()); if (saveSnapshot.isScaleAnimInProgress()) saveSnapshot.stopScaleAnim(pAnimTime); @@ -228,10 +228,10 @@ private void resetBoneTransformationMarkers() { } @NotNull - private Map updateBoneSnapshots(@NotNull Map pSnapshots) { + private Map updateBoneSnapshots(@NotNull Map pSnapshots) { for (BoneCache bone : getRegisteredBones()) { if (!pSnapshots.containsKey(bone.getName())) - pSnapshots.put(bone.getName(), BoneSnapshot.copy(bone.getInitialSnapshot())); + pSnapshots.put(bone.getName(), BoneFrame.copy(bone.getInitialSnapshot())); } return pSnapshots; diff --git a/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java index 00728344..5ebee6d2 100644 --- a/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java +++ b/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java @@ -2,22 +2,26 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import software.bluelib.loader.animation.bone.BoneSnapshot; import software.bluelib.loader.animation.keyframe.frame.AnimationFrameVector; import software.bluelib.loader.cache.animations.keyframe.KeyframeCache; import software.bluelib.loader.cache.model.BoneCache; -public record BoneAnimationFrame(@NotNull BoneCache bone, - @NotNull AnimationFrameVector rotation, - @NotNull AnimationFrameVector position, - @NotNull AnimationFrameVector scale) { +public final class BoneAnimationFrame { + + private final BoneCache bone; + private final AnimationFrameVector rotation; + private final AnimationFrameVector position; + private final AnimationFrameVector scale; public BoneAnimationFrame(@NotNull BoneCache pBone) { - this(pBone, new AnimationFrameVector(), new AnimationFrameVector(), new AnimationFrameVector()); + this.bone = pBone; + this.rotation = new AnimationFrameVector(); + this.position = new AnimationFrameVector(); + this.scale = new AnimationFrameVector(); } public void addNextPosition(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, - @NotNull BoneSnapshot pStartSnapshot, + @NotNull BoneFrame pStartSnapshot, @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { position.addPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getOffsetX(), pNextX.startValue(), @@ -26,7 +30,7 @@ public void addNextPosition(@Nullable KeyframeCache pKeyFrame, double pLerped } public void addNextScale(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, - @NotNull BoneSnapshot pStartSnapshot, + @NotNull BoneFrame pStartSnapshot, @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { scale.addPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getScaleX(), pNextX.startValue(), @@ -35,7 +39,7 @@ public void addNextScale(@Nullable KeyframeCache pKeyFrame, double pLerpedTic } public void addNextRotation(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, - @NotNull BoneSnapshot pStartSnapshot, @NotNull BoneSnapshot pInitialSnapshot, + @NotNull BoneFrame pStartSnapshot, @NotNull BoneFrame pInitialSnapshot, @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { rotation.addPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getRotX() - pInitialSnapshot.getRotX(), pNextX.startValue(), @@ -54,4 +58,20 @@ public void addNextPosition(@NotNull InterpolationData pX, @NotNull Interpolatio public void addNextScale(@NotNull InterpolationData pX, @NotNull InterpolationData pY, @NotNull InterpolationData pZ) { scale.add(pX, pY, pZ); } + + public BoneCache getBone() { + return bone; + } + + public AnimationFrameVector getRotation() { + return rotation; + } + + public AnimationFrameVector getPosition() { + return position; + } + + public AnimationFrameVector getScale() { + return scale; + } } \ No newline at end of file diff --git a/common/src/main/java/software/bluelib/loader/animation/bone/BoneSnapshot.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneFrame.java similarity index 94% rename from common/src/main/java/software/bluelib/loader/animation/bone/BoneSnapshot.java rename to common/src/main/java/software/bluelib/loader/animation/keyframe/BoneFrame.java index 3085c50d..66bacf2c 100644 --- a/common/src/main/java/software/bluelib/loader/animation/bone/BoneSnapshot.java +++ b/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneFrame.java @@ -5,13 +5,13 @@ * If a copy of the MIT License was not distributed with this file, * You can obtain one at https://opensource.org/licenses/MIT. */ -package software.bluelib.loader.animation.bone; +package software.bluelib.loader.animation.keyframe; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bluelib.loader.cache.model.BoneCache; -public class BoneSnapshot { +public class BoneFrame { @NotNull private final BoneCache bone; @@ -36,7 +36,7 @@ public class BoneSnapshot { private boolean posAnimInProgress = true; private boolean scaleAnimInProgress = true; - public BoneSnapshot(@NotNull BoneCache pBone) { + public BoneFrame(@NotNull BoneCache pBone) { this.rotX = pBone.getRotX(); this.rotY = pBone.getRotY(); this.rotZ = pBone.getRotZ(); @@ -53,8 +53,8 @@ public BoneSnapshot(@NotNull BoneCache pBone) { } @NotNull - public static BoneSnapshot copy(@NotNull BoneSnapshot pSnapshot) { - BoneSnapshot newSnapshot = new BoneSnapshot(pSnapshot.bone); + public static BoneFrame copy(@NotNull BoneFrame pSnapshot) { + BoneFrame newSnapshot = new BoneFrame(pSnapshot.bone); newSnapshot.scaleX = pSnapshot.scaleX; newSnapshot.scaleY = pSnapshot.scaleY; diff --git a/common/src/main/java/software/bluelib/loader/cache/model/BoneCache.java b/common/src/main/java/software/bluelib/loader/cache/model/BoneCache.java index 49a4c8ea..572f5241 100644 --- a/common/src/main/java/software/bluelib/loader/cache/model/BoneCache.java +++ b/common/src/main/java/software/bluelib/loader/cache/model/BoneCache.java @@ -16,7 +16,7 @@ import org.joml.Matrix4f; import org.joml.Vector3d; import org.joml.Vector4f; -import software.bluelib.loader.animation.bone.BoneSnapshot; +import software.bluelib.loader.animation.keyframe.BoneFrame; // TODO: Record Class?!?!?!? @SuppressWarnings("unused") @@ -42,7 +42,7 @@ public class BoneCache { private final Boolean reset; @Nullable - private BoneSnapshot initialSnapshot; + private BoneFrame initialSnapshot; private boolean hidden; private boolean childrenHidden = false; @@ -296,7 +296,7 @@ public void resetStateChanges() { } @Nullable - public BoneSnapshot getInitialSnapshot() { + public BoneFrame getInitialSnapshot() { return this.initialSnapshot; } @@ -447,8 +447,8 @@ public void addRotationOffsetFromBone(@NotNull BoneCache pSource) { } @NotNull - public BoneSnapshot saveSnapshot() { - return new BoneSnapshot(this); + public BoneFrame saveSnapshot() { + return new BoneFrame(this); } public boolean equals(@Nullable Object pObj) { From d743c08106e4adb965b22b7048802a680db46fb9 Mon Sep 17 00:00:00 2001 From: Aram Date: Mon, 5 Jan 2026 13:14:14 +0100 Subject: [PATCH 3/6] Possible Texture Desync Fix --- changelog.md | 3 ++ .../api/entity/variant/IVariantEntity.java | 6 ++++ .../registry/BlueClientNetworkRegistry.java | 6 ++++ .../net/variant/SetVariantPacketHandler.java | 26 ++++++++++++++++ .../registry/BlueNetworkRegistry.java | 5 ++++ .../client/variant/SetVariantPacket.java | 30 +++++++++++++++++++ 6 files changed, 76 insertions(+) create mode 100644 common/src/main/java/software/bluelib/client/net/variant/SetVariantPacketHandler.java create mode 100644 common/src/main/java/software/bluelib/net/messages/client/variant/SetVariantPacket.java diff --git a/changelog.md b/changelog.md index e06272e7..e21a43f0 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,9 @@ - `toString()` method added to `Animation` and `AnimationState` for better debugging - Input validation with `IllegalArgumentException` for negative ticks, non-positive play counts, and NaN animation values +- New packet that syncs the Variant Name with all clients when changed on the server + - Shouldn't be necessary to add this manually, but due to a high amount of reports about desyncs, we added it just + to be sure ## Changed diff --git a/common/src/main/java/software/bluelib/api/entity/variant/IVariantEntity.java b/common/src/main/java/software/bluelib/api/entity/variant/IVariantEntity.java index a2903f55..60d4c27c 100644 --- a/common/src/main/java/software/bluelib/api/entity/variant/IVariantEntity.java +++ b/common/src/main/java/software/bluelib/api/entity/variant/IVariantEntity.java @@ -10,16 +10,19 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; + import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.Entity; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import software.bluelib.api.net.NetworkRegistry; import software.bluelib.api.utils.logging.BaseLogLevel; import software.bluelib.api.utils.logging.BaseLogger; import software.bluelib.api.utils.variant.ParameterUtils; import software.bluelib.entity.variant.IVariantAccessor; import software.bluelib.internal.BlueTranslation; +import software.bluelib.net.messages.client.variant.SetVariantPacket; @SuppressWarnings("unused") public interface IVariantEntity { @@ -56,6 +59,9 @@ default String getVariantName() { default void setVariantName(@NotNull String pVariantName) { T entity = getEntity(); + int id = entity.getId(); + SetVariantPacket packet = new SetVariantPacket(id, pVariantName); + NetworkRegistry.sendToAllPlayers(entity.getServer(), packet); ((IVariantAccessor) entity).setEntityVariantName(pVariantName); } } diff --git a/common/src/main/java/software/bluelib/client/internal/registry/BlueClientNetworkRegistry.java b/common/src/main/java/software/bluelib/client/internal/registry/BlueClientNetworkRegistry.java index bfe3575b..ed142396 100644 --- a/common/src/main/java/software/bluelib/client/internal/registry/BlueClientNetworkRegistry.java +++ b/common/src/main/java/software/bluelib/client/internal/registry/BlueClientNetworkRegistry.java @@ -9,14 +9,17 @@ import java.util.ArrayList; import java.util.List; + import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import software.bluelib.api.net.PacketProvider; import software.bluelib.client.net.OpenLoggerPacketHandler; import software.bluelib.client.net.loader.*; +import software.bluelib.client.net.variant.SetVariantPacketHandler; import software.bluelib.net.PacketRegisterInfo; import software.bluelib.net.messages.client.OpenLoggerPacket; import software.bluelib.net.messages.client.loader.*; +import software.bluelib.net.messages.client.variant.SetVariantPacket; import software.bluelib.net.messages.server.TestPacket; @ApiStatus.Internal @@ -35,6 +38,9 @@ public class BlueClientNetworkRegistry implements PacketProvider { public @NotNull List> getS2CPackets() { List> list = new ArrayList<>(); + // Variants + list.add(new PacketRegisterInfo<>(SetVariantPacket.ID, SetVariantPacket::decode, SetVariantPacketHandler::new)); + // Logger list.add(new PacketRegisterInfo<>(OpenLoggerPacket.ID, OpenLoggerPacket::decode, OpenLoggerPacketHandler::new)); diff --git a/common/src/main/java/software/bluelib/client/net/variant/SetVariantPacketHandler.java b/common/src/main/java/software/bluelib/client/net/variant/SetVariantPacketHandler.java new file mode 100644 index 00000000..b69bd3f3 --- /dev/null +++ b/common/src/main/java/software/bluelib/client/net/variant/SetVariantPacketHandler.java @@ -0,0 +1,26 @@ +package software.bluelib.client.net.variant; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import org.jetbrains.annotations.NotNull; +import software.bluelib.api.net.ClientNetworkPacketHandler; +import software.bluelib.entity.variant.IVariantAccessor; +import software.bluelib.net.messages.client.variant.SetVariantPacket; + +public class SetVariantPacketHandler implements ClientNetworkPacketHandler { + + @Override + public void handle(@NotNull SetVariantPacket pPacket, @NotNull Minecraft pClient) { + pClient.execute(() -> { + ClientLevel level = pClient.level; + if (level == null) return; + + Entity e = level.getEntity(pPacket.entityId()); + if (!(e instanceof LivingEntity living)) return; + + ((IVariantAccessor) living).setEntityVariantName(pPacket.variant()); + }); + } +} \ No newline at end of file diff --git a/common/src/main/java/software/bluelib/internal/registry/BlueNetworkRegistry.java b/common/src/main/java/software/bluelib/internal/registry/BlueNetworkRegistry.java index 42d96df0..4397f6e6 100644 --- a/common/src/main/java/software/bluelib/internal/registry/BlueNetworkRegistry.java +++ b/common/src/main/java/software/bluelib/internal/registry/BlueNetworkRegistry.java @@ -9,12 +9,15 @@ import java.util.ArrayList; import java.util.List; + import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import software.bluelib.api.net.PacketProvider; +import software.bluelib.client.net.variant.SetVariantPacketHandler; import software.bluelib.net.PacketRegisterInfo; import software.bluelib.net.messages.client.OpenLoggerPacket; import software.bluelib.net.messages.client.loader.*; +import software.bluelib.net.messages.client.variant.SetVariantPacket; import software.bluelib.net.messages.server.TestPacket; import software.bluelib.net.serverHandling.TestPacketHandler; @@ -34,6 +37,8 @@ public class BlueNetworkRegistry implements PacketProvider { public @NotNull List> getS2CPackets() { List> list = new ArrayList<>(); + list.add(new PacketRegisterInfo<>(SetVariantPacket.ID, SetVariantPacket::decode)); + list.add(new PacketRegisterInfo<>(OpenLoggerPacket.ID, OpenLoggerPacket::decode)); list.add(new PacketRegisterInfo<>(ControllerCachePacket.ID, ControllerCachePacket::decode)); diff --git a/common/src/main/java/software/bluelib/net/messages/client/variant/SetVariantPacket.java b/common/src/main/java/software/bluelib/net/messages/client/variant/SetVariantPacket.java new file mode 100644 index 00000000..ce625d23 --- /dev/null +++ b/common/src/main/java/software/bluelib/net/messages/client/variant/SetVariantPacket.java @@ -0,0 +1,30 @@ +package software.bluelib.net.messages.client.variant; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; +import software.bluelib.api.net.NetworkPacket; +import software.bluelib.internal.BlueResource; + +public record SetVariantPacket(int entityId, @NotNull String variant) implements NetworkPacket { + + @NotNull + public static final ResourceLocation ID = BlueResource.resource("set_variant_packet"); + + @Override + public void encode(@NotNull RegistryFriendlyByteBuf pBuffer) { + pBuffer.writeVarInt(entityId); + pBuffer.writeUtf(variant); + } + + public static @NotNull SetVariantPacket decode(@NotNull RegistryFriendlyByteBuf pBuffer) { + int entityId = pBuffer.readVarInt(); + String variant = pBuffer.readUtf(); + return new SetVariantPacket(entityId, variant); + } + + @Override + public @NotNull ResourceLocation getId() { + return ID; + } +} \ No newline at end of file From c3d806a2ac871517a850513fb306babbad8d5652 Mon Sep 17 00:00:00 2001 From: Aram Date: Mon, 5 Jan 2026 17:44:56 +0100 Subject: [PATCH 4/6] Revise changelog for recent updates and removals Updated changelog with recent changes and deletions. --- changelog.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index e21a43f0..378c34f2 100644 --- a/changelog.md +++ b/changelog.md @@ -35,8 +35,6 @@ - `setControllerSpeed()` parameter changed from `Double` to primitive `double` - `animationTick` field in `AnimationState` is now private with getter/setter methods - Improved `equals()` and `hashCode()` implementations for `Animation` and `Animation.Frame` -- Added `/fabric/out` to `.gitignore` -- Enabled example logging (`isExampleEnabled = true`) ## Deleted @@ -48,4 +46,4 @@ ## Bug Fixes - Fixed `equals()` method in `Animation` and `Animation.Frame` to properly compare field values instead of just hashCode -- Added proper null handling in `AnimationExtraData.set()` method \ No newline at end of file +- Added proper null handling in `AnimationExtraData.set()` method From 2f37c9e63f493257aa7d0e99100fc1946e10ca27 Mon Sep 17 00:00:00 2001 From: MeAlam1 Date: Wed, 14 Jan 2026 20:17:01 +0100 Subject: [PATCH 5/6] Spotless + License --- .../api/entity/variant/IVariantEntity.java | 1 - .../registry/BlueClientNetworkRegistry.java | 1 - .../net/variant/SetVariantPacketHandler.java | 9 +++++++- .../software/bluelib/config/LoggerConfig.java | 6 +++--- .../registry/BlueNetworkRegistry.java | 2 -- .../bluelib/loader/animation/Animation.java | 7 ++----- .../loader/animation/AnimationController.java | 8 +++---- .../loader/animation/AnimationExtraData.java | 4 +--- .../loader/animation/AnimationProcessor.java | 7 ++----- .../loader/animation/AnimationSnapshot.java | 6 +++--- .../loader/animation/AnimationState.java | 10 ++++----- .../keyframe/BoneAnimationFrame.java | 21 ++++++++++++------- .../animation/keyframe/InterpolationData.java | 5 ++--- .../keyframe/frame/AnimationFrame.java | 3 +-- .../keyframe/frame/AnimationFrameVector.java | 19 +++++++++++------ .../client/variant/SetVariantPacket.java | 9 +++++++- 16 files changed, 64 insertions(+), 54 deletions(-) diff --git a/common/src/main/java/software/bluelib/api/entity/variant/IVariantEntity.java b/common/src/main/java/software/bluelib/api/entity/variant/IVariantEntity.java index 60d4c27c..fd58e928 100644 --- a/common/src/main/java/software/bluelib/api/entity/variant/IVariantEntity.java +++ b/common/src/main/java/software/bluelib/api/entity/variant/IVariantEntity.java @@ -10,7 +10,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; - import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.Entity; diff --git a/common/src/main/java/software/bluelib/client/internal/registry/BlueClientNetworkRegistry.java b/common/src/main/java/software/bluelib/client/internal/registry/BlueClientNetworkRegistry.java index ed142396..0e8021f1 100644 --- a/common/src/main/java/software/bluelib/client/internal/registry/BlueClientNetworkRegistry.java +++ b/common/src/main/java/software/bluelib/client/internal/registry/BlueClientNetworkRegistry.java @@ -9,7 +9,6 @@ import java.util.ArrayList; import java.util.List; - import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import software.bluelib.api.net.PacketProvider; diff --git a/common/src/main/java/software/bluelib/client/net/variant/SetVariantPacketHandler.java b/common/src/main/java/software/bluelib/client/net/variant/SetVariantPacketHandler.java index b69bd3f3..548f0766 100644 --- a/common/src/main/java/software/bluelib/client/net/variant/SetVariantPacketHandler.java +++ b/common/src/main/java/software/bluelib/client/net/variant/SetVariantPacketHandler.java @@ -1,3 +1,10 @@ +/* + * Copyright (C) 2024 BlueLib Contributors + * + * This Source Code Form is subject to the terms of the MIT License. + * If a copy of the MIT License was not distributed with this file, + * You can obtain one at https://opensource.org/licenses/MIT. + */ package software.bluelib.client.net.variant; import net.minecraft.client.Minecraft; @@ -23,4 +30,4 @@ public void handle(@NotNull SetVariantPacket pPacket, @NotNull Minecraft pClient ((IVariantAccessor) living).setEntityVariantName(pPacket.variant()); }); } -} \ No newline at end of file +} diff --git a/common/src/main/java/software/bluelib/config/LoggerConfig.java b/common/src/main/java/software/bluelib/config/LoggerConfig.java index c6203f38..4d285a49 100644 --- a/common/src/main/java/software/bluelib/config/LoggerConfig.java +++ b/common/src/main/java/software/bluelib/config/LoggerConfig.java @@ -12,8 +12,8 @@ public class LoggerConfig { // TODO: BlueLib Logging should remain false by default - public static boolean isBlueLibLoggingEnabled = false; - public static boolean isLoggingEnabled = false; + public static boolean isBlueLibLoggingEnabled = true; + public static boolean isLoggingEnabled = true; @ApiStatus.Internal - public static final boolean isExampleEnabled = true; + public static final boolean isExampleEnabled = false; } diff --git a/common/src/main/java/software/bluelib/internal/registry/BlueNetworkRegistry.java b/common/src/main/java/software/bluelib/internal/registry/BlueNetworkRegistry.java index 4397f6e6..51394091 100644 --- a/common/src/main/java/software/bluelib/internal/registry/BlueNetworkRegistry.java +++ b/common/src/main/java/software/bluelib/internal/registry/BlueNetworkRegistry.java @@ -9,11 +9,9 @@ import java.util.ArrayList; import java.util.List; - import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import software.bluelib.api.net.PacketProvider; -import software.bluelib.client.net.variant.SetVariantPacketHandler; import software.bluelib.net.PacketRegisterInfo; import software.bluelib.net.messages.client.OpenLoggerPacket; import software.bluelib.net.messages.client.loader.*; diff --git a/common/src/main/java/software/bluelib/loader/animation/Animation.java b/common/src/main/java/software/bluelib/loader/animation/Animation.java index 34fedfb4..1941a571 100644 --- a/common/src/main/java/software/bluelib/loader/animation/Animation.java +++ b/common/src/main/java/software/bluelib/loader/animation/Animation.java @@ -8,11 +8,9 @@ package software.bluelib.loader.animation; import it.unimi.dsi.fastutil.objects.ObjectArrayList; - import java.util.Collections; import java.util.List; import java.util.Objects; - import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bluelib.loader.cache.animations.AnimationCache; @@ -22,8 +20,7 @@ public final class Animation { @NotNull private final List animationList = new ObjectArrayList<>(); - private Animation() { - } + private Animation() {} @NotNull public static Animation begin() { @@ -143,4 +140,4 @@ public int hashCode() { return Objects.hash(this.animationName, this.loopType, this.additionalTicks); } } -} \ No newline at end of file +} diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationController.java b/common/src/main/java/software/bluelib/loader/animation/AnimationController.java index b313b5c5..b6050b3a 100644 --- a/common/src/main/java/software/bluelib/loader/animation/AnimationController.java +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationController.java @@ -9,19 +9,17 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; - import java.util.*; import java.util.function.Function; - import net.minecraft.core.Direction.Axis; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bluelib.api.utils.logging.BaseLogLevel; import software.bluelib.api.utils.logging.BaseLogger; import software.bluelib.loader.animatable.base.BlueAnimatable; +import software.bluelib.loader.animation.keyframe.BoneAnimationFrame; import software.bluelib.loader.animation.keyframe.BoneFrame; import software.bluelib.loader.animation.keyframe.InterpolationData; -import software.bluelib.loader.animation.keyframe.BoneAnimationFrame; import software.bluelib.loader.animation.keyframe.KeyframeLocation; import software.bluelib.loader.animation.keyframe.data.CustomInstructionKeyframeData; import software.bluelib.loader.animation.keyframe.data.KeyFrameData; @@ -556,7 +554,7 @@ protected double adjustTick(double pTick) { @NotNull private InterpolationData getAnimationPointAtTick(@NotNull List> pFrames, double pTick, boolean pIsRotation, - @NotNull Axis pAxis) { + @NotNull Axis pAxis) { KeyframeLocation> location = getCurrentKeyFrameLocation(pFrames, pTick); KeyframeCache currentFrame = location.keyframe(); double startValue = currentFrame.startValue().get(); @@ -583,7 +581,7 @@ private InterpolationData getAnimationPointAtTick(@NotNull List> getCurrentKeyFrameLocation(@NotNull List> pFrames, - double pAgeInTicks) { + double pAgeInTicks) { double totalFrameTime = 0; for (KeyframeCache frame : pFrames) { diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationExtraData.java b/common/src/main/java/software/bluelib/loader/animation/AnimationExtraData.java index 3cedf10c..5cf1b8be 100644 --- a/common/src/main/java/software/bluelib/loader/animation/AnimationExtraData.java +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationExtraData.java @@ -8,11 +8,9 @@ package software.bluelib.loader.animation; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; - import java.util.Collections; import java.util.Map; import java.util.Objects; - import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bluelib.loader.geckolib.constant.dataticket.DataTicket; @@ -50,4 +48,4 @@ public void clear() { public Map, ?> asUnmodifiableMap() { return Collections.unmodifiableMap(this.data); } -} \ No newline at end of file +} diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java b/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java index 7defe4b3..b486b61a 100644 --- a/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationProcessor.java @@ -8,12 +8,10 @@ package software.bluelib.loader.animation; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; - import java.util.Collection; import java.util.LinkedList; import java.util.Map; import java.util.Queue; - import net.minecraft.util.Mth; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -21,9 +19,9 @@ import software.bluelib.api.utils.logging.BaseLogger; import software.bluelib.loader.animatable.base.AnimatableManager; import software.bluelib.loader.animatable.base.BlueAnimatable; +import software.bluelib.loader.animation.keyframe.BoneAnimationFrame; import software.bluelib.loader.animation.keyframe.BoneFrame; import software.bluelib.loader.animation.keyframe.InterpolationData; -import software.bluelib.loader.animation.keyframe.BoneAnimationFrame; import software.bluelib.loader.animation.math.Easing; import software.bluelib.loader.cache.animations.AnimationCache; import software.bluelib.loader.cache.model.BoneCache; @@ -269,6 +267,5 @@ public void preAnimationSetup(@NotNull AnimationState pAnimationState, double this.model.applyMolangQueries(pAnimationState, pAnimTime); } - public record QueuedAnimation(@NotNull AnimationCache animationCache, @NotNull AnimationCache.LoopType loopType) { - } + public record QueuedAnimation(@NotNull AnimationCache animationCache, @NotNull AnimationCache.LoopType loopType) {} } diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationSnapshot.java b/common/src/main/java/software/bluelib/loader/animation/AnimationSnapshot.java index 59b42b9c..32d4252f 100644 --- a/common/src/main/java/software/bluelib/loader/animation/AnimationSnapshot.java +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationSnapshot.java @@ -11,11 +11,11 @@ public record AnimationSnapshot( float limbSwing, float limbSwingAmount, float partialTick, - boolean isMoving -) { + boolean isMoving) { + public AnimationSnapshot { if (Float.isNaN(limbSwing) || Float.isNaN(limbSwingAmount) || Float.isNaN(partialTick)) { throw new IllegalArgumentException("Animation values cannot be NaN"); } } -} \ No newline at end of file +} diff --git a/common/src/main/java/software/bluelib/loader/animation/AnimationState.java b/common/src/main/java/software/bluelib/loader/animation/AnimationState.java index b958aced..b914a271 100644 --- a/common/src/main/java/software/bluelib/loader/animation/AnimationState.java +++ b/common/src/main/java/software/bluelib/loader/animation/AnimationState.java @@ -7,15 +7,14 @@ */ package software.bluelib.loader.animation; +import java.util.Map; +import java.util.Objects; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bluelib.loader.animatable.base.BlueAnimatable; import software.bluelib.loader.animation.state.PlayState; import software.bluelib.loader.geckolib.constant.dataticket.DataTicket; -import java.util.Map; -import java.util.Objects; - /** * Represents the current state of an animation for an animatable entity. * Combines immutable snapshot data with mutable controller interaction. @@ -40,8 +39,7 @@ public AnimationState( float pLimbSwing, float pLimbSwingAmount, float pPartialTick, - boolean pIsMoving - ) { + boolean pIsMoving) { this.animatable = pAnimatable; this.snapshot = new AnimationSnapshot(pLimbSwing, pLimbSwingAmount, pPartialTick, pIsMoving); this.extraData = new AnimationExtraData(); @@ -155,4 +153,4 @@ public String toString() { ", hasController=" + (this.controller != null) + '}'; } -} \ No newline at end of file +} diff --git a/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java index 5ebee6d2..d1fd38e0 100644 --- a/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java +++ b/common/src/main/java/software/bluelib/loader/animation/keyframe/BoneAnimationFrame.java @@ -1,3 +1,10 @@ +/* + * Copyright (C) 2024 BlueLib Contributors + * + * This Source Code Form is subject to the terms of the MIT License. + * If a copy of the MIT License was not distributed with this file, + * You can obtain one at https://opensource.org/licenses/MIT. + */ package software.bluelib.loader.animation.keyframe; import org.jetbrains.annotations.NotNull; @@ -21,8 +28,8 @@ public BoneAnimationFrame(@NotNull BoneCache pBone) { } public void addNextPosition(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, - @NotNull BoneFrame pStartSnapshot, - @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { + @NotNull BoneFrame pStartSnapshot, + @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { position.addPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getOffsetX(), pNextX.startValue(), pStartSnapshot.getOffsetY(), pNextY.startValue(), @@ -30,8 +37,8 @@ public void addNextPosition(@Nullable KeyframeCache pKeyFrame, double pLerped } public void addNextScale(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, - @NotNull BoneFrame pStartSnapshot, - @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { + @NotNull BoneFrame pStartSnapshot, + @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { scale.addPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getScaleX(), pNextX.startValue(), pStartSnapshot.getScaleY(), pNextY.startValue(), @@ -39,8 +46,8 @@ public void addNextScale(@Nullable KeyframeCache pKeyFrame, double pLerpedTic } public void addNextRotation(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, - @NotNull BoneFrame pStartSnapshot, @NotNull BoneFrame pInitialSnapshot, - @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { + @NotNull BoneFrame pStartSnapshot, @NotNull BoneFrame pInitialSnapshot, + @NotNull InterpolationData pNextX, @NotNull InterpolationData pNextY, @NotNull InterpolationData pNextZ) { rotation.addPoint(pKeyFrame, pLerpedTick, pTransitionLength, pStartSnapshot.getRotX() - pInitialSnapshot.getRotX(), pNextX.startValue(), pStartSnapshot.getRotY() - pInitialSnapshot.getRotY(), pNextY.startValue(), @@ -74,4 +81,4 @@ public AnimationFrameVector getPosition() { public AnimationFrameVector getScale() { return scale; } -} \ No newline at end of file +} diff --git a/common/src/main/java/software/bluelib/loader/animation/keyframe/InterpolationData.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/InterpolationData.java index 891582bb..e6a045bd 100644 --- a/common/src/main/java/software/bluelib/loader/animation/keyframe/InterpolationData.java +++ b/common/src/main/java/software/bluelib/loader/animation/keyframe/InterpolationData.java @@ -33,8 +33,7 @@ public record InterpolationData( double currentTick, double transitionLength, double startValue, - double endValue -) { + double endValue) { /** * Calculates the normalized progress (0.0 to 1.0) through this interpolation. @@ -56,4 +55,4 @@ public double getProgress() { ", progress=" + String.format("%.2f", getProgress()) + '}'; } -} \ No newline at end of file +} diff --git a/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrame.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrame.java index b766758d..fbac28b3 100644 --- a/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrame.java +++ b/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrame.java @@ -7,10 +7,9 @@ */ package software.bluelib.loader.animation.keyframe.frame; -import software.bluelib.loader.animation.keyframe.InterpolationData; - import java.io.Serial; import java.util.LinkedList; +import software.bluelib.loader.animation.keyframe.InterpolationData; public final class AnimationFrame extends LinkedList { diff --git a/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrameVector.java b/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrameVector.java index c15efee0..b7618dfe 100644 --- a/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrameVector.java +++ b/common/src/main/java/software/bluelib/loader/animation/keyframe/frame/AnimationFrameVector.java @@ -1,3 +1,10 @@ +/* + * Copyright (C) 2024 BlueLib Contributors + * + * This Source Code Form is subject to the terms of the MIT License. + * If a copy of the MIT License was not distributed with this file, + * You can obtain one at https://opensource.org/licenses/MIT. + */ package software.bluelib.loader.animation.keyframe.frame; import org.jetbrains.annotations.NotNull; @@ -6,17 +13,17 @@ import software.bluelib.loader.cache.animations.keyframe.KeyframeCache; public record AnimationFrameVector(@NotNull AnimationFrame x, - @NotNull AnimationFrame y, - @NotNull AnimationFrame z) { + @NotNull AnimationFrame y, + @NotNull AnimationFrame z) { public AnimationFrameVector() { this(new AnimationFrame(), new AnimationFrame(), new AnimationFrame()); } public void addPoint(@Nullable KeyframeCache pKeyFrame, double pLerpedTick, double pTransitionLength, - double pStartX, double pEndX, - double pStartY, double pEndY, - double pStartZ, double pEndZ) { + double pStartX, double pEndX, + double pStartY, double pEndY, + double pStartZ, double pEndZ) { x.add(new InterpolationData(pKeyFrame, pLerpedTick, pTransitionLength, pStartX, pEndX)); y.add(new InterpolationData(pKeyFrame, pLerpedTick, pTransitionLength, pStartY, pEndY)); z.add(new InterpolationData(pKeyFrame, pLerpedTick, pTransitionLength, pStartZ, pEndZ)); @@ -27,4 +34,4 @@ public void add(@NotNull InterpolationData pXPoint, @NotNull InterpolationData p y.add(pYPoint); z.add(pZPoint); } -} \ No newline at end of file +} diff --git a/common/src/main/java/software/bluelib/net/messages/client/variant/SetVariantPacket.java b/common/src/main/java/software/bluelib/net/messages/client/variant/SetVariantPacket.java index ce625d23..14e2f3f1 100644 --- a/common/src/main/java/software/bluelib/net/messages/client/variant/SetVariantPacket.java +++ b/common/src/main/java/software/bluelib/net/messages/client/variant/SetVariantPacket.java @@ -1,3 +1,10 @@ +/* + * Copyright (C) 2024 BlueLib Contributors + * + * This Source Code Form is subject to the terms of the MIT License. + * If a copy of the MIT License was not distributed with this file, + * You can obtain one at https://opensource.org/licenses/MIT. + */ package software.bluelib.net.messages.client.variant; import net.minecraft.network.RegistryFriendlyByteBuf; @@ -27,4 +34,4 @@ public void encode(@NotNull RegistryFriendlyByteBuf pBuffer) { public @NotNull ResourceLocation getId() { return ID; } -} \ No newline at end of file +} From 1dd96cf6cd71fced290786873eef349be9d97d04 Mon Sep 17 00:00:00 2001 From: MeAlam1 Date: Wed, 14 Jan 2026 20:22:23 +0100 Subject: [PATCH 6/6] Version Change --- build.gradle.kts | 4 ++-- common/src/main/java/software/bluelib/BlueLibConstants.java | 2 +- gradle/libs.versions.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index b5e8be9f..6a4343e8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,9 +14,9 @@ githubRelease { token(System.getenv("GITHUB") ?: "Invalid/No API Token Found") owner.set("MeAlam1") repo.set("BlueLib") - tagName.set("2.4.0") + tagName.set("2.4.4") targetCommitish.set("1.21-1.21.3") - releaseName.set("BlueLib 2.4.0") + releaseName.set("BlueLib 2.4.4") body.set(rootProject.file("changelog.md").readText()) draft.set(false) prerelease.set(false) diff --git a/common/src/main/java/software/bluelib/BlueLibConstants.java b/common/src/main/java/software/bluelib/BlueLibConstants.java index 5de95f87..a695f262 100644 --- a/common/src/main/java/software/bluelib/BlueLibConstants.java +++ b/common/src/main/java/software/bluelib/BlueLibConstants.java @@ -51,7 +51,7 @@ public static ServiceLoader loadAll(@NotNull Class pClazz) { public static final String MOD_NAME = "BlueLib"; @NotNull - public static final String VERSION = "2.4.2"; + public static final String VERSION = "2.4.4"; @Nullable public static MinecraftServer server; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a9953d13..7987f9f2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # BlueLib -bluelib = "2.4.3" +bluelib = "2.4.4" # Common minecraft-range = "[1.21,)"