-
-
Notifications
You must be signed in to change notification settings - Fork 98
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
Enhancements regarding polygon boolean and polygon deflating geometry methods #913
Comments
Geometry.polygons_boolean_2d with strictly_simple option greatly improves stability of drawing complex polygons. Current behavior when boolean merging polygons: With strictly_simple option in geomtools: |
I'd like to link some other misc methods related to polygons I've previously created:
It's not required to expose those since godotengine/godot#29867 already uses the suggested implementation internally. |
@Xrayez : Thank you Andrii -- this looks like some excellent work! It would open up Godot to be not just a full-fledged bitmap display engine for games but also to be a tool to deal with vectors in a much more sophisticated way, both for games and other applications. The use cases for this reach far. Since Godot is already great at rendering, opening it up to more robust and complex 2D polygon vector math operations would make it a truly astonishing tool chest for 2D Vector graphics. I fully support this! |
I have tested the strictly simple option with polygon merge and found that it fixes all invalid polygon problems in my project and with great performance! Hope this can be accepted into Godot some day. |
I found the Geometry. clip_polygons_2d method of no use because it is unable to cut a hole into a polygon and return for example, two new polygons that represent my cut shape (it only works with overlapping polygons) it simply returns the original polygon, and the shape of the hole so ideally what it would return would either be a list of triangle representing my new shape, or perhaps two new concave polygons the reason i needed this: i think there's many other usage cases two, it's the same as the way CSG is useful for 3D.... i hope people don't think something so fundamental would be engine bloat.... if we then move on to adding higher level functions for it everyone will love booleans for 2D |
I think this would make a great core addition. As it is, the polygon functions in
The polygon functions in This was where I got stuck in my project (I need to make a collision shape out of the complement of a number of polygons in order to build a level), and using Goost has got me unstuck. If adding the lovely A fear was raised here that deep access would require too much in-depth knowledge about subject and clip polygons from the user. A small change that wouldn't create too much complexity in this regard and that would minimise bloat would be too keep merge, intersect etc as binary operations, but allow them to also accept an array of polygons in the same format as they currently output them:
The current implementation already expects users to understand the 'polygons with holes' structure as an output, so additionally allowing them as input doesn't add much complexity. Having polygons with holes as an input is also well within Clipper's functionality. |
@snailrhymer I agree, thanks for outlining the limitations!
The output is still usable by navigation nodes as far as I know (via
Rather than operating on a collection of Here's a list of new/existing Godot proposals that can be directly or indirectly resolved by adding
|
On the philosophical aspect, the last time I talked with Juan about this 3 years ago, it was difficult to convince him to add even basic clipping functionality in Godot core. You have to be aware of Godot's development philosophy as seen by Goost. The 2D boolean operations may be a candidate for GDExtension in Godot 4.0 anyways, and I presume CSG nodes (3D) will also be migrated to officially supported GDExtension (I may be wrong). Therefore, it won't make much difference whether this kind of thing will be supported officially or semi-officially (by myself). 🙂 Due to this, I'd say using Goost may be an optimal solution for you. The only concern is that I'm mostly the one who currently actively maintains Goost, but if more people use Goost in production, the more chances that there will be someone who'd be willing to maintain it. Only a few people know about Goost's existence and its purpose (same old Godot story). I'd say a good chunk of currently opened proposals in Godot could already be implemented in Goost right away. But without a doubt, if you think that something should be in Godot, let it be in Godot. But at the same time, I wouldn't want to be torn between improving Goost features and adding the same stripped features which will never be complete in Godot specifically. In Goost, it only takes me two hours to prepare and merge a feature. In Godot, it could take up to two years (see the date when this proposal was created). This is reality, not speculation. |
There are currently no plans to move CSG nodes to an extension. |
I've noticed https://github.com/SoloByte/godot-polygon2d-fracture/ by @SoloByte, which uses current Godot's boolean operation methods on polygons. The use case is very concrete, see the project description there (thanks for mentioning Goost as well). |
personally i don't think it's to do with anything other than no-one has the code when i was interested in this project i checked the goost library, it didn't have what i concider a "boolean", it has a clip a boolean to me, returns the triangles back as a result of the cut, ir it could return back a big ngon reconstructed back from them triangles ... and this is the same usage of the term "boolean" i have observed in all other programming enviroments to me, and i recon, most normal people.... calling these functions "boolean" is a miss-sell and as a programmer encourages you to waste time coding something.... THINKING, that a boolean is available... which happened to me with my shelved doom reading addon which i only coded at all because there was a "boolean" available (allegedly) included is a diagram of how a boolean works normally and manages to return an ngon from a cutting a hole in another ngon |
I think the more appropriate term would be set-theoretic operations on polygons. But using this kind of terminology could be potentially problematic for someone who's not a mathematician. There are not enough words in a natural language to describe different concepts. Different fields tend to use the same words, but define them differently (like in graph theory). But if you think about it, the boolean here actually refers to operands called the subject and clip polygons, and operators refer to AND, OR, NOT. Reading the documentation and/or researching the topic is essential to understanding this anyways. 😮 The picture you've shown results in cutline polygon. I think that not a lot of libraries support such operation. But it's always possible to triangulate or decompose into convex the resulting shape that contains holes (with Goost, of course). Why you need to have a cutline representation of a polygon containing a hole? What if a polygon contains dozens of holes? |
it wouldn't have to be cutline that would be what would normally be expected of a bool, a collection of trinagles would be acceptible in the doom map format, maps are defined by linedefs, so this means you can have sectors within sectors... the only way to translate them to polygons therefore is to be able to create sectors with holes in them.... different sectors can have different heightlevels. so i was trying to contruct a mesh from a doom map, just for a hyperthetical thing really and cos i didn't see the solution elsewhere |
Describe the project you are working on:
Goost - Godot Engine Extension.
I've previously implemented polygon boolean operation methods in Godot: godotengine/godot#28987.
I'm developing Goost module as an extension for Godot, it has geometry component which realizes my vision to a great extent when it comes to polygon-based operations, making most of the internal features as configurable as possible, so you can more easily compare my vision in relation to this proposal.
Describe the problem or limitation you are having in your project:
With this proposal I'd like to summarize some of the inconsistencies, limitations and hurdles of using the geometry methods related to polygons at large.
Describe the feature / enhancement and how it helps to overcome the problem or limitation:
Polygon boolean operations
Knowing that it's not really good to bloat the engine, I propose to do the following:
merge_polygons_2d
,clip_polygons_2d
etc) which accept only two polygons at a time currently.boolean_polygons_2d
, which would accept multiple polygons, basically Add polygon boolean methods operating on multiple paths godot#35929. The rationale behind this is that I've seen people are oftentimes requesting a method to merge a list of polygons: Unable to perform polygon boolean operation on a list of polygons simultaneously godot#29784 (comment), but it does makes sense to provide the support of this for other boolean operations (I believe that even if some operations are not used as often, it's silly to deny the existence of elementary math operations).I guess
polylines_boolean_2d
might not be worth it, considering that there's only two types of operations supported for this: clip and intersect (akaclip_polyline_with_polygon
etc).This actually solves another issue of duplicate documentation which are spread between those individual methods.
Exposing parameters
The Clipper library provides a quite useful option which allows you to turn self-intersecting polygons into strictly-simple polygons. I'm leaving describing the actual use case for this to @HEAVYPOLY, the author of http://www.heavypoly.com/heavypaint. Depending on how those polygons can be simplified, it's also important to expose an enum specifying the fill rule (EvenOdd, NonZero etc).
Alternatively, a dedicated method
simplify_polygons
could be added, but this would be just a wrapper formerge_polygons(strictly_simple = true)
, so not much added gain.Polygon deflating/inflating
I've exposed the methods (
offset_polygon_2d
andoffset_polyline_2d
) along with boolean ones because that's what the underlying Clipper library provided. I'm not sure whether this is actually useful for most users. In fact this creates confusion as seen in #777, so it might be worth splitting the method todeflate_polygon
andinflate_polygon
. It's also possible to deflate a polyline which would turn into a polygon, so again it only makes sense to createdeflate_polyline
method (yet this wouldn't be used often anyways I guess).Exposing parameters
It's also a question of whether it makes sense to expose other parameters like
miter_limit
andarc_tolerance
there as seen in godotengine/godot#36369. I've stumbled upon an issue of having to bind more than 6 parameters. Circumventing this limitation is possible by includingmethod_bind_ext
header but I suppose this bloats the engine binary size unnecessarily. For that I've simply managed to combine the two existing enums used to configure the join and end types together, but again this kinda creates complexity.Resolving workarounds
Maybe #1389, #2567.
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
Given my previous conversations with @reduz regarding making this configurable (summary: not so enthusiastic), and nonetheless taking into account the request I've received from people, I propose the updated API similar to the following
Every method not on the list is proposed to be removed...
If this enhancement will not be used often, can it be worked around with a few lines of script?:
Some methods can be removed, but it's quite difficult to reimplement them via script, given the performance is quite critical when it comes to clipping polygons at 60 FPS.
Is there a reason why this should be core and not an add-on in the asset library?:
Already part of core, too late. 😛
Note that it's totally fine to leave everything as-is, I personally invite people who need specific features to use the aforementioned module which does provide an extensive solution. I've just created this proposal upon some requests I've received from the community.
The text was updated successfully, but these errors were encountered: