three-to-cannon icon indicating copy to clipboard operation
three-to-cannon copied to clipboard

Physics simulation stops when generated convex hulls collide

Open isaac-mason opened this issue 1 year ago • 10 comments

It looks like there may be some issues with generated convex hulls. When two bodies with generated convex hull shapes collide, the physics simulation stops and the page becomes unresponsive.

I made a simple codesandbox demonstrating the issue: https://codesandbox.io/s/repro-three-to-cannon-hull-collision-issue-68jtcd?file=/src/index.ts

I haven't checked what versions have the issue, but it appears to at least be present in 4.0.2, predating the introduction of the getShapeParameters function. The issue may be somewhere in ConvexHull.js?

isaac-mason avatar Jul 12 '22 10:07 isaac-mason

Happy to help with looking into this too - just need to find some time 🙂

isaac-mason avatar Jul 12 '22 10:07 isaac-mason

The THREE.ConvexHull is not used by the simulation at runtime — only to construct a CANNON.ConvexPolyhedron. I would guess that because collisions with other types of shapes still work, and the debug outlines look reasonable, the hulls themselves are valid. The way this hangs the browser, it looks a bit like an infinite loop in collision code?

donmccurdy avatar Jul 14 '22 02:07 donmccurdy

Thanks @donmccurdy. It looks like this might be a duplicate of this issue: https://github.com/donmccurdy/three-to-cannon/issues/59

There's an interesting related cannon-es issue linked there: https://github.com/pmndrs/cannon-es/issues/103

I'll find some time to have a read and try a few things, will get back here with what I find.

isaac-mason avatar Jul 16 '22 03:07 isaac-mason

Potentially relevant: https://github.com/schteppe/cannon.js/issues/459#issuecomment-887939884

Because of the way that cannon.js is programmed, if the convex triangles are not all connected, then convex-convex collision will not work.

isaac-mason avatar Jul 16 '22 05:07 isaac-mason

The simplifyGeometry() method is intended to ensure vertices are merged and convex triangles are connected...

https://github.com/donmccurdy/three-to-cannon/blob/2927293f04f1551d16723e0ec15d4b32c4f1c6ac/src/utils.ts#L114-L122

...but we invoke it only if we're merging multiple geometries —

https://github.com/donmccurdy/three-to-cannon/blob/2927293f04f1551d16723e0ec15d4b32c4f1c6ac/src/utils.ts#L17-L29

This might be the cause? Unfortunately it's not as simple as just adding a call to simplifyGeometry above — if we simplify single geometries then we can't get precise parameters for primitive geometries, by accessing things like geometry.parameters.radiusTop for cylinders.

There's a lot in this library that could use serious refactoring and better unit tests, sorry for that. 😮‍💨 If you'd be interested in push access and just making more changes as you see fit, I'm happy to go that direction.

donmccurdy avatar Jul 23 '22 03:07 donmccurdy

Thanks @donmccurdy for the info! I think it's sent me down a good path 🙂

It looks like the issue may be in how getConvexPolyhedronParameters constructs faces? From reading ConvexPolyhedron.clipFaceAgainstHull in the cannon-es repo, this is my current understanding:

As part of convex-convex collision, a list of connected faces is built for a given hull face. The connected faces list is is populated by searching for faces (convexPolyhedron.faces) with vertices that are shared with the given face's vertices (polyA.indexOf(hullA.faces[i][j]) !== -1 - ConvexPolyhedron.ts:L478).

In getConvexPolyhedronParameters, currentFaceVertex is incremented for each face vertex. So when ConvexPolyhedron.clipFaceAgainstHull is looking for connected faces, it won't find any, as all of the face vertex values produced by getConvexPolyhedronParameters are unique.

isaac-mason avatar Jul 25 '22 15:07 isaac-mason

There's a lot in this library that could use serious refactoring and better unit tests, sorry for that. 😮‍💨 If you'd be interested in push access and just making more changes as you see fit, I'm happy to go that direction.

No apologies are necessary! Thanks for creating and supporting this lib!

I'm pretty keen to get to the bottom of generating convex hulls that support convex-convex collision! Happy to keep on with this and (hopefully) create a PR once I've got something working.

From there, I'd also be happy to help with general improvements/upkeep, for sure 🙂

isaac-mason avatar Jul 25 '22 15:07 isaac-mason

Sorry, haven't had much time to progress this.

I did however notice there's a new PR in the cannon-es repo for simplifying the creation of convex hulls: https://github.com/pmndrs/cannon-es/pull/155

I did a quick test, simply pulled the QuickHull class from that PR into three-to-cannon, and convex-convex collision works with the faces it returns.

I'm going to watch that PR for now and see if something can be merged into cannon-es itself. If not, pulling that implementation into this lib could be good too!

isaac-mason avatar Jul 30 '22 05:07 isaac-mason

That sounds promising, thanks!

donmccurdy avatar Aug 02 '22 00:08 donmccurdy

Looks like that PR was closed. I'll keep watching the related issue, but in the meantime I'll find some time to create a PR using the same approach to fix this issue!

isaac-mason avatar Aug 09 '22 02:08 isaac-mason