summaryrefslogtreecommitdiff
path: root/modules/csg
diff options
context:
space:
mode:
Diffstat (limited to 'modules/csg')
-rw-r--r--modules/csg/csg.cpp2
-rw-r--r--modules/csg/csg_gizmos.cpp36
-rw-r--r--modules/csg/csg_shape.cpp19
-rw-r--r--modules/csg/doc_classes/CSGMesh3D.xml3
4 files changed, 34 insertions, 26 deletions
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index 8b46447f04..7387842259 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -931,7 +931,7 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_
// Delete the old faces in reverse index order.
merge_faces_idx.sort();
- merge_faces_idx.invert();
+ merge_faces_idx.reverse();
for (int i = 0; i < merge_faces_idx.size(); ++i) {
faces.remove(merge_faces_idx[i]);
}
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp
index e23442ef99..8a46dcca65 100644
--- a/modules/csg/csg_gizmos.cpp
+++ b/modules/csg/csg_gizmos.cpp
@@ -292,27 +292,16 @@ bool CSGShape3DGizmoPlugin::is_selectable_when_hidden() const {
}
void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
- CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
-
p_gizmo->clear();
- Ref<Material> material;
- switch (cs->get_operation()) {
- case CSGShape3D::OPERATION_UNION:
- material = get_material("shape_union_material", p_gizmo);
- break;
- case CSGShape3D::OPERATION_INTERSECTION:
- material = get_material("shape_intersection_material", p_gizmo);
- break;
- case CSGShape3D::OPERATION_SUBTRACTION:
- material = get_material("shape_subtraction_material", p_gizmo);
- break;
- }
-
- Ref<Material> handles_material = get_material("handles");
+ CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
Vector<Vector3> faces = cs->get_brush_faces();
+ if (faces.size() == 0) {
+ return;
+ }
+
Vector<Vector3> lines;
lines.resize(faces.size() * 2);
{
@@ -328,6 +317,21 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
}
+ Ref<Material> material;
+ switch (cs->get_operation()) {
+ case CSGShape3D::OPERATION_UNION:
+ material = get_material("shape_union_material", p_gizmo);
+ break;
+ case CSGShape3D::OPERATION_INTERSECTION:
+ material = get_material("shape_intersection_material", p_gizmo);
+ break;
+ case CSGShape3D::OPERATION_SUBTRACTION:
+ material = get_material("shape_subtraction_material", p_gizmo);
+ break;
+ }
+
+ Ref<Material> handles_material = get_material("handles");
+
p_gizmo->add_lines(lines, material);
p_gizmo->add_collision_segments(lines);
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index b97ee6ce4c..541b7036ac 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -89,6 +89,7 @@ uint32_t CSGShape3D::get_collision_mask() const {
}
void CSGShape3D::set_collision_mask_bit(int p_bit, bool p_value) {
+ ERR_FAIL_INDEX_MSG(p_bit, 32, "Collision mask bit must be between 0 and 31 inclusive.");
uint32_t mask = get_collision_mask();
if (p_value) {
mask |= 1 << p_bit;
@@ -99,20 +100,23 @@ void CSGShape3D::set_collision_mask_bit(int p_bit, bool p_value) {
}
bool CSGShape3D::get_collision_mask_bit(int p_bit) const {
+ ERR_FAIL_INDEX_V_MSG(p_bit, 32, false, "Collision mask bit must be between 0 and 31 inclusive.");
return get_collision_mask() & (1 << p_bit);
}
void CSGShape3D::set_collision_layer_bit(int p_bit, bool p_value) {
- uint32_t mask = get_collision_layer();
+ ERR_FAIL_INDEX_MSG(p_bit, 32, "Collision layer bit must be between 0 and 31 inclusive.");
+ uint32_t layer = get_collision_layer();
if (p_value) {
- mask |= 1 << p_bit;
+ layer |= 1 << p_bit;
} else {
- mask &= ~(1 << p_bit);
+ layer &= ~(1 << p_bit);
}
- set_collision_layer(mask);
+ set_collision_layer(layer);
}
bool CSGShape3D::get_collision_layer_bit(int p_bit) const {
+ ERR_FAIL_INDEX_V_MSG(p_bit, 32, false, "Collision layer bit must be between 0 and 31 inclusive.");
return get_collision_layer() & (1 << p_bit);
}
@@ -880,7 +884,7 @@ void CSGMesh3D::set_mesh(const Ref<Mesh> &p_mesh) {
mesh->connect("changed", callable_mp(this, &CSGMesh3D::_mesh_changed));
}
- _make_dirty();
+ _mesh_changed();
}
Ref<Mesh> CSGMesh3D::get_mesh() {
@@ -1679,7 +1683,7 @@ CSGBrush *CSGPolygon3D::_build_brush() {
Vector<Point2> final_polygon = polygon;
if (Triangulate::get_area(final_polygon) > 0) {
- final_polygon.invert();
+ final_polygon.reverse();
}
Vector<int> triangles = Geometry2D::triangulate_polygon(final_polygon);
@@ -1741,7 +1745,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
path_cache->connect("tree_exited", callable_mp(this, &CSGPolygon3D::_path_exited));
path_cache->connect("curve_changed", callable_mp(this, &CSGPolygon3D::_path_changed));
- path_cache = nullptr;
}
curve = path->get_curve();
if (curve.is_null()) {
@@ -2226,7 +2229,7 @@ void CSGPolygon3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_depth", "get_depth");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spin_degrees", PROPERTY_HINT_RANGE, "1,360,0.1"), "set_spin_degrees", "get_spin_degrees");
ADD_PROPERTY(PropertyInfo(Variant::INT, "spin_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_spin_sides", "get_spin_sides");
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "path_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Path"), "set_path_node", "get_path_node");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "path_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Path3D"), "set_path_node", "get_path_node");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_interval", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_path_interval", "get_path_interval");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_rotation", PROPERTY_HINT_ENUM, "Polygon,Path,PathFollow"), "set_path_rotation", "get_path_rotation");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_local"), "set_path_local", "is_path_local");
diff --git a/modules/csg/doc_classes/CSGMesh3D.xml b/modules/csg/doc_classes/CSGMesh3D.xml
index 1bab8f4ee9..5fa8427843 100644
--- a/modules/csg/doc_classes/CSGMesh3D.xml
+++ b/modules/csg/doc_classes/CSGMesh3D.xml
@@ -4,7 +4,7 @@
A CSG Mesh shape that uses a mesh resource.
</brief_description>
<description>
- This CSG node allows you to use any mesh resource as a CSG shape, provided it is closed, does not self-intersect, does not contain internal faces and has no edges that connect to more then two faces.
+ This CSG node allows you to use any mesh resource as a CSG shape, provided it is closed, does not self-intersect, does not contain internal faces and has no edges that connect to more than two faces.
</description>
<tutorials>
</tutorials>
@@ -16,6 +16,7 @@
</member>
<member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh">
The [Mesh] resource to use as a CSG shape.
+ [b]Note:[/b] When using an [ArrayMesh], avoid meshes with vertex normals unless a flat shader is required. By default, CSGMesh will ignore the mesh's vertex normals and use a smooth shader calculated using the faces' normals. If a flat shader is required, ensure that all faces' vertex normals are parallel.
</member>
</members>
<constants>