使用 gltf-transform 合并具有一些公共节点的多个 GLTF
Merging Multiple GLTF having some common nodes using gltf-transform
此问题是 的扩展。
我正在尝试合并具有一些公共节点的多个 GLTF 文件。
答案帮助我合并文件,我通过以下代码组合场景并完美呈现
const scenes = root.listScenes()
const scene0 = scenes[0]
root.setDefaultScene(scene0);
if(scenes.length > 1) {
for(let i = 1 ; i < scenes.length;i++) {
let scene = scenes[i];
let nodes = scene.listChildren()
for(let j = 0 ; j < nodes.length; j++) {
scene0.addChild(nodes[j]);
}
}
}
root.listScenes().forEach((b, index) => index > 0 ? b.dispose() : null);
我的问题是 GLTF 中常见的所有数据都是重复的,这会在需要更改根骨骼时在动画中产生问题。有没有一种方法可以合并以使公共节点不重复?我也在尝试一些自定义合并。
const gltfLoader=() => {
const document = new Document();
const root = document.getRoot();
document.merge(io.read(filePaths[0]));
let model;
for (let i = 1 ; i < filePaths.length; i++) {
const inDoc = new Document();
inDoc.merge(io.read(filePaths[i]));
model = inDoc.getRoot().listScenes()[0];
model.listChildren().forEach((child) => {
mergeStructure(root.listScenes()[0], child);
});
}
io.write('output.gltf', document);
}
const mergeStructure = (parent, childToMerge) => {
let contains = false;
parent.listChildren().forEach((child) => {
if (child.t === childToMerge.t && !contains && child.getName() === childToMerge.getName()) {
childToMerge.listChildren().forEach((subChild) => {
mergeStructure(child, subChild);
});
contains = true;
}
});
if (!contains) {
console.log("Adding " + childToMerge.getName() + " to " + parent.getName() + " as child")
parent.addChild(childToMerge);
}
}
但是由于 Error: Cannot link disconnected graphs/documents
,此合并无法正常工作。
我是 3D 建模的新手。有方向就好了。
谢谢!
您在上面看到的错误是因为代码试图移动单个资源而发生的——例如Nodes — from one glTF Document 给另一个。这是不可能的,每个文档都在内部管理其资源图,但等效的工作流程是:
- 加载N个文件并合并成一个文档(N个场景)。
import { Document, NodeIO } from '@gltf-transform/core';
const io = new NodeIO();
const document = new Document();
for (const path of paths) {
document.merge(io.read(path));
}
- 遍历所有场景,将它们 children 移动到一些常见场景:
const root = document.getRoot();
const mainScene = root.listScenes()[0];
for (const scene of root.listScenes()) {
if (scene === mainScene) continue;
for (const child of scene.listChildren()) {
// If conditions are met, append child to `mainScene`.
// Doing so will automatically detach it from the
// previous scene.
}
scene.dispose();
}
- 清理所有剩余的未合并资源。
import { prune } from '@gltf-transform/functions';
await document.transform(prune());
此问题是
我正在尝试合并具有一些公共节点的多个 GLTF 文件。 答案帮助我合并文件,我通过以下代码组合场景并完美呈现
const scenes = root.listScenes()
const scene0 = scenes[0]
root.setDefaultScene(scene0);
if(scenes.length > 1) {
for(let i = 1 ; i < scenes.length;i++) {
let scene = scenes[i];
let nodes = scene.listChildren()
for(let j = 0 ; j < nodes.length; j++) {
scene0.addChild(nodes[j]);
}
}
}
root.listScenes().forEach((b, index) => index > 0 ? b.dispose() : null);
我的问题是 GLTF 中常见的所有数据都是重复的,这会在需要更改根骨骼时在动画中产生问题。有没有一种方法可以合并以使公共节点不重复?我也在尝试一些自定义合并。
const gltfLoader=() => {
const document = new Document();
const root = document.getRoot();
document.merge(io.read(filePaths[0]));
let model;
for (let i = 1 ; i < filePaths.length; i++) {
const inDoc = new Document();
inDoc.merge(io.read(filePaths[i]));
model = inDoc.getRoot().listScenes()[0];
model.listChildren().forEach((child) => {
mergeStructure(root.listScenes()[0], child);
});
}
io.write('output.gltf', document);
}
const mergeStructure = (parent, childToMerge) => {
let contains = false;
parent.listChildren().forEach((child) => {
if (child.t === childToMerge.t && !contains && child.getName() === childToMerge.getName()) {
childToMerge.listChildren().forEach((subChild) => {
mergeStructure(child, subChild);
});
contains = true;
}
});
if (!contains) {
console.log("Adding " + childToMerge.getName() + " to " + parent.getName() + " as child")
parent.addChild(childToMerge);
}
}
但是由于 Error: Cannot link disconnected graphs/documents
,此合并无法正常工作。
我是 3D 建模的新手。有方向就好了。
谢谢!
您在上面看到的错误是因为代码试图移动单个资源而发生的——例如Nodes — from one glTF Document 给另一个。这是不可能的,每个文档都在内部管理其资源图,但等效的工作流程是:
- 加载N个文件并合并成一个文档(N个场景)。
import { Document, NodeIO } from '@gltf-transform/core';
const io = new NodeIO();
const document = new Document();
for (const path of paths) {
document.merge(io.read(path));
}
- 遍历所有场景,将它们 children 移动到一些常见场景:
const root = document.getRoot();
const mainScene = root.listScenes()[0];
for (const scene of root.listScenes()) {
if (scene === mainScene) continue;
for (const child of scene.listChildren()) {
// If conditions are met, append child to `mainScene`.
// Doing so will automatically detach it from the
// previous scene.
}
scene.dispose();
}
- 清理所有剩余的未合并资源。
import { prune } from '@gltf-transform/functions';
await document.transform(prune());