Skip to content

Add TypeScript FBX loader#18483

Draft
PatrickRyanMS wants to merge 10 commits into
BabylonJS:masterfrom
PatrickRyanMS:fbx-loader
Draft

Add TypeScript FBX loader#18483
PatrickRyanMS wants to merge 10 commits into
BabylonJS:masterfrom
PatrickRyanMS:fbx-loader

Conversation

@PatrickRyanMS
Copy link
Copy Markdown
Member

@PatrickRyanMS PatrickRyanMS commented May 20, 2026

🤖 This PR was created by the create-pr skill.

Summary

  • Add a built-in SDK-free FBX loader with binary/ASCII parsing, scene interpretation, meshes, materials, textures, skeletons, animation groups, cameras, and lights.
  • Register and export the FBX loader through the loaders package, including dynamic loader registration and SceneLoader plugin options.
  • Add focused unit coverage for FBX parsing/interpreter behavior, loader registration, material texture handling, normal-map coordinate options, embedded texture loading, and asset-container ownership.

Notes

  • FBX normal-map slots default to Y-up tangent-space convention, with an opt-in Y-down loader option.
  • FBX Bump and BumpFactor slots are treated as normal-map-like inputs for compatibility until true grayscale height-to-normal conversion is implemented.
  • Embedded FBX textures use Babylon's delayed texture buffer path; sidecar textures remain supported when no embedded bytes are present.
  • Visual test assets are still being prepared and will be added before this draft is marked ready.

Validation

  • npm run compile -w @dev/loaders
  • npm run test -- packages/dev/loaders/test/unit
  • npm run format:check

npm run lint:check currently fails on pre-existing core tree-shaking manifest/side-effect-stub drift outside the FBX changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

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.

@PatrickRyanMS
Copy link
Copy Markdown
Member Author

I added two initial test models for visual testing to the assets repo. I need to build out all of the visual test variations, but wanted to get this in draft PR for review since it's large while I build out the visual test assets.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

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

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

To test a playground add it to the URL, for example:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18483/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/18483/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18483/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18483/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18483/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/18483/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
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

🟢 Memory Leak Test Results

13 passed, 0 leaked out of 13 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (13)
Scenario Package
Core Feature Stack @babylonjs/core
Core Rendering Materials Shadows Stack @babylonjs/core
Core Textures Render Targets PostProcess Stack @babylonjs/core
GUI Fullscreen UI Controls @babylonjs/gui
GUI Mesh ADT Controls @babylonjs/gui
Loaders Boombox Import @babylonjs/loaders
Loaders OBJ Direct Load @babylonjs/loaders
Loaders STL Direct Load @babylonjs/loaders
Materials Library Stack @babylonjs/materials
Serializers glTF Export @babylonjs/serializers
Serializers GLB Export @babylonjs/serializers
PostProcesses Digital Rain Stack @babylonjs/post-processes
Procedural Textures Stack @babylonjs/procedural-textures

@RaananW
Copy link
Copy Markdown
Member

RaananW commented May 20, 2026

Just explaining the reason it fails on native (before fully reviewing this) -

This PR uses BigInt syntax (let nextLegacyId = -1n;), which babylon native doesn't support. if possible we should use the standard number system. if BitInt is needed we should find a good solution for native support.

@deltakosh deltakosh removed request for bghgary and sebavan May 20, 2026 15:22
@deltakosh
Copy link
Copy Markdown
Contributor

@RaananW I'll take care of it. We dont need bigint

deltakosh and others added 2 commits May 20, 2026 08:45
Remove bigint usage from the FBX loader and harden parser validation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Document SceneLoader callback parameters for FBX public loader methods.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

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
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

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

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

To test a playground add it to the URL, for example:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18483/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/18483/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18483/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18483/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18483/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/18483/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
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 20, 2026

🟢 Memory Leak Test Results

13 passed, 0 leaked out of 13 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (13)
Scenario Package
Core Feature Stack @babylonjs/core
Core Rendering Materials Shadows Stack @babylonjs/core
Core Textures Render Targets PostProcess Stack @babylonjs/core
GUI Fullscreen UI Controls @babylonjs/gui
GUI Mesh ADT Controls @babylonjs/gui
Loaders Boombox Import @babylonjs/loaders
Loaders OBJ Direct Load @babylonjs/loaders
Loaders STL Direct Load @babylonjs/loaders
Materials Library Stack @babylonjs/materials
Serializers glTF Export @babylonjs/serializers
Serializers GLB Export @babylonjs/serializers
PostProcesses Digital Rain Stack @babylonjs/post-processes
Procedural Textures Stack @babylonjs/procedural-textures

Comment thread specs/fbx-loader/architecture.md Outdated
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.

Is the specs folder a thing now? I only see one file in this folder right now for tree shaking.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor

@Popov72 Popov72 left a comment

Choose a reason for hiding this comment

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

Code review comments from Copilot CLI. I left out the quality-gate notes as requested.

Comment thread packages/dev/loaders/src/FBX/interpreter/geometry.ts
Comment thread packages/dev/loaders/src/FBX/interpreter/blendShapes.ts Outdated
Comment thread packages/dev/loaders/src/FBX/interpreter/animation.ts
Comment thread packages/dev/loaders/src/FBX/fbxFileLoader.ts Outdated
Comment thread packages/dev/loaders/src/FBX/types/fbxTypes.ts
Comment thread packages/dev/loaders/src/FBX/parsers/fbxBinaryParser.ts
Comment thread packages/dev/loaders/test/unit/FBX/materials.test.ts Outdated
…tion standards.

Changes made:
- Removed the standalone FBX architectural/spec documentation from `specs/fbx-loader`.
- Kept documentation coverage limited to source-level TSDoc/JSDoc for public API surfaces.
- Added missing TSDoc for `FBXFileLoaderMetadata`, `FBXFileLoader.name`, and `FBXFileLoader.extensions`.
- Fixed a changed-file lint issue in the FBX material tests by replacing the directory barrel import `core/Engines` with `core/Engines/nullEngine`.

Validation:
- Confirmed there are no remaining markdown/text documentation changes in the effective branch diff.
- Confirmed edited FBX source files have no VS Code diagnostics.
- Ran changed-file eslint coverage via `npx.cmd eslint ...`; it passes cleanly.
- Note: `npm run lint:changed` still exits with `ENOENT` in this Windows shell because the script uses `spawnSync("npx", ...)`, but the equivalent `npx.cmd` eslint command passes.
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

🟢 Memory Leak Test Results

13 passed, 0 leaked out of 13 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (13)
Scenario Package
Core Feature Stack @babylonjs/core
Core Rendering Materials Shadows Stack @babylonjs/core
Core Textures Render Targets PostProcess Stack @babylonjs/core
GUI Fullscreen UI Controls @babylonjs/gui
GUI Mesh ADT Controls @babylonjs/gui
Loaders Boombox Import @babylonjs/loaders
Loaders OBJ Direct Load @babylonjs/loaders
Loaders STL Direct Load @babylonjs/loaders
Materials Library Stack @babylonjs/materials
Serializers glTF Export @babylonjs/serializers
Serializers GLB Export @babylonjs/serializers
PostProcesses Digital Rain Stack @babylonjs/post-processes
Procedural Textures Stack @babylonjs/procedural-textures

Addresses Popov72's review comment on PR BabylonJS#18483:
BabylonJS#18483 (comment)

Read Materials[0] for LayerElementMaterial entries using
MappingInformationType "AllSame" instead of assuming slot 0. Preserve
non-zero all-same slots through triangulation so meshes with multiple
connected materials resolve the intended material.

Also fixes the FBX material test NullEngine import noted in:
BabylonJS#18483 (comment)
Addresses Popov72's review comment on PR BabylonJS#18483:
BabylonJS#18483 (comment)

Validate that binary FBX data contains the full 27-byte header before
reading the version field, so malformed files produce a controlled parse
error instead of a raw RangeError.
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

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.

Addresses Popov72's review comment on PR BabylonJS#18483:
BabylonJS#18483 (comment)

Convert numeric typed arrays for Shape Indexes so ASCII FBX shorthand
arrays parsed as Float64Array do not cause morph targets to be dropped.
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

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.

Addresses Popov72's review comment on PR BabylonJS#18483:
BabylonJS#18483 (comment)

Convert numeric typed arrays for KeyAttrFlags and KeyAttrRefCount so ASCII
FBX shorthand arrays parsed as Float64Array preserve constant and cubic
interpolation flags.

Also add missing TSDoc for exported animation diagnostic types and curve
sampling helpers touched by this change.
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

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.

Addresses Popov72's review comment on PR BabylonJS#18483:
BabylonJS#18483 (comment)

Reject numeric FBX object IDs that cannot be represented as safe JavaScript
integers before they enter number-keyed object and connection maps. This
prevents precision loss from miswiring materials, skins, animations, or
hierarchy relationships.

Also add missing TSDoc for exported FBX document and connection graph types
touched by this change.
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

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.

Addresses Popov72's review comment on PR BabylonJS#18483:
BabylonJS#18483 (comment)

Continue traversing mesh subtrees when a parent mesh does not match
meshesNames but a descendant does. Use a TransformNode placeholder for the
filtered parent so requested child meshes can be imported with hierarchy
preserved.
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

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
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

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

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

To test a playground add it to the URL, for example:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18483/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/18483/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18483/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18483/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18483/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/18483/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
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 26, 2026

🟢 Memory Leak Test Results

13 passed, 0 leaked out of 13 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (13)
Scenario Package
Core Feature Stack @babylonjs/core
Core Rendering Materials Shadows Stack @babylonjs/core
Core Textures Render Targets PostProcess Stack @babylonjs/core
GUI Fullscreen UI Controls @babylonjs/gui
GUI Mesh ADT Controls @babylonjs/gui
Loaders Boombox Import @babylonjs/loaders
Loaders OBJ Direct Load @babylonjs/loaders
Loaders STL Direct Load @babylonjs/loaders
Materials Library Stack @babylonjs/materials
Serializers glTF Export @babylonjs/serializers
Serializers GLB Export @babylonjs/serializers
PostProcesses Digital Rain Stack @babylonjs/post-processes
Procedural Textures Stack @babylonjs/procedural-textures

Copy link
Copy Markdown
Contributor

@Popov72 Popov72 left a comment

Choose a reason for hiding this comment

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

The PR description still says this adds specs/fbx-loader documentation, but the latest commits remove that folder. Can you either restore the specs or update the PR description if the deletion is intentional?

@PatrickRyanMS
Copy link
Copy Markdown
Member Author

The PR description still says this adds specs/fbx-loader documentation, but the latest commits remove that folder. Can you either restore the specs or update the PR description if the deletion is intentional?

Yes, the deletion was intentional, so I updated the PR description.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants