diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/FunctionHelper.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/FunctionHelper.java index 00adec235..43e88bde5 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/FunctionHelper.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/FunctionHelper.java @@ -1,67 +1,68 @@ package moe.mickey.minecraft.skin.fx; +import javafx.event.Event; +import javafx.event.EventHandler; + import java.util.Arrays; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; -import javafx.event.Event; -import javafx.event.EventHandler; - public final class FunctionHelper { - private FunctionHelper() { - } - @SafeVarargs - public static void always(Consumer consumer, T... ts) { - Arrays.asList(ts).forEach(consumer); - } + private FunctionHelper() { + } - @SafeVarargs - public static void alwaysA(BiConsumer consumer, A a, B... bs) { - Arrays.asList(bs).forEach(b -> consumer.accept(a, b)); - } + @SafeVarargs + public static void always(Consumer consumer, T... ts) { + Arrays.asList(ts).forEach(consumer); + } - @SafeVarargs - public static void alwaysB(BiConsumer consumer, B b, A... as) { - Arrays.asList(as).forEach(a -> consumer.accept(a, b)); - } + @SafeVarargs + public static void alwaysA(BiConsumer consumer, A a, B... bs) { + Arrays.asList(bs).forEach(b -> consumer.accept(a, b)); + } - public static BiConsumer exchange(BiConsumer consumer) { - return (b, a) -> consumer.accept(a, b); - } + @SafeVarargs + public static void alwaysB(BiConsumer consumer, B b, A... as) { + Arrays.asList(as).forEach(a -> consumer.accept(a, b)); + } - @SafeVarargs - public static Consumer link(Consumer... consumers) { - return t -> { - for (Consumer consumer : consumers) - consumer.accept(t); - }; - } + public static BiConsumer exchange(BiConsumer consumer) { + return (b, a) -> consumer.accept(a, b); + } - @SafeVarargs - public static EventHandler link(EventHandler... handlers) { - return t -> { - for (EventHandler handler : handlers) - handler.handle(t); - }; - } + @SafeVarargs + public static Consumer link(Consumer... consumers) { + return t -> { + for (Consumer consumer : consumers) + consumer.accept(t); + }; + } - public static Consumer link1(Function function, Consumer consumer) { - return a -> consumer.accept(function.apply(a)); - } + @SafeVarargs + public static EventHandler link(EventHandler... handlers) { + return t -> { + for (EventHandler handler : handlers) + handler.handle(t); + }; + } - public static BiConsumer link2(Function function, BiConsumer consumer) { - return (a, c) -> consumer.accept(function.apply(a), c); - } + public static Consumer link1(Function function, Consumer consumer) { + return a -> consumer.accept(function.apply(a)); + } - public static Consumer link2(Supplier supplier, BiConsumer consumer) { - return b -> consumer.accept(supplier.get(), b); - } + public static BiConsumer link2(Function function, BiConsumer consumer) { + return (a, c) -> consumer.accept(function.apply(a), c); + } - public static Supplier link1(Supplier supplier, Function function) { - return () -> function.apply(supplier.get()); - } + public static Consumer link2(Supplier supplier, BiConsumer consumer) { + return b -> consumer.accept(supplier.get(), b); + } + + public static Supplier link1(Supplier supplier, Function function) { + return () -> function.apply(supplier.get()); + } } diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinAnimation.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinAnimation.java index d160feca9..2899b0ea0 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinAnimation.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinAnimation.java @@ -1,58 +1,58 @@ package moe.mickey.minecraft.skin.fx; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; + import java.util.Arrays; import java.util.LinkedList; import java.util.List; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; - public class SkinAnimation { - - protected int weight, left; - protected List transitions; - - @Deprecated - public SkinAnimation() { - this.transitions = new LinkedList<>(); - } - - public SkinAnimation(int weight, SkinTransition... transitions) { - this.weight = weight; - this.transitions = Arrays.asList(transitions); - init(); - } - - protected void init() { - transitions.forEach(t -> { - EventHandler oldHandler = t.getOnFinished(); - EventHandler newHandler = e -> left--; - newHandler = oldHandler == null ? newHandler : FunctionHelper.link(oldHandler, newHandler); - t.setOnFinished(newHandler); - }); - } - - public int getWeight() { - return weight; - } - - public boolean isPlaying() { - return left > 0; - } - - public void play() { - transitions.forEach(SkinTransition::play); - left = transitions.size(); - } - - public void playFromStart() { - transitions.forEach(SkinTransition::playFromStart); - left = transitions.size(); - } - - public void stop() { - transitions.forEach(SkinTransition::stop); - left = 0; - } + + protected int weight, left; + protected List transitions; + + @Deprecated + public SkinAnimation() { + this.transitions = new LinkedList<>(); + } + + public SkinAnimation(int weight, SkinTransition... transitions) { + this.weight = weight; + this.transitions = Arrays.asList(transitions); + init(); + } + + protected void init() { + transitions.forEach(t -> { + EventHandler oldHandler = t.getOnFinished(); + EventHandler newHandler = e -> left--; + newHandler = oldHandler == null ? newHandler : FunctionHelper.link(oldHandler, newHandler); + t.setOnFinished(newHandler); + }); + } + + public int getWeight() { + return weight; + } + + public boolean isPlaying() { + return left > 0; + } + + public void play() { + transitions.forEach(SkinTransition::play); + left = transitions.size(); + } + + public void playFromStart() { + transitions.forEach(SkinTransition::playFromStart); + left = transitions.size(); + } + + public void stop() { + transitions.forEach(SkinTransition::stop); + left = 0; + } } diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinAnimationPlayer.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinAnimationPlayer.java index aa37d16af..a17d17f1d 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinAnimationPlayer.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinAnimationPlayer.java @@ -1,93 +1,93 @@ package moe.mickey.minecraft.skin.fx; +import javafx.animation.AnimationTimer; + import java.util.Arrays; import java.util.LinkedList; import java.util.Random; -import javafx.animation.AnimationTimer; - public class SkinAnimationPlayer { - - protected final Random random = new Random(); - protected LinkedList animations = new LinkedList<>(); - protected SkinAnimation playing; - protected boolean running; - protected int weightedSum = 0; - protected long lastPlayTime = -1L, interval = 10_000_000_000L; - protected AnimationTimer animationTimer = new AnimationTimer() { - @Override - public void handle(long now) { - if (playing == null || !playing.isPlaying() && now - lastPlayTime > interval) { - int nextAni = random.nextInt(weightedSum); - SkinAnimation tmp = null; - for (SkinAnimation animation : animations) { - nextAni -= animation.getWeight(); - tmp = animation; - if (nextAni <= 0) - break; - } - playing = tmp; - if (playing == null && animations.size() > 0) - playing = animations.getLast(); - if (playing != null) { - playing.playFromStart(); - lastPlayTime = now; - } - } - } - }; - - public int getWeightedSum() { - return weightedSum; - } - - public void setInterval(long interval) { - this.interval = interval; - if (interval <1) - animationTimer.stop(); - else - start(); - } - - public long getInterval() { - return interval; - } - - public long getLastPlayTime() { - return lastPlayTime; - } - - public boolean isRunning() { - return running; - } - - public boolean isPlaying() { - return playing != null; - } - - public SkinAnimation getPlaying() { - return playing; - } - - public void addSkinAnimation(SkinAnimation... animations) { - this.animations.addAll(Arrays.asList(animations)); - this.weightedSum = this.animations.stream().mapToInt(SkinAnimation::getWeight).sum(); - start(); - } - - public void start() { - if (!running && weightedSum > 0 && interval > 0) { - animationTimer.start(); - running = true; - } - } - - public void stop() { - if (running) - animationTimer.stop(); - if (playing != null) - playing.stop(); - running = false; - } + + protected final Random random = new Random(); + protected LinkedList animations = new LinkedList<>(); + protected SkinAnimation playing; + protected boolean running; + protected int weightedSum = 0; + protected long lastPlayTime = -1L, interval = 10_000_000_000L; + protected AnimationTimer animationTimer = new AnimationTimer() { + @Override + public void handle(long now) { + if (playing == null || !playing.isPlaying() && now - lastPlayTime > interval) { + int nextAni = random.nextInt(weightedSum); + SkinAnimation tmp = null; + for (SkinAnimation animation : animations) { + nextAni -= animation.getWeight(); + tmp = animation; + if (nextAni <= 0) + break; + } + playing = tmp; + if (playing == null && animations.size() > 0) + playing = animations.getLast(); + if (playing != null) { + playing.playFromStart(); + lastPlayTime = now; + } + } + } + }; + + public int getWeightedSum() { + return weightedSum; + } + + public void setInterval(long interval) { + this.interval = interval; + if (interval < 1) + animationTimer.stop(); + else + start(); + } + + public long getInterval() { + return interval; + } + + public long getLastPlayTime() { + return lastPlayTime; + } + + public boolean isRunning() { + return running; + } + + public boolean isPlaying() { + return playing != null; + } + + public SkinAnimation getPlaying() { + return playing; + } + + public void addSkinAnimation(SkinAnimation... animations) { + this.animations.addAll(Arrays.asList(animations)); + this.weightedSum = this.animations.stream().mapToInt(SkinAnimation::getWeight).sum(); + start(); + } + + public void start() { + if (!running && weightedSum > 0 && interval > 0) { + animationTimer.start(); + running = true; + } + } + + public void stop() { + if (running) + animationTimer.stop(); + if (playing != null) + playing.stop(); + running = false; + } } diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinCanvas.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinCanvas.java index 759c32a2b..ce6fd7bdd 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinCanvas.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinCanvas.java @@ -12,246 +12,244 @@ import javafx.scene.transform.Scale; import javafx.scene.transform.Translate; public class SkinCanvas extends Group { - - public static final Image ALEX = new Image(SkinCanvas.class.getResourceAsStream("/assets/img/alex.png")); - public static final Image STEVE = new Image(SkinCanvas.class.getResourceAsStream("/assets/img//steve.png")); - - public static final SkinCube ALEX_LARM = new SkinCube(3, 12, 4, 14F / 64F, 16F / 64F, 32F / 64F, 48F / 64F, 0F, true); - public static final SkinCube ALEX_RARM = new SkinCube(3, 12, 4, 14F / 64F, 16F / 64F, 40F / 64F, 16F / 64F, 0F, true); - - public static final SkinCube STEVEN_LARM = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 32F / 64F, 48F / 64F, 0F, false); - public static final SkinCube STEVEN_RARM = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 40F / 64F, 16F / 64F, 0F, false); - - protected Image srcSkin, skin; - protected boolean isSlim; - - protected double preW, preH; - protected boolean msaa; - - protected SubScene subScene; - protected Group root = new Group(); - - public final SkinMultipleCubes headOuter = new SkinMultipleCubes(8, 8, 8, 32F / 64F, 0F, 1.125, 0.2); - public final SkinMultipleCubes bodyOuter = new SkinMultipleCubes(8, 12, 4, 16F / 64F, 32F / 64F, 1, 0.2); - public final SkinMultipleCubes larmOuter = new SkinMultipleCubes(4, 12, 4, 48F / 64F, 48F / 64F, 1.0625, 0.2); - public final SkinMultipleCubes rarmOuter = new SkinMultipleCubes(4, 12, 4, 40F / 64F, 32F / 64F, 1.0625, 0.2); - public final SkinMultipleCubes llegOuter = new SkinMultipleCubes(4, 12, 4, 0F / 64F, 48F / 64F, 1.0625, 0.2); - public final SkinMultipleCubes rlegOuter = new SkinMultipleCubes(4, 12, 4, 0F / 64F, 32F / 64F, 1.0625, 0.2); - - public final SkinCube headInside = new SkinCube(8, 8, 8, 32F / 64F, 16F / 64F, 0F, 0F, 0F, false); - public final SkinCube bodyInside = new SkinCube(8, 12, 4, 24F / 64F, 16F / 64F, 16F / 64F, 16F / 64F, 0.03F, false); - public final SkinCube larmInside = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 32F / 64F, 48F / 64F, 0F, false); - public final SkinCube rarmInside = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 40F / 64F, 16F / 64F, 0F, false); - public final SkinCube llegInside = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 16F / 64F, 48F / 64F, 0F, false); - public final SkinCube rlegInside = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 0F, 16F / 64F, 0F, false); - - public final SkinGroup head = new SkinGroup( - new Rotate(0, 0, headInside.getHeight() / 2, 0, Rotate.X_AXIS), - new Rotate(0, Rotate.Y_AXIS), - new Rotate(0, 0, headInside.getHeight() / 2, 0, Rotate.Z_AXIS), - headOuter, headInside - ); - public final SkinGroup body = new SkinGroup( - new Rotate(0, Rotate.X_AXIS), - new Rotate(0, Rotate.Y_AXIS), - new Rotate(0, Rotate.Z_AXIS), - bodyOuter, bodyInside - ); - public final SkinGroup larm = new SkinGroup( - new Rotate(0, 0, -larmInside.getHeight() / 2, 0, Rotate.X_AXIS), - new Rotate(0, Rotate.Y_AXIS), - new Rotate(0, +larmInside.getWidth() / 2, -larmInside.getHeight() / 2, 0, Rotate.Z_AXIS), - larmOuter, larmInside - ); - public final SkinGroup rarm = new SkinGroup( - new Rotate(0, 0, -rarmInside.getHeight() / 2, 0, Rotate.X_AXIS), - new Rotate(0, Rotate.Y_AXIS), - new Rotate(0, -rarmInside.getWidth() / 2, -rarmInside.getHeight() / 2, 0, Rotate.Z_AXIS), - rarmOuter, rarmInside - ); - public final SkinGroup lleg = new SkinGroup( - new Rotate(0, 0, -llegInside.getHeight() / 2, 0, Rotate.X_AXIS), - new Rotate(0, Rotate.Y_AXIS), - new Rotate(0, 0, -llegInside.getHeight() / 2, 0, Rotate.Z_AXIS), - llegOuter, llegInside - ); - public final SkinGroup rleg = new SkinGroup( - new Rotate(0, 0, -rlegInside.getHeight() / 2, 0, Rotate.X_AXIS), - new Rotate(0, Rotate.Y_AXIS), - new Rotate(0, 0, -rlegInside.getHeight() / 2, 0, Rotate.Z_AXIS), - rlegOuter, rlegInside - ); - - protected PerspectiveCamera camera = new PerspectiveCamera(true); - - protected Rotate xRotate = new Rotate(0, Rotate.X_AXIS); - protected Rotate yRotate = new Rotate(180, Rotate.Y_AXIS); - protected Rotate zRotate = new Rotate(0, Rotate.Z_AXIS); - protected Translate translate = new Translate(0, 0, -80); - protected Scale scale = new Scale(1, 1); - - protected SkinAnimationPlayer animationplayer = new SkinAnimationPlayer(); - - public SkinAnimationPlayer getAnimationplayer() { - return animationplayer; - } - - public Image getSrcSkin() { - return srcSkin; - } - - public Image getSkin() { - return skin; - } - - public void updateSkin(Image skin, boolean isSlim) { - if (SkinHelper.isNoRequest(skin) && SkinHelper.isSkin(skin)) { - this.srcSkin = skin; - this.skin = SkinHelper.x32Tox64(skin); - int multiple = Math.max((int) (1024 / skin.getWidth()), 1); - if (multiple > 1) - this.skin = SkinHelper.enlarge(this.skin, multiple); - if (this.isSlim != isSlim) - updateSkinModel(isSlim); - bindMaterial(root); - } - } - - protected void updateSkinModel(boolean isSlim) { - this.isSlim = isSlim; - FunctionHelper.alwaysB(SkinMultipleCubes::setWidth, isSlim ? 3 : 4, larmOuter, rarmOuter); - FunctionHelper.alwaysB(SkinCube::setWidth, isSlim ? 3D : 4D, larmInside, rarmInside); - - FunctionHelper.alwaysB(Node::setTranslateX, -(bodyInside.getWidth() + larmInside.getWidth()) / 2, larm); - FunctionHelper.alwaysB(Node::setTranslateX, +(bodyInside.getWidth() + rarmInside.getWidth()) / 2, rarm); - if (isSlim) { - larmInside.setModel(ALEX_LARM.getModel()); - rarmInside.setModel(ALEX_RARM.getModel()); - } else { - larmInside.setModel(STEVEN_LARM.getModel()); - rarmInside.setModel(STEVEN_RARM.getModel()); - } - - larm.getZRotate().setPivotX(-larmInside.getWidth() / 2); - rarm.getZRotate().setPivotX(+rarmInside.getWidth() / 2); - } - - public SkinCanvas(double preW, double preH) { - this(STEVE, preW, preH, true); - } - - public SkinCanvas(Image skin, double preW, double preH, boolean msaa) { - this.skin = skin; - this.preW = preW; - this.preH = preH; - this.msaa = msaa; - - init(); - } - - protected Material createMaterial() { - PhongMaterial material = new PhongMaterial(); - material.setDiffuseMap(skin); - return material; - } - - protected void bindMaterial(Group group) { - Material material = createMaterial(); - for (Node node : group.getChildren()) - if (node instanceof Shape3D) - ((Shape3D) node).setMaterial(material); - else if (node instanceof SkinMultipleCubes) - ((SkinMultipleCubes) node).updateSkin(skin); - else if (node instanceof Group) - bindMaterial((Group) node); - } - - - - protected Group createPlayerModel() { - head.setTranslateY(-(bodyInside.getHeight() + headInside.getHeight()) / 2); - - larm.setTranslateX(-(bodyInside.getWidth() + larmInside.getWidth()) / 2); - rarm.setTranslateX(+(bodyInside.getWidth() + rarmInside.getWidth()) / 2); - - lleg.setTranslateX(-(bodyInside.getWidth() - llegInside.getWidth()) / 2); - rleg.setTranslateX(+(bodyInside.getWidth() - rlegInside.getWidth()) / 2); - - lleg.setTranslateY(+(bodyInside.getHeight() + llegInside.getHeight()) / 2); - rleg.setTranslateY(+(bodyInside.getHeight() + rlegInside.getHeight()) / 2); - - root.getTransforms().addAll(xRotate); - - root.getChildren().addAll( - head, - body, - larm, - rarm, - lleg, - rleg - ); - updateSkin(skin, false); - - return root; - } - - protected SubScene createSubScene() { - Group group = new Group(); - group.getChildren().add(createPlayerModel()); - group.getTransforms().add(zRotate); - - camera.getTransforms().addAll(yRotate, translate, scale); - - subScene = new SubScene(group, preW, preH, true, - msaa ? SceneAntialiasing.BALANCED : SceneAntialiasing.DISABLED); + + public static final Image ALEX = new Image(SkinCanvas.class.getResourceAsStream("/assets/img/alex.png")); + public static final Image STEVE = new Image(SkinCanvas.class.getResourceAsStream("/assets/img//steve.png")); + + public static final SkinCube ALEX_LARM = new SkinCube(3, 12, 4, 14F / 64F, 16F / 64F, 32F / 64F, 48F / 64F, 0F, true); + public static final SkinCube ALEX_RARM = new SkinCube(3, 12, 4, 14F / 64F, 16F / 64F, 40F / 64F, 16F / 64F, 0F, true); + + public static final SkinCube STEVEN_LARM = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 32F / 64F, 48F / 64F, 0F, false); + public static final SkinCube STEVEN_RARM = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 40F / 64F, 16F / 64F, 0F, false); + + protected Image srcSkin, skin; + protected boolean isSlim; + + protected double preW, preH; + protected boolean msaa; + + protected SubScene subScene; + protected Group root = new Group(); + + public final SkinMultipleCubes headOuter = new SkinMultipleCubes(8, 8, 8, 32F / 64F, 0F, 1.125, 0.2); + public final SkinMultipleCubes bodyOuter = new SkinMultipleCubes(8, 12, 4, 16F / 64F, 32F / 64F, 1, 0.2); + public final SkinMultipleCubes larmOuter = new SkinMultipleCubes(4, 12, 4, 48F / 64F, 48F / 64F, 1.0625, 0.2); + public final SkinMultipleCubes rarmOuter = new SkinMultipleCubes(4, 12, 4, 40F / 64F, 32F / 64F, 1.0625, 0.2); + public final SkinMultipleCubes llegOuter = new SkinMultipleCubes(4, 12, 4, 0F / 64F, 48F / 64F, 1.0625, 0.2); + public final SkinMultipleCubes rlegOuter = new SkinMultipleCubes(4, 12, 4, 0F / 64F, 32F / 64F, 1.0625, 0.2); + + public final SkinCube headInside = new SkinCube(8, 8, 8, 32F / 64F, 16F / 64F, 0F, 0F, 0F, false); + public final SkinCube bodyInside = new SkinCube(8, 12, 4, 24F / 64F, 16F / 64F, 16F / 64F, 16F / 64F, 0.03F, false); + public final SkinCube larmInside = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 32F / 64F, 48F / 64F, 0F, false); + public final SkinCube rarmInside = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 40F / 64F, 16F / 64F, 0F, false); + public final SkinCube llegInside = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 16F / 64F, 48F / 64F, 0F, false); + public final SkinCube rlegInside = new SkinCube(4, 12, 4, 16F / 64F, 16F / 64F, 0F, 16F / 64F, 0F, false); + + public final SkinGroup head = new SkinGroup( + new Rotate(0, 0, headInside.getHeight() / 2, 0, Rotate.X_AXIS), + new Rotate(0, Rotate.Y_AXIS), + new Rotate(0, 0, headInside.getHeight() / 2, 0, Rotate.Z_AXIS), + headOuter, headInside + ); + public final SkinGroup body = new SkinGroup( + new Rotate(0, Rotate.X_AXIS), + new Rotate(0, Rotate.Y_AXIS), + new Rotate(0, Rotate.Z_AXIS), + bodyOuter, bodyInside + ); + public final SkinGroup larm = new SkinGroup( + new Rotate(0, 0, -larmInside.getHeight() / 2, 0, Rotate.X_AXIS), + new Rotate(0, Rotate.Y_AXIS), + new Rotate(0, +larmInside.getWidth() / 2, -larmInside.getHeight() / 2, 0, Rotate.Z_AXIS), + larmOuter, larmInside + ); + public final SkinGroup rarm = new SkinGroup( + new Rotate(0, 0, -rarmInside.getHeight() / 2, 0, Rotate.X_AXIS), + new Rotate(0, Rotate.Y_AXIS), + new Rotate(0, -rarmInside.getWidth() / 2, -rarmInside.getHeight() / 2, 0, Rotate.Z_AXIS), + rarmOuter, rarmInside + ); + public final SkinGroup lleg = new SkinGroup( + new Rotate(0, 0, -llegInside.getHeight() / 2, 0, Rotate.X_AXIS), + new Rotate(0, Rotate.Y_AXIS), + new Rotate(0, 0, -llegInside.getHeight() / 2, 0, Rotate.Z_AXIS), + llegOuter, llegInside + ); + public final SkinGroup rleg = new SkinGroup( + new Rotate(0, 0, -rlegInside.getHeight() / 2, 0, Rotate.X_AXIS), + new Rotate(0, Rotate.Y_AXIS), + new Rotate(0, 0, -rlegInside.getHeight() / 2, 0, Rotate.Z_AXIS), + rlegOuter, rlegInside + ); + + protected PerspectiveCamera camera = new PerspectiveCamera(true); + + protected Rotate xRotate = new Rotate(0, Rotate.X_AXIS); + protected Rotate yRotate = new Rotate(180, Rotate.Y_AXIS); + protected Rotate zRotate = new Rotate(0, Rotate.Z_AXIS); + protected Translate translate = new Translate(0, 0, -80); + protected Scale scale = new Scale(1, 1); + + protected SkinAnimationPlayer animationplayer = new SkinAnimationPlayer(); + + public SkinAnimationPlayer getAnimationplayer() { + return animationplayer; + } + + public Image getSrcSkin() { + return srcSkin; + } + + public Image getSkin() { + return skin; + } + + public void updateSkin(Image skin, boolean isSlim) { + if (SkinHelper.isNoRequest(skin) && SkinHelper.isSkin(skin)) { + this.srcSkin = skin; + this.skin = SkinHelper.x32Tox64(skin); + int multiple = Math.max((int) (1024 / skin.getWidth()), 1); + if (multiple > 1) + this.skin = SkinHelper.enlarge(this.skin, multiple); + if (this.isSlim != isSlim) + updateSkinModel(isSlim); + bindMaterial(root); + } + } + + protected void updateSkinModel(boolean isSlim) { + this.isSlim = isSlim; + FunctionHelper.alwaysB(SkinMultipleCubes::setWidth, isSlim ? 3 : 4, larmOuter, rarmOuter); + FunctionHelper.alwaysB(SkinCube::setWidth, isSlim ? 3D : 4D, larmInside, rarmInside); + + FunctionHelper.alwaysB(Node::setTranslateX, -(bodyInside.getWidth() + larmInside.getWidth()) / 2, larm); + FunctionHelper.alwaysB(Node::setTranslateX, +(bodyInside.getWidth() + rarmInside.getWidth()) / 2, rarm); + if (isSlim) { + larmInside.setModel(ALEX_LARM.getModel()); + rarmInside.setModel(ALEX_RARM.getModel()); + } else { + larmInside.setModel(STEVEN_LARM.getModel()); + rarmInside.setModel(STEVEN_RARM.getModel()); + } + + larm.getZRotate().setPivotX(-larmInside.getWidth() / 2); + rarm.getZRotate().setPivotX(+rarmInside.getWidth() / 2); + } + + public SkinCanvas(double preW, double preH) { + this(STEVE, preW, preH, true); + } + + public SkinCanvas(Image skin, double preW, double preH, boolean msaa) { + this.skin = skin; + this.preW = preW; + this.preH = preH; + this.msaa = msaa; + + init(); + } + + protected Material createMaterial() { + PhongMaterial material = new PhongMaterial(); + material.setDiffuseMap(skin); + return material; + } + + protected void bindMaterial(Group group) { + Material material = createMaterial(); + for (Node node : group.getChildren()) + if (node instanceof Shape3D) + ((Shape3D) node).setMaterial(material); + else if (node instanceof SkinMultipleCubes) + ((SkinMultipleCubes) node).updateSkin(skin); + else if (node instanceof Group) + bindMaterial((Group) node); + } + + protected Group createPlayerModel() { + head.setTranslateY(-(bodyInside.getHeight() + headInside.getHeight()) / 2); + + larm.setTranslateX(-(bodyInside.getWidth() + larmInside.getWidth()) / 2); + rarm.setTranslateX(+(bodyInside.getWidth() + rarmInside.getWidth()) / 2); + + lleg.setTranslateX(-(bodyInside.getWidth() - llegInside.getWidth()) / 2); + rleg.setTranslateX(+(bodyInside.getWidth() - rlegInside.getWidth()) / 2); + + lleg.setTranslateY(+(bodyInside.getHeight() + llegInside.getHeight()) / 2); + rleg.setTranslateY(+(bodyInside.getHeight() + rlegInside.getHeight()) / 2); + + root.getTransforms().addAll(xRotate); + + root.getChildren().addAll( + head, + body, + larm, + rarm, + lleg, + rleg + ); + updateSkin(skin, false); + + return root; + } + + protected SubScene createSubScene() { + Group group = new Group(); + group.getChildren().add(createPlayerModel()); + group.getTransforms().add(zRotate); + + camera.getTransforms().addAll(yRotate, translate, scale); + + subScene = new SubScene(group, preW, preH, true, + msaa ? SceneAntialiasing.BALANCED : SceneAntialiasing.DISABLED); subScene.setCamera(camera); - + return subScene; - } - - protected void init() { - getChildren().add(createSubScene()); - } + } + + protected void init() { + getChildren().add(createSubScene()); + } private double lastX, lastY; - public void enableRotation(double sensitivity) { - addEventHandler(MouseEvent.MOUSE_PRESSED, e -> { - lastX = -1; - lastY = -1; - }); - addEventHandler(MouseEvent.MOUSE_DRAGGED, e -> { - if (!(lastX == -1 || lastY == -1)) { - if (e.isAltDown() || e.isControlDown() || e.isShiftDown()) { - if (e.isShiftDown()) - zRotate.setAngle(zRotate.getAngle() - (e.getSceneY() - lastY) * sensitivity); - if (e.isAltDown()) - yRotate.setAngle(yRotate.getAngle() + (e.getSceneX() - lastX) * sensitivity); - if (e.isControlDown()) - xRotate.setAngle(xRotate.getAngle() + (e.getSceneY() - lastY) * sensitivity); - } else { - double yaw = yRotate.getAngle() + (e.getSceneX() - lastX) * sensitivity; - yaw %= 360; - if (yaw < 0) - yaw += 360; + public void enableRotation(double sensitivity) { + addEventHandler(MouseEvent.MOUSE_PRESSED, e -> { + lastX = -1; + lastY = -1; + }); + addEventHandler(MouseEvent.MOUSE_DRAGGED, e -> { + if (!(lastX == -1 || lastY == -1)) { + if (e.isAltDown() || e.isControlDown() || e.isShiftDown()) { + if (e.isShiftDown()) + zRotate.setAngle(zRotate.getAngle() - (e.getSceneY() - lastY) * sensitivity); + if (e.isAltDown()) + yRotate.setAngle(yRotate.getAngle() + (e.getSceneX() - lastX) * sensitivity); + if (e.isControlDown()) + xRotate.setAngle(xRotate.getAngle() + (e.getSceneY() - lastY) * sensitivity); + } else { + double yaw = yRotate.getAngle() + (e.getSceneX() - lastX) * sensitivity; + yaw %= 360; + if (yaw < 0) + yaw += 360; - int flagX = yaw < 90 || yaw > 270 ? 1 : -1; - int flagZ = yaw < 180 ? -1 : 1; - double kx = Math.abs(90 - yaw % 180) / 90 * flagX, kz = Math.abs(90 - (yaw + 90) % 180) / 90 * flagZ; + int flagX = yaw < 90 || yaw > 270 ? 1 : -1; + int flagZ = yaw < 180 ? -1 : 1; + double kx = Math.abs(90 - yaw % 180) / 90 * flagX, kz = Math.abs(90 - (yaw + 90) % 180) / 90 * flagZ; - xRotate.setAngle(xRotate.getAngle() + (e.getSceneY() - lastY) * sensitivity * kx); - yRotate.setAngle(yaw); - zRotate.setAngle(zRotate.getAngle() + (e.getSceneY() - lastY) * sensitivity * kz); - } - } - lastX = e.getSceneX(); - lastY = e.getSceneY(); - }); - addEventHandler(ScrollEvent.SCROLL, e -> { - double delta = (e.getDeltaY() > 0 ? 1 : e.getDeltaY() == 0 ? 0 : -1) / 10D * sensitivity; - scale.setX(Math.min(Math.max(scale.getX() - delta, 0.1), 10)); - scale.setY(Math.min(Math.max(scale.getY() - delta, 0.1), 10)); - }); - } + xRotate.setAngle(xRotate.getAngle() + (e.getSceneY() - lastY) * sensitivity * kx); + yRotate.setAngle(yaw); + zRotate.setAngle(zRotate.getAngle() + (e.getSceneY() - lastY) * sensitivity * kz); + } + } + lastX = e.getSceneX(); + lastY = e.getSceneY(); + }); + addEventHandler(ScrollEvent.SCROLL, e -> { + double delta = (e.getDeltaY() > 0 ? 1 : e.getDeltaY() == 0 ? 0 : -1) / 10D * sensitivity; + scale.setX(Math.min(Math.max(scale.getX() - delta, 0.1), 10)); + scale.setY(Math.min(Math.max(scale.getY() - delta, 0.1), 10)); + }); + } } diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinCube.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinCube.java index 40980cae8..8570a0428 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinCube.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinCube.java @@ -8,135 +8,135 @@ import org.jackhuang.hmcl.util.ArrayUtils; public class SkinCube extends MeshView { - public static class Model extends TriangleMesh { + public static class Model extends TriangleMesh { - public Model(float width, float height, float depth, float scaleX, float scaleY, float startX, float startY, boolean isSlim) { - getPoints().addAll(createPoints(width, height, depth)); - getTexCoords().addAll(createTexCoords(width, height, depth, scaleX, scaleY, startX, startY, isSlim)); - getFaces().addAll(createFaces()); - } + public Model(float width, float height, float depth, float scaleX, float scaleY, float startX, float startY, boolean isSlim) { + getPoints().addAll(createPoints(width, height, depth)); + getTexCoords().addAll(createTexCoords(width, height, depth, scaleX, scaleY, startX, startY, isSlim)); + getFaces().addAll(createFaces()); + } - public static float[] createPoints(float width, float height, float depth) { - width /= 2F; - height /= 2F; - depth /= 2F; + public static float[] createPoints(float width, float height, float depth) { + width /= 2F; + height /= 2F; + depth /= 2F; - return new float[]{ - -width, -height, depth, // P0 - width, -height, depth, // P1 - -width, height, depth, // P2 - width, height, depth, // P3 - -width, -height, -depth, // P4 - width, -height, -depth, // P5 - -width, height, -depth, // P6 - width, height, -depth // P7 - }; - } + return new float[]{ + -width, -height, depth, // P0 + width, -height, depth, // P1 + -width, height, depth, // P2 + width, height, depth, // P3 + -width, -height, -depth, // P4 + width, -height, -depth, // P5 + -width, height, -depth, // P6 + width, height, -depth // P7 + }; + } - public static float[] createTexCoords(float width, float height, float depth, float scaleX, float scaleY, - float startX, float startY, boolean isSlim) { - float x = (width + depth) * 2, y = height + depth, half_width = width / x * scaleX, half_depth = depth / x * scaleX, - top_x = depth / x * scaleX + startX, top_y = startY, arm4 = isSlim ? half_depth : half_width, - bottom_x = startX, middle_y = depth / y * scaleY + top_y, bottom_y = scaleY + top_y; - return new float[]{ - top_x, top_y, // T0 --- - top_x + half_width, top_y, // T1 | - top_x + half_width * 2, top_y, // T2 --- - bottom_x, middle_y, // T3 --- - bottom_x + half_depth, middle_y, // T4 | - bottom_x + half_depth + half_width, middle_y, // T5 | - bottom_x + scaleX - arm4, middle_y, // T6 | - bottom_x + scaleX, middle_y, // T7 --- - bottom_x, bottom_y, // T8 --- - bottom_x + half_depth, bottom_y, // T9 | - bottom_x + half_depth + half_width, bottom_y, // T10 | - bottom_x + scaleX - arm4, bottom_y, // T11 | - bottom_x + scaleX, bottom_y // T12 --- - }; - } + public static float[] createTexCoords(float width, float height, float depth, float scaleX, float scaleY, + float startX, float startY, boolean isSlim) { + float x = (width + depth) * 2, y = height + depth, half_width = width / x * scaleX, half_depth = depth / x * scaleX, + top_x = depth / x * scaleX + startX, top_y = startY, arm4 = isSlim ? half_depth : half_width, + bottom_x = startX, middle_y = depth / y * scaleY + top_y, bottom_y = scaleY + top_y; + return new float[]{ + top_x, top_y, // T0 --- + top_x + half_width, top_y, // T1 | + top_x + half_width * 2, top_y, // T2 --- + bottom_x, middle_y, // T3 --- + bottom_x + half_depth, middle_y, // T4 | + bottom_x + half_depth + half_width, middle_y, // T5 | + bottom_x + scaleX - arm4, middle_y, // T6 | + bottom_x + scaleX, middle_y, // T7 --- + bottom_x, bottom_y, // T8 --- + bottom_x + half_depth, bottom_y, // T9 | + bottom_x + half_depth + half_width, bottom_y, // T10 | + bottom_x + scaleX - arm4, bottom_y, // T11 | + bottom_x + scaleX, bottom_y // T12 --- + }; + } - public static int[] createFaces() { - int faces[] = new int[]{ - // TOP - 5, 0, 4, 1, 0, 5, //P5,T0, P4,T1, P0,T5 - 5, 0, 0, 5, 1, 4, //P5,T0, P0,T5, P1,T4 - // RIGHT - 0, 5, 4, 6, 6, 11, //P0,T4 ,P4,T3, P6,T8 - 0, 5, 6, 11, 2, 10, //P0,T4 ,P6,T8, P2,T9 - // FRONT - 1, 4, 0, 5, 2, 10, //P1,T5, P0,T4, P2,T9 - 1, 4, 2, 10, 3, 9, //P1,T5, P2,T9, P3,T10 - // LEFT - 5, 3, 1, 4, 3, 9, //P5,T6, P1,T5, P3,T10 - 5, 3, 3, 9, 7, 8, //P5,T6, P3,T10,P7,T11 - // BACK - 4, 6, 5, 7, 7, 12, //P4,T6, P5,T7, P7,T12 - 4, 6, 7, 12, 6, 11, //P4,T6, P7,T12,P6,T11 - // BOTTOM - 3, 5, 2, 6, 6, 2, //P3,T2, P2,T1, P6,T5 - 3, 5, 6, 2, 7, 1 //P3,T2, P6,T5, P7,T6 - }; + public static int[] createFaces() { + int[] faces = new int[]{ + // TOP + 5, 0, 4, 1, 0, 5, //P5,T0, P4,T1, P0,T5 + 5, 0, 0, 5, 1, 4, //P5,T0, P0,T5, P1,T4 + // RIGHT + 0, 5, 4, 6, 6, 11, //P0,T4 ,P4,T3, P6,T8 + 0, 5, 6, 11, 2, 10, //P0,T4 ,P6,T8, P2,T9 + // FRONT + 1, 4, 0, 5, 2, 10, //P1,T5, P0,T4, P2,T9 + 1, 4, 2, 10, 3, 9, //P1,T5, P2,T9, P3,T10 + // LEFT + 5, 3, 1, 4, 3, 9, //P5,T6, P1,T5, P3,T10 + 5, 3, 3, 9, 7, 8, //P5,T6, P3,T10,P7,T11 + // BACK + 4, 6, 5, 7, 7, 12, //P4,T6, P5,T7, P7,T12 + 4, 6, 7, 12, 6, 11, //P4,T6, P7,T12,P6,T11 + // BOTTOM + 3, 5, 2, 6, 6, 2, //P3,T2, P2,T1, P6,T5 + 3, 5, 6, 2, 7, 1 //P3,T2, P6,T5, P7,T6 + }; - int[] copy = faces.clone(); - ArrayUtils.reverse(copy); - for (int i = 0; i < copy.length; i += 2) { - int tmp = copy[i]; - copy[i] = copy[i + 1]; - copy[i + 1] = tmp; - } - return ArrayUtils.addAll(faces, copy); - } + int[] copy = faces.clone(); + ArrayUtils.reverse(copy); + for (int i = 0; i < copy.length; i += 2) { + int tmp = copy[i]; + copy[i] = copy[i + 1]; + copy[i + 1] = tmp; + } + return ArrayUtils.addAll(faces, copy); + } - } + } - private double width, height, depth; - private boolean isSlim; - private Image skin; - private Mesh model; + private double width, height, depth; + private boolean isSlim; + private Image skin; + private Mesh model; - public SkinCube(float width, float height, float depth, float scaleX, float scaleY, float startX, float startY, float enlarge, boolean isSlim) { - this.width = width; - this.height = height; - this.depth = depth; - this.isSlim = isSlim; - setMesh(model = new Model(width + enlarge, height + enlarge, depth + enlarge, scaleX, scaleY, startX, startY, isSlim)); - } + public SkinCube(float width, float height, float depth, float scaleX, float scaleY, float startX, float startY, float enlarge, boolean isSlim) { + this.width = width; + this.height = height; + this.depth = depth; + this.isSlim = isSlim; + setMesh(model = new Model(width + enlarge, height + enlarge, depth + enlarge, scaleX, scaleY, startX, startY, isSlim)); + } - public void setWidth(double width) { - this.width = width; - } + public void setWidth(double width) { + this.width = width; + } - public double getWidth() { - return width; - } + public double getWidth() { + return width; + } - public void setHeight(double height) { - this.height = height; - } + public void setHeight(double height) { + this.height = height; + } - public double getHeight() { - return height; - } + public double getHeight() { + return height; + } - public void setDepth(double depth) { - this.depth = depth; - } + public void setDepth(double depth) { + this.depth = depth; + } - public double getDepth() { - return depth; - } + public double getDepth() { + return depth; + } - public boolean isSlim() { - return isSlim; - } + public boolean isSlim() { + return isSlim; + } - public Mesh getModel() { - return model; - } + public Mesh getModel() { + return model; + } - public void setModel(Mesh model) { - this.model = model; - setMesh(model); - } + public void setModel(Mesh model) { + this.model = model; + setMesh(model); + } } diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinGroup.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinGroup.java index c66712bb8..70134e85a 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinGroup.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinGroup.java @@ -5,41 +5,41 @@ import javafx.scene.Node; import javafx.scene.transform.Rotate; public class SkinGroup extends Group { - - protected Rotate xRotate, yRotate, zRotate; - - public SkinGroup(Rotate xRotate, Rotate yRotate, Rotate zRotate, Node... nodes) { - this.xRotate = xRotate; - this.yRotate = yRotate; - this.zRotate = zRotate; - Group group = new Group(); - group.getChildren().addAll(nodes); - getChildren().add(addRotate(group, xRotate, yRotate, zRotate)); - } - - protected Group addRotate(Group group, Rotate... rotates) { - for (Rotate rotate : rotates) - group = addRotate(group, rotate); - return group; - } - - protected Group addRotate(Group group, Rotate rotate) { - Group newGroup = new Group(); - group.getTransforms().add(rotate); - newGroup.getChildren().add(group); - return newGroup; - } - - public Rotate getXRotate() { - return xRotate; - } - - public Rotate getYRotate() { - return yRotate; - } - - public Rotate getZRotate() { - return zRotate; - } + + protected Rotate xRotate, yRotate, zRotate; + + public SkinGroup(Rotate xRotate, Rotate yRotate, Rotate zRotate, Node... nodes) { + this.xRotate = xRotate; + this.yRotate = yRotate; + this.zRotate = zRotate; + Group group = new Group(); + group.getChildren().addAll(nodes); + getChildren().add(addRotate(group, xRotate, yRotate, zRotate)); + } + + protected Group addRotate(Group group, Rotate... rotates) { + for (Rotate rotate : rotates) + group = addRotate(group, rotate); + return group; + } + + protected Group addRotate(Group group, Rotate rotate) { + Group newGroup = new Group(); + group.getTransforms().add(rotate); + newGroup.getChildren().add(group); + return newGroup; + } + + public Rotate getXRotate() { + return xRotate; + } + + public Rotate getYRotate() { + return yRotate; + } + + public Rotate getZRotate() { + return zRotate; + } } diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinHelper.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinHelper.java index 4f02f45f1..9f559de56 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinHelper.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinHelper.java @@ -1,138 +1,140 @@ package moe.mickey.minecraft.skin.fx; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; - -import javax.imageio.ImageIO; - import javafx.embed.swing.SwingFXUtils; import javafx.scene.image.Image; import javafx.scene.image.PixelReader; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; -public interface SkinHelper { - - public static class PixelCopyer { - - protected Image srcImage; - protected WritableImage newImage; - - public PixelCopyer(Image srcImage, WritableImage newImage) { - this.srcImage = srcImage; - this.newImage = newImage; - } - - public void copy(int srcX, int srcY, int width, int height) { - copy(srcX, srcY, srcX, srcY, width, height); - } - - public void copy(int srcX, int srcY, int toX, int toY, int width, int height) { - copy(srcX, srcY, toX, toY, width, height, false, false); - } - - public void copy(int srcX, int srcY, int toX, int toY, int width, int height, boolean reversalX, boolean reversalY) { - PixelReader reader = srcImage.getPixelReader(); - PixelWriter writer = newImage.getPixelWriter(); - for (int x = 0; x < width; x++) - for (int y = 0; y < height; y++) - writer.setArgb(toX + x, toY + y, - reader.getArgb(srcX + (reversalX ? width - x - 1 : x), srcY + (reversalY ? height - y - 1 : y))); - } - - public void copy(float srcX, float srcY, float toX, float toY, float width, float height) { - copy(srcX, srcY, toX, toY, width, height, false, false); - } - - public void copy(float srcX, float srcY, float toX, float toY, float width, float height, boolean reversalX, boolean reversalY) { - PixelReader reader = srcImage.getPixelReader(); - PixelWriter writer = newImage.getPixelWriter(); - int srcScaleX = (int) srcImage.getWidth(); - int srcScaleY = (int) srcImage.getHeight(); - int newScaleX = (int) newImage.getWidth(); - int newScaleY = (int) newImage.getHeight(); - int srcWidth = (int) (width * srcScaleX); - int srcHeight = (int) (height * srcScaleY); - - for (int x = 0; x < srcWidth; x++) - for (int y = 0; y < srcHeight; y++) - writer.setArgb((int) (toX * newScaleX + x), (int) (toY * newScaleY + y), - reader.getArgb((int) (srcX * srcScaleX + (reversalX ? srcWidth - x - 1 : x)), - (int) (srcY * srcScaleY + (reversalY ? srcHeight - y - 1 : y)))); - } +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; - } - - public static boolean isNoRequest(Image image) { - return image.getRequestedWidth() == 0 && image.getRequestedHeight() == 0; - } - - public static boolean isSkin(Image image) { - return image.getWidth() % 64 == 0 && image.getWidth() / 64 > 0 && - (image.getHeight() == image.getWidth() / 2 || image.getHeight() == image.getWidth()); - } - - public static Image x32Tox64(Image srcSkin) { - if (srcSkin.getHeight() == 64) - return srcSkin; - - WritableImage newSkin = new WritableImage((int) srcSkin.getWidth(), (int) srcSkin.getHeight() * 2); - PixelCopyer copyer = new PixelCopyer(srcSkin, newSkin); - // HEAD & HAT - copyer.copy(0 / 64F, 0 / 32F, 0 / 64F, 0 / 64F, 64 / 64F, 16 / 32F); - // LEFT-LEG - x32Tox64(copyer, 0 / 64F, 16 / 32F, 16 / 64F, 48 / 64F, 4 / 64F, 12 / 32F, 4 / 64F); - // RIGHT-LEG - copyer.copy(0 / 64F, 16 / 32F, 0 / 64F, 16 / 64F, 16 / 64F, 16 / 32F); - // BODY - copyer.copy(16 / 64F, 16 / 32F, 16 / 64F, 16 / 64F, 24 / 64F, 16 / 32F); - // LEFT-ARM - x32Tox64(copyer, 40 / 64F, 16 / 32F, 32 / 64F, 48 / 64F, 4 / 64F, 12 / 32F, 4 / 64F); - // RIGHT-ARM - copyer.copy(40 / 64F, 16 / 32F, 40 / 64F, 16 / 64F, 16 / 64F, 16 / 32F); - - return newSkin; - } - - static void x32Tox64(PixelCopyer copyer, float srcX, float srcY, float toX, float toY, float width, float height, float depth) { - // TOP - copyer.copy(srcX + depth, srcY, toX + depth, toY, width, depth * 2, true, false); - // BOTTOM - copyer.copy(srcX + depth + width, srcY, toX + depth + width, toY, width, depth * 2, true, false); - // INS - copyer.copy(srcX, srcY + depth * 2, toX + width + depth, toY + depth, depth, height, true, false); - // OUTS - copyer.copy(srcX + width + depth, srcY + depth * 2, toX, toY + depth, depth, height, true, false); - // FRONT - copyer.copy(srcX + depth, srcY + depth * 2, toX + depth, toY + depth, width, height, true, false); - // BACK - copyer.copy(srcX + width + depth * 2, srcY + depth * 2, toX + width + depth * 2, toY + depth, width, height, true, false); - } - - public static Image enlarge(Image srcSkin, int multiple) { - WritableImage newSkin = new WritableImage((int) srcSkin.getWidth() * multiple, (int) srcSkin.getHeight() * multiple); - PixelReader reader = srcSkin.getPixelReader(); - PixelWriter writer = newSkin.getPixelWriter(); - - for (int x = 0, lenX = (int) srcSkin.getWidth(); x < lenX; x++) - for (int y = 0, lenY = (int) srcSkin.getHeight(); y < lenY; y++) - for (int mx = 0; mx < multiple; mx++) - for (int my = 0; my < multiple; my++) { - int argb = reader.getArgb(x, y); - writer.setArgb(x * multiple + mx, y * multiple + my, argb); - } - - return newSkin; - } - - public static void saveToFile(Image image, File output) { - BufferedImage buffer = SwingFXUtils.fromFXImage(image, null); - try { - ImageIO.write(buffer, "png", output); - } catch (IOException e) { - throw new RuntimeException(e); - } - } +public final class SkinHelper { + + private SkinHelper() { + } + + public static class PixelCopyer { + + protected Image srcImage; + protected WritableImage newImage; + + public PixelCopyer(Image srcImage, WritableImage newImage) { + this.srcImage = srcImage; + this.newImage = newImage; + } + + public void copy(int srcX, int srcY, int width, int height) { + copy(srcX, srcY, srcX, srcY, width, height); + } + + public void copy(int srcX, int srcY, int toX, int toY, int width, int height) { + copy(srcX, srcY, toX, toY, width, height, false, false); + } + + public void copy(int srcX, int srcY, int toX, int toY, int width, int height, boolean reversalX, boolean reversalY) { + PixelReader reader = srcImage.getPixelReader(); + PixelWriter writer = newImage.getPixelWriter(); + for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) + writer.setArgb(toX + x, toY + y, + reader.getArgb(srcX + (reversalX ? width - x - 1 : x), srcY + (reversalY ? height - y - 1 : y))); + } + + public void copy(float srcX, float srcY, float toX, float toY, float width, float height) { + copy(srcX, srcY, toX, toY, width, height, false, false); + } + + public void copy(float srcX, float srcY, float toX, float toY, float width, float height, boolean reversalX, boolean reversalY) { + PixelReader reader = srcImage.getPixelReader(); + PixelWriter writer = newImage.getPixelWriter(); + int srcScaleX = (int) srcImage.getWidth(); + int srcScaleY = (int) srcImage.getHeight(); + int newScaleX = (int) newImage.getWidth(); + int newScaleY = (int) newImage.getHeight(); + int srcWidth = (int) (width * srcScaleX); + int srcHeight = (int) (height * srcScaleY); + + for (int x = 0; x < srcWidth; x++) + for (int y = 0; y < srcHeight; y++) + writer.setArgb((int) (toX * newScaleX + x), (int) (toY * newScaleY + y), + reader.getArgb((int) (srcX * srcScaleX + (reversalX ? srcWidth - x - 1 : x)), + (int) (srcY * srcScaleY + (reversalY ? srcHeight - y - 1 : y)))); + } + + } + + public static boolean isNoRequest(Image image) { + return image.getRequestedWidth() == 0 && image.getRequestedHeight() == 0; + } + + public static boolean isSkin(Image image) { + return image.getWidth() % 64 == 0 && image.getWidth() / 64 > 0 && + (image.getHeight() == image.getWidth() / 2 || image.getHeight() == image.getWidth()); + } + + public static Image x32Tox64(Image srcSkin) { + if (srcSkin.getHeight() == 64) + return srcSkin; + + WritableImage newSkin = new WritableImage((int) srcSkin.getWidth(), (int) srcSkin.getHeight() * 2); + PixelCopyer copyer = new PixelCopyer(srcSkin, newSkin); + // HEAD & HAT + copyer.copy(0 / 64F, 0 / 32F, 0 / 64F, 0 / 64F, 64 / 64F, 16 / 32F); + // LEFT-LEG + x32Tox64(copyer, 0 / 64F, 16 / 32F, 16 / 64F, 48 / 64F, 4 / 64F, 12 / 32F, 4 / 64F); + // RIGHT-LEG + copyer.copy(0 / 64F, 16 / 32F, 0 / 64F, 16 / 64F, 16 / 64F, 16 / 32F); + // BODY + copyer.copy(16 / 64F, 16 / 32F, 16 / 64F, 16 / 64F, 24 / 64F, 16 / 32F); + // LEFT-ARM + x32Tox64(copyer, 40 / 64F, 16 / 32F, 32 / 64F, 48 / 64F, 4 / 64F, 12 / 32F, 4 / 64F); + // RIGHT-ARM + copyer.copy(40 / 64F, 16 / 32F, 40 / 64F, 16 / 64F, 16 / 64F, 16 / 32F); + + return newSkin; + } + + static void x32Tox64(PixelCopyer copyer, float srcX, float srcY, float toX, float toY, float width, float height, float depth) { + // TOP + copyer.copy(srcX + depth, srcY, toX + depth, toY, width, depth * 2, true, false); + // BOTTOM + copyer.copy(srcX + depth + width, srcY, toX + depth + width, toY, width, depth * 2, true, false); + // INS + copyer.copy(srcX, srcY + depth * 2, toX + width + depth, toY + depth, depth, height, true, false); + // OUTS + copyer.copy(srcX + width + depth, srcY + depth * 2, toX, toY + depth, depth, height, true, false); + // FRONT + copyer.copy(srcX + depth, srcY + depth * 2, toX + depth, toY + depth, width, height, true, false); + // BACK + copyer.copy(srcX + width + depth * 2, srcY + depth * 2, toX + width + depth * 2, toY + depth, width, height, true, false); + } + + public static Image enlarge(Image srcSkin, int multiple) { + WritableImage newSkin = new WritableImage((int) srcSkin.getWidth() * multiple, (int) srcSkin.getHeight() * multiple); + PixelReader reader = srcSkin.getPixelReader(); + PixelWriter writer = newSkin.getPixelWriter(); + + for (int x = 0, lenX = (int) srcSkin.getWidth(); x < lenX; x++) + for (int y = 0, lenY = (int) srcSkin.getHeight(); y < lenY; y++) + for (int mx = 0; mx < multiple; mx++) + for (int my = 0; my < multiple; my++) { + int argb = reader.getArgb(x, y); + writer.setArgb(x * multiple + mx, y * multiple + my, argb); + } + + return newSkin; + } + + public static void saveToFile(Image image, File output) { + BufferedImage buffer = SwingFXUtils.fromFXImage(image, null); + try { + ImageIO.write(buffer, "png", output); + } catch (IOException e) { + throw new RuntimeException(e); + } + } } diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinMultipleCubes.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinMultipleCubes.java index fa1e7086d..c8f3f128e 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinMultipleCubes.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinMultipleCubes.java @@ -1,8 +1,5 @@ package moe.mickey.minecraft.skin.fx; -import java.util.function.BiConsumer; -import java.util.function.Supplier; - import javafx.geometry.Point2D; import javafx.scene.Group; import javafx.scene.image.Image; @@ -12,150 +9,153 @@ import javafx.scene.paint.Material; import javafx.scene.paint.PhongMaterial; import javafx.scene.shape.Box; +import java.util.function.BiConsumer; +import java.util.function.Supplier; + public class SkinMultipleCubes extends Group { - - public static class Face extends Group { - - public Face(Image image, int startX, int startY, int width, int height, int interval, boolean reverseX, boolean reverseY, - Supplier supplier, BiConsumer consumer) { - PixelReader reader = image.getPixelReader(); - for (int x = 0; x < width; x++) - for (int y = 0; y < height; y++) { - int argb; - if ((argb = reader.getArgb(startX + (reverseX ? width - x - 1 : x) * interval, - startY + (reverseY ? height - y - 1 : y) * interval)) != 0) { - Box pixel = supplier.get(); - consumer.accept(pixel, new Point2D(x, y)); - pixel.setMaterial(createMaterial(Color.rgb( - (argb >> 16) & 0xFF, (argb >> 8) & 0xFF, (argb >> 0) & 0xFF))); - getChildren().add(pixel); - } - } - } - - protected Material createMaterial(Color color) { - return new PhongMaterial(color); - } - - } - - protected int width, height, depth; - protected float startX, startY; - protected double length, thick; - - public SkinMultipleCubes(int width, int height, int depth, float startX, float startY, double length, double thick) { - this.width = width; - this.height = height; - this.depth = depth; - this.startX = startX; - this.startY = startY; - this.length = length; - this.thick = thick; - } - - public void setWidth(int width) { - this.width = width; - } - - public int getWidth() { - return width; - } - - public void setHeight(int height) { - this.height = height; - } - - public int getHeight() { - return height; - } - - public void setDepth(int depth) { - this.depth = depth; - } - - public int getDepth() { - return depth; - } - - public void setStartX(float startX) { - this.startX = startX; - } - - public float getStartX() { - return startX; - } - - public void setStartY(float startY) { - this.startY = startY; - } - - public float getStartY() { - return startY; - } - - public void setLength(double length) { - this.length = length; - } - - public double getLength() { - return length; - } - - public void setThick(double thick) { - this.thick = thick; - } - - public double getThick() { - return thick; - } - - public void updateSkin(Image skin) { - getChildren().clear(); - int start_x = (int) (startX * skin.getWidth()), start_y = (int) (startY * skin.getHeight()), - interval = (int) Math.max(skin.getWidth() / 64, 1), - width_interval = width * interval, height_interval = height * interval, depth_interval = depth * interval; - // FRONT - getChildren().add(new Face(skin, start_x + depth_interval, start_y + depth_interval, width, height, interval, false, false, - () -> new Box(length, length, thick), (b, p) -> { - b.setTranslateX(((width - 1) / 2.0 - p.getX()) * b.getWidth()); - b.setTranslateY(-((height - 1) / 2.0 - p.getY()) * b.getHeight()); - b.setTranslateZ((depth * length + thick) / 2.0); - })); - // BACK - getChildren().add(new Face(skin, start_x + width_interval + depth_interval * 2, start_y + depth_interval, width, height, interval, true, false, - () -> new Box(length, length, thick), (b, p) -> { - b.setTranslateX(((width - 1) / 2.0 - p.getX()) * b.getWidth()); - b.setTranslateY(-((height - 1) / 2.0 - p.getY()) * b.getHeight()); - b.setTranslateZ(-(depth * length + thick) / 2.0); - })); - // LEFT - getChildren().add(new Face(skin, start_x + width_interval + depth_interval, start_y + depth_interval, depth, height, interval, false, false, - () -> new Box(thick, length, length), (b, p) -> { - b.setTranslateX((width * length + thick) / 2.0); - b.setTranslateY(-((height - 1) / 2.0 - p.getY()) * b.getHeight()); - b.setTranslateZ(((depth - 1) / 2.0 - p.getX()) * b.getDepth()); - })); - // RIGHT - getChildren().add(new Face(skin, start_x, start_y + depth_interval, depth, height, interval, true, false, - () -> new Box(thick, length, length), (b, p) -> { - b.setTranslateX(-(width * length + thick) / 2.0); - b.setTranslateY(-((height - 1) / 2.0 - p.getY()) * b.getHeight()); - b.setTranslateZ(((depth - 1) / 2.0 - p.getX()) * b.getDepth()); - })); - // TOP - getChildren().add(new Face(skin, start_x + depth_interval, start_y, width, depth, interval, false, false, - () -> new Box(length, thick, length), (b, p) -> { - b.setTranslateX(((width - 1) / 2.0 - p.getX()) * b.getWidth()); - b.setTranslateY(-(height * length + thick) / 2.0); - b.setTranslateZ(-((depth - 1) / 2.0 - p.getY()) * b.getDepth()); - })); - // BOTTOM - getChildren().add(new Face(skin, start_x + width_interval + depth_interval, start_y, width, depth, interval, false, false, - () -> new Box(length, thick, length), (b, p) -> { - b.setTranslateX(((width - 1) / 2.0 - p.getX()) * b.getWidth()); - b.setTranslateY((height * length + thick) / 2.0); - b.setTranslateZ(-((depth - 1) / 2.0 - p.getY()) * b.getDepth()); - })); - } - + + public static class Face extends Group { + + public Face(Image image, int startX, int startY, int width, int height, int interval, boolean reverseX, boolean reverseY, + Supplier supplier, BiConsumer consumer) { + PixelReader reader = image.getPixelReader(); + for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) { + int argb; + if ((argb = reader.getArgb(startX + (reverseX ? width - x - 1 : x) * interval, + startY + (reverseY ? height - y - 1 : y) * interval)) != 0) { + Box pixel = supplier.get(); + consumer.accept(pixel, new Point2D(x, y)); + pixel.setMaterial(createMaterial(Color.rgb( + (argb >> 16) & 0xFF, (argb >> 8) & 0xFF, (argb >> 0) & 0xFF))); + getChildren().add(pixel); + } + } + } + + protected Material createMaterial(Color color) { + return new PhongMaterial(color); + } + + } + + protected int width, height, depth; + protected float startX, startY; + protected double length, thick; + + public SkinMultipleCubes(int width, int height, int depth, float startX, float startY, double length, double thick) { + this.width = width; + this.height = height; + this.depth = depth; + this.startX = startX; + this.startY = startY; + this.length = length; + this.thick = thick; + } + + public void setWidth(int width) { + this.width = width; + } + + public int getWidth() { + return width; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getHeight() { + return height; + } + + public void setDepth(int depth) { + this.depth = depth; + } + + public int getDepth() { + return depth; + } + + public void setStartX(float startX) { + this.startX = startX; + } + + public float getStartX() { + return startX; + } + + public void setStartY(float startY) { + this.startY = startY; + } + + public float getStartY() { + return startY; + } + + public void setLength(double length) { + this.length = length; + } + + public double getLength() { + return length; + } + + public void setThick(double thick) { + this.thick = thick; + } + + public double getThick() { + return thick; + } + + public void updateSkin(Image skin) { + getChildren().clear(); + int start_x = (int) (startX * skin.getWidth()), start_y = (int) (startY * skin.getHeight()), + interval = (int) Math.max(skin.getWidth() / 64, 1), + width_interval = width * interval, height_interval = height * interval, depth_interval = depth * interval; + // FRONT + getChildren().add(new Face(skin, start_x + depth_interval, start_y + depth_interval, width, height, interval, false, false, + () -> new Box(length, length, thick), (b, p) -> { + b.setTranslateX(((width - 1) / 2.0 - p.getX()) * b.getWidth()); + b.setTranslateY(-((height - 1) / 2.0 - p.getY()) * b.getHeight()); + b.setTranslateZ((depth * length + thick) / 2.0); + })); + // BACK + getChildren().add(new Face(skin, start_x + width_interval + depth_interval * 2, start_y + depth_interval, width, height, interval, true, false, + () -> new Box(length, length, thick), (b, p) -> { + b.setTranslateX(((width - 1) / 2.0 - p.getX()) * b.getWidth()); + b.setTranslateY(-((height - 1) / 2.0 - p.getY()) * b.getHeight()); + b.setTranslateZ(-(depth * length + thick) / 2.0); + })); + // LEFT + getChildren().add(new Face(skin, start_x + width_interval + depth_interval, start_y + depth_interval, depth, height, interval, false, false, + () -> new Box(thick, length, length), (b, p) -> { + b.setTranslateX((width * length + thick) / 2.0); + b.setTranslateY(-((height - 1) / 2.0 - p.getY()) * b.getHeight()); + b.setTranslateZ(((depth - 1) / 2.0 - p.getX()) * b.getDepth()); + })); + // RIGHT + getChildren().add(new Face(skin, start_x, start_y + depth_interval, depth, height, interval, true, false, + () -> new Box(thick, length, length), (b, p) -> { + b.setTranslateX(-(width * length + thick) / 2.0); + b.setTranslateY(-((height - 1) / 2.0 - p.getY()) * b.getHeight()); + b.setTranslateZ(((depth - 1) / 2.0 - p.getX()) * b.getDepth()); + })); + // TOP + getChildren().add(new Face(skin, start_x + depth_interval, start_y, width, depth, interval, false, false, + () -> new Box(length, thick, length), (b, p) -> { + b.setTranslateX(((width - 1) / 2.0 - p.getX()) * b.getWidth()); + b.setTranslateY(-(height * length + thick) / 2.0); + b.setTranslateZ(-((depth - 1) / 2.0 - p.getY()) * b.getDepth()); + })); + // BOTTOM + getChildren().add(new Face(skin, start_x + width_interval + depth_interval, start_y, width, depth, interval, false, false, + () -> new Box(length, thick, length), (b, p) -> { + b.setTranslateX(((width - 1) / 2.0 - p.getX()) * b.getWidth()); + b.setTranslateY((height * length + thick) / 2.0); + b.setTranslateZ(-((depth - 1) / 2.0 - p.getY()) * b.getDepth()); + })); + } + } diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinTransition.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinTransition.java index ad132067f..29289c8ca 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinTransition.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/SkinTransition.java @@ -1,42 +1,42 @@ package moe.mickey.minecraft.skin.fx; -import java.util.Arrays; -import java.util.List; -import java.util.function.Function; - import javafx.animation.Transition; import javafx.beans.value.WritableValue; import javafx.util.Duration; -public class SkinTransition extends Transition { - - protected Function expression; - protected List> observables; - protected boolean fix; - protected int count; - - public int getCount() { - return count; - } - - public SkinTransition(Duration duration, Function expression, WritableValue... observables) { - setCycleDuration(duration); - this.expression = expression; - this.observables = Arrays.asList(observables); - } +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +public class SkinTransition extends Transition { + + protected Function expression; + protected List> observables; + protected boolean fix; + protected int count; + + public int getCount() { + return count; + } + + public SkinTransition(Duration duration, Function expression, WritableValue... observables) { + setCycleDuration(duration); + this.expression = expression; + this.observables = Arrays.asList(observables); + } + + @Override + protected void interpolate(double frac) { + if (frac == 0 || frac == 1) + count++; + double val = expression.apply(frac); + observables.forEach(w -> w.setValue(val)); + } + + @Override + public void play() { + count = 0; + super.play(); + } - @Override - protected void interpolate(double frac) { - if (frac == 0 || frac == 1) - count++; - double val = expression.apply(frac); - observables.forEach(w -> w.setValue(val)); - } - - @Override - public void play() { - count = 0; - super.play(); - } - } diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/animation/SkinAniRunning.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/animation/SkinAniRunning.java index 4cbe6e5e8..5a2b83693 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/animation/SkinAniRunning.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/animation/SkinAniRunning.java @@ -7,23 +7,23 @@ import moe.mickey.minecraft.skin.fx.SkinCanvas; import moe.mickey.minecraft.skin.fx.SkinTransition; public final class SkinAniRunning extends SkinAnimation { - - private SkinTransition larmTransition, rarmTransition; - - public SkinAniRunning(int weight, int time, double angle, SkinCanvas canvas) { - larmTransition = new SkinTransition(Duration.millis(time), - v -> v * (larmTransition.getCount() % 4 < 2 ? 1 : -1) * angle, - canvas.larm.getXRotate().angleProperty(), canvas.rleg.getXRotate().angleProperty()); - - rarmTransition = new SkinTransition(Duration.millis(time), - v -> v * (rarmTransition.getCount() % 4 < 2 ? 1 : -1) * -angle, - canvas.rarm.getXRotate().angleProperty(), canvas.lleg.getXRotate().angleProperty()); - - FunctionHelper.alwaysB(SkinTransition::setAutoReverse, true, larmTransition, rarmTransition); - FunctionHelper.alwaysB(SkinTransition::setCycleCount, 16, larmTransition, rarmTransition); - FunctionHelper.always(transitions::add, larmTransition, rarmTransition); - this.weight = weight; - init(); - } + + private SkinTransition larmTransition, rarmTransition; + + public SkinAniRunning(int weight, int time, double angle, SkinCanvas canvas) { + larmTransition = new SkinTransition(Duration.millis(time), + v -> v * (larmTransition.getCount() % 4 < 2 ? 1 : -1) * angle, + canvas.larm.getXRotate().angleProperty(), canvas.rleg.getXRotate().angleProperty()); + + rarmTransition = new SkinTransition(Duration.millis(time), + v -> v * (rarmTransition.getCount() % 4 < 2 ? 1 : -1) * -angle, + canvas.rarm.getXRotate().angleProperty(), canvas.lleg.getXRotate().angleProperty()); + + FunctionHelper.alwaysB(SkinTransition::setAutoReverse, true, larmTransition, rarmTransition); + FunctionHelper.alwaysB(SkinTransition::setCycleCount, 16, larmTransition, rarmTransition); + FunctionHelper.always(transitions::add, larmTransition, rarmTransition); + this.weight = weight; + init(); + } } diff --git a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/animation/SkinAniWavingArms.java b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/animation/SkinAniWavingArms.java index 84544ba4d..46060216d 100644 --- a/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/animation/SkinAniWavingArms.java +++ b/HMCL/src/main/java/moe/mickey/minecraft/skin/fx/animation/SkinAniWavingArms.java @@ -8,18 +8,18 @@ import moe.mickey.minecraft.skin.fx.SkinTransition; public final class SkinAniWavingArms extends SkinAnimation { - public SkinAniWavingArms(int weight, int time, double angle, SkinCanvas canvas) { - SkinTransition larmTransition = new SkinTransition(Duration.millis(time), v -> v * angle, - canvas.larm.getZRotate().angleProperty()); - - SkinTransition rarmTransition = new SkinTransition(Duration.millis(time), v -> v * -angle, - canvas.rarm.getZRotate().angleProperty()); - - FunctionHelper.alwaysB(SkinTransition::setAutoReverse, true, larmTransition, rarmTransition); - FunctionHelper.alwaysB(SkinTransition::setCycleCount, 2, larmTransition, rarmTransition); - FunctionHelper.always(transitions::add, larmTransition, rarmTransition); - this.weight = weight; - init(); - } - + public SkinAniWavingArms(int weight, int time, double angle, SkinCanvas canvas) { + SkinTransition larmTransition = new SkinTransition(Duration.millis(time), v -> v * angle, + canvas.larm.getZRotate().angleProperty()); + + SkinTransition rarmTransition = new SkinTransition(Duration.millis(time), v -> v * -angle, + canvas.rarm.getZRotate().angleProperty()); + + FunctionHelper.alwaysB(SkinTransition::setAutoReverse, true, larmTransition, rarmTransition); + FunctionHelper.alwaysB(SkinTransition::setCycleCount, 2, larmTransition, rarmTransition); + FunctionHelper.always(transitions::add, larmTransition, rarmTransition); + this.weight = weight; + init(); + } + } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/HintPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/HintPane.java index b03b3f656..0682ad4f2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/HintPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/HintPane.java @@ -22,17 +22,12 @@ import javafx.beans.property.StringProperty; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; -import javafx.scene.control.Label; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; -import javafx.scene.paint.Color; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.ui.SVG; -import org.jackhuang.hmcl.util.javafx.BindingMapping; - -import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public class HintPane extends VBox { private final Text label = new Text(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java index 72ee5d1c8..2bd64e23f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java @@ -58,7 +58,6 @@ import org.jackhuang.hmcl.util.AggregatedObservableList; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.i18n.I18n; import org.jackhuang.hmcl.util.javafx.BindingMapping; -import org.jackhuang.hmcl.util.versioning.VersionNumber; import java.io.File; import java.util.*; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java index 86a3fbc14..9c7421916 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java @@ -30,7 +30,6 @@ import javafx.scene.layout.VBox; import org.jackhuang.hmcl.event.EventBus; import org.jackhuang.hmcl.event.RefreshingVersionsEvent; import org.jackhuang.hmcl.game.HMCLGameRepository; -import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.Profiles; import org.jackhuang.hmcl.ui.*; @@ -40,11 +39,8 @@ import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.ui.profile.ProfileListItem; import org.jackhuang.hmcl.ui.profile.ProfilePage; import org.jackhuang.hmcl.util.javafx.MappedObservableList; -import org.jackhuang.hmcl.util.versioning.VersionNumber; import java.util.Collections; -import java.util.Comparator; -import java.util.Date; import java.util.List; import java.util.stream.Collectors; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java index b5c15f9e6..12c11215d 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java @@ -17,7 +17,17 @@ */ package org.jackhuang.hmcl.util; -import java.io.*; +import com.google.gson.JsonParseException; +import com.google.gson.annotations.SerializedName; +import org.jackhuang.hmcl.util.function.ExceptionalSupplier; +import org.jackhuang.hmcl.util.gson.JsonUtils; +import org.jackhuang.hmcl.util.io.FileUtils; +import org.jackhuang.hmcl.util.io.IOUtils; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; +import java.io.RandomAccessFile; import java.net.URLConnection; import java.nio.channels.Channels; import java.nio.channels.FileChannel; @@ -32,17 +42,9 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.BiFunction; -import java.util.function.Supplier; import java.util.logging.Level; import java.util.stream.Stream; -import com.google.gson.JsonParseException; -import com.google.gson.annotations.SerializedName; -import org.jackhuang.hmcl.util.function.ExceptionalSupplier; -import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.FileUtils; -import org.jackhuang.hmcl.util.io.IOUtils; - import static java.nio.charset.StandardCharsets.UTF_8; import static org.jackhuang.hmcl.util.Logging.LOG;