godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.07k stars 69 forks source link

Add a general-purpose CSGConvexHull3D node #9933

Open 31 opened 3 weeks ago

31 commented 3 weeks ago

Describe the project you are working on

A game that includes a 3d modeling tool using CSG, where "fill all the space between this set of points" is a common operation, and the result must be displayed as a mesh.

Describe the problem or limitation you are having in your project

It's not trivial to create a triangle mesh from a 3d convex hull. It's hard to find a library that properly handles common edge cases (faces with more than 3 vertices, which occurs in something as simple as a common cube). Godot has some features available that use convex hulls (especially collision), but none do meshing.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

CSGConvexHull3D, a simple CSG node that has points and makes it into a convex hull mesh compatible with the rest of the CSG system.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

PR https://github.com/godotengine/godot/pull/91748 integrates Manifold, which seems to have good convex hull meshing support. I wrote up a CSGConvexHull3D node implementation based on that PR here: https://github.com/godotengine/godot/compare/80f72e687cfb3ffcee1547d4dc67ec4b59dad871...31:godot:a22c49cf46dcbf05c85c0fc661ce10de60f38968.

I'm not familiar with https://github.com/godotengine/godot/blob/5833f597865c773fae3ee09fc4e31d4a243f812d/core/math/convex_hull.h and if it creates good meshes, but it's not usable from game code. If the API were exposed, it might be reasonable to use this to generate a mesh to pass into CSGMesh3D. I suspect that would be relatively slow.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No.

Is there a reason why this should be core and not an add-on in the asset library?

In theory I could create a 3d convex hull mesh by bringing in some other library or implementation and then pass the result into CSGMesh3D, but there are reasons I don't want to try:


Related:

Calinou commented 3 weeks ago

Does this have to be a CSG mesh? I'm concerned about adding more CSG meshes without an equivalent PrimitiveMesh, as this can encourage users to use slow CSG functionality when it's not needed. We have the same problem with CSGPolygon3D's Path mode, which lacks a PrimitiveMesh equivalent.

CSG meshes also don't support UV2 generation for lightmapping, while primitive meshes do.

31 commented 3 weeks ago

Does this have to be a CSG mesh?

No, it doesn't need to be a CSGPrimitive3D, but the cost is (potential) performance. That's what this is about from the proposal:

[Passing a convex hull mesh into the CSGMesh3D node] wouldn't be able to benefit from any optimizations that can happen due to keeping the hull in a more "native" format.

Internally, the CSG system could avoid creating a Godot mesh until it has applied all the CSG operations using Manifold, and avoid some pointless conversions back and forth. (Does it do this? Maybe not, but it seems like fairly obvious potential to me. 😄)

I'm concerned about adding more CSG meshes without an equivalent PrimitiveMesh, as this can encourage users to use slow CSG functionality when it's not needed. We have the same problem with CSGPolygon3D's Path mode, which lacks a PrimitiveMesh equivalent.

That's reasonable, I have nothing against also adding meshes for this, and for path-mode polygons as well.

Another factor: it was super easy to add the CSG node because all the functionality is right there for interop with Manifold. I'm not sure it would be so easy with meshes. For practical reasons I want to file a proposal with a ready implementation to try to get it done sooner rather than waiting for someone who knows how to implement it as a mesh--which might never happen. (It looks pretty overwhelming to me, personally.)

fire commented 2 weeks ago

I support this proposal. Hulling and keeping the promise of manifold, is not trivial to do. I think manifold is the primary FOSS library that can do this.