Repository navigation
Description
I wrote this issue back in May, but seem to have forgotten to submit it?
Issue writeup below. I apologize if the details turn out to be somewhat out of date.
I'm sorry, none of the issue templates seemed to fit. "Feature Request" was the closest, but it didn't quite seem right.
Question
In README.md, you state that one of your design goals is to be modular; a user can choose to use only those features they need.
Yet the crate bevy_transform seems to bundle two unrelated concerns:
- The concept of a parent-child hierarchy of entities.
- The concept of a
Transform, roughly a similarity transformation of Euclidean space.
Its description in Cargo.toml even admits this — "Provides hierarchy and transform functionality for Bevy Engine"! (Emphasis mine.)
Why aren't these two separate crates, with the latter depending on the former?
Reason
I discovered this issue while exploring the possibility of using Bevy to make games that take place in curved space.
The concept of a parent-child hierarchy is still completely applicable. But Transform, at least as currently implemented in Bevy, is not.
Details of Code Splitting
To ensure that this crate splitting would actually work, I tried it in a clone of the repository. Here are the results.
The crate bevy_transform was split into two: bevy_hierarchy and bevy_transform.
bevy_hierarchy contains these things:
- Everything in the modules
components::{children, parent}. - Everything in
hierarchyand its submodules, except for the test inhierarchy::hierarchy_maintenance.
It has dependencies bevy_ecs, bevy_reflect, bevy_utils, and smallvec.
It does not need bevy_app or bevy_math.
bevy-transform contains everything else:
- Everything in the modules
components::{transform, global_transform}. - Everything in the module
transform_propagate_system. - Everything in the root module.
- The test from
hierarchy::hierarchy_maintenance.
It depends on the new bevy-hierarchy, as well as bevy_app, bevy_ecs, bevy_math, and bevy_reflect.
It does not need bevy_utils or smallvec.
A few changes were necessary to get bevy_transform to compile again:
- Some imports needed to be fixed.
- In three instances, the code
children.0.iter()started failing, because the fieldchildren.0is private, and is now defined in a different crate. This was easily fixable; just dochildren.iter()(using theDerefimpl) instead.
Finally, the dependent crates needed to be adjusted.
bevy_scenedepends onbevy_hierarchy, but notbevy_transform.bevy_gltfandbevy_uidepend on bothbevy_hierarchyandbevy_transform.bevy_internalneededbevy_hierarchyadded to its reexports and prelude.bevy_pbr,bevy_render,bevy_sprite, andbevy_text, despite depending onbevy_transform, seem to need no changes.
cargo --test passes. I have not done any performance testing.
Activity
MinerSebas commentedon Aug 31, 2021
You already posted this in #2187, but there wasnt realy any discussion.
finegeometer commentedon Aug 31, 2021
Oh, that's why I couldn't find it. I didn't think to check the discussion section. Sorry!
Should this be closed, or is it useful to have it here as well?
LegNeato commentedon Sep 2, 2021
It sounds like you already have a fix...why not put up a PR?
finegeometer commentedon Sep 2, 2021
Because there's too much I don't know, and I'm afraid of doing something wrong.
In conclusion, I'm afraid to open a PR because I feel like I have no clue what I'm doing. I'd be willing to try, but I'm afraid I'll make a mistake.
mockersf commentedon Sep 2, 2021
If you want to try your hands on it, there would probably be someone available to mentor you through your first PR 👍 . Don't hesitate to ask on Discord (or here if that's better for you). I'm slow to answer nowadays but you can ping me for that.
There are extensive contributing guidelines for things more specific to how Bevy work too.
Though, before starting on the PR to split transforms / hierarchy, it would probably be better to ask @cart to chime in on his point of view.
cart commentedon Sep 4, 2021
I agree that the split could happen. I think its worth discussing what we "win" by splitting them out though. I expect compile times to be pretty much unaffected and in some ways splitting them out makes things harder (when both parents and transforms are needed we now need to pull in two crates instead of one). Given that most Bevy features will generally pull in both transform and hierarchy types, in most cases they will all be in the tree anyway (and they definitely will be when the
bevycrate is consumed directly). @finegeometer, can you describe your specific scenario a bit more / what you want your crate tree to look like?Note that guidelines like "split it if it can be split out" and "dont split it unless you have a good reason to", taken to their extremes are both undesirable. The former results in a giant mesh of tiny crates that is difficult to navigate. The latter results in monolithic / unmodular crates. Its all a weird "art" based on taste :)
finegeometer commentedon Sep 4, 2021
My motivating use case is games that take place in curved space¹ ².
What is
Transform? In my view,Transformrepresents the collection of ways you can move an object without distorting it³.Mathematically, it is SE(3), the group of transformations of space that do not change the distances between points, and are not mirror-image transformations.
Notice that this definition depends on the shape of space. So for curved space,
Transformneeds to be implemented differently.Instead of SE(3), it would need to be a group like SO(4) or SO(3,1).
I'm happy to reimplement the relevant
Transforms for curved spaces in my own projects. SO(4) has a nice representation as a pair of quaternions...But implementing my own
Transformwould require implementing my own version oftransform_propagate_system⁴, which depends on the hierarchy types, which are inbevy_transform. It just seems wrong for a crate implementingTransformin curved space to depend on one that implements it in flat space!There's also an aesthetic argument for the split. To me, the concept of a logical hierarchy of entities seems almost entirely unrelated to the concept of a symmetry of Euclidean space.
Imagine the reverse scenario, where
bevy_transformandbevy_hierarchyhad always been separate. If for some reason, you had to combinebevy_transformwith another crate, isbevy_hierarchyeven the one you'd choose?My particular use case could also be accommodated by reverting
Transformto be a 4x4 matrix, because all of the groups I've mentioned are subgroups of the group of 4x4 matrices. But I don't like this option, for a few reasons.Transformwere a 4x4 matrix, a lot of code would probably implicitly assume that everyTransformis in SE(3) anyway. Such code would work fine for most applications, only to fail when I try to use it.Transformwas aMat4, most ofTransform's methods made that exact assumption.¹ Also known as non-Euclidean space, though that term has often been misused to mean flat space with portals.
² For a good example of such a game, look up HyperRogue.
³ For simplicity, I will ignore the fact that
Transformhas ascalefield.⁴ Off topic: I wonder if there's a useful generalization of
transform_propagate_system, which folds an arbitrary function down the parent-child hierarchy? Thentransform_propagate_systemwould be that generalization applied toGlobalTransform::mul_transform.cart commentedon Sep 6, 2021
Ok I'm sold on this. Feel free to put together a pr!
finegeometer commentedon Sep 9, 2021
Based on the discussion in my attempted PR, I have decided to close this issue.
Split bevy_hierarchy out from bevy_transform (#4168)
Split bevy_hierarchy out from bevy_transform (bevyengine#4168)
Split bevy_hierarchy out from bevy_transform (bevyengine#4168)
Split bevy_hierarchy out from bevy_transform (#4168)