USDLoader - #18738
Conversation
Introduce the USD SceneLoader plugin, Sdf model, parser and resolver, resolved-stage contract, Babylon adapters, and initial geometry coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 96a2032c-9f46-4633-8c91-93918442c15a
Surface parser diagnostics, add the pinned USDA corpus, support xform stacks and inherited visibility, and strengthen string and version handling. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 96a2032c-9f46-4633-8c91-93918442c15a
Select USDA by content, reject binary containers, validate mesh topology, primvars and GeomSubsets, and enforce finite USD timing semantics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 96a2032c-9f46-4633-8c91-93918442c15a
Parse typed values strictly, resolve inherited materials and UV networks safely, and cap UTF-8 input, token count, and parser work. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 96a2032c-9f46-4633-8c91-93918442c15a
Reject composition and external USD layers, remove USDC/USDZ and out-of-profile schema adapters, and retain only the supported single-layer USDA pipeline. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 96a2032c-9f46-4633-8c91-93918442c15a
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
|
Reviewer - this PR has made changes to one or more package.json files. |
There was a problem hiding this comment.
Pull request overview
This PR introduces an experimental OpenUSD loader as a Babylon SceneLoader plugin, focused on importing single-layer USDA text (including textual .usd), with an explicit non-goal of supporting USD composition/layering for now. The implementation is split into a resolution layer (format sniffing, parsing, single-layer policy validation, stage mapping) and a Babylon adapter layer (meshes/materials/cameras/skeletons/animations).
Changes:
- Adds a new USD loader plugin (
USDFileLoader) with content sniffing (USDA vs USDC vs USDZ), structured diagnostics, and resource-limit enforcement for untrusted input. - Implements resolved-stage mapping + Babylon adaptation for key USD features (mesh geometry, PreviewSurface materials, cameras, transforms/visibility, skinning + skeleton animation), along with a substantial unit-test and corpus harness.
- Wires the loader into tree-shaking/side-effects manifests, dynamic loader registration, public package exports, and visualization test configuration.
Reviewed changes
Copilot reviewed 84 out of 87 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| scripts/treeshaking/side-effects-manifest/loaders/USD.json | Declares side-effect entry points for USD loader registration and module augmentation. |
| packages/tools/tests/test/visualization/config.json | Adds a visualization test entry for a USD loader playground/corpus scenario. |
| packages/public/@babylonjs/loaders/package.json | Ships the built USD loader entry (USD/usdFileLoader.js) in the public loaders package. |
| packages/dev/loaders/package.json | Adds fflate to devDependencies (used by existing SPLAT code via import("fflate") typing). |
| package-lock.json | Lockfile update reflecting added dev dependency. |
| packages/dev/loaders/src/pure.ts | Exports the new USD pure barrel from the loaders pure entry. |
| packages/dev/loaders/src/index.ts | Exports the USD loader from the loaders main entry. |
| packages/dev/loaders/src/dynamic.ts | Registers the USD loader as a dynamically-imported built-in SceneLoader plugin. |
| packages/dev/loaders/src/USD/usdLoadingOptions.ts | Defines loader options (FPS override + parser/resource budgets). |
| packages/dev/loaders/src/USD/usdFileLoader.metadata.ts | Defines plugin name/extensions and the “read bytes then sniff” policy for .usd/.usda. |
| packages/dev/loaders/src/USD/usdFileLoader.types.ts | Adds SceneLoader plugin option typing for the USD loader. |
| packages/dev/loaders/src/USD/usdFileLoader.ts | Side-effect wrapper that re-exports and registers the loader. |
| packages/dev/loaders/src/USD/usdFileLoader.pure.ts | Core loader implementation: exclusive-load queueing, diagnostics logging, asset-container support, raw byte limit guard, normalization. |
| packages/dev/loaders/src/USD/usdErrors.ts | Introduces typed errors for resource limits, invalid configuration, and unsupported binary containers. |
| packages/dev/loaders/src/USD/pure.ts | Pure barrel exports for side-effect-free consumption (resolver, adapter, data contracts). |
| packages/dev/loaders/src/USD/index.ts | Main USD barrel exports (includes registered loader wrapper). |
| packages/dev/loaders/src/USD/resolution/usdResolver.ts | Resolution entry point: sniff container, enforce input limits, parse USDA, apply single-layer policy, map + freeze resolved stage, propagate diagnostics. |
| packages/dev/loaders/src/USD/resolution/assetPath.ts | Resolves relative asset identifiers (URL-aware, supports dropped-file scheme). |
| packages/dev/loaders/src/USD/resolution/sdf/index.ts | Sdf model type barrel. |
| packages/dev/loaders/src/USD/resolution/sdf/sdfLayer.ts | Defines the plain-data Sdf layer model used at the parser→policy seam. |
| packages/dev/loaders/src/USD/resolution/sdf/sdfListOp.ts | Defines list-op model + canonical “standalone list op” flattener. |
| packages/dev/loaders/src/USD/resolution/sdf/sdfSpec.ts | Defines prim/property specs and composition-arc fields for detection/rejection in single-layer policy. |
| packages/dev/loaders/src/USD/resolution/mapping/mappingContext.ts | Defines shared mapping context for stage mapping (pools, lookups, diagnostics). |
| packages/dev/loaders/src/USD/resolution/mapping/valueAccess.ts | Implements typed helpers for reading Sdf values/attributes/relationships. |
| packages/dev/loaders/src/USD/resolution/mapping/cameraMapping.ts | Maps UsdGeomCamera authored attributes into resolved camera payloads. |
| packages/dev/loaders/src/USD/resolution/mapping/animationMapping.ts | Bakes timeSamples into resolved animation tracks (incl. visibility/transform channels). |
| packages/dev/loaders/src/USD/adapter/usdAdapter.ts | Adapts a resolved stage into Babylon scene entities and returns an ISceneLoaderAsyncResult. |
| packages/dev/loaders/src/USD/adapter/sceneGraphAdapter.ts | Walks resolved prim tree and instantiates Babylon nodes/meshes/materials/cameras/skeletons/animations. |
| packages/dev/loaders/src/USD/adapter/transformAdapter.ts | Creates stage root (RH mode, up-axis/unit conversion) and applies resolved transforms (matrix or TRS). |
| packages/dev/loaders/src/USD/adapter/animationAdapter.ts | Converts resolved animation tracks into Babylon Animations and assembles animation groups. |
| packages/dev/loaders/src/USD/adapter/cameraAdapter.ts | Converts resolved cameras into Babylon cameras (perspective/ortho mapping). |
| packages/dev/loaders/src/USD/adapter/materialAdapter.ts | Converts resolved PreviewSurface-style material payloads into Babylon PBRMaterials + textures. |
| packages/dev/loaders/src/USD/adapter/skinningAdapter.ts | Builds Babylon skeletons, applies skinning vertex buffers, and creates skeleton animations. |
| packages/dev/loaders/src/USD/adapter/geometryAdapter.ts | Builds Babylon meshes from resolved geometry buffers, including subdivision tessellation + subsets. |
| packages/dev/loaders/test/unit/USD/usdSpike.test.ts | Phase-0 smoke tests for basic mesh import + failure state cleanup. |
| packages/dev/loaders/test/unit/USD/usdSkinningValidation.test.ts | Validates skel:joints typing and influence index validation behavior. |
| packages/dev/loaders/test/unit/USD/usdResourceLimits.test.ts | Tests parser safety behavior against pathological nesting/variants and typed resource limit errors. |
| packages/dev/loaders/test/unit/USD/usdParserResourceLimits.test.ts | Tests configurable parser budgets (bytes/tokens/work), configuration validation, and boundary enforcement. |
| packages/dev/loaders/test/unit/USD/usdParserDiagnostics.test.ts | Tests propagation/logging of recoverable parser diagnostics vs fatal parse failures. |
| packages/dev/loaders/test/unit/USD/usdFormatSniffing.test.ts | Tests metadata + container sniffing (USDA accepted; USDC/USDZ rejected with typed errors). |
| packages/dev/loaders/test/unit/USD/usdFidelityDiagnostics.test.ts | Ensures unsupported/approximated features produce honest diagnostics. |
| packages/dev/loaders/test/unit/USD/usdCorpusSmoke.test.ts | Offline pinned corpus harness for in-profile vs out-of-profile fixtures (end-to-end resolution + loader). |
| packages/dev/loaders/test/unit/USD/usdContracts.test.ts | Validates resolved-stage immutability contract + RH adaptation invariants. |
| packages/dev/loaders/test/unit/USD/usdConformance.test.ts | End-to-end conformance-style tests for animation baking and skeleton binding via public loader. |
| packages/dev/loaders/test/unit/USD/transformHierarchyVisibility.test.ts | Tests xformOpOrder semantics, reset/invert behavior, inherited visibility, and adapter outcomes. |
| packages/dev/loaders/test/unit/USD/transformAdapter.test.ts | Unit tests for stage-root conversion and transform application behavior. |
| packages/dev/loaders/test/unit/USD/skinningAdapter.test.ts | Unit tests for skeleton creation, skinning buffer binding, and skeleton animation construction. |
| packages/dev/loaders/test/unit/USD/skeletonMapping.test.ts | Tests mapping of Skeleton/SkelAnimation/mesh skinning into resolved stage structures. |
| packages/dev/loaders/test/unit/USD/sdfModel.test.ts | Validates Sdf data model expressiveness for metadata, arcs, and variant structures. |
| packages/dev/loaders/test/unit/USD/sdfListOp.test.ts | Validates canonical standalone list-op flattening behavior. |
| packages/dev/loaders/test/unit/USD/materialAdapter.test.ts | Unit tests for resolved material → Babylon PBR material mapping. |
| packages/dev/loaders/test/unit/USD/geometryAdapter.test.ts | Unit tests for mesh creation, normals generation, subdivision, primvar buffers, and subsets. |
| packages/dev/loaders/test/unit/USD/cameraMapping.test.ts | Unit tests for camera mapping defaults and diagnostic behavior. |
| packages/dev/loaders/test/unit/USD/cameraAdapter.test.ts | Unit tests for resolved camera → Babylon camera conversion. |
| packages/dev/loaders/test/unit/USD/assetPath.test.ts | Unit tests for asset identifier resolution (URLs, root-relative, data URIs). |
| packages/dev/loaders/test/unit/USD/animationAdapter.test.ts | Unit tests for resolved animation tracks → Babylon animation keys/groups. |
| packages/dev/loaders/test/unit/USD/corpus/PROVENANCE.md | Documents corpus provenance, pinning, and licensing/attribution. |
| packages/dev/loaders/test/unit/USD/corpus/parser/simple.usda | Pinned USDA parser fixture. |
| packages/dev/loaders/test/unit/USD/corpus/parser/simple.json | Golden parse oracle for the pinned USDA parser fixture. |
| packages/dev/loaders/test/unit/USD/corpus/geometry/triangles.usda | Pinned geometry corpus fixture (triangulated cube). |
| packages/dev/loaders/test/unit/USD/corpus/geometry/mixed.usda | Pinned geometry corpus fixture (mixed face counts). |
| packages/dev/loaders/test/unit/USD/corpus/geometry/subdiv_none.usda | Pinned geometry corpus fixture (explicit no subdivision). |
| packages/dev/loaders/test/unit/USD/corpus/transforms/simple_transform.usda | Pinned transform corpus fixture (TRS xformOp stack). |
| packages/dev/loaders/test/unit/USD/corpus/transforms/matrix_transform.usda | Pinned transform corpus fixture (matrix xformOp). |
| packages/dev/loaders/test/unit/USD/corpus/scenes/animated_cube_translation.usda | Pinned scene corpus fixture with camera + animated translation. |
| packages/dev/loaders/test/unit/USD/corpus/out-of-scope/subdiv_catmullClark.usda | Out-of-profile corpus fixture to assert diagnostic behavior for subdivision. |
| packages/dev/loaders/test/unit/USD/corpus/out-of-scope/materialx_basic.usda | Out-of-profile corpus fixture to assert diagnostic behavior for external references. |
| packages/dev/loaders/test/unit/USD/corpus/out-of-scope/implicit_sphere.usda | Out-of-profile corpus fixture to assert diagnostic behavior for implicit gprims. |
| function QuaternionFromEulerXyz(degrees: Vec3): Quat { | ||
| return MultiplyQuaternions( | ||
| MultiplyQuaternions(QuaternionFromAxisAngle([1, 0, 0], degrees[0]), QuaternionFromAxisAngle([0, 1, 0], degrees[1])), | ||
| QuaternionFromAxisAngle([0, 0, 1], degrees[2]) | ||
| ); |
|
Snapshot stored with reference name: Test environment: To test a playground add it to the URL, for example: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18738/merge/index.html#WGZLGJ#4600 Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves): https://playground.babylonjs.com/?snapshot=refs/pull/18738/merge To test the snapshot in the playground with a playground ID add it after the snapshot query string: https://playground.babylonjs.com/?snapshot=refs/pull/18738/merge#BCU1XR#0 If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools. |
🟢 Memory Leak Test Results4 passed, 0 leaked out of 4 scenarios 🟢 All memory leak tests passed — no leaks detected. Passed Scenarios (4)
|
|
WebGL2 visualization test reporter: |
⚡ Performance Test Results🟢 All performance tests passed — no regressions detected. |
|
Visualization tests for WebGPU |
Summary
This draft adds an experimental USD loader, a SceneLoader plugin, to allow for the import of USD assets into Babylon.
It starts by targeting the simplest useful case: a human-readable USDA file that contains the scene directly. No other USD layers should need to be loaded or combined. This lets the first PR focus on parsing USDA and converting a useful set of USD types into Babylon meshes, materials, cameras, skeletons, and animations.
USD can also build scenes by combining layers, references, variants, payloads, inheritance, and overrides-- all referred to as layering & composition. This PR does not implement layering or composition support.
For now, a composed USD scene can often be prepared for this loader by flattening it into one layer. This will not make every USD asset work yet: the loader supports only part of USD, and flattening may preserve some composition arcs that this loader can't yet handle (e.g., references used for instancing may still appear in a flattened asset.)
Later PRs may extend on this by implementing USDC, USDZ, layering, and/or composition support.
Longer term, a good target (I think) is the scene returned by OpenUSD’s normal
UsdStage::Traverse(): the active, defined, loaded, and concrete prims that make up the final scene. This PR is the first step toward that goal.