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

Simultaneous mutable/immutable access to different mesh attributes #2134

Open
SorteKanin opened this issue May 9, 2021 · 6 comments
Open
Labels
A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use

Comments

@SorteKanin
Copy link

What problem does this solve or what need does it fill?

You cannot at the moment have a mutable and an immutable reference to different mesh attributes at the same time. My specific use case that caused me to file this feature requests was when I was trying to calculate normals for a generated mesh. The normals must be calculated from the geometry. Hence I need mutable access to the normals and immutable access to the positions and indices. I need to clone the positions and indices to do this at the moment and I don't think having mutable access to both positions and normals is possible at all. It would be nice if this was possible.

What solution would you like?

Not sure what is best but it would be great if there was a way to access (both mutably and immutably) mesh attributes simultaneously.

What alternative(s) have you considered?

For my specific use case I can clone but this is needlessly expensive. For the use case of simultaneous mutable access to different mesh attributes, I suspect there is no way to do it.

@SorteKanin SorteKanin added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels May 9, 2021
@cart
Copy link
Member

cart commented May 9, 2021

If we stored attributes in a Vec instead of a BTreeMap (or other key/value pair collections like HashMap) we could safely do split_at_mut to get multiple attributes. The downside it that implementation complexity goes up (and lookup perf likely goes down)

@cart
Copy link
Member

cart commented May 9, 2021

It would be nice if rust key/value collections exposed a get_disjoint_mut(keys: &[Key]) -> &mut [Value] style api, but I totally get why they dont. (they need to check for collisions, which is expensive).

@cart
Copy link
Member

cart commented May 9, 2021

Alternatively, we could add interior mutability by wrapping values in RefCell (although Mesh needs to be Send/Sync, which means this would probably need Mutex instead)

@alice-i-cecile alice-i-cecile added A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use and removed C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels May 9, 2021
@SorteKanin
Copy link
Author

I'm just starting out using Bevy and don't know much about the internals, but I'm just shooting ideas here. Could it not be possible to split a mesh into several different components? As in, instead of an entity having a mesh (handle) component, it would have a positions (handle I guess) component and a normals component and so on. Then you could mutably query for both positions and normals components simultaneously, just like you would with other components. Just spitballing, don't know if this is a viable idea.

@cart
Copy link
Member

cart commented May 14, 2021

Meshes are currently stored in an Assets collection, which is a Resource. This means that they cannot have components added to them.

Handling Assets like this as components is a novel idea, but I have a feeling that breaking it up would ultimately make it harder to work with.

@SorteKanin
Copy link
Author

Just ran into this issue a second time, so investigated possible solutions a bit more.

It would be nice if rust key/value collections exposed a get_disjoint_mut(keys: &[Key]) -> &mut [Value] style api, but I totally get why they dont. (they need to check for collisions, which is expensive).

This answer on StackOverflow has some suggestions for how to do this actually. hashbrown::HashMap (which is what std uses anyway) has a method to do this, or there's the multi_mut crate. Or a bit of unsafe code could do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants