Hi Babylon Experts, I got a question about customizing URDF loader.
As we all know, the importMeshAsync function needs to return the array of loaded mesh. Visual properties of URDF could refer to another model which type could be DAE. My question is that weather the loaded meshes of DAE file need to be included in the loaded meshes of URDF file?
Below is example code:
{
async importMeshAsync(meshesNames: string | readonly string[] | null | undefined, scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<ISceneLoaderAsyncResult> {
const loadedMeshes = [];
const robot = new Robot();
await deserializeUrdfToRobot(data as string, robot);
// robot.visual is another model, so need to import the model using importMesh
SceneLoader.ImportMesh(null, base, filename, scene, (daeFileLoadedMeshes,) => {
// weather the loaded meshes of DAE file need to be included in the loaded meshes of URDF file?
loadedMeshes.push([...daeFileLoadedMeshes]);
});
robot.create(scene);
return {
meshes: loadedMeshes,
particleSystems: [],
skeletons: [],
animationGroups: [],
transformNodes: [],
geometries: [],
lights: [],
spriteManagers: [],
};
}
}
Not an expert. It seems to me that you’re generally doing it right.
The URDF format can reference 3d files in a variety of formats, not just dae, (including from a brief search: dae, obj, .mesh, stl). Loading those referenced meshes with subsequent calls. Unfortunately, URDF files do not require a “name,” so the standard method of selecting which meshes to load (with name parameter) won’t work.
Note also the newer method of loading using appendSceneAsync but I’m not sure how flushed out it is (the examples are primarily using gltf format).
One thing you might have to work out is how to specify any options for the subsequent loads. Or just try the defaults and see how well it works!
I think this seems pretty reasonable, but as @HiGreg mentioned it would be better to use the new module level functions as they are better for tree shaking and allow options to be passed through. For the module level functions, we did not include importMeshAsync because we believed that loadAssetContainerAsync can do all the same things, but this case is interesting since ISceneLoaderPluginAsync requires you to implement importMeshAsync. We could definitely include it if it is needed for scenarios like this.
Also just FYI, we are doing work right now to make it possible to have loaders by created through async factories, which makes it possible to do dynamic imports for the loaders, which I think is especially good for this kind of scenario, where your URDF may reference various other formats. In that case, you would only have to pay the download cost of a DAE loader (for example) when loading a specific URDF that references a DAE.
Wow,I’ve always heard that Babylon.js has a fantastic community, and today I experienced it.
Thank you very much for your reply. It’s very useful for me.
Besides, I find that appendSceneAsync will invoke the load or loadAsync provided by customized plugin. So I think appendSceneAsync method is suitable for other formats. For reference only.
I think registering other loaders(eg: DAE loader) to Babylon.js in the URDF loaders is one option. My implement is that just invoking appendSceneAsync method when load those referenced mesh, developers need to register other loaders in their app instead of registering in the URDF Loader. Maybe I need to find a way to overwrite the subsequent loader’s configuration temporarily if necessary. I will try it to see how it works.
Yes, I find the createPlugin factory method in the code. It’s pretty good. I will try it when most of loader plugins have already implemented this factory method in the URDF loader.
Yes, This project builds upon the work done in GitHub - polyhobbyist/babylon_ros , with additional configurations and integration with the standard loader interface designed by Babylon.js.