Skip to content

Allow users to fix glTF coordinate system imports #19633

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 40 commits into from
Jun 16, 2025

Conversation

janhohenheim
Copy link
Member

@janhohenheim janhohenheim commented Jun 13, 2025

Objective

Fixes #5670 as an opt-in for now

glTF uses the following coordinate system:

  • forward: Z
  • up: Y
  • right: -X

and Bevy uses:

  • forward: -Z
  • up: Y
  • right: X

For the longest time, Bevy has simply ignored this distinction. That caused issues when working across programs, as most software respects the
glTF coordinate system when importing and exporting glTFs. Your scene might have looked correct in Blender, Maya, TrenchBroom, etc. but everything would be flipped when importing it into Bevy!

Solution

Add an option to the glTF loader to perform coordinate conversion. Note that this makes a distinction in the camera nodes, as glTF uses a different coordinate system for them.

Follow Ups

  • Add global glTF loader settings, similar to the image loader, so that users can make third-party crates also load their glTFs with corrected coordinates
  • Decide on a migration strategy to make this the future default
    • Create an issue
    • Get feedback from Patrick Walton and Cart (not pinging them here to not spam them)
    • Include this pic for reference of how Blender assumes -Y as forward:
      image

Testing

I ran all glTF animation examples with the new setting enabled to validate that they look the same, just flipped.

Also got a nice test scene from Chris that includes a camera inside the glTF. Thanks @ChristopherBiscardi!

Blender (-Y forward):
image

Bevy (-Z forward, but the model looks the wrong way):
image

Bevy with convert_coordinates enabled (-Z forward):
image

Validation that the axes are correct with F3D's glTF viewer (+Z forward):
image

@janhohenheim janhohenheim added M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide X-Blessed Has a large architectural impact or tradeoffs, but the design has been endorsed by decision makers D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward A-glTF Related to the glTF 3D scene/model format labels Jun 13, 2025
Copy link
Contributor

You added a new feature but didn't update the readme. Please run cargo run -p build-templated-pages -- update features to update it, and commit the file change.

@janhohenheim
Copy link
Member Author

Will fix the CI and expand the PR description in a few minutes :)

@mockersf
Copy link
Member

  • Will wait until porting the examples until this PR is merged

I would prefer them to be fixed in this PR. Introducing temporary changes in examples makes it harder to sort actual regressions

@janhohenheim
Copy link
Member Author

janhohenheim commented Jun 13, 2025

Sure, can do :)
Edit: actually, this is not necessary. The flag is not enabled by default in this PR, so all examples look exactly the same.

@ChristopherBiscardi
Copy link
Contributor

you can simply

We should remove the term "simply" entirely and make sure that phrasing is not used in the migration guide.

@janhohenheim
Copy link
Member Author

janhohenheim commented Jun 14, 2025

@ChristopherBiscardi done.

Also, I fixed the CI and expanded the PR description. Right now I'm porting all examples, but that will take quite a while. This PR can be merged in the meantime without any issues, as the flag is not enabled by default yet

@ChristopherBiscardi
Copy link
Contributor

Seems to do what it says on the tin re: rotation. I checked a few static assets from kenney and kaykit.

with camera:

    commands.spawn((
        Camera3d::default(),
        Transform::from_xyz(4., 5., 7.0)
            .looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
    ));

before:

before

after (with feature flag):

after

@janhohenheim
Copy link
Member Author

janhohenheim commented Jun 14, 2025

Alright, fixed the camera issues. See the PR description.

I've been thinking about this some more, and I really think that it would be better to split this off into two PRs, as described above. I'd like

  • Have one PR that just allows you to set the conversion option in the loader manually. No defaults changed, just an opt-in for coordinate conversion. Then,
  • do a second PR that introduces some migration strategy. This could be right after, or we could even wait a release with this while the opt-in already exists, to see whether it is causing issues.

I believe this approach will allow us to separate the concerns of

  • Implement the functionality (technical, not controversial, fairly simple)
  • Migrate the default (nontechnical, controversial, requires careful deliberation, maybe not even wanted in the end)

Does that sound good to you, @alice-i-cecile?

@janhohenheim janhohenheim added S-Needs-Review Needs reviewer attention (from anyone!) to move forward and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Jun 14, 2025
@janhohenheim
Copy link
Member Author

Update: got Alice's okay for the above plan on Discord :)

@janhohenheim janhohenheim removed X-Controversial There is active debate or serious implications around merging this PR M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide labels Jun 14, 2025
@alice-i-cecile alice-i-cecile added the X-Uncontroversial This work is generally agreed upon label Jun 14, 2025
@alice-i-cecile alice-i-cecile changed the title Fix glTF coordinate system imports Allow users to fix glTF coordinate system imports Jun 14, 2025
@alice-i-cecile alice-i-cecile added this to the 0.17 milestone Jun 14, 2025
@alice-i-cecile alice-i-cecile added the M-Needs-Release-Note Work that should be called out in the blog due to impact label Jun 14, 2025
Copy link
Contributor

It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note.

Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes.

@alice-i-cecile
Copy link
Member

Now that this is opt-in and not breaking, I want a brief release note to gather feedback please.

@janhohenheim
Copy link
Member Author

janhohenheim commented Jun 14, 2025

@alice-i-cecile done 👍
Will additionally expand the release notes when I'm adding global default glTF import settings in a followup PR

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jun 15, 2025
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Jun 16, 2025
Merged via the queue into bevyengine:main with commit 9b743d2 Jun 16, 2025
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-glTF Related to the glTF 3D scene/model format D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes M-Needs-Release-Note Work that should be called out in the blog due to impact S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it X-Uncontroversial This work is generally agreed upon
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Coordinate system mismatch between Bevy and glTF
6 participants