KeyframeAnimation.java

net.minecraft.client.animation.KeyframeAnimation

信息

  • 全限定名:net.minecraft.client.animation.KeyframeAnimation
  • 类型:public class
  • 包:net.minecraft.client.animation
  • 源码路径:src/main/java/net/minecraft/client/animation/KeyframeAnimation.java
  • 起始行号:L15
  • 职责:

    TODO

字段/常量

  • definition

    • 类型: AnimationDefinition
    • 修饰符: private final
    • 源码定位: L16
    • 说明:

      TODO

  • entries

    • 类型: List<KeyframeAnimation.Entry>
    • 修饰符: private final
    • 源码定位: L17
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.animation.KeyframeAnimation.Entry
    • 类型: record
    • 修饰符: private
    • 源码定位: L77
    • 说明:

      TODO

构造器

private KeyframeAnimation(AnimationDefinition definition, List<KeyframeAnimation.Entry> entries) @ L19

  • 构造器名:KeyframeAnimation
  • 源码定位:L19
  • 修饰符:private

参数:

  • definition: AnimationDefinition
  • entries: List<KeyframeAnimation.Entry>

说明:

TODO

方法

下面的方法块按源码顺序生成。

static KeyframeAnimation bake(ModelPart root, AnimationDefinition definition) @ L24

  • 方法名:bake
  • 源码定位:L24
  • 返回类型:KeyframeAnimation
  • 修饰符:static

参数:

  • root: ModelPart
  • definition: AnimationDefinition

说明:

TODO

public void applyStatic() @ L44

  • 方法名:applyStatic
  • 源码定位:L44
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void applyWalk(float animationPos, float animationSpeed, float speedFactor, float scaleFactor) @ L48

  • 方法名:applyWalk
  • 源码定位:L48
  • 返回类型:void
  • 修饰符:public

参数:

  • animationPos: float
  • animationSpeed: float
  • speedFactor: float
  • scaleFactor: float

说明:

TODO

public void apply(AnimationState animationState, float currentTime) @ L54

  • 方法名:apply
  • 源码定位:L54
  • 返回类型:void
  • 修饰符:public

参数:

  • animationState: AnimationState
  • currentTime: float

说明:

TODO

public void apply(AnimationState animationState, float currentTime, float speedFactor) @ L58

  • 方法名:apply
  • 源码定位:L58
  • 返回类型:void
  • 修饰符:public

参数:

  • animationState: AnimationState
  • currentTime: float
  • speedFactor: float

说明:

TODO

public void apply(long millisSinceStart, float targetScale) @ L62

  • 方法名:apply
  • 源码定位:L62
  • 返回类型:void
  • 修饰符:public

参数:

  • millisSinceStart: long
  • targetScale: float

说明:

TODO

private float getElapsedSeconds(long millisSinceStart) @ L71

  • 方法名:getElapsedSeconds
  • 源码定位:L71
  • 返回类型:float
  • 修饰符:private

参数:

  • millisSinceStart: long

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class KeyframeAnimation {
    private final AnimationDefinition definition;
    private final List<KeyframeAnimation.Entry> entries;
 
    private KeyframeAnimation(AnimationDefinition definition, List<KeyframeAnimation.Entry> entries) {
        this.definition = definition;
        this.entries = entries;
    }
 
    static KeyframeAnimation bake(ModelPart root, AnimationDefinition definition) {
        List<KeyframeAnimation.Entry> entries = new ArrayList<>();
        Function<String, ModelPart> partLookup = root.createPartLookup();
 
        for (Map.Entry<String, List<AnimationChannel>> entry : definition.boneAnimations().entrySet()) {
            String partName = entry.getKey();
            List<AnimationChannel> channels = entry.getValue();
            ModelPart part = partLookup.apply(partName);
            if (part == null) {
                throw new IllegalArgumentException("Cannot animate " + partName + ", which does not exist in model");
            }
 
            for (AnimationChannel channel : channels) {
                entries.add(new KeyframeAnimation.Entry(part, channel.target(), channel.keyframes()));
            }
        }
 
        return new KeyframeAnimation(definition, List.copyOf(entries));
    }
 
    public void applyStatic() {
        this.apply(0L, 1.0F);
    }
 
    public void applyWalk(float animationPos, float animationSpeed, float speedFactor, float scaleFactor) {
        long time = (long)(animationPos * 50.0F * speedFactor);
        float scale = Math.min(animationSpeed * scaleFactor, 1.0F);
        this.apply(time, scale);
    }
 
    public void apply(AnimationState animationState, float currentTime) {
        this.apply(animationState, currentTime, 1.0F);
    }
 
    public void apply(AnimationState animationState, float currentTime, float speedFactor) {
        animationState.ifStarted(state -> this.apply((long)((float)state.getTimeInMillis(currentTime) * speedFactor), 1.0F));
    }
 
    public void apply(long millisSinceStart, float targetScale) {
        float secondsSinceStart = this.getElapsedSeconds(millisSinceStart);
        Vector3f scratchVector = new Vector3f();
 
        for (KeyframeAnimation.Entry entry : this.entries) {
            entry.apply(secondsSinceStart, targetScale, scratchVector);
        }
    }
 
    private float getElapsedSeconds(long millisSinceStart) {
        float secondsSinceStart = (float)millisSinceStart / 1000.0F;
        return this.definition.looping() ? secondsSinceStart % this.definition.lengthInSeconds() : secondsSinceStart;
    }
 
    @OnlyIn(Dist.CLIENT)
    private record Entry(ModelPart part, AnimationChannel.Target target, Keyframe[] keyframes) {
        public void apply(float secondsSinceStart, float targetScale, Vector3f scratchVector) {
            int prev = Math.max(0, Mth.binarySearch(0, this.keyframes.length, i -> secondsSinceStart <= this.keyframes[i].timestamp()) - 1);
            int next = Math.min(this.keyframes.length - 1, prev + 1);
            Keyframe previousFrame = this.keyframes[prev];
            Keyframe nextFrame = this.keyframes[next];
            float keyframeTimeDelta = secondsSinceStart - previousFrame.timestamp();
            float lerpAlpha;
            if (next != prev) {
                lerpAlpha = Mth.clamp(keyframeTimeDelta / (nextFrame.timestamp() - previousFrame.timestamp()), 0.0F, 1.0F);
            } else {
                lerpAlpha = 0.0F;
            }
 
            nextFrame.interpolation().apply(scratchVector, lerpAlpha, this.keyframes, prev, next, targetScale);
            this.target.apply(this.part, scratchVector);
        }
    }
}

引用的其他类