Skip to content

Conversation

NthTensor
Copy link
Contributor

Objective

Add a dedicated 2d transform type. Having to deal with 3d math for 2d logic is no fun at all.

Solution

  • Rename Transform to Transform3d (This is the bulk of the diff).
  • Add a new Transform2d type using Rot2 and Vec2.

This is a draft PR, with the bare-bones logic scaffolded out. It lacks polish and testing. Putting it up now so I can sense how people feel about these changes.

Questions for Reviewers

  • Why are you reviewing this?
  • How are you reviewing this?
  • Why would anyone want to review this?

And more seriously:

  • We can reduce the api churn significantly by simply keeping the current name of Transform, or exporting it as an alias for Transform3d. Is this worth it?

@NthTensor NthTensor changed the title Transform 2d 2d Transforms May 26, 2025
@NthTensor NthTensor added C-Usability A targeted quality-of-life change that makes Bevy easier to use A-Transform Translations, rotations and scales M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide M-Needs-Release-Note Work that should be called out in the blog due to impact S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels May 26, 2025
@rparrett
Copy link
Contributor

rparrett commented May 26, 2025

Is the intended mechanism for controlling draw order / "z index" using Transform3d instead?

Or are there plans to add another component on top of this changeset?

@NthTensor
Copy link
Contributor Author

NthTensor commented May 26, 2025

Is the intended mechanism for controlling draw order / "z index" using Transform3d instead?
Or are there plans to add another component on top of this changeset?

This is the first of a few PRs I have planned. For the initial implementation, if you want to have layers just parent a 3d transform to a 2d transform. 2d transforms are in effect 3d transforms which only let you specify coords in XY, and you can mix-and-match 2d and 3d within the same hierarchy.

I'd like to have a z index solution, but I think it should be built on top. I certainly don't want to do it as part of this PR, which is very large and mostly mechanical.

@rparrett
Copy link
Contributor

parent a 3d transform to a 2d transform ... mix-and-match 2d and 3d within the same hierarchy.

That sounds pretty unpleasant. I would personally rather deal with quaternions.

This is the first of a few PRs I have planned.

It would be helpful to see an outline / timeline of this plan. It is hard to get a feeling for what working in 2d will be like without this.

@NthTensor
Copy link
Contributor Author

NthTensor commented May 26, 2025

That sounds pretty unpleasant. I would personally rather deal with quaternions.

Could you expand on this? Clearly it's not ideal but this is a stronger reaction than I was expecting. What about it is so unpleasant? Here's a quick sample of what I was picturing:

commands.spawn((
    Name("Layer five")
    Transform3d::from_translation(Vec3::Z * 5.0), // Add a layer at +5 Z.
    children![
        (MyComponent, Transform2d::from_translation(Vec2::splat(10.0))) // X 10, Y 10, Z 5
        /* Add all the things to your layer here */
    ]
));

It would be helpful to see an outline / timeline of this plan. It is hard to get a feeling for what working in 2d will be like without this.

Yeah, that's fair. I can't give one, since this is pretty early in the process. I wanted to gauge if a working group would be necessary to get this in, and now it seems like it might be.

Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@rparrett
Copy link
Contributor

rparrett commented May 27, 2025

Could you expand on this?

A bit of a gut (perhaps over-)reaction to the idea of adding more layers of hierarchy to my stuff, but:

If I want to spawn an entity on a particular layer that already exists, I now have an added step of looking up a layer entity.

If I want to move an entity from one layer to another, I now need to look up the new layer entity and reparent the entity.

If my character has a sword which must be drawn on top of the main sprite, and a cape which must be drawn below the main sprite, I guess I'm using Transform3d / quats anyway?

If I have 1000 entities and just want to ensure a particular consistent render order, I guess I'm using Transform3d / quats, or dealing with another layer of hierarchy when I want to interact with the entity.

There are probably other use-cases like isometric / y-sorting that don't fit neatly into the "layers" approach, and it is nice that Transform3d is there are a fallback.

I'm not anti-Transform2d, but it would be hard for me to imagine releasing the feature without some other solution to this.

@NthTensor
Copy link
Contributor Author

NthTensor commented May 27, 2025

Great, that makes a lot of sense. Yeah, I totally see your concerns.

I'm trying to figure out how to cut this change up into manageable bits. There's a lot we need to do with transforms, and if we go for all of them at once it's going to be a slog.

What would your ideal API be? I do want to land this along with a proper z-layer solution within the same release cycle, but I'm worried about pinning them together so closely: These changes are big and (mostly) uncontroversial, and the z-layer api will be smaller and much more prone to bike-shedding. Is there a temporary fix that would make this more palatable in the meantime? For instance, if Transform2d had a z: f32 component, that seems like it would help with a lot of the non-hierarchy-layered depth issues you mentioned.

@tbillington
Copy link
Contributor

What about an optional ZIndex component. Read it into transform3d's z POS if it exists otherwise 0.

@NthTensor
Copy link
Contributor Author

NthTensor commented Jun 9, 2025

@tychedelia was wonderful and wrote a y-sorting implementation for us here: #19463. There's a working group on the discord to discuss next steps, and I've collected some of my thoughts here.

I agree that shipping this without a sorting solution isn't ideal, so I'd like to get some sort of graphical sorting merged as part of this package.

/// TODO
pub rotation: Rot2,
/// TODO
pub scale: f32,
Copy link
Contributor

@ConnerPetzold ConnerPetzold Jun 13, 2025

Choose a reason for hiding this comment

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

Is there a reason to only allow uniform scaling? Could this be a Vec2 instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just initial simplicity. I want to look and 2D and 3D scaling in a follow up PR

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

Labels

A-Transform Translations, rotations and scales C-Usability A targeted quality-of-life change that makes Bevy easier to use M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide M-Needs-Release-Note Work that should be called out in the blog due to impact S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants