-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Contacts and PhysicsDirectBodyState3D #58880
Conversation
Thanks for opening a pull request 🙂 Feature pull requests should be associated to a feature proposal to justify the need for implementing the feature in Godot core. Please open a proposal on the Godot proposals repository (and link to this pull request in the proposal's body). |
Could you please make a separate PR with only the bugfix for |
I dont know much about this stuff myself. I am struggling with get_contact_local_postion() and a google search lead me here. From what I understand you fixed the function. What Id like to know is how can I impliment the fix. |
@rburing I’m out of town for until the end of the week, but could look at a new PR then. After perusing the docs more carefully, I think the implementation of “ get_contact_collider_velocity_at_position()” is actually a bug and so this change does not break compatibility. The only new feature being propose is the new function “ get_contact_velocity_at_position()” @chabi211 I’ll take a look at the code you mentioned when I get back. A separate PR with the just the local position fixes should be easier for you to merge in. |
Was using contact reporting in 3.5 and am probably experiencing this mirrored 50% of the time bug. Same object already in the scene reporting opposite collision points vs that object instanced. Could be they spawn as body B in the pair instead of A. |
Important comment here for this PR. So I tried to take the changes and apply them to 3.5 without the added velocity feature, and I found a bug in the proposed reporting fix. In godot_body_pair_3d.cpp on line 363 in the updated code, it should test A if it can report contacts. Instead it tests B twice and A never reports. So when I tried the changes as is it fixed 1/2 of the problem. Changing line 363 to I'm using Godot 3.5 and now my stuff is working. I hope you guys get this resolved! |
@evanrinehart Thanks for catching that |
This issues seems to be fixed but is awaiting review? Just wanted to add the following: When a collision occurs two contacts will be reported, one for each collider. The first contact gets reported correct, the second one seems to get a copy of that contact but does not translate the position into its own location. The contact normal does work correctly. Would love to see this fixed but im not the c++ guy and i dont know if i can help with the needed review. |
@D2klass, I need to address the can_report_contacts() error first and we'll see after that. Rburing suggested I split the PR up into bug fixes vs. the new feature. Probably what I should have done to start with, but I just don't have time to work on this at the moment. If I get time I'll fix the contacts and re-post but unfortunately godot is on the backburner at the moment. |
Updated to the latest version of the main branch and corrected issues related to that. Also fixed the error found by evanrinehart. |
2c6d5e3
to
3ece13d
Compare
Still using a hacked version of 3.5 with the fix for this bug, which as I understand it still exists in godot 4. I hope it doesn't get forgotten now that it's over a year later and godot 4 is getting a lot of work. UPDATE: actually I see work on the place where the mirroring bug used to be. And someone told me they can't reproduce the effect in godot 4. So maybe that part of the PR is no longer needed. |
@evanrinehart From a brief test it looks like this PR still fixes a bug. I think the method (IMHO the I think it's okay to put the new method and the bugfix in this same PR. @tgift could you please rebase? |
I'll try to bring the PR up to date this weekend and I'll look at the possible name change. Will have to refresh my memory on all of this. |
Rebased and conflicts resolved. @rburing I looked at the function names and you are correct. I renamed "get_contact_velocity_at_position" to "get_contact_local_velocity_at_position" to be more consistent. |
Thanks @tgift, the changes look great now. Could you just amend the commit message (using Edit: Also the documentation of the new method was lost in the rebase. The docs you wrote earlier can be viewed at 3ece13d. It would be great if you could add those docs back as well. |
Resolved a problem with PhysicsDirectBodyState3D sometimes returning incorrect contact positions and added a new get_contact_local_velocity_at_position method to compliment the existing one for the collider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Thanks! And congrats for your first merged Godot contribution 🎉 |
Yay! No more hacks needed for damage on collision <3 |
Two changes to PhysicsDirectBodyState3D and some associated classes. Both related to the way contact information is stored and passed to the scripting language.
The first modification makes it possible to compute the impact velocity at the time of contact. For that both the velocity of the state object as well as the collider at the point and time of contact are needed. Velocities can be obtained in "on_body_entered()", but these are after collision has been resolved and don't reflect the velocities at the moment of impact.
The original "get_contact_collider_velocity_at_position()" method was returning not the velocity of the collider, but the velocity of the state body. This method was changed to return the collider's velocity, and a new method "get_contact_local_velocity_at_position()" was added to return the velocity of the state object. Changes were made to the contact structure to store the new velocity. With these changes the impact velocity (or speed in this case) can be computed as:
Anyone relying on the previous behavior of "get_contact_collider_velocity_at_position()" would have to switch to the new method.
The second changes the values returned by "get_contact_local_position()" and "get_contact_collider_local_position()". The physics engine resolves collisions in world space relative to the A body in a GodotBodyPair3D pair. Body B is oriented in world space but translated relative to body A. Contact information was stored in this A relative space and body_B's contact position was always in this space. These values were being returned as is, which is incorrect half the time. The state objects contacts are mirror's (almost) of each other, so if your object was body B in the pair, then your contact position would be in the wrong space. If you were body A in a pair, then the collider's position would be in the wrong space.
This change amends the contacts to always store and return positions relative to their respective objects.
Bugsquad edit: This closes godotengine/godot-proposals#4184.
Physics squad edit: Fixes #75803.