-
-
Notifications
You must be signed in to change notification settings - Fork 261
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
Bevy parent transform is not used #172
Comments
I agree that using the |
Maybe I'm confused, but isn't that a non-issue? Currently, the relevant stages are physics -> update -> transform propagation. Users are expected to make changes in the update step which means physics won't see any changes until the next frame anyway. Using global transforms doesn't seem to change this in any way. |
@SUPERCILEX Thank you for your input! I wasn’t aware of this convention. What about the initialization of new colliders or rigid-bodies? Is is reasonable to require the user to do that after the physics stage too? Because, otherwise, if a collider/rigid-body component is inserted (with a tranform/global transform) before the physics step, they will have the wrong (un-propagated) transform during one physics step. |
That's true, but I think it can be solved though documentation: people can then set up their systems to run in the correct order relative to the physics stage. This is the correct long-term choice because stages won't be a thing soon meaning people will always have to explicitly decide when their systems should run relative to others. A startup system should probably be added similar to this that runs after those transform propagations so that startup entities are positioned correctly initially.
I think the physics stage should be moved to after transform propagation so that everything is in sync by the end of the frame. This is consistent with how transform propagation works and means people need to run systems that depend on physics before spawning those entities (and the spawning also happens before physics). Either way you have to carefully consider when systems are running. Thinking about my own game, this would be the ideal ordering:
This results in the following:
|
@SUPERCILEX That makes sense.
If we move the physics stage after transform propagation at the frame |
Are you thinking people will want to use the global transforms? The physics updates would still be visible to frame |
Yeah, I’m thinking about the global transforms. |
How do other physics engines handle the transform hierarchy? Do they model the hierarchical relationships as joints? (Sorry for all the edits, updated to follow the suggestion on my next comment). If Rapier copies from Bevy's It'd be awesome if we only have to propagate the transform hierarchy once, after all the changes have been made, since Bevy is currently trying to optimize those systems (bevyengine/bevy#4697), but if everything has to be in global-space for physics, then we're looking at something like:
The main takeaway is that you would be adding two new propagation systems that filter on entities with rigidbodies rather than move relative to the existing one that deals with all entities. Any user systems related to movement should happen before the physics step, then those actions will all be accounted for in the same frame and everything will be synced. I think that's true whether or not you put these systems inside a fixed timestep. |
I'd actually suggest completely avoiding I think |
So assuming this is easy (I thought you'd need global transforms), I agree with your ordering except for the fixed time step part. Why would we want physics to run on fixed intervals? It should take in a res time and apply position changes accordingly. |
So that part is optional and I was only using it as an example here, but in general it's better for game physics—and I mean simulation-related math in general, not just the rigidbody physics—to be fed a constant Δt for consistent and repeatable results, independent of framerate or even independent of GPU (headless app). Because it still has finite-precision, floating-point math isn't associative, so for example, integrating velocity by 100ms once will give slightly different results than integrating velocity by 10ms ten times. (IIRC variable timesteps can lead to the kinds of physics glitches speedrunners like to use to launch themselves across a map.) And then when you have a fixed timestep, to keep the visuals looking smooth, you interpolate entities between two physics steps while you build up to the next one. |
Gotya, that was going to be my next question. Found this to clarify: https://gafferongames.com/post/fix_your_timestep/. I think using a fixed timestep should be a separate discussion from fixing the parent/child relationships since it'll require a lot of design. |
This sensor will be used to determine the attack range of the tower. NOTE: discovered that the collider doesn't use the global transform to stay in sync. More about this issue can be found here: - dimforge/bevy_rapier#172 - TLDR: bevy_rapier might need a rework
This sensor will be used to determine the attack range of the tower. NOTE: discovered that the collider doesn't use the global transform to stay in sync. More about this issue can be found here: - dimforge/bevy_rapier#172 - TLDR: bevy_rapier might need a rework
Wondering how https://github.com/jcornaz/heron mitigating this issue. It doesn't have this problem. |
@Shatur Looks like heron simply runs a second transform propagation: https://github.com/jcornaz/heron/blob/main/rapier/src/lib.rs#L107 I think we should do something similar, at least as a stopgap solution until we get more feedback on the limitations of this approach. I am not a big fan of the suggestions where Rapier implements its own transform hierarchy since that was one of the main pain point in previous versions of |
@sebcrozet Hm... It's a nice solution actually. At least it will solve the issue. So we should run it before this system? bevy_rapier/src/plugin/plugin.rs Line 82 in 3f04e8d
|
@Shatur If we keep running our stages before If on the other hand we run our stages after So... maybe we should just call it once before |
@sebcrozet Hm... Is there any downside to run rapier stages after |
After I still think You should be able to use change detection to reduce work in both systems. |
@Shatur I don’t think there is a downside, no.
There is little-to-no transform hierarchy in physics engines. The only cases where you have a hierarchy is where:
Maybe, though that would be a more complicated change than just adding a call to bevy’s transform propagation. As you mentioned earlier, there is a bit of ongoing movement regarding the definition of
Yeah, the |
I recommend against it because it IMO creates undesirable coupling with a render component. The definition thing is prominent but likewise headless apps may stop registering the global transforms component, and some users or plugins may be relying on (or want to rely on) global transforms being a frame stale until the moment of propagation in Earlier, what I meant was that you could duplicate Bevy's transform propagation logic and just replace the parts involving
That's is only a concern if you run after |
@sebcrozet then I would probably would go with this. It involves a bit more changes then just using two additional
But |
It's okay to use One line to add another instance of the propagate system is the simplest thing, sure, but it wouldn't take much more to copy its logic and tweak it to reference a |
To me it looks like the docs says that the So, here is my though: we need a solution as soon as possible, and we know (thanks to We also know thanks to @maniwani that this may not be a perfect long-term solution (e.g. we are screwed if all its fields are merged into a single affine matrix), so we should keep our minds open to alternatives. I’m not sure I like adding another |
Agree with you! Are you planning to make this change yourself? |
Right now I need to finish updating the JS bindings for Rapier (it’s been waiting to leave |
Got it, then I will try send a PR ASAP myself. |
@sebcrozet done: #177 |
@sebcrozet thank you! Could you draft a new release? |
@Shatur I’ll probably make a release of Rapier first next week. I’ll make a new release of |
Thanks for fast resolution! I really appreciate it! |
Currently
bevy_rapier3d
usesTransform
component to read entity absolute transform. But this component is a transform relative to a parent in Bevy world. On the other handGlobalTransform
is an absolute transform for entity. Because of this if there is an entity with non-identity transform and as a children of it is another entity with a collider, collisions will not be detected in the real object location. For example when running following code ball collider will be placed at 0,0,0 instead of 0,10,0:The text was updated successfully, but these errors were encountered: