From cf4d9145a7993cfebae23bd5b7e5eafc8846f8b1 Mon Sep 17 00:00:00 2001 From: Chaosus Date: Fri, 16 Aug 2024 20:19:00 +0300 Subject: [PATCH] Fix shader doc comments to show up for `instance` uniforms --- scene/3d/mesh_instance_3d.cpp | 100 ++++++++++++++++++++++++++++++++++ scene/resources/shader.cpp | 18 +++--- 2 files changed, 109 insertions(+), 9 deletions(-) diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 85bf8846b94..2e82a5d0ea9 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -36,6 +36,16 @@ #include "scene/resources/3d/concave_polygon_shape_3d.h" #include "scene/resources/3d/convex_polygon_shape_3d.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_help.h" +#include "scene/resources/3d/primitive_meshes.h" + +#include "modules/modules_enabled.gen.h" // For regex. +#ifdef MODULE_REGEX_ENABLED +#include "modules/regex/regex.h" +#endif // MODULE_REGEX_ENABLED +#endif // TOOLS_ENABLED + bool MeshInstance3D::_set(const StringName &p_name, const Variant &p_value) { //this is not _too_ bad performance wise, really. it only arrives here if the property was not set anywhere else. //add to it that it's probably found on first call to _set anyway. @@ -87,6 +97,96 @@ bool MeshInstance3D::_get(const StringName &p_name, Variant &r_ret) const { } void MeshInstance3D::_get_property_list(List *p_list) const { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + DocData::ClassDoc class_doc; + List code_list; + + class_doc.name = "GeometryInstance3D"; + class_doc.is_script_doc = true; + + if (get_material_override().is_valid()) { + Ref shader_material = Object::cast_to(get_material_override().ptr()); + if (shader_material.is_valid()) { + Ref shader = shader_material->get_shader(); + if (shader.is_valid()) { + code_list.push_back(shader->get_code()); + } + } + } else { + bool found = false; + + for (const Ref &material : surface_override_materials) { + if (material.ptr()) { + found = true; + } + + const Ref shader_material = Object::cast_to(material.ptr()); + if (shader_material.is_valid()) { + const Ref shader = shader_material->get_shader(); + if (shader.is_valid()) { + code_list.push_back(shader->get_code()); + } + } + } + + if (!found && mesh.is_valid()) { + const Ref primitive_mesh = Object::cast_to(mesh.ptr()); + if (primitive_mesh.is_valid()) { + const Ref shader_material = Object::cast_to(primitive_mesh->get_material().ptr()); + if (shader_material.is_valid()) { + const Ref shader = shader_material->get_shader(); + if (shader.is_valid()) { + code_list.push_back(shader->get_code()); + } + } + } + } + } + + if (get_material_overlay().is_valid()) { + Ref shader_material = Object::cast_to(get_material_overlay().ptr()); + if (shader_material.is_valid()) { + Ref shader = shader_material->get_shader(); + if (shader.is_valid()) { + code_list.push_back(shader->get_code()); + } + } + } + + List pinfo; + RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo); + + for (PropertyInfo &pi : pinfo) { + DocData::PropertyDoc prop_doc; + prop_doc.name = "instance_shader_parameters/" + pi.name; +#ifdef MODULE_REGEX_ENABLED + const RegEx pattern(R"(/\*\*\s([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/\s*instance\s+uniform\s+\w+\s+)" + pi.name + R"((?=[\s:;=]))"); + + for (const String &code : code_list) { + Ref pattern_ref = pattern.search(code); + if (pattern_ref != nullptr) { + RegExMatch *match = pattern_ref.ptr(); + const RegEx pattern_tip(R"(\/\*\*([\s\S]*?)\*/)"); + Ref pattern_tip_ref = pattern_tip.search(match->get_string(0)); + RegExMatch *match_tip = pattern_tip_ref.ptr(); + const RegEx pattern_stripped(R"(\n\s*\*\s*)"); + prop_doc.description = pattern_stripped.sub(match_tip->get_string(1), "\n", true); + if (!prop_doc.description.is_empty()) { + break; + } + } + } +#endif // MODULE_REGEX_ENABLED + class_doc.properties.push_back(prop_doc); + } + + if (EditorHelp::get_doc_data() != nullptr && p_list) { + EditorHelp::get_doc_data()->add_doc(class_doc); + } + } +#endif // TOOLS_ENABLED + List ls; for (const KeyValue &E : blend_shape_properties) { ls.push_back(E.key); diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index dfe5bd4a472..9191f301856 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -42,8 +42,8 @@ #include "modules/modules_enabled.gen.h" // For regex. #ifdef MODULE_REGEX_ENABLED #include "modules/regex/regex.h" -#endif -#endif +#endif // MODULE_REGEX_ENABLED +#endif // TOOLS_ENABLED Shader::Mode Shader::get_mode() const { return mode; @@ -133,7 +133,7 @@ void Shader::get_shader_uniform_list(List *p_params, bool p_get_gr DocData::ClassDoc class_doc; class_doc.name = get_path(); class_doc.is_script_doc = true; -#endif +#endif // TOOLS_ENABLED for (PropertyInfo &pi : local) { bool is_group = pi.usage == PROPERTY_USAGE_GROUP || pi.usage == PROPERTY_USAGE_SUBGROUP; @@ -155,20 +155,20 @@ void Shader::get_shader_uniform_list(List *p_params, bool p_get_gr DocData::PropertyDoc prop_doc; prop_doc.name = "shader_parameter/" + pi.name; #ifdef MODULE_REGEX_ENABLED - const RegEx pattern("/\\*\\*\\s([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/\\s*uniform\\s+\\w+\\s+" + pi.name + "(?=[\\s:;=])"); + const RegEx pattern(R"(/\*\*\s([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/\s*uniform\s+\w+\s+)" + pi.name + R"((?=[\s:;=]))"); Ref pattern_ref = pattern.search(code); if (pattern_ref != nullptr) { RegExMatch *match = pattern_ref.ptr(); - const RegEx pattern_tip("\\/\\*\\*([\\s\\S]*?)\\*/"); + const RegEx pattern_tip(R"(\/\*\*([\s\S]*?)\*/)"); Ref pattern_tip_ref = pattern_tip.search(match->get_string(0)); RegExMatch *match_tip = pattern_tip_ref.ptr(); - const RegEx pattern_stripped("\\n\\s*\\*\\s*"); + const RegEx pattern_stripped(R"(\n\s*\*\s*)"); prop_doc.description = pattern_stripped.sub(match_tip->get_string(1), "\n", true); } -#endif +#endif // MODULE_REGEX_ENABLED class_doc.properties.push_back(prop_doc); } -#endif +#endif // TOOLS_ENABLED p_params->push_back(pi); } } @@ -176,7 +176,7 @@ void Shader::get_shader_uniform_list(List *p_params, bool p_get_gr if (EditorHelp::get_doc_data() != nullptr && Engine::get_singleton()->is_editor_hint() && !class_doc.name.is_empty() && p_params) { EditorHelp::get_doc_data()->add_doc(class_doc); } -#endif +#endif // TOOLS_ENABLED } RID Shader::get_rid() const {