Skip to content
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

Fix Maya-exported rigs by not trying to topologically sort glTF nodes. #17641

Merged
merged 1 commit into from
Feb 2, 2025

Conversation

pcwalton
Copy link
Contributor

@pcwalton pcwalton commented Feb 2, 2025

The code added in #14343 seems to be trying to ensure that a Handle for each glTF node exists by topologically sorting the directed graph of glTF nodes containing edges from parent to child and from skin to joint. Unfortunately, such a graph can contain cycles, as there's no guarantee that joints are descendants of nodes with the skin. In particular, glTF exported from Maya using the popular babylon.js export plugin create skins attached to nodes that animate their parent nodes. This was causing the topological sort code to enter an infinite loop.

Assuming that the intent of the topological sort is indeed to ensure that Handles exist for each glTF node before populating them, there's a better mechanism for this: LoadContext::get_label_handle. This is the documented way to obtain a handle for a node before populating it, obviating the need for a topological sort. This patch replaces the topological sort with a pre-pass that uses
LoadContext::get_label_handle to get handles for each Node before populating them. This fixes the problem with Maya rigs, in addition to making the code simpler and faster.

@pcwalton pcwalton added A-glTF Related to the glTF 3D scene/model format C-Bug An unexpected or incorrect behavior S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Feb 2, 2025
@alice-i-cecile alice-i-cecile added this to the 0.16 milestone Feb 2, 2025
Copy link
Contributor

@bushrat011899 bushrat011899 left a comment

Choose a reason for hiding this comment

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

What a great fix, nice work!

@tychedelia tychedelia 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 Feb 2, 2025
The code added in bevyengine#14343 seems to be trying to ensure that a `Handle`
for each glTF node exists by topologically sorting the directed graph of
glTF nodes containing edges from parent to child and from skin to joint.
Unfortunately, such a graph can contain cycles, as there's no guarantee
that joints are descendants of nodes with the skin. In particular, glTF
exported from Maya using the popular babylon.js export plugin create
skins attached to nodes that animate their parent nodes. This was
causing the topological sort code to enter an infinite loop.

Assuming that the intent of the topological sort is indeed to ensure
that `Handle`s exist for each glTF node before populating them, there's
a better mechanism for this: `LoadContext::get_label_handle`. This is
the documented way to obtain a handle for a node before populating it,
obviating the need for a topological sort. This patch replaces the
topological sort with a pre-pass that uses
`LoadContext::get_label_handle` to get handles for each `Node` before
populating them. This fixes the problem with Maya rigs, in addition to
making the code simpler and faster.
@pcwalton
Copy link
Contributor Author

pcwalton commented Feb 2, 2025

The tests failed because I wasn't checking for cycles. I added code to do that.

@mockersf mockersf added this pull request to the merge queue Feb 2, 2025
Merged via the queue into bevyengine:main with commit 7774a62 Feb 2, 2025
32 checks passed
@pcwalton pcwalton deleted the maya-skins branch February 2, 2025 20:12
mrchantey pushed a commit to mrchantey/bevy that referenced this pull request Feb 4, 2025
bevyengine#17641)

The code added in bevyengine#14343 seems to be trying to ensure that a `Handle`
for each glTF node exists by topologically sorting the directed graph of
glTF nodes containing edges from parent to child and from skin to joint.
Unfortunately, such a graph can contain cycles, as there's no guarantee
that joints are descendants of nodes with the skin. In particular, glTF
exported from Maya using the popular babylon.js export plugin create
skins attached to nodes that animate their parent nodes. This was
causing the topological sort code to enter an infinite loop.

Assuming that the intent of the topological sort is indeed to ensure
that `Handle`s exist for each glTF node before populating them, there's
a better mechanism for this: `LoadContext::get_label_handle`. This is
the documented way to obtain a handle for a node before populating it,
obviating the need for a topological sort. This patch replaces the
topological sort with a pre-pass that uses
`LoadContext::get_label_handle` to get handles for each `Node` before
populating them. This fixes the problem with Maya rigs, in addition to
making the code simpler and faster.
joshua-holmes pushed a commit to joshua-holmes/bevy that referenced this pull request Feb 5, 2025
bevyengine#17641)

The code added in bevyengine#14343 seems to be trying to ensure that a `Handle`
for each glTF node exists by topologically sorting the directed graph of
glTF nodes containing edges from parent to child and from skin to joint.
Unfortunately, such a graph can contain cycles, as there's no guarantee
that joints are descendants of nodes with the skin. In particular, glTF
exported from Maya using the popular babylon.js export plugin create
skins attached to nodes that animate their parent nodes. This was
causing the topological sort code to enter an infinite loop.

Assuming that the intent of the topological sort is indeed to ensure
that `Handle`s exist for each glTF node before populating them, there's
a better mechanism for this: `LoadContext::get_label_handle`. This is
the documented way to obtain a handle for a node before populating it,
obviating the need for a topological sort. This patch replaces the
topological sort with a pre-pass that uses
`LoadContext::get_label_handle` to get handles for each `Node` before
populating them. This fixes the problem with Maya rigs, in addition to
making the code simpler and faster.
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 C-Bug An unexpected or incorrect behavior S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants