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 6dad447c05 - Show all commits

View File

@@ -113,6 +113,10 @@ public final class GlbParser {
String name = node.has("name")
? node.get("name").getAsString()
: "joint_" + j;
// Strip armature prefix (e.g., "MyRig|body" -> "body")
if (name.contains("|")) {
name = name.substring(name.lastIndexOf('|') + 1);
}
if (GltfBoneMapper.isKnownBone(name)) {
skinJointRemap[j] = filteredJointNodes.size();
filteredJointNodes.add(nodeIdx);
@@ -145,9 +149,13 @@ public final class GlbParser {
int nodeIdx = filteredJointNodes.get(j);
JsonObject node = nodes.get(nodeIdx).getAsJsonObject();
jointNames[j] = node.has("name")
String rawName = node.has("name")
? node.get("name").getAsString()
: "joint_" + j;
// Strip armature prefix consistently
jointNames[j] = rawName.contains("|")
? rawName.substring(rawName.lastIndexOf('|') + 1)
: rawName;
// Rest rotation
if (node.has("rotation")) {
@@ -215,20 +223,36 @@ public final class GlbParser {
}
}
// -- Find mesh (ignore "Player" mesh, take LAST non-Player) --
// WORKAROUND: Takes the LAST non-Player mesh because modelers may leave prototype meshes
// in the .glb. Revert to first non-Player mesh once modeler workflow is standardized.
// -- Find mesh by convention, then fallback --
// Priority: 1) mesh named "Item", 2) last non-Player mesh
int targetMeshIdx = -1;
String selectedMeshName = null;
int nonPlayerCount = 0;
if (meshes != null) {
for (int mi = 0; mi < meshes.size(); mi++) {
JsonObject mesh = meshes.get(mi).getAsJsonObject();
String meshName = mesh.has("name")
? mesh.get("name").getAsString()
: "";
if ("Item".equals(meshName)) {
targetMeshIdx = mi;
selectedMeshName = meshName;
break; // Convention match — use it
}
if (!"Player".equals(meshName)) {
targetMeshIdx = mi;
selectedMeshName = meshName;
nonPlayerCount++;
}
}
if (nonPlayerCount > 1 && !"Item".equals(selectedMeshName)) {
LOGGER.warn(
"[GltfPipeline] {} non-Player meshes found in {} — using '{}'. "
+ "Name your mesh 'Item' for explicit selection.",
nonPlayerCount, debugName,
selectedMeshName != null ? selectedMeshName : "(unnamed)"
);
}
}
// -- Parse root material names (for tint channel detection) --