Skip to content

Commit

Permalink
Add CSGConvexCage3D
Browse files Browse the repository at this point in the history
  • Loading branch information
fire committed Sep 29, 2024
1 parent bd5966f commit 9223988
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 6 deletions.
1 change: 1 addition & 0 deletions modules/csg/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def get_doc_classes():
"CSGShape3D",
"CSGSphere3D",
"CSGTorus3D",
"CSGConvexCage3D",
]


Expand Down
34 changes: 28 additions & 6 deletions modules/csg/csg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,10 +387,8 @@ static void pack_manifold(
static void unpack_manifold(
const manifold::Manifold &p_manifold,
const HashMap<int32_t, Ref<Material>> &mesh_materials,
Ref<StandardMaterial3D> default_material,
CSGBrush *r_mesh_merge) {
Ref<StandardMaterial3D> default_material;
default_material.instantiate();

manifold::MeshGL64 mesh = p_manifold.GetMeshGL64();

constexpr int32_t order[3] = { 0, 2, 1 };
Expand Down Expand Up @@ -426,6 +424,7 @@ static void unpack_manifold(

ERR_FAIL_COND_MSG(property_i * mesh.numProp >= mesh.vertProperties.size(), "Invalid index into vertex properties");

// Position is guaranteed. Others are not.
face.vertices[tri_order_i] = Vector3(
mesh.vertProperties[property_i * mesh.numProp + MANIFOLD_PROPERTY_POSITION_X],
mesh.vertProperties[property_i * mesh.numProp + MANIFOLD_PROPERTY_POSITION_Y],
Expand All @@ -435,8 +434,12 @@ static void unpack_manifold(
mesh.vertProperties[property_i * mesh.numProp + MANIFOLD_PROPERTY_UV_X_0],
mesh.vertProperties[property_i * mesh.numProp + MANIFOLD_PROPERTY_UV_Y_0]);

face.smooth = mesh.vertProperties[property_i * mesh.numProp + MANIFOLD_PROPERTY_SMOOTH_GROUP] > 0.5f;
face.invert = mesh.vertProperties[property_i * mesh.numProp + MANIFOLD_PROPERTY_INVERT] > 0.5f;
if (mesh.numProp > MANIFOLD_PROPERTY_SMOOTH_GROUP) {
face.smooth = mesh.vertProperties[property_i * mesh.numProp + MANIFOLD_PROPERTY_SMOOTH_GROUP] > 0.5f;
}
if (mesh.numProp > MANIFOLD_PROPERTY_INVERT) {
face.invert = mesh.vertProperties[property_i * mesh.numProp + MANIFOLD_PROPERTY_INVERT] > 0.5f;
}
}

r_mesh_merge->faces.push_back(face);
Expand All @@ -449,6 +452,9 @@ static void unpack_manifold(
// CSGBrushOperation

void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_brush_a, const CSGBrush &p_brush_b, CSGBrush &r_merged_brush, float p_vertex_snap) {
Ref<StandardMaterial3D> default_material;
default_material.instantiate();

HashMap<int32_t, Ref<Material>> mesh_materials;
manifold::Manifold brush_a;
pack_manifold(&p_brush_a, brush_a, mesh_materials, p_vertex_snap);
Expand All @@ -466,7 +472,23 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b
merged_brush = brush_a - brush_b;
break;
}
unpack_manifold(merged_brush, mesh_materials, &r_merged_brush);
unpack_manifold(merged_brush, mesh_materials, default_material, &r_merged_brush);
}

void make_brush_hull(
CSGBrush *brush,
const Vector<Vector3> &points,
const Ref<Material> material) {

std::vector<manifold::vec3> converted_points;
for (int i = 0; i < points.size(); i++) {
converted_points.push_back(manifold::vec3(points[i].x, points[i].y, points[i].z));
}

HashMap<int32_t, Ref<Material>> mesh_materials;
manifold::Manifold m;
m = m.Hull(converted_points);
unpack_manifold(m, mesh_materials, material, brush);
}

// CSGBrushOperation::MeshMerge
Expand Down
5 changes: 5 additions & 0 deletions modules/csg/csg.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,9 @@ struct CSGBrushOperation {
void update_faces(const CSGBrush &p_brush_a, const int p_face_idx_a, const CSGBrush &p_brush_b, const int p_face_idx_b, Build2DFaceCollection &p_collection, float p_vertex_snap);
};

extern void make_brush_hull(
CSGBrush *brush,
const Vector<Vector3> &points,
const Ref<Material> material);

#endif // CSG_H
25 changes: 25 additions & 0 deletions modules/csg/csg_shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2444,3 +2444,28 @@ CSGPolygon3D::CSGPolygon3D() {
path_joined = false;
path = nullptr;
}

///////////////

CSGBrush *CSGConvexCage3D::_build_brush() {
CSGBrush *new_brush = memnew(CSGBrush);
Ref<Mesh> mesh = get_mesh();

Check failure on line 2452 in modules/csg/csg_shape.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor w/ Mono (target=editor)

declaration of 'mesh' shadows a member of 'CSGConvexCage3D' [-Werror=shadow]

Check failure on line 2452 in modules/csg/csg_shape.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with doubles and GCC sanitizers (target=editor, tests=yes, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=gold)

declaration of 'mesh' shadows a member of 'CSGConvexCage3D' [-Werror=shadow]

Check failure on line 2452 in modules/csg/csg_shape.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Template w/ Mono (target=template_release)

declaration of 'mesh' shadows a member of 'CSGConvexCage3D' [-Werror=shadow]

Check failure on line 2452 in modules/csg/csg_shape.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Editor (target=editor, tests=yes)

the following warning is treated as an error

Check failure on line 2452 in modules/csg/csg_shape.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Template (target=template_release)

the following warning is treated as an error
Vector<Vector3> points;
if (mesh.is_valid()) {
for (int i = 0; i < mesh->get_surface_count(); ++i) {
Array vertices = mesh->surface_get_arrays(i)[Mesh::ARRAY_VERTEX];
for (int j = 0; j < vertices.size(); ++j) {
points.push_back(vertices[j]);
}
}
if (points.size() < 4) {
return new_brush;
}
} else {
return new_brush;
}

make_brush_hull(new_brush, points, get_material());

return new_brush;
}
7 changes: 7 additions & 0 deletions modules/csg/csg_shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,4 +456,11 @@ VARIANT_ENUM_CAST(CSGPolygon3D::Mode)
VARIANT_ENUM_CAST(CSGPolygon3D::PathRotation)
VARIANT_ENUM_CAST(CSGPolygon3D::PathIntervalType)

class CSGConvexCage3D : public CSGMesh3D {
GDCLASS(CSGConvexCage3D, CSGMesh3D);

private:
virtual CSGBrush *_build_brush() override;
};

#endif // CSG_SHAPE_H
13 changes: 13 additions & 0 deletions modules/csg/doc_classes/CSGConvexCage3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CSGConvexCage3D" inherits="CSGMesh3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A CSG convex hull shape.
</brief_description>
<description>
This node creates a mesh based on the convex hull of a set of points for use with the CSG system.
[b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay.
</description>
<tutorials>
<link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link>
</tutorials>
</class>
65 changes: 65 additions & 0 deletions modules/csg/icons/CSGConvexCage3D.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions modules/csg/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ void initialize_csg_module(ModuleInitializationLevel p_level) {
GDREGISTER_CLASS(CSGCylinder3D);
GDREGISTER_CLASS(CSGTorus3D);
GDREGISTER_CLASS(CSGPolygon3D);
GDREGISTER_CLASS(CSGConvexCage3D);
GDREGISTER_CLASS(CSGCombiner3D);
}
#ifdef TOOLS_ENABLED
Expand Down

0 comments on commit 9223988

Please sign in to comment.