57 lines
2.2 KiB
Java
57 lines
2.2 KiB
Java
package net.minecraft.client.animation;
|
|
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.Map.Entry;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.model.Model;
|
|
import net.minecraft.client.model.geom.ModelPart;
|
|
import net.minecraft.util.Mth;
|
|
import org.joml.Vector3f;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class KeyframeAnimations {
|
|
public static void animate(Model model, AnimationDefinition definition, long accumulatedTime, float scale, Vector3f vector) {
|
|
float f = getElapsedSeconds(definition, accumulatedTime);
|
|
|
|
for (Entry<String, List<AnimationChannel>> entry : definition.boneAnimations().entrySet()) {
|
|
Optional<ModelPart> optional = model.getAnyDescendantWithName((String)entry.getKey());
|
|
List<AnimationChannel> list = (List<AnimationChannel>)entry.getValue();
|
|
optional.ifPresent(modelPart -> list.forEach(animationChannel -> {
|
|
Keyframe[] keyframes = animationChannel.keyframes();
|
|
int i = Math.max(0, Mth.binarySearch(0, keyframes.length, ix -> f <= keyframes[ix].timestamp()) - 1);
|
|
int j = Math.min(keyframes.length - 1, i + 1);
|
|
Keyframe keyframe = keyframes[i];
|
|
Keyframe keyframe2 = keyframes[j];
|
|
float h = f - keyframe.timestamp();
|
|
float k;
|
|
if (j != i) {
|
|
k = Mth.clamp(h / (keyframe2.timestamp() - keyframe.timestamp()), 0.0F, 1.0F);
|
|
} else {
|
|
k = 0.0F;
|
|
}
|
|
|
|
keyframe2.interpolation().apply(vector, k, keyframes, i, j, scale);
|
|
animationChannel.target().apply(modelPart, vector);
|
|
}));
|
|
}
|
|
}
|
|
|
|
private static float getElapsedSeconds(AnimationDefinition animationDefinition, long accumulatedTime) {
|
|
float f = (float)accumulatedTime / 1000.0F;
|
|
return animationDefinition.looping() ? f % animationDefinition.lengthInSeconds() : f;
|
|
}
|
|
|
|
public static Vector3f posVec(float x, float y, float z) {
|
|
return new Vector3f(x, -y, z);
|
|
}
|
|
|
|
public static Vector3f degreeVec(float xDegrees, float yDegrees, float zDegrees) {
|
|
return new Vector3f(xDegrees * (float) (Math.PI / 180.0), yDegrees * (float) (Math.PI / 180.0), zDegrees * (float) (Math.PI / 180.0));
|
|
}
|
|
|
|
public static Vector3f scaleVec(double xScale, double yScale, double zScale) {
|
|
return new Vector3f((float)(xScale - 1.0), (float)(yScale - 1.0), (float)(zScale - 1.0));
|
|
}
|
|
}
|