-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
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
Optimize Convex Collision #66294
Optimize Convex Collision #66294
Conversation
|
||
for (uint32_t i = 0; i < ch.edges.size(); i++) { | ||
edge_faces[i] = -1; | ||
} |
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.
I was going to say we had a fill()
method for this, but I see it was added to 3.x in #60426 but not yet added to 4.x. Might be worth adding this at the same time as it is fairly common? 🤔
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.
#60426 is a backport of a master
PR so it should be in master
too?
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.
#60426 is a backport of a
master
PR so it should be inmaster
too?
It wasn't included in the original as far as I can see. I don't think it is present in LocalVector
in 4.x?
92e87d3
to
2d9046f
Compare
This implementation still involves nested loops over Have you tried benchmarking it and comparing to the implementation in #63702? For medium to large meshes, I believe that one will be faster by orders of magnitude. Its speed is essentially independent of the size of the meshes, aside from the dependence that comes from the calls to |
@peastman My issue with #63702, as I mentioned before, is not performance related but precision related. For throwing stuff into a pile of bodies these sort of approximation algorithms work fine, but for game related collision where you need extremely precise collision responses, they can be troublesome and fail in specific situations and corner cases. This has been my experience back in the day with GJKEpa and MPR, and its the current experience with Bullet in Godot 3.x. This is IMO the main reason why, besides Godot, engines like Unity or Unreal, and production physics engines like PhysX or Havok (or the hundreds of ODE based simulation engines) also use SAT based collision algorithms. Again, it's not the performance, its that approximation based algorithms have unexpected corner cases. I still intend, if the amount of vertices beyond a certain threshold, to fallback into GJKEpa (which is already implemented and works) because I assume at that point the user is not looking for precise collision, but it should just not be the default even if its faster. |
@peastman Let me explain the problem in a bit more detail. Its mostly about sizes and precision. If you have a box and a sphere of the same size and they collide, its probably be ok with an approximation. If you want the box to fall over a very large sphere (say a planetoid in a game), then the lack of precision will be a lot more noticeable and the collision will jitter. This is the main issue with iterative solvers that work in minkowski sum space. Bullet sort of makes up this in large part because of enforced margins, because GJK is a lot more precise (and faster) than EPA or MPR. |
That's a great suggestion for test. Here's a video showing how MPR handles it. (I had to add .txt to the name so github would let me upload it.) A cube of size 1 (represented as a mesh with 8 vertices) strikes and rolls down a sphere of radius 100 (represented as a mesh with 4986 vertices). As you can see, the collision handling is flawless, no jittering at all. Remember that MPR is not an approximation. If you converge it to machine precision (which is very cheap, just a few extra iterations), the result is exact. |
@peastman I think we are talking about different things. I already stated that with convex polyhedra the result is exact, but for this case we already have EPA implemented and I prefer to use this than MPR as optimization as it makes no sense to support both. The problem is when you use MPR/EPA against continous surfaces (spheres, capsules), or convex polyhedra with margin (which we use for depentration in character controllers). In that case, the result is not always exact. |
Ok, it's your call! Just remember you have that code sitting around, in case you get tired of dealing with all the problems of GJK-EPA in the future. :)
EPA is an approximation, but I believe MPR is still exact in that case (assuming you converge to machine precision). |
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.
Tested with https://github.com/fabriceci/Godot-Physics-Tests.
No regression found and noticeable performance improvement:
Implements the Gauss Mapping optimization to SAT convex collision test. * Described [here](https://ubm-twvideo01.s3.amazonaws.com/o1/vault/gdc2013/slides/822403Gregorius_Dirk_TheSeparatingAxisTest.pdf) by Dirk Gregorius. * Requires adding of face information to edges in MeshData * Took the chance to convert MeshData to LocalVector for performance.
2d9046f
to
71d2e38
Compare
Thanks! |
Implements the Gauss Mapping optimization to SAT convex collision test.
Next Steps:
NOTE: This is a draft, it has not been tested yet.