diff --git a/src/main/java/com/tiedup/remake/client/gltf/GltfPoseConverter.java b/src/main/java/com/tiedup/remake/client/gltf/GltfPoseConverter.java index c35b3eb..d19b831 100644 --- a/src/main/java/com/tiedup/remake/client/gltf/GltfPoseConverter.java +++ b/src/main/java/com/tiedup/remake/client/gltf/GltfPoseConverter.java @@ -208,12 +208,14 @@ public final class GltfPoseConverter { } } - // Selective: enable owned parts always, free parts only if they have keyframes + // Selective: enable owned parts always, free parts only for "Full" animations + // that explicitly opt into full-body control. enableSelectiveParts( builder, ownedParts, enabledParts, - partsWithKeyframes + partsWithKeyframes, + animName ); KeyframeAnimation anim = builder.build(); @@ -554,22 +556,35 @@ public final class GltfPoseConverter { * *
The "Full" prefix convention (FullIdle, FullStruggle, FullWalk) is the artist's + * explicit declaration that this animation is designed to control the entire body, + * not just the item's owned regions. Without this prefix, free bones are never enabled, + * even if the GLB contains keyframes for them. This prevents accidental bone hijacking + * when an artist keyframes all bones in Blender by default.
+ * * @param builder the animation builder with keyframes already added * @param ownedParts parts the item explicitly owns (always enabled) * @param enabledParts parts the item may animate (owned + free) * @param partsWithKeyframes parts that received actual animation data from the GLB + * @param animName resolved animation name (checked for "Full" prefix) */ private static void enableSelectiveParts( KeyframeAnimation.AnimationBuilder builder, Set