Remove internal phase comments and format code

Strip all Phase references, TODO/FUTURE roadmap notes, and internal
planning comments from the codebase. Run Prettier for consistent
formatting across all Java files.
This commit is contained in:
NotEvil
2026-04-12 01:24:49 +02:00
parent 73d70e212d
commit a71093ba9c
482 changed files with 8500 additions and 5155 deletions

View File

@@ -5,11 +5,11 @@ import dev.kosmx.playerAnim.core.data.KeyframeAnimation;
import dev.kosmx.playerAnim.core.util.Ease;
import java.util.HashSet;
import java.util.Set;
import org.jetbrains.annotations.Nullable;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@@ -52,10 +52,16 @@ public final class GltfPoseConverter {
* @param animationName the name of the animation to convert (e.g. "Struggle", "Idle")
* @return a static looping KeyframeAnimation suitable for PlayerAnimator
*/
public static KeyframeAnimation convert(GltfData data, String animationName) {
public static KeyframeAnimation convert(
GltfData data,
String animationName
) {
GltfData.AnimationClip rawClip = data.getRawAnimation(animationName);
if (rawClip == null) {
LOGGER.warn("[GltfPipeline] Animation '{}' not found, falling back to default", animationName);
LOGGER.warn(
"[GltfPipeline] Animation '{}' not found, falling back to default",
animationName
);
return convert(data);
}
return convertClip(data, rawClip, "gltf_" + animationName);
@@ -76,8 +82,12 @@ public final class GltfPoseConverter {
* are only enabled if the GLB has keyframes for them
* @return KeyframeAnimation with selective parts active
*/
public static KeyframeAnimation convertSelective(GltfData data, @Nullable String animationName,
Set<String> ownedParts, Set<String> enabledParts) {
public static KeyframeAnimation convertSelective(
GltfData data,
@Nullable String animationName,
Set<String> ownedParts,
Set<String> enabledParts
) {
GltfData.AnimationClip rawClip;
String animName;
if (animationName != null) {
@@ -90,7 +100,13 @@ public final class GltfPoseConverter {
if (rawClip == null) {
rawClip = data.rawGltfAnimation();
}
return convertClipSelective(data, rawClip, animName, ownedParts, enabledParts);
return convertClipSelective(
data,
rawClip,
animName,
ownedParts,
enabledParts
);
}
/**
@@ -105,10 +121,17 @@ public final class GltfPoseConverter {
* @param ownedParts parts the item explicitly owns (always enabled)
* @param enabledParts parts the item may animate (owned + free)
*/
private static KeyframeAnimation convertClipSelective(GltfData data, GltfData.AnimationClip rawClip,
String animName, Set<String> ownedParts, Set<String> enabledParts) {
private static KeyframeAnimation convertClipSelective(
GltfData data,
GltfData.AnimationClip rawClip,
String animName,
Set<String> ownedParts,
Set<String> enabledParts
) {
KeyframeAnimation.AnimationBuilder builder =
new KeyframeAnimation.AnimationBuilder(AnimationFormat.JSON_EMOTECRAFT);
new KeyframeAnimation.AnimationBuilder(
AnimationFormat.JSON_EMOTECRAFT
);
builder.beginTick = 0;
builder.endTick = 1;
@@ -129,21 +152,27 @@ public final class GltfPoseConverter {
// Check if this joint has explicit animation data (not just rest pose fallback).
// A bone counts as explicitly animated if it has rotation OR translation keyframes.
boolean hasExplicitAnim = rawClip != null && (
(j < rawClip.rotations().length && rawClip.rotations()[j] != null)
|| (rawClip.translations() != null
&& j < rawClip.translations().length
&& rawClip.translations()[j] != null)
);
boolean hasExplicitAnim =
rawClip != null &&
((j < rawClip.rotations().length &&
rawClip.rotations()[j] != null) ||
(rawClip.translations() != null &&
j < rawClip.translations().length &&
rawClip.translations()[j] != null));
Quaternionf animQ = getRawAnimQuaternion(rawClip, rawRestRotations, j);
Quaternionf animQ = getRawAnimQuaternion(
rawClip,
rawRestRotations,
j
);
Quaternionf restQ = rawRestRotations[j];
// delta_local = inverse(rest_q) * anim_q (in bone-local frame)
Quaternionf deltaLocal = new Quaternionf(restQ).invert().mul(animQ);
// Convert to PARENT frame: delta_parent = rest * delta_local * inv(rest)
Quaternionf deltaParent = new Quaternionf(restQ).mul(deltaLocal)
Quaternionf deltaParent = new Quaternionf(restQ)
.mul(deltaLocal)
.mul(new Quaternionf(restQ).invert());
// Convert from glTF parent frame to MC model-def frame.
@@ -168,7 +197,9 @@ public final class GltfPoseConverter {
if (GltfBoneMapper.isLowerBone(boneName)) {
String upperBone = GltfBoneMapper.getUpperBoneFor(boneName);
if (upperBone != null) {
String upperPart = GltfBoneMapper.getAnimPartName(upperBone);
String upperPart = GltfBoneMapper.getAnimPartName(
upperBone
);
if (upperPart != null) {
partsWithKeyframes.add(upperPart);
}
@@ -178,11 +209,21 @@ public final class GltfPoseConverter {
}
// Selective: enable owned parts always, free parts only if they have keyframes
enableSelectiveParts(builder, ownedParts, enabledParts, partsWithKeyframes);
enableSelectiveParts(
builder,
ownedParts,
enabledParts,
partsWithKeyframes
);
KeyframeAnimation anim = builder.build();
LOGGER.debug("[GltfPipeline] Converted selective animation '{}' (owned: {}, enabled: {}, withKeyframes: {})",
animName, ownedParts, enabledParts, partsWithKeyframes);
LOGGER.debug(
"[GltfPipeline] Converted selective animation '{}' (owned: {}, enabled: {}, withKeyframes: {})",
animName,
ownedParts,
enabledParts,
partsWithKeyframes
);
return anim;
}
@@ -200,10 +241,11 @@ public final class GltfPoseConverter {
* @return set of part names that received actual keyframe data from the GLB
*/
public static Set<String> addBonesToBuilder(
KeyframeAnimation.AnimationBuilder builder,
GltfData data, @Nullable GltfData.AnimationClip rawClip,
Set<String> ownedParts) {
KeyframeAnimation.AnimationBuilder builder,
GltfData data,
@Nullable GltfData.AnimationClip rawClip,
Set<String> ownedParts
) {
String[] jointNames = data.jointNames();
Quaternionf[] rawRestRotations = data.rawGltfRestRotations();
Set<String> partsWithKeyframes = new HashSet<>();
@@ -221,23 +263,33 @@ public final class GltfPoseConverter {
if (GltfBoneMapper.isLowerBone(boneName)) {
String upperBone = GltfBoneMapper.getUpperBoneFor(boneName);
if (upperBone != null) {
String upperPart = GltfBoneMapper.getAnimPartName(upperBone);
if (upperPart == null || !ownedParts.contains(upperPart)) continue;
String upperPart = GltfBoneMapper.getAnimPartName(
upperBone
);
if (
upperPart == null || !ownedParts.contains(upperPart)
) continue;
}
}
boolean hasExplicitAnim = rawClip != null && (
(j < rawClip.rotations().length && rawClip.rotations()[j] != null)
|| (rawClip.translations() != null
&& j < rawClip.translations().length
&& rawClip.translations()[j] != null)
);
boolean hasExplicitAnim =
rawClip != null &&
((j < rawClip.rotations().length &&
rawClip.rotations()[j] != null) ||
(rawClip.translations() != null &&
j < rawClip.translations().length &&
rawClip.translations()[j] != null));
Quaternionf animQ = getRawAnimQuaternion(rawClip, rawRestRotations, j);
Quaternionf animQ = getRawAnimQuaternion(
rawClip,
rawRestRotations,
j
);
Quaternionf restQ = rawRestRotations[j];
Quaternionf deltaLocal = new Quaternionf(restQ).invert().mul(animQ);
Quaternionf deltaParent = new Quaternionf(restQ).mul(deltaLocal)
Quaternionf deltaParent = new Quaternionf(restQ)
.mul(deltaLocal)
.mul(new Quaternionf(restQ).invert());
Quaternionf deltaQ = new Quaternionf(deltaParent);
@@ -255,8 +307,12 @@ public final class GltfPoseConverter {
if (GltfBoneMapper.isLowerBone(boneName)) {
String upperBone = GltfBoneMapper.getUpperBoneFor(boneName);
if (upperBone != null) {
String upperPart = GltfBoneMapper.getAnimPartName(upperBone);
if (upperPart != null) partsWithKeyframes.add(upperPart);
String upperPart = GltfBoneMapper.getAnimPartName(
upperBone
);
if (upperPart != null) partsWithKeyframes.add(
upperPart
);
}
}
}
@@ -281,16 +337,25 @@ public final class GltfPoseConverter {
* @return a static looping KeyframeAnimation with all parts enabled
*/
public static KeyframeAnimation convertWithSkeleton(
GltfData skeleton, GltfData.AnimationClip clip, String animName) {
GltfData skeleton,
GltfData.AnimationClip clip,
String animName
) {
return convertClip(skeleton, clip, animName);
}
/**
* Internal: convert a specific raw animation clip to a KeyframeAnimation.
*/
private static KeyframeAnimation convertClip(GltfData data, GltfData.AnimationClip rawClip, String animName) {
private static KeyframeAnimation convertClip(
GltfData data,
GltfData.AnimationClip rawClip,
String animName
) {
KeyframeAnimation.AnimationBuilder builder =
new KeyframeAnimation.AnimationBuilder(AnimationFormat.JSON_EMOTECRAFT);
new KeyframeAnimation.AnimationBuilder(
AnimationFormat.JSON_EMOTECRAFT
);
builder.beginTick = 0;
builder.endTick = 1;
@@ -307,7 +372,11 @@ public final class GltfPoseConverter {
if (!GltfBoneMapper.isKnownBone(boneName)) continue;
Quaternionf animQ = getRawAnimQuaternion(rawClip, rawRestRotations, j);
Quaternionf animQ = getRawAnimQuaternion(
rawClip,
rawRestRotations,
j
);
Quaternionf restQ = rawRestRotations[j];
// delta_local = inverse(rest_q) * anim_q (in bone-local frame)
@@ -315,7 +384,8 @@ public final class GltfPoseConverter {
// Convert to PARENT frame: delta_parent = rest * delta_local * inv(rest)
// Simplifies algebraically to: animQ * inv(restQ)
Quaternionf deltaParent = new Quaternionf(restQ).mul(deltaLocal)
Quaternionf deltaParent = new Quaternionf(restQ)
.mul(deltaLocal)
.mul(new Quaternionf(restQ).invert());
// Convert from glTF parent frame to MC model-def frame.
@@ -324,12 +394,24 @@ public final class GltfPoseConverter {
deltaQ.x = -deltaQ.x;
deltaQ.y = -deltaQ.y;
LOGGER.debug(String.format(
"[GltfPipeline] Bone '%s': restQ=(%.3f,%.3f,%.3f,%.3f) animQ=(%.3f,%.3f,%.3f,%.3f) deltaQ=(%.3f,%.3f,%.3f,%.3f)",
boneName,
restQ.x, restQ.y, restQ.z, restQ.w,
animQ.x, animQ.y, animQ.z, animQ.w,
deltaQ.x, deltaQ.y, deltaQ.z, deltaQ.w));
LOGGER.debug(
String.format(
"[GltfPipeline] Bone '%s': restQ=(%.3f,%.3f,%.3f,%.3f) animQ=(%.3f,%.3f,%.3f,%.3f) deltaQ=(%.3f,%.3f,%.3f,%.3f)",
boneName,
restQ.x,
restQ.y,
restQ.z,
restQ.w,
animQ.x,
animQ.y,
animQ.z,
animQ.w,
deltaQ.x,
deltaQ.y,
deltaQ.z,
deltaQ.w
)
);
if (GltfBoneMapper.isLowerBone(boneName)) {
convertLowerBone(builder, boneName, deltaQ);
@@ -341,7 +423,10 @@ public final class GltfPoseConverter {
builder.fullyEnableParts();
KeyframeAnimation anim = builder.build();
LOGGER.debug("[GltfPipeline] Converted glTF animation '{}' to KeyframeAnimation", animName);
LOGGER.debug(
"[GltfPipeline] Converted glTF animation '{}' to KeyframeAnimation",
animName
);
return anim;
}
@@ -350,10 +435,15 @@ public final class GltfPoseConverter {
* Falls back to rest rotation if the clip is null or has no data for this joint.
*/
private static Quaternionf getRawAnimQuaternion(
GltfData.AnimationClip rawClip, Quaternionf[] rawRestRotations, int jointIndex
GltfData.AnimationClip rawClip,
Quaternionf[] rawRestRotations,
int jointIndex
) {
if (rawClip != null && jointIndex < rawClip.rotations().length
&& rawClip.rotations()[jointIndex] != null) {
if (
rawClip != null &&
jointIndex < rawClip.rotations().length &&
rawClip.rotations()[jointIndex] != null
) {
return rawClip.rotations()[jointIndex][0]; // first frame
}
return rawRestRotations[jointIndex]; // fallback to rest
@@ -361,29 +451,36 @@ public final class GltfPoseConverter {
private static void convertUpperBone(
KeyframeAnimation.AnimationBuilder builder,
String boneName, Quaternionf deltaQ
String boneName,
Quaternionf deltaQ
) {
// Decompose delta quaternion to Euler ZYX
// JOML's getEulerAnglesZYX stores: euler.x = X rotation, euler.y = Y rotation, euler.z = Z rotation
// (the "ZYX" refers to rotation ORDER, not storage order)
Vector3f euler = new Vector3f();
deltaQ.getEulerAnglesZYX(euler);
float pitch = euler.x; // X rotation (pitch)
float yaw = euler.y; // Y rotation (yaw)
float roll = euler.z; // Z rotation (roll)
float pitch = euler.x; // X rotation (pitch)
float yaw = euler.y; // Y rotation (yaw)
float roll = euler.z; // Z rotation (roll)
LOGGER.debug(String.format(
"[GltfPipeline] Upper bone '%s': pitch=%.1f° yaw=%.1f° roll=%.1f°",
boneName,
Math.toDegrees(pitch),
Math.toDegrees(yaw),
Math.toDegrees(roll)));
LOGGER.debug(
String.format(
"[GltfPipeline] Upper bone '%s': pitch=%.1f° yaw=%.1f° roll=%.1f°",
boneName,
Math.toDegrees(pitch),
Math.toDegrees(yaw),
Math.toDegrees(roll)
)
);
// Get the StateCollection for this body part
String animPart = GltfBoneMapper.getAnimPartName(boneName);
if (animPart == null) return;
KeyframeAnimation.StateCollection part = getPartByName(builder, animPart);
KeyframeAnimation.StateCollection part = getPartByName(
builder,
animPart
);
if (part == null) return;
part.pitch.addKeyFrame(0, pitch, Ease.CONSTANT);
@@ -393,12 +490,12 @@ public final class GltfPoseConverter {
private static void convertLowerBone(
KeyframeAnimation.AnimationBuilder builder,
String boneName, Quaternionf deltaQ
String boneName,
Quaternionf deltaQ
) {
// Extract bend angle and axis from the delta quaternion
float angle = 2.0f * (float) Math.acos(
Math.min(1.0, Math.abs(deltaQ.w))
);
float angle =
2.0f * (float) Math.acos(Math.min(1.0, Math.abs(deltaQ.w)));
// Determine bend direction from axis
float bendDirection = 0.0f;
@@ -411,11 +508,14 @@ public final class GltfPoseConverter {
angle = -angle;
}
LOGGER.debug(String.format(
"[GltfPipeline] Lower bone '%s': bendAngle=%.1f° bendDir=%.1f°",
boneName,
Math.toDegrees(angle),
Math.toDegrees(bendDirection)));
LOGGER.debug(
String.format(
"[GltfPipeline] Lower bone '%s': bendAngle=%.1f° bendDir=%.1f°",
boneName,
Math.toDegrees(angle),
Math.toDegrees(bendDirection)
)
);
// Apply bend to the upper bone's StateCollection
String upperBone = GltfBoneMapper.getUpperBoneFor(boneName);
@@ -424,7 +524,10 @@ public final class GltfPoseConverter {
String animPart = GltfBoneMapper.getAnimPartName(upperBone);
if (animPart == null) return;
KeyframeAnimation.StateCollection part = getPartByName(builder, animPart);
KeyframeAnimation.StateCollection part = getPartByName(
builder,
animPart
);
if (part == null || !part.isBendable) return;
part.bend.addKeyFrame(0, angle, Ease.CONSTANT);
@@ -432,7 +535,8 @@ public final class GltfPoseConverter {
}
private static KeyframeAnimation.StateCollection getPartByName(
KeyframeAnimation.AnimationBuilder builder, String name
KeyframeAnimation.AnimationBuilder builder,
String name
) {
return switch (name) {
case "head" -> builder.head;
@@ -461,17 +565,32 @@ public final class GltfPoseConverter {
* @param partsWithKeyframes parts that received actual animation data from the GLB
*/
private static void enableSelectiveParts(
KeyframeAnimation.AnimationBuilder builder,
Set<String> ownedParts, Set<String> enabledParts,
Set<String> partsWithKeyframes) {
String[] allParts = {"head", "body", "rightArm", "leftArm", "rightLeg", "leftLeg"};
KeyframeAnimation.AnimationBuilder builder,
Set<String> ownedParts,
Set<String> enabledParts,
Set<String> partsWithKeyframes
) {
String[] allParts = {
"head",
"body",
"rightArm",
"leftArm",
"rightLeg",
"leftLeg",
};
for (String partName : allParts) {
KeyframeAnimation.StateCollection part = getPartByName(builder, partName);
KeyframeAnimation.StateCollection part = getPartByName(
builder,
partName
);
if (part != null) {
if (ownedParts.contains(partName)) {
// Always enable owned parts — the item controls these bones
part.fullyEnablePart(false);
} else if (enabledParts.contains(partName) && partsWithKeyframes.contains(partName)) {
} else if (
enabledParts.contains(partName) &&
partsWithKeyframes.contains(partName)
) {
// Free part WITH keyframes: enable so the GLB animation drives it
part.fullyEnablePart(false);
} else {