feature/gltf-pipeline-v2 #18

Merged
NotEvil merged 19 commits from feature/gltf-pipeline-v2 into develop 2026-04-17 02:07:45 +00:00
Showing only changes of commit 8af58b5dd5 - Show all commits

View File

@@ -103,10 +103,8 @@ public final class GlbParser {
JsonObject skin = skins.get(0).getAsJsonObject();
JsonArray skinJoints = skin.getAsJsonArray("joints");
// Filter skin joints to only include known deforming bones
List<Integer> filteredJointNodes = new ArrayList<>();
int[] skinJointRemap = new int[skinJoints.size()]; // old skin index -> new filtered index
java.util.Arrays.fill(skinJointRemap, -1);
// Accept all skin joints (no filtering — custom bones are supported)
List<Integer> allJointNodes = new ArrayList<>();
for (int j = 0; j < skinJoints.size(); j++) {
int nodeIdx = skinJoints.get(j).getAsInt();
JsonObject node = nodes.get(nodeIdx).getAsJsonObject();
@@ -117,19 +115,25 @@ public final class GlbParser {
if (name.contains("|")) {
name = name.substring(name.lastIndexOf('|') + 1);
}
if (GltfBoneMapper.isKnownBone(name)) {
skinJointRemap[j] = filteredJointNodes.size();
filteredJointNodes.add(nodeIdx);
// Log info for non-MC bones
if (!GltfBoneMapper.isKnownBone(name)) {
String suggestion = GltfBoneMapper.suggestBoneName(name);
if (suggestion != null) {
LOGGER.warn(
"[GltfPipeline] Unknown bone '{}' in {} — did you mean '{}'? (treated as custom bone)",
name, debugName, suggestion
);
} else {
LOGGER.debug(
"[GltfPipeline] Skipping non-deforming bone: '{}' (node {})",
name,
nodeIdx
LOGGER.info(
"[GltfPipeline] Custom bone '{}' in {} (will follow parent hierarchy in rest pose)",
name, debugName
);
}
}
allJointNodes.add(nodeIdx);
}
int jointCount = filteredJointNodes.size();
int jointCount = allJointNodes.size();
String[] jointNames = new String[jointCount];
int[] parentJointIndices = new int[jointCount];
Quaternionf[] restRotations = new Quaternionf[jointCount];
@@ -139,14 +143,14 @@ public final class GlbParser {
int[] nodeToJoint = new int[nodes.size()];
java.util.Arrays.fill(nodeToJoint, -1);
for (int j = 0; j < jointCount; j++) {
int nodeIdx = filteredJointNodes.get(j);
int nodeIdx = allJointNodes.get(j);
nodeToJoint[nodeIdx] = j;
}
// Read joint names, rest pose, and build parent mapping
java.util.Arrays.fill(parentJointIndices, -1);
for (int j = 0; j < jointCount; j++) {
int nodeIdx = filteredJointNodes.get(j);
int nodeIdx = allJointNodes.get(j);
JsonObject node = nodes.get(nodeIdx).getAsJsonObject();
String rawName = node.has("name")
@@ -200,7 +204,6 @@ public final class GlbParser {
}
// -- Inverse Bind Matrices --
// IBM accessor is indexed by original skin joint order, so we pick the filtered entries
Matrix4f[] inverseBindMatrices = new Matrix4f[jointCount];
if (skin.has("inverseBindMatrices")) {
int ibmAccessor = skin.get("inverseBindMatrices").getAsInt();
@@ -210,12 +213,9 @@ public final class GlbParser {
binData,
ibmAccessor
);
for (int origJ = 0; origJ < skinJoints.size(); origJ++) {
int newJ = skinJointRemap[origJ];
if (newJ >= 0) {
inverseBindMatrices[newJ] = new Matrix4f();
inverseBindMatrices[newJ].set(ibmData, origJ * 16);
}
for (int j = 0; j < jointCount; j++) {
inverseBindMatrices[j] = new Matrix4f();
inverseBindMatrices[j].set(ibmData, j * 16);
}
} else {
for (int j = 0; j < jointCount; j++) {
@@ -344,15 +344,10 @@ public final class GlbParser {
binData,
attributes.get("JOINTS_0").getAsInt()
);
// Remap vertex joint indices from original skin order to filtered order
// No remap needed — all joints are kept, indices match directly.
// Guard against out-of-range joint indices.
for (int i = 0; i < primJoints.length; i++) {
int origIdx = primJoints[i];
if (origIdx >= 0 && origIdx < skinJointRemap.length) {
primJoints[i] =
skinJointRemap[origIdx] >= 0
? skinJointRemap[origIdx]
: 0;
} else {
if (primJoints[i] < 0 || primJoints[i] >= jointCount) {
primJoints[i] = 0;
}
}