Make `GlobalTransform` more usable
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## What problem does this solve or what need does it fill?
`GlobalTransform` is useless outside of purely passing data around, due to:
- lack of mutation functions
- impossibility to access its content `Affine3` to modify it (can only get a copy)
- impossibility to create a new `GlobalTransform` (no constructor)
On the other hand it contains valuable functions like `.scale()` not available on other math types (it's indirectly available in `Affine3::to_scale_rotation_translation()` but that assumes you want the full conversion).
## What solution would you like?
- Either add `affine_mut()` as an escape hatch so user can modify the content of an existing instance:
```rust
pub fn affine_mut(&mut self) -> &mut Affine3 { &mut self.0 }
```
- Or move those critical utilities out of `GlobalTransform` into traits or whatnot, if the intent is for `GlobalTransform` to be a storage-only component.
## What alternative(s) have you considered?
I struggled to find one so far, outside of making a bunch of copies and conversions back and forth, like `Affine3::to_scale_rotation_translation()` which is relatively costly when you don't need the full conversion (for example, you only need to apply an extra scale to an existing transform).
## Additional context
Writing some code to display some gizmos for a bunch of objects (the colliders of Avian). This requires access to `GlobalTransform` to display in the correct world location. Some of those may be recursive (e.g. an object to render contains several child objects to render too; note that I'm not talking about the `Transform` hierarchy here, but some other relationship, the Avian compound colliders which have offsets).
- I started by using `&GlobalTransform` which works as long as you pass unmodified transforms around. As soon as you need to mutate, e.g. to add the child position to the parent's global transform to call recursively the draw code, then you're in an impasse because you 1) cannot create a `GlobalTransform` outside Bevy's own code, and 2) cannot access the content of an existing one to mutate it.
- I tried then to use `Affine3` directly, but I need to extract the scale with `GlobalTransform::scale()` which doesn't exist on `Affine3`. I could just copy/paste the implementation but this is ugly and harder to maintain, and defeats the point of having a math library.
- I can't immediately think of any other solution. I guess I'll have to use separate translation/rotation/scale parameters? But then manipulating those probably means locally building a `Transform` or other math type to access their math functions, then re-decomposing back.
Contributor guide
Research direction
Start by reading the existing GlobalTransform and Affine3 APIs, including GlobalTransform::scale() and the limitations described in the issue. Determine the intended ownership and mutability model, then define completion as a documented, maintainable way to manipulate or construct global transforms without unnecessary conversions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100