-
Notifications
You must be signed in to change notification settings - Fork 96
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
Improve Godot Engine's boolean operator engine (CSG) with elalish/manifold
#91
Comments
That would be awesome! Technically it should be possible to build Thrust with the C++ backend without using nvcc (from the CUDA toolkit) since Thrust is just a C++ header library. However, I haven't tried it yet. I'd like to migrate from Thrust to C++17 parallel algorithms partially to simplify the code and make it run in parallel on more than just CUDA GPUs, but also to make standard compiler chains work better. Are you interested in helping to try some of these options? |
Can you briefly describe a guide?
|
I think this test and the following one demonstrate all of that: https://github.com/elalish/manifold/blob/master/test/mesh_test.cpp#L698 And of course the docs: https://elalish.github.io/manifold/classmanifold_1_1_manifold.html |
Is it difficult to disable assimp? |
Assimp is only linked for building |
To give some context on Godot's CSG usage, Godot features CSG nodes (with both primitive and user-supplied custom meshes) that can be used to block out levels. CSG nodes can also have one or more material slots configured (and assigned on a per-face basis), which are preserved by the CSG algorithm and can be assigned by the user. The documentation can be found here. Custom code had to be written for this back in 2018, since CSG libraries available at that time were generally GPL-licensed. (Godot is MIT-licensed and therefore needs to avoid (L)GPL-licensed components.) This custom code is relatively small, but it also suffers from many bugs, especially with coplanar faces:
Mesh generation performance is good enough for static level design, but performing real-time changes should be avoided to prevent stuttering during gameplay. (That said, I doubt any CSG library can be fast enough to guarantee that mesh generation happens in < 16 milliseconds with typical low-poly game meshes. Moving mesh generation to a separate thread is probably a good idea.)
For reference, the current custom CSG implementation already has this as a requirement:
In parallel, we'd like to rework the CSG editor for better usability, but this can be done separately from the underlying mesh generation algorithm. Footnotes
|
@elalish Can you remove boost graph dependency? https://github.com/haasdo95/graphlite was the closest I can find. |
I was able to extract https://github.com/V-Sekai/godot/tree/csg-manifold [does not compile] and did a build system trick to enable |
Interesting, I'm still relatively new to the world of C++ libraries and didn't imagine Boost would be a big problem dependency-wise. I'm only using it for a connected components algorithm - figured better not to reinvent the wheel. Still, that's a generic algorithm and I'm sure it's available elsewhere, or we could just write our own. Thoughts? |
Can you evaluate https://github.com/haasdo95/graphlite? I wasn't able to find many substitutes. What operations are you using? |
All I use is connected_components (in two places): Line 427 in 3e92f47
graphlite doesn't technically include it, but it basically has it sketched out here: https://github.com/haasdo95/graphlite/blob/dde08e41c75b5fe42f7e3e0c6b02c4883b23155f/src/graph_lite/serialize.h#L156 Shouldn't be too hard to switch over. I like the idea of keeping my dependencies light. |
Can you do an estimate how difficult the work is, and if you need help? |
Shouldn't be more than a few hours, ideally. However, I'm leaving on vacation tomorrow for the rest of the week. If you want to take a stab at it, you're welcome to. Otherwise I'll take a look next week. As far as taking a dependency on graphlite, should I just copy in |
I'm swamped with pending work. I can't promise anything. It'll mostly like be next week. Regarding dependencies, Godot Engine has a readme and a licenses document. |
Here's my thoughts on the two Material Case.
|
Yeah, pretty much. You can do steps 1 and 2 after 3 (which means you can do it after many boolean operations and just deal with the UV coords that are left if you want). This is what the |
I've got a WIP #92 to change the graph dependency. |
Debugging winding order and conventions. Do you have an example cube with the positions and the triangle vertex indices? |
CCW. |
Nice work! So @fire, if this is working, does that mean the Boost dependency is okay, or you still need that removed? |
The Boost dependency still needs to be removed if this is to be integrated in Godot core. We can't integrate such a massive dependency in Godot's repository (as we include the source of all dependencies within https://github.com/godotengine/godot). Small binary size and fast build times are important to us, so we had to make this decision. |
I posted the changes I used here #93. Here's a Godot Engine master patched branch https://github.com/V-Sekai/godot/tree/csg-manifold-03. |
Notes:
|
To clarify, we want Godot to remain buildable without exceptions, so they need to be disableable at build-time. It's fine to keep exception code for those who want it, but it needs to be optional. |
Here are the logs that fail on exceptions. |
Posting my test godot project so I can clean up my desktop. |
You can see for yourself that our tests are passing, perhaps you can write a test to catch the problem you're having? |
@fire Any more information you can give me on this? I see you're now restoring materials, which presumably means you're now using |
I am currently trying to release Godot Engine 4.0 so things have been hectic. Sorry for the lack of communication. |
Some interesting new development. https://github.com/SarahWeiii/CoACD was able to turn arbitrary meshes into a manifold meshes. Not sure how, but something to do with openvdb. Useful for supporting arbitrary meshes as input |
@fire Yeah, I have quite a bit of familiarity with algorithms to make meshes manifold - I managed Microsoft's relationship with Netfabb when we were integrating their watertighting algorithms into our software. If you want to do it generically (like they did) you need a lot of heuristics and there's no avoiding having some very surprising results occasionally. This library isn't about heuristics, but reliability. That said, I would like to help with meshes that are at least attempting to be manifold to get over the hump. I'm considering a function like However, it would help my development greatly if you could supply some example models that you were expecting to work and reported as |
@fire did a thing here https://github.com/yetigit/force-manifold that uses just the openvdb part without the convex hull decomposition (which is still quality stuff); basically this is raymarching looking meshes being generated, guaranteeing that the mesh is a manifold. however often times the resolution is high LEFT is the result RIGHT is the input |
Thanks for sharing! Yeah, voxels are a reliable way to get manifoldness, though of course they kill the efficiency of a mesh. I'm almost done with my |
I decided to try for fun today and after vendoring thrust, glm, nanobind, quickhull subrepos I hit a roadblock with thrust requiring cuda.. I think I will have a hard time convincing the other Godot Engine maintainers that adding all these libraries is worth the load. |
but thrust doesn't require cuda? you can try to supply the thrust directory into manifold by setting |
I posted an updated branch to https://github.com/V-Sekai/godot/tree/vsk-csg-4.3. Note that the default csg shapes aren't manifold so they tend to disappear on use in a csg tree. Edited: Something about the indexed meshes requirement breaks the vertex attributes if I try to add more. |
Happy to help if you can give a little more detail. When you have discontinuous vertex properties, you'll need the |
Merge() helped significantly. Now I am stuck on associating ??? ReservedIDs with each csg shape's Vector<Ref<Materials>> because each shape has it's own material index and it's unique to the vector of materials. The above is a blender monkey and a mesh. Edited: Use the branch due to bugfixes. |
Looks like great progress!
Yes, that's exactly what they're for. I like to make a map of Does that make sense? |
The task would be to convert TypedArray<Face> into runs of single materials from its current mixed materials. Then something. The face struct looks like: struct CSGBrush {
struct Face {
Vector3 vertices[3];
Vector2 uvs[3];
AABB aabb; // We calculate this directly.
bool smooth = false;
bool invert = false;
int material = 0;
};
// ...
}; Then the task gets fuzzy after that. |
Yes, so just sort your vector of faces by material. Then find the indices of that vector where the material changes. These values become When you get a |
This comment was marked as resolved.
This comment was marked as resolved.
@elalish I gave up trying to learn the manifold runs api. I treat each material as a separate manifold surface and hacked them together as csg booleans unions where the single material is the id of the mesh. Multiple materials! |
That sound like a great basis for a tutorial, with demo code. I guess it looks trivial to @elalish , but my brain hurts reading that paragraph :) . |
Yes, fair feedback - I have some sample code in JS, but it's complicated by other things. Okay, I'll take it upon myself to make a tutorial for this. Does anyone have a preference as far as language? I usually default to JS, since it's pretty easy to read and commonly-known. And @fire, in fact |
I think TS would be a bit better: We have type support, so it may be better to show how to use those types. One can read it as JS by removing all the type annotations. |
I have no preference. |
if JS/TS is being weighted I vote for TS, I think it would be better suited for the mentioned demo. I do not code backend in JS, I only do frontend. On front I enjoy the freedom away from TS chains, but I am grateful for all the great tooling TS popularity brought, and ppl doing more typings via TS/jsdoc, .... |
Okay, I updated our basic Three.js interop example to demonstrate the use of I merged it quickly to make sure it deployed properly - seems to be all good. If anything is still unclear, please add a review to the merged PR above and I'll be happy to do a follow-on. |
The text was updated successfully, but these errors were encountered: