Hi, I’m working on a simulation project in NVIDIA Omniverse and have encountered an issue with unit preservation during GLB to USD conversion.
I create 3D wall assets using Blender and export them in .glb format. In Blender, I make sure that the unit scale is set to meters (Unit Scale = 1.0, Length = Meters). The GLB files saved this way have correct real-world dimensions—for example, a wall 30 meters long is indeed 30 meters in the exported GLB file.
I then convert the GLB to USD using a headless Python script in Isaac Sim with the omni.kit.asset_converter API. Here’s the relevant part of the code I’m using:
python
CopyEdit
# ==== Function: Convert a GLB to USD ====
async def convert_glb_to_usd(input_path: Path, output_path: Path):
converter = asset_converter.get_instance()
ctx = asset_converter.AssetConverterContext()
# Set all meter-related context attributes
ctx.use_meter_as_world_unit = True # Set stage metadata to meters
ctx.ignore_materials = False
ctx.embed_textures = True
ctx.allow_material_conversion = True
ctx.create_materials = True
ctx.flatten = False
task = converter.create_converter_task(str(input_path), str(output_path), ctx)
await task.wait_until_finished()
status = task.get_status()
if status != "succeeded":
print(f" [SUCCESS] Initial USD Saved: {output_path}")
return
print(f"[FAILED]:", task.get_error_message())
Despite setting ctx.use_meter_as_world_unit = True, the resulting USD file still has its stage units in centimeters (metersPerUnit = 0.01).
This leads to a problem:
If I load this USD again and explicitly set the stage metadata using:
python
stage.SetMetadata("metersPerUnit", 1.0)
Then the 30-meter wall which was stored as 3000 cm in the USD (using the above asset_converter) is now interpreted as 3000 meters, which is incorrect. This forces me to manually scale the model down to 0.01 to fix it, which I want to avoid entirely.
My Goal:
I’m looking for a reliable way to convert a GLB (authored in meters) to USD such that:
- The world units are set to meters (
metersPerUnit = 1.0) - The geometry is correctly scaled (i.e., a 30 m wall stays 30 m in USD, not 3000 m)
I found this JSON example in some documentation that seems to imply such a configuration is possible:
json
{
"import_path": "/path/to/animated_model.glb",
"output_path": "/path/to/output/animated_model.usd",
"converter_settings": {
"merge_all_meshes": false,
"smooth_normals": true,
"embed_mdl_in_usd": true,
"embed_textures": true,
"create_world_as_default_root_prim": true,
"ignore_animations": false,
"ignore_camera": false,
"ignore_light": false,
"ignore_materials": false,
"use_meter_as_world_unit": true
}
}
But I’m not sure how to apply this correctly using the Python API, and whether it handles the scaling properly internally.
Is there a known way to preserve actual meter dimensions during GLB → USD conversion and set the USD’s metersPerUnit = 1.0 without creating the 100× scaling issue?
Thanks in advance for any help!