From 375429cafc8b2e313ee59b64c95e2ec78f24fada Mon Sep 17 00:00:00 2001 From: James Pelter Date: Tue, 4 Feb 2025 23:13:10 -0600 Subject: [PATCH] More Anim Notify Progress - Deprecated old state machine animation sequence stuff - Added "AnimNotifies" class --- .../sample/AnimationBlendSpacePlayer.java | 5 - .../pose/sample/AnimationMontage.java | 10 +- .../pose/sample/AnimationMontageTrack.java | 26 +++-- .../pose/sample/AnimationSequencePlayer.java | 8 +- .../pose/sample/TimeBasedPoseSampler.java | 95 ++++--------------- .../pose/sample/notify/AnimNotifies.java | 18 ++++ 6 files changed, 57 insertions(+), 105 deletions(-) create mode 100644 src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/notify/AnimNotifies.java diff --git a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationBlendSpacePlayer.java b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationBlendSpacePlayer.java index 7c3eff5..c1f9629 100644 --- a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationBlendSpacePlayer.java +++ b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationBlendSpacePlayer.java @@ -63,11 +63,6 @@ public AnimationBlendSpacePlayer build() { } } - public AnimationBlendSpacePlayer addEntry(float position, ResourceLocation resourceLocation, float playRate){ - blendSpaceEntryTreeMap.put(position, new BlendSpaceEntry(resourceLocation, playRate)); - return this; - } - public AnimationBlendSpacePlayer setPlayRateMultipler(float newPlayRate){ this.playRateMultiplier = newPlayRate; return this; diff --git a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationMontage.java b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationMontage.java index 01f4511..8b757d9 100644 --- a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationMontage.java +++ b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationMontage.java @@ -15,8 +15,8 @@ public class AnimationMontage { private float playRate = 1; private float blendInDuration = 1; private float blendOutDuration = 1; - private Easing blendInEasing = Easing.Linear.of(); - private Easing blendOutEasing = Easing.Linear.of(); + private Easing blendInEasing = Easing.LINEAR; + private Easing blendOutEasing = Easing.LINEAR; public float timeElapsed = 0; private boolean active = true; @@ -32,10 +32,10 @@ public static AnimationMontage of(ResourceLocation resourceLocation){ } public void tick(){ - // Tick time forwards using the playrare + // Tick time forwards using the play rate this.timeElapsed += this.playRate; - // Only make the active state changable when its active. Once it becomes deactive, it will be destroyed upon blendWeight == 0 + // Only make the active state changeable when its active. Once it becomes deactive, it will be destroyed upon blendWeight == 0 if(isActive()){ setActive(this.timeElapsed < this.length); } @@ -45,7 +45,7 @@ public void tick(){ } public > AnimationPose getAnimationPose(JointSkeleton jointSkeleton){ - return AnimationPose.fromAnimationSequence(jointSkeleton, this.resourceLocation, (this.timeElapsed + this.startOffset) / AnimationSequenceData.INSTANCE.get(resourceLocation).getFrameLength()); + return AnimationPose.fromAnimationSequence(jointSkeleton, this.resourceLocation, (this.timeElapsed + this.startOffset) / AnimationSequenceData.INSTANCE.get(resourceLocation).frameLength()); } /** diff --git a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationMontageTrack.java b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationMontageTrack.java index c8d7b57..7a21bd3 100644 --- a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationMontageTrack.java +++ b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationMontageTrack.java @@ -1,11 +1,13 @@ package com.trainguy9512.animationoverhaul.animation.pose.sample; +import com.trainguy9512.animationoverhaul.animation.data.AnimationDriverContainer; +import com.trainguy9512.animationoverhaul.animation.data.PoseSamplerStateContainer; import com.trainguy9512.animationoverhaul.animation.pose.AnimationPose; import com.trainguy9512.animationoverhaul.animation.pose.JointSkeleton; import net.minecraft.util.Mth; import java.util.ArrayList; -public class AnimationMontageTrack extends PoseSampler { +public class AnimationMontageTrack extends PoseSampler implements SampleableFromInput { private final ArrayList activeMontages = new ArrayList(); @@ -31,9 +33,9 @@ public AnimationMontageTrack build() { } @Override - public void tick(){ + public void tick(AnimationDriverContainer animationDriverContainer, PoseSamplerStateContainer poseSamplerStateContainer){ // Only run if there's actually montages currently loaded - if(this.isActive()){ + if(this.hasActiveMontages()){ ArrayList montagesToRemove = new ArrayList<>(); for(AnimationMontage animationMontage : activeMontages){ animationMontage.tick(); @@ -50,20 +52,12 @@ public void tick(){ } @Override - public > AnimationPose sampleFromInputPose(AnimationPose inputPose, JointSkeleton jointSkeleton) { - return getBlendedPose(inputPose, jointSkeleton); - } - - public boolean isActive(){ - return !this.activeMontages.isEmpty(); - } - - private > AnimationPose getBlendedPose(AnimationPose inputPose, JointSkeleton jointSkeleton){ + public AnimationPose sample(AnimationDriverContainer animationDriverContainer, PoseSamplerStateContainer poseSamplerStateContainer, JointSkeleton jointSkeleton, AnimationPose inputPose) { // Initialize the animation pose - AnimationPose animationPose = AnimationPose.of(jointSkeleton); + AnimationPose animationPose = AnimationPose.of(jointSkeleton); // Only do this stuff if there's any loaded animation montages - if(this.isActive()){ + if(this.hasActiveMontages()){ // Iterate over each montage and get the blended animation between top and bottom layers for(int i = 0; i < this.activeMontages.size(); i++){ AnimationMontage animationMontage = this.activeMontages.get(i); @@ -86,6 +80,10 @@ private > AnimationPose getBlendedPose(AnimationPose inp return animationPose; } + public boolean hasActiveMontages(){ + return !this.activeMontages.isEmpty(); + } + /** * Plays the given montage. Should be accessed within the tick phase for intended functionality * diff --git a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationSequencePlayer.java b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationSequencePlayer.java index dfbfd85..8c1c972 100644 --- a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationSequencePlayer.java +++ b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/AnimationSequencePlayer.java @@ -38,7 +38,7 @@ public static Builder of(ResourceLocation resourceLocation){ @Override public AnimationPose sample(AnimationDriverContainer animationDriverContainer, PoseSamplerStateContainer poseSamplerStateContainer, JointSkeleton jointSkeleton) { - return AnimationPose.fromAnimationSequence(jointSkeleton, this.resourceLocation, this.getTimeFromTicks()); + return AnimationPose.fromAnimationSequence(jointSkeleton, this.resourceLocation, this.processTime(this.getTimeElapsed())); } @@ -97,10 +97,10 @@ public void tick(AnimationDriverContainer animationDriverContainer, PoseSamplerS super.tick(animationDriverContainer, poseSamplerStateContainer); } - private float getTimeFromTicks(){ + private float processTime(float inputTime){ return this.looping ? - (((this.getTimeElapsed()) % (this.endTime - this.startTime)) + this.startTime) / this.frameLength : - Mth.clamp(this.getTimeElapsed(), 0, this.endTime) / this.frameLength; + (((inputTime) % (this.endTime - this.startTime)) + this.startTime) / this.frameLength : + Mth.clamp(inputTime, 0, this.endTime) / this.frameLength; } public float getTimeElapsedLooped(){ diff --git a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/TimeBasedPoseSampler.java b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/TimeBasedPoseSampler.java index 52c939b..f009237 100644 --- a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/TimeBasedPoseSampler.java +++ b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/TimeBasedPoseSampler.java @@ -1,29 +1,25 @@ package com.trainguy9512.animationoverhaul.animation.pose.sample; -import com.google.common.collect.Maps; import com.trainguy9512.animationoverhaul.animation.data.AnimationDriverContainer; import com.trainguy9512.animationoverhaul.animation.data.PoseSamplerKey; import com.trainguy9512.animationoverhaul.animation.data.PoseSamplerStateContainer; +import com.trainguy9512.animationoverhaul.animation.pose.sample.notify.AnimNotify; import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; public class TimeBasedPoseSampler extends PoseSampler { protected float timeElapsed; private float playRate; private boolean playing; - private final HashMap>, List>> playFromStartOnActiveStates; - private final HashMap>, List>> progressTimeOnActiveStates; + private boolean resetting; protected TimeBasedPoseSampler(Builder builder) { super(builder); this.timeElapsed = 0; this.playRate = builder.playRate; - this.playing = builder.isPlaying; - this.playFromStartOnActiveStates = builder.playFromStartOnActiveStates; - this.progressTimeOnActiveStates = builder.progressTimeOnActiveStates; + this.playing = builder.playing; + this.resetting = false; } public static Builder of(){ @@ -34,14 +30,10 @@ public static Builder of(){ public static class Builder> extends PoseSampler.Builder { private float playRate = 1; - private boolean isPlaying = true; - private final HashMap>, List>> playFromStartOnActiveStates; - private final HashMap>, List>> progressTimeOnActiveStates; + private boolean playing = true; protected Builder() { super(); - this.playFromStartOnActiveStates = Maps.newHashMap(); - this.progressTimeOnActiveStates = Maps.newHashMap(); } @SuppressWarnings("unchecked") @@ -51,26 +43,8 @@ public B setPlayRate(float playRate){ } @SuppressWarnings("unchecked") - public B setIsPlaying(boolean isPlaying){ - this.isPlaying = isPlaying; - return (B) this; - } - - @SuppressWarnings("unchecked") - public > B addPlayFromStartOnActiveStates(PoseSamplerKey> animationStateMachineKey, Enum... states){ - this.playFromStartOnActiveStates.putIfAbsent(animationStateMachineKey, new ArrayList<>()); - for(Enum state : states){ - this.playFromStartOnActiveStates.get(animationStateMachineKey).add(state); - } - return (B) this; - } - - @SuppressWarnings("unchecked") - public > B addProgressTimeOnActiveStates(PoseSamplerKey> animationStateMachineKey, Enum... states){ - this.progressTimeOnActiveStates.putIfAbsent( animationStateMachineKey, new ArrayList<>()); - for(Enum state : states){ - this.progressTimeOnActiveStates.get(animationStateMachineKey).add(state); - } + public B setPlaying(boolean playing){ + this.playing = playing; return (B) this; } @@ -92,62 +66,29 @@ public void setTimeElapsed(float timeElapsed){ this.timeElapsed = timeElapsed; } - public void resetTime(){ - this.setTimeElapsed(0); - } - - public boolean getIsPlaying(){ - return this.playing; - } - public float getTimeElapsed(){ return this.timeElapsed; } + public void resetTime(){ + this.setTimeElapsed(0); + this.resetting = true; + } - /** - * Iterates over all state machines/state enums listed for playing from start on state active, and if the state is currently not active then it repeatedly resets until the state is active. - */ - public void playFromStartOnStateActive(PoseSamplerStateContainer poseSamplerStateContainer){ - if(!this.playFromStartOnActiveStates.isEmpty()) { - for (PoseSamplerKey> animationStateMachineKey : this.playFromStartOnActiveStates.keySet()) { - AnimationStateMachine animationStateMachine = poseSamplerStateContainer.getPoseSampler(animationStateMachineKey); - - for (Enum stateEnum : this.playFromStartOnActiveStates.get(animationStateMachineKey)) { - if (animationStateMachine.getActiveStates().contains(stateEnum)) { - return; - } - } - } - this.resetTime(); - } + public void setPlaying(boolean playing){ + this.playing = playing; } - /** - * Iterates over all state machine/state enums listed for progressing time on state active, and if any of the states are active then time is progressed. - */ - public void progressTimeIfStateActive(PoseSamplerStateContainer poseSamplerStateContainer){ - if(!this.progressTimeOnActiveStates.isEmpty()){ - for(PoseSamplerKey> animationStateMachineKey : this.progressTimeOnActiveStates.keySet()){ - AnimationStateMachine animationStateMachine = poseSamplerStateContainer.getPoseSampler(animationStateMachineKey); - - for(Enum stateEnum : this.progressTimeOnActiveStates.get(animationStateMachineKey)){ - if(animationStateMachine.getActiveStates().contains(stateEnum)){ - this.playing = true; - return; - } - } - } - this.playing = false; - } + public boolean getPlaying(){ + return this.playing; } + @Override public void tick(AnimationDriverContainer animationDriverContainer, PoseSamplerStateContainer poseSamplerStateContainer){ - progressTimeIfStateActive(poseSamplerStateContainer); - if(this.getIsPlaying()){ + if(this.getPlaying() && !this.resetting){ this.timeElapsed += this.playRate; } - playFromStartOnStateActive(poseSamplerStateContainer); + this.resetting = false; } } diff --git a/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/notify/AnimNotifies.java b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/notify/AnimNotifies.java new file mode 100644 index 0000000..42eadb9 --- /dev/null +++ b/src/main/java/com/trainguy9512/animationoverhaul/animation/pose/sample/notify/AnimNotifies.java @@ -0,0 +1,18 @@ +package com.trainguy9512.animationoverhaul.animation.pose.sample.notify; + +import com.trainguy9512.animationoverhaul.animation.data.PoseSamplerKey; +import com.trainguy9512.animationoverhaul.animation.pose.sample.TimeBasedPoseSampler; + +/** + * Class with preset anim notify functions + */ +public class AnimNotifies { + + /** + * Provides an anim notify that resets the time on the time-based pose sampler associated with the provided key. + * @param poseSamplerKey Time-based pose sampler key to reset the time on. + */ + public static AnimNotify resetTimeAnimNotify(PoseSamplerKey poseSamplerKey){ + return (animationDriverContainer, poseSamplerStateContainer) -> poseSamplerStateContainer.getPoseSampler(poseSamplerKey).resetTime(); + } +}