ソースを参照

Improve the CSG shape gizmo drawing

The gizmo colors now depend on the operation. Subtraction will
result in an inverted gizmo color, whereas intersection is now displayed
as white.

A solid translucent overlay is now drawn over a selected node
to make it easier to distinguish.
Hugo Locurcio 6 年 前
コミット
e87e8c0485
2 ファイル変更50 行追加3 行削除
  1. 49 3
      modules/csg/csg_gizmos.cpp
  2. 1 0
      modules/csg/csg_shape.cpp

+ 49 - 3
modules/csg/csg_gizmos.cpp

@@ -34,8 +34,18 @@
 
 
 CSGShapeSpatialGizmoPlugin::CSGShapeSpatialGizmoPlugin() {
 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");
 	create_handle_material("handles");
 }
 }
 
 
@@ -311,7 +321,19 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
 
 
 	p_gizmo->clear();
 	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");
 	Ref<Material> handles_material = get_material("handles");
 
 
 	PoolVector<Vector3> faces = cs->get_brush_faces();
 	PoolVector<Vector3> faces = cs->get_brush_faces();
@@ -334,6 +356,30 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
 	p_gizmo->add_lines(lines, material);
 	p_gizmo->add_lines(lines, material);
 	p_gizmo->add_collision_segments(lines);
 	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)) {
 	if (Object::cast_to<CSGSphere>(cs)) {
 		CSGSphere *s = Object::cast_to<CSGSphere>(cs);
 		CSGSphere *s = Object::cast_to<CSGSphere>(cs);
 
 

+ 1 - 0
modules/csg/csg_shape.cpp

@@ -557,6 +557,7 @@ void CSGShape::set_operation(Operation p_operation) {
 
 
 	operation = p_operation;
 	operation = p_operation;
 	_make_dirty();
 	_make_dirty();
+	update_gizmo();
 }
 }
 
 
 CSGShape::Operation CSGShape::get_operation() const {
 CSGShape::Operation CSGShape::get_operation() const {