Skip to content

USDLoader - #18738

Draft
alexchuber wants to merge 5 commits into
BabylonJS:masterfrom
alexchuber:feat/usd-loader/usda-no-composition
Draft

USDLoader#18738
alexchuber wants to merge 5 commits into
BabylonJS:masterfrom
alexchuber:feat/usd-loader/usda-no-composition

Conversation

@alexchuber

Copy link
Copy Markdown
Member

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.

alexchuber and others added 5 commits July 27, 2026 10:55
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
Copilot AI review requested due to automatic review settings July 27, 2026 16:38
@bjsplat

bjsplat commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

@bjsplat

bjsplat commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Reviewer - this PR has made changes to one or more package.json files.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +167 to +171
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])
);
@bjsplat

bjsplat commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Snapshot stored with reference name:
refs/pull/18738/merge

Test environment:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18738/merge/index.html

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
https://sandbox.babylonjs.com/?snapshot=refs/pull/18738/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18738/merge
https://nme.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.

@bjsplat

bjsplat commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

🟢 Memory Leak Test Results

4 passed, 0 leaked out of 4 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (4)
Scenario Package
Core Playground #2FDQT5#1508 @babylonjs/core
Core Playground #T90MQ4#14 @babylonjs/core
Core Playground #8EDB5N#2 @babylonjs/core
Core Playground #LL5BIQ#636 @babylonjs/core

@bjsplat

bjsplat commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

@bjsplat

bjsplat commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants