diff --git a/core/src/main/java/com/zigythebird/playeranimcore/animation/AnimationController.java b/core/src/main/java/com/zigythebird/playeranimcore/animation/AnimationController.java index 4c78a82..f017c5c 100644 --- a/core/src/main/java/com/zigythebird/playeranimcore/animation/AnimationController.java +++ b/core/src/main/java/com/zigythebird/playeranimcore/animation/AnimationController.java @@ -24,6 +24,7 @@ package com.zigythebird.playeranimcore.animation; +import com.zigythebird.playeranimcore.PlayerAnimLib; import com.zigythebird.playeranimcore.animation.keyframe.*; import com.zigythebird.playeranimcore.animation.keyframe.event.CustomKeyFrameEvents; import com.zigythebird.playeranimcore.animation.keyframe.event.data.CustomInstructionKeyframeData; @@ -544,6 +545,9 @@ private void processCurrentAnimation(float adjustedTick, AnimationData animation for (AdvancedPlayerAnimBone bone : this.bones.values()) { bone.setToInitialPose(); } + for (PlayerAnimBone bone : this.pivotBones.values()) { + bone.setToInitialPose(); + } return; } else { @@ -561,6 +565,9 @@ private void processCurrentAnimation(float adjustedTick, AnimationData animation for (PlayerAnimBone bone : this.bones.values()) { bone.setToInitialPose(); } + for (PlayerAnimBone bone : this.pivotBones.values()) { + bone.setToInitialPose(); + } for (Map.Entry entry : animation.boneAnimations().entrySet()) { PlayerAnimBone bone = this.bones.getOrDefault(entry.getKey(), null); @@ -632,27 +639,38 @@ protected void applyCustomPivotPoints() { Map parentsMap = this.currentAnimation.animation().parents(); if (parentsMap.isEmpty()) return; - List bones1 = new ArrayList<>(this.bones.values()); - for (PlayerAnimBone pivotBone : this.pivotBones.values()) { - if (!parentsMap.containsValue(pivotBone.getName())) - bones1.add(pivotBone); + Set processedBones = new HashSet<>(); + for (PlayerAnimBone bone : this.bones.values()) { + processBoneHierarchy(bone, parentsMap, processedBones); + } + for (PlayerAnimBone bone : this.pivotBones.values()) { + processBoneHierarchy(bone, parentsMap, processedBones); } + } - for (PlayerAnimBone bone : bones1) { - if (parentsMap.containsKey(bone.getName())) { - this.activeBones.put(bone.getName(), bone); + private void processBoneHierarchy(PlayerAnimBone bone, Map parentsMap, Set processedBones) { + String boneName = bone.getName(); + if (processedBones.contains(boneName)) return; - List parents = new ArrayList<>(); - PivotBone currentParent = this.pivotBones.get(parentsMap.get(bone.getName())); - parents.add(currentParent); - while (parentsMap.containsKey(currentParent.getName())) { - currentParent = this.pivotBones.get(parentsMap.get(currentParent.getName())); - parents.addFirst(currentParent); - } + String parentName = parentsMap.get(boneName); + if (parentName == null) { + processedBones.add(boneName); + return; + } - MatrixUtil.applyParentsToChild(bone, parents, this::getBonePosition); - } + PlayerAnimBone parent = this.pivotBones.get(parentName); + if (parent == null) parent = this.bones.get(parentName); + if (parent == null) { + PlayerAnimLib.LOGGER.error("Parent {} not found for {}", parentName, boneName); + return; } + + processBoneHierarchy(parent, parentsMap, processedBones); + + this.activeBones.put(boneName, bone); + MatrixUtil.applyParentsToChild(bone, Collections.singletonList(parent), this::getBonePosition); + + processedBones.add(boneName); } protected void handleCustomKeyframe(T[] keyframes, @Nullable CustomKeyFrameEvents.CustomKeyFrameHandler main, CustomKeyFrameEvents.CustomKeyFrameHandler event, float animationTick, AnimationData animationData) { diff --git a/core/src/main/java/com/zigythebird/playeranimcore/util/MatrixUtil.java b/core/src/main/java/com/zigythebird/playeranimcore/util/MatrixUtil.java index 52f4184..ad4b6d3 100644 --- a/core/src/main/java/com/zigythebird/playeranimcore/util/MatrixUtil.java +++ b/core/src/main/java/com/zigythebird/playeranimcore/util/MatrixUtil.java @@ -12,6 +12,10 @@ * Used for applying custom pivot bones to player bones */ public class MatrixUtil { + public static void translateMatrixForBone(ModMatrix4f matrix, PlayerAnimBone bone) { + matrix.translate(-bone.getPosX(), bone.getPosY(), -bone.getPosZ()); + } + public static void rotateMatrixAroundBone(ModMatrix4f matrix, PlayerAnimBone bone) { if (bone.getRotZ() != 0 || bone.getRotY() != 0 || bone.getRotX() != 0) matrix.rotateZ(bone.getRotZ()).rotateY(bone.getRotY()).rotateX(bone.getRotX()); @@ -31,6 +35,7 @@ public static void translateAwayFromPivotPoint(ModMatrix4f matrix, Vec3f pivot) public static void prepMatrixForBone(ModMatrix4f matrix, PlayerAnimBone bone, Vec3f pivot) { translateToPivotPoint(matrix, pivot); + translateMatrixForBone(matrix, bone); rotateMatrixAroundBone(matrix, bone); scaleMatrixForBone(matrix, bone); translateAwayFromPivotPoint(matrix, pivot); @@ -42,7 +47,6 @@ public static void applyParentsToChild(PlayerAnimBone child, Iterable