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
Expose allow_sleep and awake Box2D parameters #5405
Comments
In which scenarios is allow_sleep not desired? |
Bodies that never sleep potentially consume more resources, because they are never excluded from the simulation. If they're allowed to sleep it's handy to know wether they are asleep or not, for example to end the level in Angry Birds. |
So, @britzl , @totebo , this is about adding read/write methods for two Box2D properties. Right ?
Any second thoughts on that ? I'm not an expert in physics code, but the way i see it, if this is just about being able to run On the other hand, if we really need to extend the public physics api, we could indeed expose https://github.com/defold/defold/blob/dev/engine/physics/src/box2d/Box2D/Dynamics/b2Body.h#L315-L327 Thoughts ? |
I think the best approach would be to support the standard Box2D API for body sleep functionality. This would solve the joint issue and also allow other uses to do with sleeping bodies. |
Doesn't that function only operate on joints/constraints? Aren't the sleep and awake properties on physics bodies? And we should probably access them through go.get() and go.set() on the collision component. |
Yeah, I don't think physics.set_joint_properties() is relevant in this case.
Sounds perfect to me! |
@britzl , let me try to draft the implementation.
Example use - wake up a collision object if sleeping
Example use - disable sleeping preemptively
EditorDo we need support in editor for these properties ? If we do, should this be implemented as part of this issue ? |
This looks good. Keep in mind that we have 2 physics engines (one for 2D and one for 3D). Does Bullet have similar properties?
We do not need this, but it is a nice thing to have. And it would be for the new "allow_sleep" property if we decide to add it. |
Also note that another approach is to wake up the body when we "touch" it. I.e. when connecting two bodies with a new joint constraint. I don't mean to say that the setawake() functionality isn't desired, but I don't think it's the best solution to this particular problem. |
@britzl I skimmed through bullet's docs (those i could find :-). Sharing some thoughts... Although there seems to be a similar behaviour in bullet that deactivates a body if it comes to rest, we're still talking about a different API (from Box2D's). Both naming and semantics should be considered in order to have neutral api and not a Box2D biased feature. For semantics, bullet has the following definitions:
ACTIVE_TAG and ISLAND_SLEEPING seem to express status while the rest probably indicate transition. Copied them from this - https://pybullet.org/Bullet/BulletFull/btCollisionObject_8h_source.html Here follow the respective box2d and bullet apis in theory. I checked the docs and went through the code. I didn't run any code. Check if awakebox2D - b2Body::IsAwake() I'm not sure about putting explicitly to sleep. I'd stick to read-only behaviour. Prevent sleepingbox2d - b2Body::SetSleepingAllowed(false) Trying to move the discussion forward, i think i'll agree with @JCash. Waking up a body in certain occasions behind the scenes seems an easier, quicker and safer fix for the initial use case reported by @totebo. On the other hand we could proceed with implementing only the operation of checking-if-awake() for both box2d/bullet which seems clear and safe if read-only if it is useful. Thoughts people ? |
Yes, I agree!
Sounds reasonable to keep these read-only!
Yes, the ability to check if objects are sleeping is useful. See the example given by @totebo regarding Angry Birds levels!
How would this work? |
To address the initial use case reported we could hook As a personal preference i'd suggest moving in small steps. First implement |
Agreed! |
Started working on this. |
It seems that the low level C getters for the sleeping status of collision objects are already present both for box2d and bullet. https://github.com/defold/defold/blob/dev/engine/physics/src/physics/physics_2d.cpp#L1089 I didn't find any reference to them though in the engine code. Hmmm... @JCash , any idea if they are not used because they weren't needed so far or if there is another reason to consider ? |
I don't think there's a special reason other than that we don't want to add all functions and attributes, but add them as needed. |
@totebo , any idea how much time is that ? I'm trying to reproduce. |
From the manual:
https://box2d.org/documentation/md__d_1__git_hub_box2d_docs_dynamics.html In practice, the body appears to be stationary for some time before it sleeps, but this might have to do with precision. Which means there probably is no fixed time. |
Sharing some findings ...
To cut a long story short, for this issue, i suggest read/write support for sleeping, no support for sleeping-allowed. Both for 2D and 3D. Pending: Investigate how to awake a body in 3D. |
One more thing:
To get to the point, set('sleeping', true) makes no sense and is not clean in Bullet but we need I'm thinking to either ignore Do you see a problem with that ? Any alternatives to suggest ? |
I agree. It should be up to the physics simulation to determine when a body is asleep.
I'm not sure. It feels a bit weird to have a go.set("sleeping", true|false) that doesn't accept both values. Would it really be weird to have an "awaken" or "wake_up" message that can be sent to collision component to wake it up? |
@britzl , note we're talking about the 'go-to-sleep' command and not the 'wake-up' operation and our obstacle is in Bullet only. Yeah it's kind of weird if you only think in terms of API and not what underlies it. My point is that thinking semantically, our problem is that sometimes our collision object over-sleep and we had no way to wake them up + we wanted to know whether they sleep or not. Putting them explicitly to sleep was not a use case and seems a vain operation too (both engines put them to sleep again). I would even say that if the underlying layer does not have a clean way to do it, it would be misleading for Defold developer to claim that it's possible in our API. To me sleeping seems more an optimization feature to exclude objects from the simulation to save CPU. We do take advantage of it but we may have to deal with behavior we can't fully control. Again, to make sure we're on the same page my suggestion is to display a warning when user gives That being said, i'll check some more about putting-to-sleep in bullet to see if I'm missing something. |
Ok, so this is the suggested new API/property for both 2D and 3D physics:
What I'm not sure about is this:
It feels a bit weird to not allow any value. BUT on the other hand we do have checks in place for other values such as linear_damping which must be within 0.0 and 1.0 so I guess it is ok. The alternative would be the message I wrote in my previous post, but it is more complicated. @JCash do you have an opinion? |
Changing course a little. Instead of setting the 'sleeping' property in the collision object, a |
Added Also tested on sample project with physics debugging enabled. With both backends it works as expected. box2d
bulletThe same use case is not possible because bullet doesn't support this type of joint. However, the object's frame still changes colour for a split sec when activated. @JCash , for testing i plan to add a new test case to test_gamesys.cpp. See Does this look ok to you ? Anything else to suggest ? |
Sounds good to me! 👍 |
Almost done. Still have to merge stuff from dev branch to get up to date before creating the PR. |
* Implemented 'wakeup' call in 2D physics (box2d) - ref #5405 * collision object activation for bullet 3d - ref #5405 * WIP - Test code and files for #5405 * WIP on 5405 * proof of concept for custom project config in gamesys tests cases * Issue 5405: gamesys test for waking up sleeping box2d objects - ref #5405 * Issue 5405: final review and fixed minor stuff - ref #5405 * Applied fixed requested by PR #5848 - ref #5405
* Implemented 'wakeup' call in 2D physics (box2d) - ref defold#5405 * collision object activation for bullet 3d - ref defold#5405 * WIP - Test code and files for defold#5405 * WIP on 5405 * proof of concept for custom project config in gamesys tests cases * Issue 5405: gamesys test for waking up sleeping box2d objects - ref defold#5405 * Issue 5405: final review and fixed minor stuff - ref defold#5405 * Applied fixed requested by PR defold#5848 - ref defold#5405
Being able to detect if a 3d physics is sleep would be useful. For now using average position and orientation over time to detect sleep. |
What about reading angular_velocity and linear_velocity on the object? Or are the examples of these being zero and still considered awake? |
I had not realized those were an option. I'll try that! |
I haven't tried myself but worth checking at least! |
Is your feature request related to a problem? Please describe (REQUIRED):
Dynamic bodies are deactivated from the physics simulation if no forces have been affecting them for a certain time.
In my zero gravity game the player starts the game by connecting the player body to a different body. If the player body has gone to sleep before creating the joint, the joint doesn't work - it connects but is passive. This means physics.set_joint_properties() no longer has any effect.
Describe the solution you'd like (REQUIRED):
Expose the allow_sleep flag in Box2D so that that a body can be set to never go to sleep. Also add an physics.is_awake() to check if a body is sleeping, if using allow_sleep is not desired.
Describe alternatives you've considered (REQUIRED):
Applying a small impulse every frame to keep the body awake.
Additional context (OPTIONAL):
https://box2d.org/documentation/md__d_1__git_hub_box2d_docs_dynamics.html
The text was updated successfully, but these errors were encountered: