summaryrefslogtreecommitdiff
path: root/modules/csg
diff options
context:
space:
mode:
Diffstat (limited to 'modules/csg')
-rw-r--r--modules/csg/csg.cpp42
-rw-r--r--modules/csg/csg.h2
-rw-r--r--modules/csg/csg_gizmos.cpp70
-rw-r--r--modules/csg/csg_gizmos.h4
-rw-r--r--modules/csg/csg_shape.cpp77
-rw-r--r--modules/csg/csg_shape.h29
-rw-r--r--modules/csg/doc_classes/CSGBox.xml10
-rw-r--r--modules/csg/doc_classes/CSGCombiner.xml4
-rw-r--r--modules/csg/doc_classes/CSGCylinder.xml18
-rw-r--r--modules/csg/doc_classes/CSGMesh.xml6
-rw-r--r--modules/csg/doc_classes/CSGPolygon.xml18
-rw-r--r--modules/csg/doc_classes/CSGPrimitive.xml6
-rw-r--r--modules/csg/doc_classes/CSGShape.xml26
-rw-r--r--modules/csg/doc_classes/CSGSphere.xml14
-rw-r--r--modules/csg/doc_classes/CSGTorus.xml16
-rw-r--r--modules/csg/icons/icon_c_s_g_box.svg6
-rw-r--r--modules/csg/icons/icon_c_s_g_capsule.svg6
-rw-r--r--modules/csg/icons/icon_c_s_g_combiner.svg8
-rw-r--r--modules/csg/icons/icon_c_s_g_cylinder.svg6
-rw-r--r--modules/csg/icons/icon_c_s_g_mesh.svg6
-rw-r--r--modules/csg/icons/icon_c_s_g_polygon.svg6
-rw-r--r--modules/csg/icons/icon_c_s_g_sphere.svg6
-rw-r--r--modules/csg/icons/icon_c_s_g_torus.svg6
23 files changed, 276 insertions, 116 deletions
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index 12282b4730..f1b3fa2ac6 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -32,7 +32,7 @@
#include "core/math/face3.h"
#include "core/math/geometry.h"
#include "core/os/os.h"
-#include "core/sort.h"
+#include "core/sort_array.h"
#include "thirdparty/misc/triangulator.h"
void CSGBrush::clear() {
@@ -45,7 +45,7 @@ void CSGBrush::build_from_faces(const PoolVector<Vector3> &p_vertices, const Poo
int vc = p_vertices.size();
- ERR_FAIL_COND((vc % 3) != 0)
+ ERR_FAIL_COND((vc % 3) != 0);
PoolVector<Vector3>::Read rv = p_vertices.read();
int uvc = p_uvs.size();
@@ -242,7 +242,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_
//check if edge and poly share a vertex, of so, assign it to segment_idx
for (int i = 0; i < points.size(); i++) {
for (int j = 0; j < 2; j++) {
- if (segment[j].distance_to(points[i].point) < CMP_EPSILON) {
+ if (segment[j] == points[i].point) {
segment_idx[j] = i;
inserted_points.push_back(i);
break;
@@ -310,7 +310,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_
Vector2 edgeseg[2] = { points[edges[i].points[0]].point, points[edges[i].points[1]].point };
Vector2 closest = Geometry::get_closest_point_to_segment_2d(segment[j], edgeseg);
- if (closest.distance_to(segment[j]) < CMP_EPSILON) {
+ if (closest == segment[j]) {
//point rest of this edge
res = closest;
found = true;
@@ -439,7 +439,7 @@ void CSGBrushOperation::BuildPoly::clip(const CSGBrush *p_brush, int p_face, Mes
//transform A points to 2D
- if (segment[0].distance_to(segment[1]) < CMP_EPSILON)
+ if (segment[0] == segment[1])
return; //too small
_clip_segment(p_brush, p_face, segment, mesh_merge, p_for_B);
@@ -461,10 +461,10 @@ void CSGBrushOperation::_collision_callback(const CSGBrush *A, int p_face_a, Map
{
//check if either is a degenerate
- if (va[0].distance_to(va[1]) < CMP_EPSILON || va[0].distance_to(va[2]) < CMP_EPSILON || va[1].distance_to(va[2]) < CMP_EPSILON)
+ if (va[0] == va[1] || va[0] == va[2] || va[1] == va[2])
return;
- if (vb[0].distance_to(vb[1]) < CMP_EPSILON || vb[0].distance_to(vb[2]) < CMP_EPSILON || vb[1].distance_to(vb[2]) < CMP_EPSILON)
+ if (vb[0] == vb[1] || vb[0] == vb[2] || vb[1] == vb[2])
return;
}
@@ -611,7 +611,7 @@ void CSGBrushOperation::_add_poly_points(const BuildPoly &p_poly, int p_edge, in
{
EdgeSort es;
- es.angle = 0; //wont be checked here
+ es.angle = 0; //won't be checked here
es.edge = p_edge;
es.prev_point = p_from_point;
es.edge_point = p_to_point;
@@ -666,14 +666,14 @@ void CSGBrushOperation::_add_poly_points(const BuildPoly &p_poly, int p_edge, in
if (opposite_point == prev_point)
continue; //not going back
- EdgeSort e;
+ EdgeSort e2;
Vector2 local_vec = t2d.xform(p_poly.points[opposite_point].point);
- e.angle = -local_vec.angle(); //negate so we can sort by minimum angle
- e.edge = edge;
- e.edge_point = opposite_point;
- e.prev_point = to_point;
+ e2.angle = -local_vec.angle(); //negate so we can sort by minimum angle
+ e2.edge = edge;
+ e2.edge_point = opposite_point;
+ e2.prev_point = to_point;
- next_edges.push_back(e);
+ next_edges.push_back(e2);
}
//finally, sort by minimum angle
@@ -953,13 +953,15 @@ void CSGBrushOperation::_merge_poly(MeshMerge &mesh, int p_face_idx, const Build
//duplicate point
int insert_at = with_outline_vertex;
- polys.write[i].points.insert(insert_at, polys[i].points[insert_at]);
+ int point = polys[i].points[insert_at];
+ polys.write[i].points.insert(insert_at, point);
insert_at++;
//insert all others, outline should be backwards (must check)
int holesize = polys[i].holes[j].size();
for (int k = 0; k <= holesize; k++) {
int idx = (from_hole_vertex + k) % holesize;
- polys.write[i].points.insert(insert_at, polys[i].holes[j][idx]);
+ int point2 = polys[i].holes[j][idx];
+ polys.write[i].points.insert(insert_at, point2);
insert_at++;
}
@@ -1016,15 +1018,15 @@ int CSGBrushOperation::MeshMerge::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from
max_depth = p_depth;
}
- if (p_size <= BVH_LIMIT) {
+ if (p_size == 0) {
+
+ return -1;
+ } else if (p_size <= BVH_LIMIT) {
for (int i = 0; i < p_size - 1; i++) {
p_bb[p_from + i]->next = p_bb[p_from + i + 1] - p_bvh;
}
return p_bb[p_from] - p_bvh;
- } else if (p_size == 0) {
-
- return -1;
}
AABB aabb;
diff --git a/modules/csg/csg.h b/modules/csg/csg.h
index ac16575e82..4fa1a945cc 100644
--- a/modules/csg/csg.h
+++ b/modules/csg/csg.h
@@ -31,7 +31,6 @@
#ifndef CSG_H
#define CSG_H
-#include "core/dvector.h"
#include "core/map.h"
#include "core/math/aabb.h"
#include "core/math/plane.h"
@@ -39,6 +38,7 @@
#include "core/math/transform.h"
#include "core/math/vector3.h"
#include "core/oa_hash_map.h"
+#include "core/pool_vector.h"
#include "scene/resources/material.h"
struct CSGBrush {
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp
index 3044887ef5..e6bfa5525d 100644
--- a/modules/csg/csg_gizmos.cpp
+++ b/modules/csg/csg_gizmos.cpp
@@ -34,8 +34,18 @@
CSGShapeSpatialGizmoPlugin::CSGShapeSpatialGizmoPlugin() {
- Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/csg", Color(0.2, 0.5, 1, 0.1));
- create_material("shape_material", gizmo_color);
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/csg", Color(0.0, 0.4, 1, 0.15));
+ create_material("shape_union_material", gizmo_color);
+ create_material("shape_union_solid_material", gizmo_color);
+ gizmo_color.invert();
+ create_material("shape_subtraction_material", gizmo_color);
+ create_material("shape_subtraction_solid_material", gizmo_color);
+ gizmo_color.r = 0.95;
+ gizmo_color.g = 0.95;
+ gizmo_color.b = 0.95;
+ create_material("shape_intersection_material", gizmo_color);
+ create_material("shape_intersection_solid_material", gizmo_color);
+
create_handle_material("handles");
}
@@ -120,6 +130,10 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb);
float d = ra.x;
+ if (SpatialEditor::get_singleton()->is_snap_enabled()) {
+ d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap());
+ }
+
if (d < 0.001)
d = 0.001;
@@ -135,6 +149,10 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = ra[p_idx];
+ if (SpatialEditor::get_singleton()->is_snap_enabled()) {
+ d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap());
+ }
+
if (d < 0.001)
d = 0.001;
@@ -154,6 +172,9 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = axis.dot(ra);
+ if (SpatialEditor::get_singleton()->is_snap_enabled()) {
+ d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap());
+ }
if (d < 0.001)
d = 0.001;
@@ -173,6 +194,9 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = axis.dot(ra);
+ if (SpatialEditor::get_singleton()->is_snap_enabled()) {
+ d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap());
+ }
if (d < 0.001)
d = 0.001;
@@ -283,6 +307,10 @@ String CSGShapeSpatialGizmoPlugin::get_name() const {
return "CSGShapes";
}
+int CSGShapeSpatialGizmoPlugin::get_priority() const {
+ return -1;
+}
+
bool CSGShapeSpatialGizmoPlugin::is_selectable_when_hidden() const {
return true;
}
@@ -293,7 +321,19 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
p_gizmo->clear();
- Ref<Material> material = get_material("shape_material", p_gizmo);
+ Ref<Material> material;
+ switch (cs->get_operation()) {
+ case CSGShape::OPERATION_UNION:
+ material = get_material("shape_union_material", p_gizmo);
+ break;
+ case CSGShape::OPERATION_INTERSECTION:
+ material = get_material("shape_intersection_material", p_gizmo);
+ break;
+ case CSGShape::OPERATION_SUBTRACTION:
+ material = get_material("shape_subtraction_material", p_gizmo);
+ break;
+ }
+
Ref<Material> handles_material = get_material("handles");
PoolVector<Vector3> faces = cs->get_brush_faces();
@@ -316,6 +356,30 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
p_gizmo->add_lines(lines, material);
p_gizmo->add_collision_segments(lines);
+ if (p_gizmo->is_selected()) {
+ // Draw a translucent representation of the CSG node
+ Ref<ArrayMesh> mesh = memnew(ArrayMesh);
+ Array array;
+ array.resize(Mesh::ARRAY_MAX);
+ array[Mesh::ARRAY_VERTEX] = faces;
+ mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, array);
+
+ Ref<Material> solid_material;
+ switch (cs->get_operation()) {
+ case CSGShape::OPERATION_UNION:
+ solid_material = get_material("shape_union_solid_material", p_gizmo);
+ break;
+ case CSGShape::OPERATION_INTERSECTION:
+ solid_material = get_material("shape_intersection_solid_material", p_gizmo);
+ break;
+ case CSGShape::OPERATION_SUBTRACTION:
+ solid_material = get_material("shape_subtraction_solid_material", p_gizmo);
+ break;
+ }
+
+ p_gizmo->add_mesh(mesh, false, RID(), solid_material);
+ }
+
if (Object::cast_to<CSGSphere>(cs)) {
CSGSphere *s = Object::cast_to<CSGSphere>(cs);
diff --git a/modules/csg/csg_gizmos.h b/modules/csg/csg_gizmos.h
index b208c39938..d38dafc936 100644
--- a/modules/csg/csg_gizmos.h
+++ b/modules/csg/csg_gizmos.h
@@ -42,6 +42,7 @@ class CSGShapeSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
public:
bool has_gizmo(Spatial *p_spatial);
String get_name() const;
+ int get_priority() const;
bool is_selectable_when_hidden() const;
void redraw(EditorSpatialGizmo *p_gizmo);
@@ -54,7 +55,8 @@ public:
};
class EditorPluginCSG : public EditorPlugin {
- GDCLASS(EditorPluginCSG, EditorPlugin)
+ GDCLASS(EditorPluginCSG, EditorPlugin);
+
public:
EditorPluginCSG(EditorNode *p_editor);
};
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 809fd841c1..23725c4960 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -436,10 +436,10 @@ void CSGShape::_update_shape() {
}
// unset write access
- surfaces.write[i].verticesw = PoolVector<Vector3>::Write();
- surfaces.write[i].normalsw = PoolVector<Vector3>::Write();
- surfaces.write[i].uvsw = PoolVector<Vector2>::Write();
- surfaces.write[i].tansw = PoolVector<float>::Write();
+ surfaces.write[i].verticesw.release();
+ surfaces.write[i].normalsw.release();
+ surfaces.write[i].uvsw.release();
+ surfaces.write[i].tansw.release();
if (surfaces[i].last_added == 0)
continue;
@@ -531,6 +531,13 @@ void CSGShape::_notification(int p_what) {
}
}
+ if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+
+ if (parent) {
+ parent->_make_dirty();
+ }
+ }
+
if (p_what == NOTIFICATION_EXIT_TREE) {
if (parent)
@@ -550,6 +557,7 @@ void CSGShape::set_operation(Operation p_operation) {
operation = p_operation;
_make_dirty();
+ update_gizmo();
}
CSGShape::Operation CSGShape::get_operation() const {
@@ -575,6 +583,18 @@ void CSGShape::_validate_property(PropertyInfo &property) const {
}
}
+Array CSGShape::get_meshes() const {
+
+ if (root_mesh.is_valid()) {
+ Array arr;
+ arr.resize(2);
+ arr[0] = Transform();
+ arr[1] = root_mesh;
+ return arr;
+ }
+
+ return Array();
+}
void CSGShape::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_shape"), &CSGShape::_update_shape);
@@ -604,6 +624,8 @@ void CSGShape::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_calculate_tangents", "enabled"), &CSGShape::set_calculate_tangents);
ClassDB::bind_method(D_METHOD("is_calculating_tangents"), &CSGShape::is_calculating_tangents);
+ ClassDB::bind_method(D_METHOD("get_meshes"), &CSGShape::get_meshes);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "operation", PROPERTY_HINT_ENUM, "Union,Intersection,Subtraction"), "set_operation", "get_operation");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "snap", PROPERTY_HINT_RANGE, "0.0001,1,0.001"), "set_snap", "get_snap");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "calculate_tangents"), "set_calculate_tangents", "is_calculating_tangents");
@@ -703,6 +725,7 @@ CSGBrush *CSGMesh::_build_brush() {
PoolVector<bool> smooth;
PoolVector<Ref<Material> > materials;
PoolVector<Vector2> uvs;
+ Ref<Material> material = get_material();
for (int i = 0; i < mesh->get_surface_count(); i++) {
@@ -739,7 +762,12 @@ CSGBrush *CSGMesh::_build_brush() {
uvr_used = true;
}
- Ref<Material> mat = mesh->surface_get_material(i);
+ Ref<Material> mat;
+ if (material.is_valid()) {
+ mat = material;
+ } else {
+ mat = mesh->surface_get_material(i);
+ }
PoolVector<int> aindices = arrays[Mesh::ARRAY_INDEX];
if (aindices.size()) {
@@ -785,8 +813,8 @@ CSGBrush *CSGMesh::_build_brush() {
uvw[as + j + 1] = uv[1];
uvw[as + j + 2] = uv[2];
- sw[j / 3] = !flat;
- mw[j / 3] = mat;
+ sw[(as + j) / 3] = !flat;
+ mw[(as + j) / 3] = mat;
}
} else {
int as = vertices.size();
@@ -828,8 +856,8 @@ CSGBrush *CSGMesh::_build_brush() {
uvw[as + j + 1] = uv[1];
uvw[as + j + 2] = uv[2];
- sw[j / 3] = !flat;
- mw[j / 3] = mat;
+ sw[(as + j) / 3] = !flat;
+ mw[(as + j) / 3] = mat;
}
}
}
@@ -845,6 +873,18 @@ void CSGMesh::_mesh_changed() {
update_gizmo();
}
+void CSGMesh::set_material(const Ref<Material> &p_material) {
+ if (material == p_material)
+ return;
+ material = p_material;
+ _make_dirty();
+}
+
+Ref<Material> CSGMesh::get_material() const {
+
+ return material;
+}
+
void CSGMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &CSGMesh::set_mesh);
@@ -852,7 +892,11 @@ void CSGMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("_mesh_changed"), &CSGMesh::_mesh_changed);
+ ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGMesh::set_material);
+ ClassDB::bind_method(D_METHOD("get_material"), &CSGMesh::get_material);
+
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
}
void CSGMesh::set_mesh(const Ref<Mesh> &p_mesh) {
@@ -1132,9 +1176,9 @@ CSGBrush *CSGBox::_build_brush() {
for (int k = 0; k < 3; k++) {
if (i < 3)
- face_points[j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
+ face_points[j][(i + k) % 3] = v[k];
else
- face_points[3 - j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
+ face_points[3 - j][(i + k) % 3] = -v[k];
}
}
@@ -1773,11 +1817,9 @@ CSGBrush *CSGPolygon::_build_brush() {
path_cache = path;
- if (path_cache) {
- path_cache->connect("tree_exited", this, "_path_exited");
- path_cache->connect("curve_changed", this, "_path_changed");
- path_cache = NULL;
- }
+ path_cache->connect("tree_exited", this, "_path_exited");
+ path_cache->connect("curve_changed", this, "_path_changed");
+ path_cache = NULL;
}
curve = path->get_curve();
if (curve.is_null())
@@ -2039,6 +2081,9 @@ CSGBrush *CSGPolygon::_build_brush() {
for (int i = 0; i <= splits; i++) {
float ofs = i * path_interval;
+ if (ofs > bl) {
+ ofs = bl;
+ }
if (i == splits && path_joined) {
ofs = 0.0;
}
diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h
index df503faf2e..6c9419b3c2 100644
--- a/modules/csg/csg_shape.h
+++ b/modules/csg/csg_shape.h
@@ -38,8 +38,8 @@
#include "scene/resources/concave_polygon_shape.h"
#include "thirdparty/misc/mikktspace.h"
-class CSGShape : public VisualInstance {
- GDCLASS(CSGShape, VisualInstance);
+class CSGShape : public GeometryInstance {
+ GDCLASS(CSGShape, GeometryInstance);
public:
enum Operation {
@@ -117,6 +117,8 @@ protected:
virtual void _validate_property(PropertyInfo &property) const;
public:
+ Array get_meshes() const;
+
void set_operation(Operation p_operation);
Operation get_operation() const;
@@ -154,7 +156,8 @@ public:
VARIANT_ENUM_CAST(CSGShape::Operation)
class CSGCombiner : public CSGShape {
- GDCLASS(CSGCombiner, CSGShape)
+ GDCLASS(CSGCombiner, CSGShape);
+
private:
virtual CSGBrush *_build_brush();
@@ -163,7 +166,7 @@ public:
};
class CSGPrimitive : public CSGShape {
- GDCLASS(CSGPrimitive, CSGShape)
+ GDCLASS(CSGPrimitive, CSGShape);
private:
bool invert_faces;
@@ -180,11 +183,12 @@ public:
};
class CSGMesh : public CSGPrimitive {
- GDCLASS(CSGMesh, CSGPrimitive)
+ GDCLASS(CSGMesh, CSGPrimitive);
virtual CSGBrush *_build_brush();
Ref<Mesh> mesh;
+ Ref<Material> material;
void _mesh_changed();
@@ -194,11 +198,14 @@ protected:
public:
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh();
+
+ void set_material(const Ref<Material> &p_material);
+ Ref<Material> get_material() const;
};
class CSGSphere : public CSGPrimitive {
- GDCLASS(CSGSphere, CSGPrimitive)
+ GDCLASS(CSGSphere, CSGPrimitive);
virtual CSGBrush *_build_brush();
Ref<Material> material;
@@ -231,7 +238,7 @@ public:
class CSGBox : public CSGPrimitive {
- GDCLASS(CSGBox, CSGPrimitive)
+ GDCLASS(CSGBox, CSGPrimitive);
virtual CSGBrush *_build_brush();
Ref<Material> material;
@@ -260,7 +267,7 @@ public:
class CSGCylinder : public CSGPrimitive {
- GDCLASS(CSGCylinder, CSGPrimitive)
+ GDCLASS(CSGCylinder, CSGPrimitive);
virtual CSGBrush *_build_brush();
Ref<Material> material;
@@ -297,7 +304,7 @@ public:
class CSGTorus : public CSGPrimitive {
- GDCLASS(CSGTorus, CSGPrimitive)
+ GDCLASS(CSGTorus, CSGPrimitive);
virtual CSGBrush *_build_brush();
Ref<Material> material;
@@ -334,7 +341,7 @@ public:
class CSGPolygon : public CSGPrimitive {
- GDCLASS(CSGPolygon, CSGPrimitive)
+ GDCLASS(CSGPolygon, CSGPrimitive);
public:
enum Mode {
@@ -397,7 +404,7 @@ public:
void set_spin_degrees(float p_spin_degrees);
float get_spin_degrees() const;
- void set_spin_sides(int p_sides);
+ void set_spin_sides(int p_spin_sides);
int get_spin_sides() const;
void set_path_node(const NodePath &p_path);
diff --git a/modules/csg/doc_classes/CSGBox.xml b/modules/csg/doc_classes/CSGBox.xml
index 5ec7b5089d..14f5a1952e 100644
--- a/modules/csg/doc_classes/CSGBox.xml
+++ b/modules/csg/doc_classes/CSGBox.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGBox" inherits="CSGPrimitive" category="Core" version="3.1">
+<class name="CSGBox" inherits="CSGPrimitive" category="Core" version="3.2">
<brief_description>
A CSG Box shape.
</brief_description>
@@ -8,21 +8,19 @@
</description>
<tutorials>
</tutorials>
- <demos>
- </demos>
<methods>
</methods>
<members>
- <member name="depth" type="float" setter="set_depth" getter="get_depth">
+ <member name="depth" type="float" setter="set_depth" getter="get_depth" default="2.0">
Depth of the box measured from the center of the box.
</member>
- <member name="height" type="float" setter="set_height" getter="get_height">
+ <member name="height" type="float" setter="set_height" getter="get_height" default="2.0">
Height of the box measured from the center of the box.
</member>
<member name="material" type="Material" setter="set_material" getter="get_material">
The material used to render the box.
</member>
- <member name="width" type="float" setter="set_width" getter="get_width">
+ <member name="width" type="float" setter="set_width" getter="get_width" default="2.0">
Width of the box measured from the center of the box.
</member>
</members>
diff --git a/modules/csg/doc_classes/CSGCombiner.xml b/modules/csg/doc_classes/CSGCombiner.xml
index 69c5df5840..51428b25f8 100644
--- a/modules/csg/doc_classes/CSGCombiner.xml
+++ b/modules/csg/doc_classes/CSGCombiner.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGCombiner" inherits="CSGShape" category="Core" version="3.1">
+<class name="CSGCombiner" inherits="CSGShape" category="Core" version="3.2">
<brief_description>
A CSG node that allows you to combine other CSG modifiers.
</brief_description>
@@ -8,8 +8,6 @@
</description>
<tutorials>
</tutorials>
- <demos>
- </demos>
<methods>
</methods>
<constants>
diff --git a/modules/csg/doc_classes/CSGCylinder.xml b/modules/csg/doc_classes/CSGCylinder.xml
index 92b170ed1f..9fc0281887 100644
--- a/modules/csg/doc_classes/CSGCylinder.xml
+++ b/modules/csg/doc_classes/CSGCylinder.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGCylinder" inherits="CSGPrimitive" category="Core" version="3.1">
+<class name="CSGCylinder" inherits="CSGPrimitive" category="Core" version="3.2">
<brief_description>
A CSG Cylinder shape.
</brief_description>
@@ -8,28 +8,26 @@
</description>
<tutorials>
</tutorials>
- <demos>
- </demos>
<methods>
</methods>
<members>
- <member name="cone" type="bool" setter="set_cone" getter="is_cone">
- If true a cone is created, the [member radius] will only apply to one side.
+ <member name="cone" type="bool" setter="set_cone" getter="is_cone" default="false">
+ If [code]true[/code] a cone is created, the [member radius] will only apply to one side.
</member>
- <member name="height" type="float" setter="set_height" getter="get_height">
+ <member name="height" type="float" setter="set_height" getter="get_height" default="1.0">
The height of the cylinder.
</member>
<member name="material" type="Material" setter="set_material" getter="get_material">
The material used to render the cylinder.
</member>
- <member name="radius" type="float" setter="set_radius" getter="get_radius">
+ <member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0">
The radius of the cylinder.
</member>
- <member name="sides" type="int" setter="set_sides" getter="get_sides">
+ <member name="sides" type="int" setter="set_sides" getter="get_sides" default="8">
The number of sides of the cylinder, the higher this number the more detail there will be in the cylinder.
</member>
- <member name="smooth_faces" type="bool" setter="set_smooth_faces" getter="get_smooth_faces">
- If true the normals of the cylinder are set to give a smooth effect making the cylinder seem rounded. When false the cylinder will have a flat shaded look.
+ <member name="smooth_faces" type="bool" setter="set_smooth_faces" getter="get_smooth_faces" default="true">
+ If [code]true[/code] the normals of the cylinder are set to give a smooth effect making the cylinder seem rounded. If [code]false[/code] the cylinder will have a flat shaded look.
</member>
</members>
<constants>
diff --git a/modules/csg/doc_classes/CSGMesh.xml b/modules/csg/doc_classes/CSGMesh.xml
index 58e2bc1c4b..afe0bc262d 100644
--- a/modules/csg/doc_classes/CSGMesh.xml
+++ b/modules/csg/doc_classes/CSGMesh.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGMesh" inherits="CSGPrimitive" category="Core" version="3.1">
+<class name="CSGMesh" inherits="CSGPrimitive" category="Core" version="3.2">
<brief_description>
A CSG Mesh shape that uses a mesh resource.
</brief_description>
@@ -8,11 +8,11 @@
</description>
<tutorials>
</tutorials>
- <demos>
- </demos>
<methods>
</methods>
<members>
+ <member name="material" type="Material" setter="set_material" getter="get_material">
+ </member>
<member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh">
The mesh resource to use as a CSG shape.
</member>
diff --git a/modules/csg/doc_classes/CSGPolygon.xml b/modules/csg/doc_classes/CSGPolygon.xml
index a33e5557cb..0ecee92cd5 100644
--- a/modules/csg/doc_classes/CSGPolygon.xml
+++ b/modules/csg/doc_classes/CSGPolygon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGPolygon" inherits="CSGPrimitive" category="Core" version="3.1">
+<class name="CSGPolygon" inherits="CSGPrimitive" category="Core" version="3.2">
<brief_description>
Extrudes a 2D polygon shape to create a 3D mesh.
</brief_description>
@@ -8,31 +8,29 @@
</description>
<tutorials>
</tutorials>
- <demos>
- </demos>
<methods>
</methods>
<members>
- <member name="depth" type="float" setter="set_depth" getter="get_depth">
+ <member name="depth" type="float" setter="set_depth" getter="get_depth" default="1.0">
Extrusion depth when [member mode] is [constant MODE_DEPTH].
</member>
<member name="material" type="Material" setter="set_material" getter="get_material">
Material to use for the resulting mesh.
</member>
- <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="CSGPolygon.Mode">
+ <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="CSGPolygon.Mode" default="0">
Extrusion mode.
</member>
<member name="path_continuous_u" type="bool" setter="set_path_continuous_u" getter="is_path_continuous_u">
- If true the u component of our uv will continuously increase in unison with the distance traveled along our path when [member mode] is [constant MODE_PATH].
+ If [code]true[/code] the u component of our uv will continuously increase in unison with the distance traveled along our path when [member mode] is [constant MODE_PATH].
</member>
<member name="path_interval" type="float" setter="set_path_interval" getter="get_path_interval">
Interval at which a new extrusion slice is added along the path when [member mode] is [constant MODE_PATH].
</member>
<member name="path_joined" type="bool" setter="set_path_joined" getter="is_path_joined">
- If true the start and end of our path are joined together ensuring there is no seam when [member mode] is [constant MODE_PATH].
+ If [code]true[/code] the start and end of our path are joined together ensuring there is no seam when [member mode] is [constant MODE_PATH].
</member>
<member name="path_local" type="bool" setter="set_path_local" getter="is_path_local">
- If false we extrude centered on our path, if true we extrude in relation to the position of our CSGPolygon when [member mode] is [constant MODE_PATH].
+ If [code]false[/code] we extrude centered on our path, if [code]true[/code] we extrude in relation to the position of our CSGPolygon when [member mode] is [constant MODE_PATH].
</member>
<member name="path_node" type="NodePath" setter="set_path_node" getter="get_path_node">
The [Shape] object containing the path along which we extrude when [member mode] is [constant MODE_PATH].
@@ -40,10 +38,10 @@
<member name="path_rotation" type="int" setter="set_path_rotation" getter="get_path_rotation" enum="CSGPolygon.PathRotation">
The method by which each slice is rotated along the path when [member mode] is [constant MODE_PATH].
</member>
- <member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon">
+ <member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon" default="PoolVector2Array( 0, 0, 0, 1, 1, 1, 1, 0 )">
Point array that defines the shape that we'll extrude.
</member>
- <member name="smooth_faces" type="bool" setter="set_smooth_faces" getter="get_smooth_faces">
+ <member name="smooth_faces" type="bool" setter="set_smooth_faces" getter="get_smooth_faces" default="false">
Generates smooth normals so smooth shading is applied to our mesh.
</member>
<member name="spin_degrees" type="float" setter="set_spin_degrees" getter="get_spin_degrees">
diff --git a/modules/csg/doc_classes/CSGPrimitive.xml b/modules/csg/doc_classes/CSGPrimitive.xml
index 2591bab7e3..6c2f837637 100644
--- a/modules/csg/doc_classes/CSGPrimitive.xml
+++ b/modules/csg/doc_classes/CSGPrimitive.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGPrimitive" inherits="CSGShape" category="Core" version="3.1">
+<class name="CSGPrimitive" inherits="CSGShape" category="Core" version="3.2">
<brief_description>
Base class for CSG primitives.
</brief_description>
@@ -7,12 +7,10 @@
</description>
<tutorials>
</tutorials>
- <demos>
- </demos>
<methods>
</methods>
<members>
- <member name="invert_faces" type="bool" setter="set_invert_faces" getter="is_inverting_faces">
+ <member name="invert_faces" type="bool" setter="set_invert_faces" getter="is_inverting_faces" default="false">
Invert the faces of the mesh.
</member>
</members>
diff --git a/modules/csg/doc_classes/CSGShape.xml b/modules/csg/doc_classes/CSGShape.xml
index 56087cbb82..755d8df67e 100644
--- a/modules/csg/doc_classes/CSGShape.xml
+++ b/modules/csg/doc_classes/CSGShape.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGShape" inherits="VisualInstance" category="Core" version="3.1">
+<class name="CSGShape" inherits="GeometryInstance" category="Core" version="3.2">
<brief_description>
The CSG base class.
</brief_description>
@@ -8,8 +8,6 @@
</description>
<tutorials>
</tutorials>
- <demos>
- </demos>
<methods>
<method name="get_collision_layer_bit" qualifiers="const">
<return type="bool">
@@ -29,11 +27,17 @@
Returns an individual bit on the collision mask.
</description>
</method>
+ <method name="get_meshes" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_root_shape" qualifiers="const">
<return type="bool">
</return>
<description>
- Returns true if this is a root shape and is thus the object that is rendered.
+ Returns [code]true[/code] if this is a root shape and is thus the object that is rendered.
</description>
</method>
<method name="set_collision_layer_bit">
@@ -60,23 +64,23 @@
</method>
</methods>
<members>
- <member name="calculate_tangents" type="bool" setter="set_calculate_tangents" getter="is_calculating_tangents">
+ <member name="calculate_tangents" type="bool" setter="set_calculate_tangents" getter="is_calculating_tangents" default="true">
Calculate tangents for the CSG shape which allows the use of normal maps. This is only applied on the root shape, this setting is ignored on any child.
</member>
- <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer">
+ <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
The physics layers this area is in.
Collidable objects can exist in any of 32 different layers. These layers work like a tagging system, and are not visual. A collidable can use these layers to select with which objects it can collide, using the collision_mask property.
A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A.
</member>
- <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask">
+ <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
The physics layers this CSG shape scans for collisions.
</member>
- <member name="operation" type="int" setter="set_operation" getter="get_operation" enum="CSGShape.Operation">
+ <member name="operation" type="int" setter="set_operation" getter="get_operation" enum="CSGShape.Operation" default="0">
The operation that is performed on this shape. This is ignored for the first CSG child node as the operation is between this node and the previous child of this nodes parent.
</member>
- <member name="snap" type="float" setter="set_snap" getter="get_snap">
+ <member name="snap" type="float" setter="set_snap" getter="get_snap" default="0.001">
</member>
- <member name="use_collision" type="bool" setter="set_use_collision" getter="is_using_collision">
+ <member name="use_collision" type="bool" setter="set_use_collision" getter="is_using_collision" default="false">
Adds a collision shape to the physics engine for our CSG shape. This will always act like a static body. Note that the collision shape is still active even if the CSG shape itself is hidden.
</member>
</members>
@@ -88,7 +92,7 @@
Only intersecting geometry remains, the rest is removed.
</constant>
<constant name="OPERATION_SUBTRACTION" value="2" enum="Operation">
- The second shape is susbtracted from the first, leaving a dent with it's shape.
+ The second shape is subtracted from the first, leaving a dent with its shape.
</constant>
</constants>
</class>
diff --git a/modules/csg/doc_classes/CSGSphere.xml b/modules/csg/doc_classes/CSGSphere.xml
index a0069879cb..714e725acb 100644
--- a/modules/csg/doc_classes/CSGSphere.xml
+++ b/modules/csg/doc_classes/CSGSphere.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGSphere" inherits="CSGPrimitive" category="Core" version="3.1">
+<class name="CSGSphere" inherits="CSGPrimitive" category="Core" version="3.2">
<brief_description>
A CSG Sphere shape.
</brief_description>
@@ -8,25 +8,23 @@
</description>
<tutorials>
</tutorials>
- <demos>
- </demos>
<methods>
</methods>
<members>
<member name="material" type="Material" setter="set_material" getter="get_material">
The material used to render the sphere.
</member>
- <member name="radial_segments" type="int" setter="set_radial_segments" getter="get_radial_segments">
+ <member name="radial_segments" type="int" setter="set_radial_segments" getter="get_radial_segments" default="12">
Number of vertical slices for the sphere.
</member>
- <member name="radius" type="float" setter="set_radius" getter="get_radius">
+ <member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0">
Radius of the sphere.
</member>
- <member name="rings" type="int" setter="set_rings" getter="get_rings">
+ <member name="rings" type="int" setter="set_rings" getter="get_rings" default="6">
Number of horizontal slices for the sphere.
</member>
- <member name="smooth_faces" type="bool" setter="set_smooth_faces" getter="get_smooth_faces">
- If true the normals of the sphere are set to give a smooth effect making the sphere seem rounded. When false the sphere will have a flat shaded look.
+ <member name="smooth_faces" type="bool" setter="set_smooth_faces" getter="get_smooth_faces" default="true">
+ If [code]true[/code] the normals of the sphere are set to give a smooth effect making the sphere seem rounded. If [code]false[/code] the sphere will have a flat shaded look.
</member>
</members>
<constants>
diff --git a/modules/csg/doc_classes/CSGTorus.xml b/modules/csg/doc_classes/CSGTorus.xml
index 187d71a2fa..5dc6bb8380 100644
--- a/modules/csg/doc_classes/CSGTorus.xml
+++ b/modules/csg/doc_classes/CSGTorus.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGTorus" inherits="CSGPrimitive" category="Core" version="3.1">
+<class name="CSGTorus" inherits="CSGPrimitive" category="Core" version="3.2">
<brief_description>
A CSG Torus shape.
</brief_description>
@@ -8,28 +8,26 @@
</description>
<tutorials>
</tutorials>
- <demos>
- </demos>
<methods>
</methods>
<members>
- <member name="inner_radius" type="float" setter="set_inner_radius" getter="get_inner_radius">
+ <member name="inner_radius" type="float" setter="set_inner_radius" getter="get_inner_radius" default="2.0">
The inner radius of the torus.
</member>
<member name="material" type="Material" setter="set_material" getter="get_material">
The material used to render the torus.
</member>
- <member name="outer_radius" type="float" setter="set_outer_radius" getter="get_outer_radius">
+ <member name="outer_radius" type="float" setter="set_outer_radius" getter="get_outer_radius" default="3.0">
The outer radius of the torus.
</member>
- <member name="ring_sides" type="int" setter="set_ring_sides" getter="get_ring_sides">
+ <member name="ring_sides" type="int" setter="set_ring_sides" getter="get_ring_sides" default="6">
The number of edges each ring of the torus is constructed of.
</member>
- <member name="sides" type="int" setter="set_sides" getter="get_sides">
+ <member name="sides" type="int" setter="set_sides" getter="get_sides" default="8">
The number of slices the torus is constructed of.
</member>
- <member name="smooth_faces" type="bool" setter="set_smooth_faces" getter="get_smooth_faces">
- If true the normals of the torus are set to give a smooth effect making the torus seem rounded. When false the torus will have a flat shaded look.
+ <member name="smooth_faces" type="bool" setter="set_smooth_faces" getter="get_smooth_faces" default="true">
+ If [code]true[/code] the normals of the torus are set to give a smooth effect making the torus seem rounded. If [code]false[/code] the torus will have a flat shaded look.
</member>
</members>
<constants>
diff --git a/modules/csg/icons/icon_c_s_g_box.svg b/modules/csg/icons/icon_c_s_g_box.svg
new file mode 100644
index 0000000000..67e34df444
--- /dev/null
+++ b/modules/csg/icons/icon_c_s_g_box.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m12 9c-0.55401 0-1 0.44599-1 1v1h2v2h1c0.55401 0 1-0.44599 1-1v-2c0-0.55401-0.44599-1-1-1h-2zm1 4h-2v-2h-1c-0.55401 0-1 0.44599-1 1v2c0 0.55401 0.44599 1 1 1h2c0.55401 0 1-0.44599 1-1v-1z" fill="#84c2ff"/>
+<path transform="translate(0 1036.4)" d="m8 0.94531-7 3.5v7.2227l7 3.5 0.29492-0.14844c-0.18282-0.30101-0.29492-0.64737-0.29492-1.0195v-2c0-0.72651 0.40824-1.3664 1-1.7168v-1.6699l4-2v1.3867h1c0.36419 0 0.70336 0.10754 1 0.2832v-3.8379zm0 2.1152 3.9395 1.9707-3.9395 1.9688-3.9395-1.9688zm-5 3.5527 4 2v3.9414l-4-2.002z" fill="#fc9c9c" stroke-width="1.0667"/>
+</g>
+</svg>
diff --git a/modules/csg/icons/icon_c_s_g_capsule.svg b/modules/csg/icons/icon_c_s_g_capsule.svg
new file mode 100644
index 0000000000..92a7b5a870
--- /dev/null
+++ b/modules/csg/icons/icon_c_s_g_capsule.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g>
+<path d="m8 1c-2.7527 0-5 2.2418-5 4.9902v4.0176c0 2.7484 2.2473 4.9922 5 4.9922 0.092943 0 0.18367-0.008623 0.27539-0.013672-0.17055-0.29341-0.27539-0.62792-0.27539-0.98633v-2c0-0.72887 0.41095-1.3691 1.0059-1.7188v-0.28125c0.34771-0.034464 0.68259-0.10691 1.0156-0.19922 0.10394-0.99856 0.95603-1.8008 1.9785-1.8008h1v-2.0098c0-2.7484-2.2473-4.9902-5-4.9902zm-1.0059 2.127v4.8574c-0.66556-0.1047-1.2974-0.37231-1.9941-0.66211v-1.3223c0-1.3474 0.79841-2.4642 1.9941-2.873zm2.0117 0c1.1957 0.4088 1.9941 1.5256 1.9941 2.873v1.3457c-0.68406 0.3054-1.3142 0.57292-1.9941 0.66602v-4.8848zm-4.0059 6.334c0.67836 0.2231 1.3126 0.44599 1.9941 0.52539v2.8848c-1.1957-0.4092-1.9941-1.5237-1.9941-2.8711v-0.53906z" fill="#fc9c9c"/>
+<path d="m12 9c-0.55401 0-1 0.44599-1 1v1h2v2h1c0.55401 0 1-0.44599 1-1v-2c0-0.55401-0.44599-1-1-1zm1 4h-2v-2h-1c-0.55401 0-1 0.44599-1 1v2c0 0.55401 0.44599 1 1 1h2c0.55401 0 1-0.44599 1-1z" fill="#84c2ff"/>
+</g>
+</svg>
diff --git a/modules/csg/icons/icon_c_s_g_combiner.svg b/modules/csg/icons/icon_c_s_g_combiner.svg
new file mode 100644
index 0000000000..cce2902e24
--- /dev/null
+++ b/modules/csg/icons/icon_c_s_g_combiner.svg
@@ -0,0 +1,8 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m12 9c-0.55401 0-1 0.44599-1 1v1h2v2h1c0.55401 0 1-0.44599 1-1v-2c0-0.55401-0.44599-1-1-1h-2zm1 4h-2v-2h-1c-0.55401 0-1 0.44599-1 1v2c0 0.55401 0.44599 1 1 1h2c0.55401 0 1-0.44599 1-1v-1z" fill="#84c2ff"/>
+<g fill="#fc9c9c">
+<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2h2zm2 0v2h2v-2zm4 0v2h2v-2zm4 0v2h2c0-1.1046-0.89543-2-2-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4v2h2v-2zm0 4c0 1.1046 0.89543 2 2 2v-2zm4 0v2h2v-2z" fill="#fc9c9c"/>
+</g>
+</g>
+</svg>
diff --git a/modules/csg/icons/icon_c_s_g_cylinder.svg b/modules/csg/icons/icon_c_s_g_cylinder.svg
new file mode 100644
index 0000000000..645a74c79b
--- /dev/null
+++ b/modules/csg/icons/icon_c_s_g_cylinder.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 14.999999 14.999999" xmlns="http://www.w3.org/2000/svg">
+<g>
+<path transform="scale(.9375)" d="m8 1c-1.7469 0-3.328 0.22648-4.5586 0.63672-0.61528 0.20512-1.1471 0.45187-1.5898 0.80078-0.44272 0.34891-0.85156 0.88101-0.85156 1.5625v8c0 0.68149 0.40884 1.2155 0.85156 1.5645 0.44272 0.34891 0.97457 0.59577 1.5898 0.80078 1.2306 0.41024 2.8117 0.63477 4.5586 0.63477 0.095648 0 0.18467-0.008426 0.2793-0.009766-0.1722-0.29446-0.2793-0.62995-0.2793-0.99023v-1c-1.5668 0-2.9867-0.2195-3.9277-0.5332-0.46329-0.15435-0.90474-0.33752-1.0723-0.4668v-5.8125c0.1468 0.058667 0.2835 0.12515 0.44141 0.17773 1.2306 0.41024 2.8117 0.63477 4.5586 0.63477s3.328-0.22453 4.5586-0.63477c0.15791-0.052267 0.29461-0.11864 0.44141-0.17773v1.8125h1c0.36396 0 0.70348 0.10774 1 0.2832v-4.2832c0-0.68149-0.40884-1.2136-0.85156-1.5625-0.44272-0.34891-0.97457-0.59566-1.5898-0.80078-1.2306-0.41024-2.8117-0.63672-4.5586-0.63672zm0 2c1.5668 0 2.9867 0.22145 3.9277 0.53516 0.46368 0.15456 0.80138 0.33741 0.96875 0.4668-0.16752 0.12928-0.50546 0.3105-0.96875 0.46484-0.94102 0.31371-2.361 0.5332-3.9277 0.5332s-2.9867-0.2195-3.9277-0.5332c-0.46329-0.15435-0.80123-0.33556-0.96875-0.46484 0.16737-0.12939 0.50507-0.31224 0.96875-0.4668 0.94102-0.31371 2.361-0.53516 3.9277-0.53516z" fill="#fc9c9c" stroke-width="1.0667"/>
+<path d="m11.25 8.4375c-0.51938 0-0.9375 0.41812-0.9375 0.9375v0.9375h1.875v1.875h0.9375c0.51938 0 0.9375-0.41812 0.9375-0.9375v-1.875c0-0.51938-0.41812-0.9375-0.9375-0.9375zm0.9375 3.75h-1.875v-1.875h-0.9375c-0.51938 0-0.9375 0.41812-0.9375 0.9375v1.875c0 0.51938 0.41812 0.9375 0.9375 0.9375h1.875c0.51938 0 0.9375-0.41812 0.9375-0.9375z" fill="#84c2ff"/>
+</g>
+</svg>
diff --git a/modules/csg/icons/icon_c_s_g_mesh.svg b/modules/csg/icons/icon_c_s_g_mesh.svg
new file mode 100644
index 0000000000..6e940a4aa5
--- /dev/null
+++ b/modules/csg/icons/icon_c_s_g_mesh.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g>
+<path d="m3 1c-1.1046 0-2 0.89543-2 2 5.649e-4 0.71397 0.38169 1.3735 1 1.7305v6.541c-0.61771 0.35663-0.99874 1.0152-1 1.7285 0 1.1046 0.89543 2 2 2 0.71397-5.65e-4 1.3735-0.38169 1.7305-1h3.2695v-2h-3.2715c-0.17478-0.30301-0.42598-0.55488-0.72852-0.73047v-5.8555l4.916 4.916c0.31428-0.20669 0.68609-0.33008 1.084-0.33008 0-0.3979 0.12338-0.76971 0.33008-1.084l-4.916-4.916h5.8574c0.17478 0.30301 0.42598 0.55488 0.72852 0.73047v3.2695h2v-3.2715c0.61771-0.35663 0.99874-1.0152 1-1.7285 0-1.1046-0.89543-2-2-2-0.71397 5.648e-4 -1.3735 0.38169-1.7305 1h-6.541c-0.35663-0.61771-1.0152-0.99874-1.7285-1z" fill="#fc9c9c"/>
+<path d="m12 9c-0.55401 0-1 0.44599-1 1v1h2v2h1c0.55401 0 1-0.44599 1-1v-2c0-0.55401-0.44599-1-1-1zm1 4h-2v-2h-1c-0.55401 0-1 0.44599-1 1v2c0 0.55401 0.44599 1 1 1h2c0.55401 0 1-0.44599 1-1z" fill="#84c2ff"/>
+</g>
+</svg>
diff --git a/modules/csg/icons/icon_c_s_g_polygon.svg b/modules/csg/icons/icon_c_s_g_polygon.svg
new file mode 100644
index 0000000000..71b03cb8e6
--- /dev/null
+++ b/modules/csg/icons/icon_c_s_g_polygon.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m7.9629 1.002c-0.14254 0.00487-0.28238 0.04016-0.41016 0.10352l-6 3c-0.33878 0.16944-0.55276 0.51574-0.55273 0.89453v5.832c-0.105 0.61631 0.37487 1.1768 1 1.168h5v2c2.16e-5 0.67546 0.64487 1.1297 1.2617 0.95898-0.16118-0.28721-0.26172-0.61135-0.26172-0.95898v-2c0-0.72673 0.40794-1.3664 1-1.7168v-1.666l4-2v1.3828h1c0.36397 0 0.70348 0.10774 1 0.2832v-3.2773c6e-6 -0.00195 6e-6 -0.0039094 0-0.0058594 2.6e-5 -0.37879-0.21395-0.72509-0.55273-0.89453l-6-3c-0.15022-0.074574-0.31679-0.11017-0.48438-0.10352zm0.037109 2.1172l3.7637 1.8809-2.7637 1.3809v-1.3809c-5.52e-5 -0.55226-0.44774-0.99994-1-1h-1.7617l1.7617-0.88086zm-5 2.8809h4v4h-4v-4z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fc9c9c" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+<path transform="translate(0 1036.4)" d="m12 9c-0.55401 0-1 0.44599-1 1v1h2v2h1c0.55401 0 1-0.44599 1-1v-2c0-0.55401-0.44599-1-1-1h-2zm1 4h-2v-2h-1c-0.55401 0-1 0.44599-1 1v2c0 0.55401 0.44599 1 1 1h2c0.55401 0 1-0.44599 1-1v-1z" fill="#84c2ff"/>
+</g>
+</svg>
diff --git a/modules/csg/icons/icon_c_s_g_sphere.svg b/modules/csg/icons/icon_c_s_g_sphere.svg
new file mode 100644
index 0000000000..f81b566993
--- /dev/null
+++ b/modules/csg/icons/icon_c_s_g_sphere.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g>
+<path d="m8 1c-3.8541 0-7 3.1459-7 7 0 3.8542 3.1459 7 7 7 0.093042 0 0.18321-0.01004 0.27539-0.013672-0.17055-0.29341-0.27539-0.62792-0.27539-0.98633v-2c0-0.72673 0.40794-1.3664 1-1.7168v-0.33398c0.34074-0.019259 0.67728-0.069097 1.0156-0.10547 0.083091-1.0187 0.94713-1.8438 1.9844-1.8438h2c0.35841 0 0.69292 0.10484 0.98633 0.27539 0.003633-0.092184 0.013672-0.18235 0.013672-0.27539 0-3.8541-3.1459-7-7-7zm-1 2.0977v4.8711c-1.2931-0.071342-2.6061-0.29819-3.9434-0.69141 0.30081-2.0978 1.8852-3.7665 3.9434-4.1797zm2 0c2.0549 0.41253 3.637 2.0767 3.9414 4.1699-1.3046 0.36677-2.6158 0.60259-3.9414 0.6875v-4.8574zm-5.7793 6.2988c1.2733 0.31892 2.5337 0.50215 3.7793 0.5625v2.9414c-1.8291-0.36719-3.266-1.7339-3.7793-3.5039z" fill="#fc9c9c"/>
+<path d="m12 9c-0.55401 0-1 0.44599-1 1v1h2v2h1c0.55401 0 1-0.44599 1-1v-2c0-0.55401-0.44599-1-1-1zm1 4h-2v-2h-1c-0.55401 0-1 0.44599-1 1v2c0 0.55401 0.44599 1 1 1h2c0.55401 0 1-0.44599 1-1z" fill="#84c2ff"/>
+</g>
+</svg>
diff --git a/modules/csg/icons/icon_c_s_g_torus.svg b/modules/csg/icons/icon_c_s_g_torus.svg
new file mode 100644
index 0000000000..3d30aa47b2
--- /dev/null
+++ b/modules/csg/icons/icon_c_s_g_torus.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m8 3c-1.8145 0-3.4691 0.41721-4.7461 1.1621-1.277 0.745-2.2539 1.9082-2.2539 3.3379 0 1.4298 0.9769 2.5949 2.2539 3.3398 1.277 0.7449 2.9316 1.1602 4.7461 1.1602 0-1.0907 0.90931-2 2-2 0-0.080836 0.013744-0.15778 0.023438-0.23633-0.61769 0.14673-1.3008 0.23633-2.0234 0.23633-1.4992 0-2.8437-0.36687-3.7383-0.88867-0.89456-0.5219-1.2617-1.108-1.2617-1.6113 0-0.5032 0.36716-1.0876 1.2617-1.6094 0.89456-0.5219 2.2391-0.89062 3.7383-0.89062s2.8437 0.36872 3.7383 0.89062c0.89456 0.5218 1.2617 1.1062 1.2617 1.6094 0 0.15978-0.053679 0.32822-0.13281 0.5h1.1328c0.32481 0 0.62893 0.088408 0.90234 0.23047 0.057552-0.23582 0.097656-0.47718 0.097656-0.73047 0-1.4297-0.9769-2.5929-2.2539-3.3379-1.277-0.7449-2.9316-1.1621-4.7461-1.1621z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fc9c9c" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+<path transform="translate(0 1036.4)" d="m12 9c-0.55401 0-1 0.44599-1 1v1h2v2h1c0.55401 0 1-0.44599 1-1v-2c0-0.55401-0.44599-1-1-1h-2zm1 4h-2v-2h-1c-0.55401 0-1 0.44599-1 1v2c0 0.55401 0.44599 1 1 1h2c0.55401 0 1-0.44599 1-1v-1z" fill="#84c2ff"/>
+</g>
+</svg>