From 448c06c4792b75aedbde228f47cc1a5226ecb803 Mon Sep 17 00:00:00 2001 From: luisc Date: Wed, 28 Aug 2024 16:58:04 -0500 Subject: [PATCH 1/4] Fixed animation builder not chaining animations correctly --- .../core/controller/AnimationController.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java b/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java index c4145d9..73e35e1 100644 --- a/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java +++ b/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java @@ -574,17 +574,18 @@ private void processCurrentAnimation(double tick, double actualTick, MolangParse if (!currentAnimation.loop.isRepeatingAfterEnd()) { // Pull the next animation from the queue setAllStopping(); - Animation peek = animationQueue.peek(); - if (peek == null) { + Animation poll = animationQueue.poll(); + if (poll == null) { // No more animations left, stop the animation controller this.animationState = AnimationState.Stopped; return; } else { // Otherwise, set the state to transitioning and start transitioning to the next // animation next frame - this.animationState = AnimationState.Transitioning; +// this.animationState = AnimationState.Transitioning; + this.currentAnimation = poll; shouldResetTick = true; - currentAnimation = this.animationQueue.peek(); + tick = adjustTick(actualTick) + 0.001F; } } else { if (currentAnimation.loop == ILoopType.EDefaultLoopTypes.LOOP) { @@ -680,10 +681,6 @@ private void processCurrentAnimation(double tick, double actualTick, MolangParse } } //} - - if (this.transitionLengthTicks == 0 && shouldResetTick && this.animationState == AnimationState.Transitioning) { - this.currentAnimation = animationQueue.poll(); - } } private void processBedrockParticleEvent(ParticleKeyFrameEvent event) { From e10bd698980435a31df5b856e7b9227e92679ecf Mon Sep 17 00:00:00 2001 From: luisc Date: Wed, 28 Aug 2024 18:34:18 -0500 Subject: [PATCH 2/4] Fixed the animation controller changing source animations' properties while animating --- .../geckolib3/core/builder/Animation.java | 22 ++++++++++++++- .../core/controller/AnimationController.java | 27 ++++++++++--------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/software/bernie/geckolib3/core/builder/Animation.java b/core/src/main/java/software/bernie/geckolib3/core/builder/Animation.java index 03cee53..303f685 100644 --- a/core/src/main/java/software/bernie/geckolib3/core/builder/Animation.java +++ b/core/src/main/java/software/bernie/geckolib3/core/builder/Animation.java @@ -5,9 +5,12 @@ package software.bernie.geckolib3.core.builder; -import java.io.Serializable; +import java.io.*; import java.util.ArrayList; +import java.util.Base64; import java.util.List; + +import org.apache.commons.lang3.SerializationUtils; import software.bernie.geckolib3.core.builder.ILoopType.EDefaultLoopTypes; import software.bernie.geckolib3.core.keyframe.BoneAnimation; import software.bernie.geckolib3.core.keyframe.EventKeyFrame; @@ -29,4 +32,21 @@ public Animation() { this.particleKeyFrames = new ArrayList(); this.customInstructionKeyframes = new ArrayList(); } + + public static Animation copy(Animation animation) { + try { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(animation); + objectOutputStream.flush(); + String serialized = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()); + + byte[] data = Base64.getDecoder().decode(serialized); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data); + ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); + return (Animation) objectInputStream.readObject(); + } catch (Exception e) { + return animation; + } + } } diff --git a/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java b/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java index 73e35e1..52066c7 100644 --- a/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java +++ b/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java @@ -212,11 +212,12 @@ public void setAnimation(AnimationBuilder builder) { // Convert the list of animation names to the actual list, keeping track of the // loop boolean along the way LinkedList animations = builder.getRawAnimationList().stream().map((rawAnimation) -> { - Animation animation = model.getAnimation(rawAnimation.animationName, animatable); - if (animation == null) { + Animation originalAnimation = model.getAnimation(rawAnimation.animationName, animatable); + if (originalAnimation == null) { System.out.printf("Could not load animation: %s. Is it missing?", rawAnimation.animationName); encounteredError.set(true); } + Animation animation = Animation.copy(originalAnimation); if (animation != null && rawAnimation.loopType != null) { animation.loop = rawAnimation.loopType; } @@ -392,17 +393,17 @@ public void process(double tick, AnimationEvent event, List modelRende HashMap> boneSnapshotCollection, MolangParser parser, boolean crashWhenCantFindBone) { parser.setValue("query.life_time", tick / 20); - if (currentAnimation != null) { - IAnimatableModel model = getModel(this.animatable); - if (model != null) { - Animation animation = model.getAnimation(currentAnimation.animationName, this.animatable); - if (animation != null) { - ILoopType loop = currentAnimation.loop; - currentAnimation = animation; - currentAnimation.loop = loop; - } - } - } +// if (currentAnimation != null) { +// IAnimatableModel model = getModel(this.animatable); +// if (model != null) { +// Animation animation = Animation.copy(model.getAnimation(currentAnimation.animationName, this.animatable)); +// if (animation != null) { +// ILoopType loop = currentAnimation.loop; +// currentAnimation = animation; +// currentAnimation.loop = loop; +// } +// } +// } createInitialQueues(modelRendererList); From 982d22e38bd80c1ec5f7203cc440cb2ecdf2199e Mon Sep 17 00:00:00 2001 From: "Luis C.M." <42545778+c0508383@users.noreply.github.com> Date: Thu, 29 Aug 2024 23:47:24 -0500 Subject: [PATCH 3/4] Fixed animation builders not applying transition ticks between their animations --- .../core/controller/AnimationController.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java b/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java index 52066c7..99fbc7f 100644 --- a/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java +++ b/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java @@ -453,7 +453,7 @@ public void process(double tick, AnimationEvent event, List modelRende // Handle transitioning to a different animation (or just starting one) if (animationState == AnimationState.Transitioning) { // Just started transitioning, so set the current animation to the first one - if (tick == 0 || isJustStarting) { + if (this.justStartedTransition) { justStartedTransition = false; this.currentAnimation = animationQueue.poll(); resetEventKeyFrames(); @@ -526,6 +526,10 @@ public void process(double tick, AnimationEvent event, List modelRende } else if (getAnimationState() == AnimationState.Running) { // Actually run the animation processCurrentAnimation(tick, actualTick, parser, crashWhenCantFindBone); + if (getAnimationState() == AnimationState.Transitioning) { + saveSnapshotsForAnimation(this.currentAnimation, boneSnapshotCollection); + this.currentAnimation = this.animationQueue.poll(); + } } } @@ -575,18 +579,11 @@ private void processCurrentAnimation(double tick, double actualTick, MolangParse if (!currentAnimation.loop.isRepeatingAfterEnd()) { // Pull the next animation from the queue setAllStopping(); - Animation poll = animationQueue.poll(); - if (poll == null) { + Animation nextAnimation = animationQueue.peek(); + if (nextAnimation == null) { // No more animations left, stop the animation controller this.animationState = AnimationState.Stopped; return; - } else { - // Otherwise, set the state to transitioning and start transitioning to the next - // animation next frame -// this.animationState = AnimationState.Transitioning; - this.currentAnimation = poll; - shouldResetTick = true; - tick = adjustTick(actualTick) + 0.001F; } } else { if (currentAnimation.loop == ILoopType.EDefaultLoopTypes.LOOP) { @@ -682,6 +679,15 @@ private void processCurrentAnimation(double tick, double actualTick, MolangParse } } //} + + if (tick >= currentAnimation.animationLength && !currentAnimation.loop.isRepeatingAfterEnd()) { + Animation nextAnimation = animationQueue.peek(); + if (nextAnimation != null) { + this.animationState = AnimationState.Transitioning; + shouldResetTick = true; + adjustTick(actualTick); + } + } } private void processBedrockParticleEvent(ParticleKeyFrameEvent event) { From 6636b947bf9a1a3c1cf163e3f57705eca3556294 Mon Sep 17 00:00:00 2001 From: "Luis C.M." <42545778+c0508383@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:27:56 -0500 Subject: [PATCH 4/4] Made event key frames (sounds, instructions, particles) not reset on the last frame of hold_on_last_frame animations: caused animations to loop all previous instructions endlessly, not just the last frame's. --- .../bernie/geckolib3/core/controller/AnimationController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java b/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java index 99fbc7f..e54b6a7 100644 --- a/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java +++ b/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java @@ -572,8 +572,6 @@ private void processCurrentAnimation(double tick, double actualTick, MolangParse assert currentAnimation != null; // Animation has ended if (tick >= currentAnimation.animationLength) { - resetEventKeyFrames(); - // If the current animation is set to loop, keep it as the current animation and // just start over if (!currentAnimation.loop.isRepeatingAfterEnd()) { @@ -588,6 +586,7 @@ private void processCurrentAnimation(double tick, double actualTick, MolangParse } else { if (currentAnimation.loop == ILoopType.EDefaultLoopTypes.LOOP) { // Reset the adjusted tick so the next animation starts at tick 0 + resetEventKeyFrames(); shouldResetTick = true; tick = adjustTick(actualTick); } else {