diff --git a/doc/classes/Path3D.xml b/doc/classes/Path3D.xml index 730bcfd48ce..b650aee0a30 100644 --- a/doc/classes/Path3D.xml +++ b/doc/classes/Path3D.xml @@ -13,6 +13,10 @@ A [Curve3D] describing the path. + + The custom color to use to draw the shape in the editor. + If set to [code]Color(0.0, 0.0, 0.0)[/code] (by default), the color set in EditorSettings is used. + @@ -20,5 +24,10 @@ Emitted when the [member curve] changes. + + + Emitted when the [member debug_custom_color] changes. + + diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index 4fdcb796969..38b63cebbc8 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -272,7 +272,6 @@ void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_res void Path3DGizmo::redraw() { clear(); - Ref path_material = gizmo_plugin->get_material("path_material", this); Ref path_thin_material = gizmo_plugin->get_material("path_thin_material", this); Ref path_tilt_material = gizmo_plugin->get_material("path_tilt_material", this); Ref path_tilt_muted_material = gizmo_plugin->get_material("path_tilt_muted_material", this); @@ -284,11 +283,24 @@ void Path3DGizmo::redraw() { return; } + debug_material = gizmo_plugin->get_material("path_material", this); + + Color path_color = path->get_debug_custom_color(); + if (path_color != Color(0.0, 0.0, 0.0)) { + debug_material.instantiate(); + debug_material->set_albedo(path_color); + debug_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + debug_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + debug_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + debug_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + debug_material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); + } + real_t interval = 0.1; const real_t length = c->get_baked_length(); - // 1. Draw curve and bones. - if (length > CMP_EPSILON) { + // 1. Draw curve and bones if it is visible (alpha > 0.0). + if (length > CMP_EPSILON && path_color.a > 0.0) { const int sample_count = int(length / interval) + 2; interval = length / (sample_count - 1); // Recalculate real interval length. @@ -346,8 +358,8 @@ void Path3DGizmo::redraw() { } add_collision_segments(_collision_segments); - add_lines(bones, path_material); - add_vertices(ribbon, path_material, Mesh::PRIMITIVE_LINE_STRIP); + add_lines(bones, debug_material); + add_vertices(ribbon, debug_material, Mesh::PRIMITIVE_LINE_STRIP); } // 2. Draw handles when selected. @@ -427,7 +439,7 @@ void Path3DGizmo::redraw() { const Vector3 edge = sin(a) * side + cos(a) * up; disk.append(pos + edge * disk_size); } - add_vertices(disk, path_tilt_material, Mesh::PRIMITIVE_LINE_STRIP); + add_vertices(disk, debug_material, Mesh::PRIMITIVE_LINE_STRIP); } } } @@ -464,6 +476,7 @@ Path3DGizmo::Path3DGizmo(Path3D *p_path, float p_disk_size) { // Connecting to a signal once, rather than plaguing the implementation with calls to `Node3DEditor::update_transform_gizmo`. path->connect("curve_changed", callable_mp(this, &Path3DGizmo::_update_transform_gizmo)); + path->connect("debug_color_changed", callable_mp(this, &Path3DGizmo::redraw)); Path3DEditorPlugin::singleton->curve_edit->connect(SceneStringName(pressed), callable_mp(this, &Path3DGizmo::redraw)); Path3DEditorPlugin::singleton->curve_edit_curve->connect(SceneStringName(pressed), callable_mp(this, &Path3DGizmo::redraw)); diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h index 60cb7f940fa..b4fb29915fd 100644 --- a/editor/plugins/path_3d_editor_plugin.h +++ b/editor/plugins/path_3d_editor_plugin.h @@ -56,6 +56,7 @@ class Path3DGizmo : public EditorNode3DGizmo { }; Path3D *path = nullptr; + Ref debug_material; mutable Vector3 original; mutable float orig_in_length; mutable float orig_out_length; diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 64259a24b00..5fbaa769c7c 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -151,13 +151,15 @@ void Path3D::_update_debug_mesh() { bone_array.resize(Mesh::ARRAY_MAX); bone_array[Mesh::ARRAY_VERTEX] = bones; + _update_debug_path_material(); + debug_mesh->clear_surfaces(); debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINE_STRIP, ribbon_array); debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, bone_array); + debug_mesh->surface_set_material(0, debug_material); + debug_mesh->surface_set_material(1, debug_material); RS::get_singleton()->instance_set_base(debug_instance, debug_mesh->get_rid()); - RS::get_singleton()->mesh_surface_set_material(debug_mesh->get_rid(), 0, st->get_debug_paths_material()->get_rid()); - RS::get_singleton()->mesh_surface_set_material(debug_mesh->get_rid(), 1, st->get_debug_paths_material()->get_rid()); if (is_inside_tree()) { RS::get_singleton()->instance_set_scenario(debug_instance, get_world_3d()->get_scenario()); RS::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); @@ -165,6 +167,42 @@ void Path3D::_update_debug_mesh() { } } +void Path3D::set_debug_custom_color(const Color &p_color) { + debug_custom_color = p_color; + _update_debug_path_material(); +} + +Ref Path3D::get_debug_material() { + return debug_material; +} + +const Color &Path3D::get_debug_custom_color() const { + return debug_custom_color; +} + +void Path3D::_update_debug_path_material() { + SceneTree *st = SceneTree::get_singleton(); + if (!debug_material.is_valid()) { + Ref material = memnew(StandardMaterial3D); + debug_material = material; + + material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); + } + + Color color = debug_custom_color; + if (color == Color(0.0, 0.0, 0.0)) { + // Use the default debug path color defined in the Project Settings. + color = st->get_debug_paths_color(); + } + + get_debug_material()->set_albedo(color); + emit_signal(SNAME("debug_color_changed")); +} + void Path3D::_curve_changed() { if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) { update_gizmos(); @@ -211,9 +249,16 @@ void Path3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path3D::set_curve); ClassDB::bind_method(D_METHOD("get_curve"), &Path3D::get_curve); + ClassDB::bind_method(D_METHOD("set_debug_custom_color", "debug_custom_color"), &Path3D::set_debug_custom_color); + ClassDB::bind_method(D_METHOD("get_debug_custom_color"), &Path3D::get_debug_custom_color); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_curve", "get_curve"); + ADD_GROUP("Debug Shape", "debug_"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_custom_color"), "set_debug_custom_color", "get_debug_custom_color"); + ADD_SIGNAL(MethodInfo("curve_changed")); + ADD_SIGNAL(MethodInfo("debug_color_changed")); } void PathFollow3D::update_transform() { diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h index fb4f301375b..b8ec1622567 100644 --- a/scene/3d/path_3d.h +++ b/scene/3d/path_3d.h @@ -40,11 +40,14 @@ class Path3D : public Node3D { private: Ref curve; RID debug_instance; + Color debug_custom_color; Ref debug_mesh; + Ref debug_material; Callable update_callback; // Used only by CSG currently. void _update_debug_mesh(); + void _update_debug_path_material(); void _curve_changed(); protected: @@ -58,6 +61,14 @@ public: void set_curve(const Ref &p_curve); Ref get_curve() const; + const Color &get_debug_custom_color() const; + void set_debug_custom_color(const Color &p_color); + + bool get_debug_show() const; + void set_debug_show(bool p_show); + + Ref get_debug_material(); + Path3D(); ~Path3D(); };