-
-
Notifications
You must be signed in to change notification settings - Fork 21.2k
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
Add line-circle and circle-circle closest points functions; improve cylinder-cylinder collisions #71775
base: master
Are you sure you want to change the base?
Conversation
Just a note on the allocations - I usually hold my nose at the amount of dynamic allocations Godot does, but here you are using If possible it would be nice to reduce this to a single allocation.
On the other hand if it is nearly always returning one value, this may not be so important. |
@lawnjelly Thanks, I'll fix that (it's only in the binding, not in the core code that is used by the physics). Currently the code always returns only one pair (unlike #68958 which returned more pairs in special cases), which seems to be standard for this particular algorithm. I've indicated in some comments in the code how this could be improved if needed. |
44001ca
to
044a330
Compare
How does licensing work in this situation? I think that there should be credits to both authors, if not the whole license somewhere. |
@Riteo Yes, definitely. I meant to post this as a draft; indeed more detailed copyright notices / credits still need to be added. |
It looks like some of this code came from Numerical Recipes. They don't allow using it in open source software. http://numerical.recipes/licenses/redistribute.html |
@peastman Yes, the minimization and bracketing code in I'm looking for a solution. |
@rburing I have an implementation on a branch that does not use the code from Numerical Recipes here: hpvb@0952643 Feel free to use it, if you do please add an authored-by line for me or something to the PR :) As for where this code came from: I had ChatGPT explain the algorithm to me step by step and I implemented the C++ code based on its explanation. There was not a lot of creativity involved, mostly because there's really only so many ways to do this. But this code can't possibly be copyrighted by anyone but me, if anyone at all. |
@hpvb Thanks a lot for your help! With your latest commit I still run into the issue of getting caught (stopped) when sliding along the cap of a cylinder (which this PR is supposed to fix), see the demo attached above. There is also a test like that in https://github.com/fabriceci/Godot-Physics-Tests, but it's already passing in Could you give the minimization code another look? If needed we could generate some unit tests for the minimization. Once it's ready I'd be happy to rebase my commits on top of yours (and add more detailed license info to |
@hpvb My branch To test alternative minimization code (like yours), check out my branch, replace Running the test project with your minimization code, I get
The above output corresponds to the following plot: This shows the correct minimum |
Based on David Vranek's Fast and Accurate Circle-Circle and Circle-Line 3D Distance Computation. Implementation based on the one in MinuteTorus by Sang Hyun Son, but significantly modified.
Based on David Vranek's Fast and Accurate Circle-Circle and Circle-Line 3D Distance Computation. Implementation based on the one once included in ODE by Russell L. Smith, but heavily modified.
044a330
to
147302f
Compare
I've updated/extended the copyright notices/licenses/credits for the circle-circle and line-circle closest points code. I haven't touched the numerical minimization code yet (see the issues mentioned above). |
Looking forward to this; I noticed that the current implementation for cylinder collisions struggle both on trimesh collision shapes and the edges of a lot of shapes. For instance, if you are moving onto a different angled slope (hits the edge), it may misreport the collision normal. If a pointy spike shape's vertex pokes the rounded part of the cylinder, it can get a wrong collision normal reported and essentially become stuck. Would like to help find edge cases with this implementation by doing extensive testing with it in my character controller. * I found that testing it in a character controller environment is quite effective, as any misrepresented move_and_collide() normal will immediately be obvious as the character will not move as expected, and will chain off into a noticeable error. It obviously isn't as credible as a unit test, but I've found a lot of collision detection bugs this way. |
So I did some testing. It seems like all this improves is the collision detection along the non-circular-cap parts of the cylinder. I have a feeling that the errors still present on the edges of the cylinder mesh might be the same issue as #70508 |
This PR implements Vranek's Fast and Accurate Circle-Circle and Circle-Line 3D Distance Computation with the following API:
The line-circle implementation is based on the one in
webots
and the circle-circle implementation is based on the one inMinuteTorus
, though both have been significantly modified. The original article is sketchy regarding the line-circle case; I've added details in comments in the code, and answering my question about the choice of bracketing triplet could improve the implementation.Works well even in
precision=single
builds, unlike the alternative implementation of these functions in Improve cylinder collisions (WIP) #68958.Fixes cylinder sliding on cylinder in https://github.com/fabriceci/Godot-Physics-Tests
Shows significant improvement in the "Face Z" and "Tumbling" cases of https://github.com/Malcolmnixon/PhysicsCollisionTest. I'm not sure why "Face Y" does not work better. I could use some help debugging this.
Demo to test the circle-circle and line-circle closest points functions directly: circle-distance-demo.zip
Demo to test cylinder-cylinder collisions: CharacterAndCylinderIssue-modified.zip
To improve cylinder collisions still further (and implement cylinder-cylinder distance), disk-circle and segment-circle closest points functions should be implemented.