summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/classes/EditorSettings.xml60
-rw-r--r--editor/editor_node.cpp2
-rw-r--r--editor/editor_settings.cpp29
-rw-r--r--editor/editor_settings.h1
-rw-r--r--editor/editor_settings_dialog.cpp2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp13
-rw-r--r--editor/plugins/node_3d_editor_plugin.h2
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp209
-rw-r--r--editor/plugins/path_3d_editor_plugin.h16
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp80
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h3
-rw-r--r--editor/themes/editor_theme_manager.cpp136
-rw-r--r--editor/themes/editor_theme_manager.h1
-rw-r--r--modules/basis_universal/image_compress_basisu.cpp13
-rw-r--r--modules/gdscript/tests/gdscript_test_runner_suite.h3
-rw-r--r--scene/gui/graph_edit.cpp5
-rw-r--r--scene/resources/visual_shader.cpp5
-rw-r--r--scene/resources/visual_shader.h62
-rw-r--r--scene/resources/visual_shader_nodes.h101
-rw-r--r--scene/resources/visual_shader_particle_nodes.h20
-rw-r--r--tests/core/config/test_project_settings.h3
-rw-r--r--tests/core/io/test_image.h3
-rw-r--r--tests/core/os/test_os.h24
-rw-r--r--tests/core/string/test_translation.h2
24 files changed, 683 insertions, 112 deletions
diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml
index 8869d2a589..0f87ba2ae5 100644
--- a/doc/classes/EditorSettings.xml
+++ b/doc/classes/EditorSettings.xml
@@ -445,6 +445,66 @@
The color to use for the TileMap editor's grid.
[b]Note:[/b] Only effective if [member editors/tiles_editor/display_grid] is [code]true[/code].
</member>
+ <member name="editors/visual_editors/category_colors/color_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Color" category.
+ </member>
+ <member name="editors/visual_editors/category_colors/conditional_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Conditional" category.
+ </member>
+ <member name="editors/visual_editors/category_colors/input_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Input" category.
+ </member>
+ <member name="editors/visual_editors/category_colors/output_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Output" category.
+ </member>
+ <member name="editors/visual_editors/category_colors/particle_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Particle" category.
+ </member>
+ <member name="editors/visual_editors/category_colors/scalar_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Scalar" category.
+ </member>
+ <member name="editors/visual_editors/category_colors/special_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Special" category.
+ </member>
+ <member name="editors/visual_editors/category_colors/textures_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Textures" category.
+ </member>
+ <member name="editors/visual_editors/category_colors/transform_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Transform" category.
+ </member>
+ <member name="editors/visual_editors/category_colors/utility_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Utility" category.
+ </member>
+ <member name="editors/visual_editors/category_colors/vector_color" type="Color" setter="" getter="">
+ The color of a graph node's header when it belongs to the "Vector" category.
+ </member>
+ <member name="editors/visual_editors/color_theme" type="String" setter="" getter="">
+ The color theme to use in the visual shader editor.
+ </member>
+ <member name="editors/visual_editors/connection_colors/boolean_color" type="Color" setter="" getter="">
+ The color of a port/connection of boolean type.
+ </member>
+ <member name="editors/visual_editors/connection_colors/sampler_color" type="Color" setter="" getter="">
+ The color of a port/connection of sampler type.
+ </member>
+ <member name="editors/visual_editors/connection_colors/scalar_color" type="Color" setter="" getter="">
+ The color of a port/connection of scalar type (float, int, unsigned int).
+ </member>
+ <member name="editors/visual_editors/connection_colors/transform_color" type="Color" setter="" getter="">
+ The color of a port/connection of transform type.
+ </member>
+ <member name="editors/visual_editors/connection_colors/vector2_color" type="Color" setter="" getter="">
+ The color of a port/connection of Vector2 type.
+ </member>
+ <member name="editors/visual_editors/connection_colors/vector3_color" type="Color" setter="" getter="">
+ The color of a port/connection of Vector3 type.
+ </member>
+ <member name="editors/visual_editors/connection_colors/vector4_color" type="Color" setter="" getter="">
+ The color of a port/connection of Vector4 type.
+ </member>
+ <member name="editors/visual_editors/grid_pattern" type="int" setter="" getter="">
+ The pattern used for the background grid.
+ </member>
<member name="editors/visual_editors/lines_curvature" type="float" setter="" getter="">
The curvature to use for connection lines in the visual shader editor. Higher values will make connection lines appear more curved, with values above [code]0.5[/code] resulting in more "angular" turns in the middle of connection lines.
</member>
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 84840a1c47..cc0e954087 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -7406,7 +7406,7 @@ EditorNode::EditorNode() {
vcs_actions_menu = VersionControlEditorPlugin::get_singleton()->get_version_control_actions_panel();
vcs_actions_menu->set_name("Version Control");
vcs_actions_menu->connect("index_pressed", callable_mp(this, &EditorNode::_version_control_menu_option));
- vcs_actions_menu->add_item(TTR("Create Version Control Metadata..."), RUN_VCS_METADATA);
+ vcs_actions_menu->add_item(TTR("Create/Override Version Control Metadata..."), RUN_VCS_METADATA);
vcs_actions_menu->add_item(TTR("Version Control Settings..."), RUN_VCS_SETTINGS);
project_menu->add_child(vcs_actions_menu);
project_menu->set_item_submenu(project_menu->get_item_index(VCS_MENU), "Version Control");
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index e3c9996c97..94e55f347a 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -768,8 +768,13 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("editors/shader_editor/behavior/files/restore_shaders_on_load", true);
// Visual editors
+ EDITOR_SETTING(Variant::STRING, PROPERTY_HINT_ENUM, "editors/visual_editors/color_theme", "Default", "Default,Legacy,Custom")
+
+ _load_default_visual_shader_editor_theme();
+
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/visual_editors/minimap_opacity", 0.85, "0.0,1.0,0.01")
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/visual_editors/lines_curvature", 0.5, "0.0,1.0,0.01")
+ EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "editors/visual_editors/grid_pattern", 1, "Lines,Dots")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "editors/visual_editors/visual_shader/port_preview_size", 160, "100,400,0.01")
/* Run */
@@ -905,6 +910,30 @@ void EditorSettings::_load_godot2_text_editor_theme() {
_initial_set("text_editor/theme/highlighting/search_result_border_color", Color(0.41, 0.61, 0.91, 0.38));
}
+void EditorSettings::_load_default_visual_shader_editor_theme() {
+ // Connection type colors
+ _initial_set("editors/visual_editors/connection_colors/scalar_color", Color(0.55, 0.55, 0.55));
+ _initial_set("editors/visual_editors/connection_colors/vector2_color", Color(0.44, 0.43, 0.64));
+ _initial_set("editors/visual_editors/connection_colors/vector3_color", Color(0.337, 0.314, 0.71));
+ _initial_set("editors/visual_editors/connection_colors/vector4_color", Color(0.7, 0.65, 0.147));
+ _initial_set("editors/visual_editors/connection_colors/boolean_color", Color(0.243, 0.612, 0.349));
+ _initial_set("editors/visual_editors/connection_colors/transform_color", Color(0.71, 0.357, 0.64));
+ _initial_set("editors/visual_editors/connection_colors/sampler_color", Color(0.659, 0.4, 0.137));
+
+ // Node category colors (used for the node headers)
+ _initial_set("editors/visual_editors/category_colors/output_color", Color(0.26, 0.10, 0.15));
+ _initial_set("editors/visual_editors/category_colors/color_color", Color(0.5, 0.5, 0.1));
+ _initial_set("editors/visual_editors/category_colors/conditional_color", Color(0.208, 0.522, 0.298));
+ _initial_set("editors/visual_editors/category_colors/input_color", Color(0.502, 0.2, 0.204));
+ _initial_set("editors/visual_editors/category_colors/scalar_color", Color(0.1, 0.5, 0.6));
+ _initial_set("editors/visual_editors/category_colors/textures_color", Color(0.5, 0.3, 0.1));
+ _initial_set("editors/visual_editors/category_colors/transform_color", Color(0.5, 0.3, 0.5));
+ _initial_set("editors/visual_editors/category_colors/utility_color", Color(0.2, 0.2, 0.2));
+ _initial_set("editors/visual_editors/category_colors/vector_color", Color(0.2, 0.2, 0.5));
+ _initial_set("editors/visual_editors/category_colors/special_color", Color(0.098, 0.361, 0.294));
+ _initial_set("editors/visual_editors/category_colors/particle_color", Color(0.12, 0.358, 0.8));
+}
+
bool EditorSettings::_save_text_editor_theme(String p_file) {
String theme_section = "color_theme";
Ref<ConfigFile> cf = memnew(ConfigFile); // hex is better?
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index 87ce0cfd57..5783bac770 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -110,6 +110,7 @@ private:
void _load_defaults(Ref<ConfigFile> p_extra_config = Ref<ConfigFile>());
void _load_godot2_text_editor_theme();
+ void _load_default_visual_shader_editor_theme();
bool _save_text_editor_theme(String p_file);
bool _is_default_text_editor_theme(String p_theme_name);
const String _get_project_metadata_path() const;
diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp
index 13e3c41e3b..c339bbf365 100644
--- a/editor/editor_settings_dialog.cpp
+++ b/editor/editor_settings_dialog.cpp
@@ -71,6 +71,8 @@ void EditorSettingsDialog::_settings_property_edited(const String &p_name) {
EditorSettings::get_singleton()->set_manually("interface/theme/spacing_preset", "Custom");
} else if (full_name.begins_with("text_editor/theme/highlighting")) {
EditorSettings::get_singleton()->set_manually("text_editor/theme/color_theme", "Custom");
+ } else if (full_name.begins_with("editors/visual_editors/connection_colors") || full_name.begins_with("editors/visual_editors/category_colors")) {
+ EditorSettings::get_singleton()->set_manually("editors/visual_editors/color_theme", "Custom");
}
}
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index b9b342245f..15a9cfad22 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -646,6 +646,18 @@ void Node3DEditorViewport::cancel_transform() {
continue;
}
+ if (se && se->gizmo.is_valid()) {
+ Vector<int> ids;
+ Vector<Transform3D> restore;
+
+ for (const KeyValue<int, Transform3D> &GE : se->subgizmos) {
+ ids.push_back(GE.key);
+ restore.push_back(GE.value);
+ }
+
+ se->gizmo->commit_subgizmos(ids, restore, true);
+ }
+
sp->set_global_transform(se->original);
}
@@ -8071,6 +8083,7 @@ void Node3DEditor::_bind_methods() {
ClassDB::bind_method("_refresh_menu_icons", &Node3DEditor::_refresh_menu_icons);
ClassDB::bind_method("update_all_gizmos", &Node3DEditor::update_all_gizmos);
+ ClassDB::bind_method("update_transform_gizmo", &Node3DEditor::update_transform_gizmo);
ADD_SIGNAL(MethodInfo("transform_key_request"));
ADD_SIGNAL(MethodInfo("item_lock_status_changed"));
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index ed42e8e5ab..61b1d38cfc 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -509,7 +509,7 @@ public:
RID sbox_instance_xray;
RID sbox_instance_xray_offset;
Ref<EditorNode3DGizmo> gizmo;
- HashMap<int, Transform3D> subgizmos; // map ID -> initial transform
+ HashMap<int, Transform3D> subgizmos; // Key: Subgizmo ID, Value: Initial subgizmo transform.
Node3DEditorSelectedItem() {
sp = nullptr;
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index 6fe1949382..ffdc06ceee 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -200,22 +200,6 @@ void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_res
EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
- // Primary handles: position.
- if (!p_secondary) {
- // Special cas for primary handle, the handle id equals control point id.
- const int idx = p_id;
- if (p_cancel) {
- c->set_point_position(idx, p_restore);
- return;
- }
- ur->create_action(TTR("Set Curve Point Position"));
- ur->add_do_method(c.ptr(), "set_point_position", idx, c->get_point_position(idx));
- ur->add_undo_method(c.ptr(), "set_point_position", idx, p_restore);
- ur->commit_action();
-
- return;
- }
-
// Secondary handles: in, out, tilt.
const HandleInfo info = _secondary_handles_info[p_id];
const int idx = info.point_idx;
@@ -235,6 +219,7 @@ void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_res
ur->add_do_method(c.ptr(), "set_point_in", idx, Path3DEditorPlugin::singleton->mirror_length_enabled() ? -c->get_point_out(idx) : (-c->get_point_out(idx).normalized() * orig_in_length));
ur->add_undo_method(c.ptr(), "set_point_in", idx, Path3DEditorPlugin::singleton->mirror_length_enabled() ? -static_cast<Vector3>(p_restore) : (-static_cast<Vector3>(p_restore).normalized() * orig_in_length));
}
+
ur->commit_action();
break;
}
@@ -252,6 +237,7 @@ void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_res
ur->add_do_method(c.ptr(), "set_point_out", idx, Path3DEditorPlugin::singleton->mirror_length_enabled() ? -c->get_point_in(idx) : (-c->get_point_in(idx).normalized() * orig_out_length));
ur->add_undo_method(c.ptr(), "set_point_out", idx, Path3DEditorPlugin::singleton->mirror_length_enabled() ? -static_cast<Vector3>(p_restore) : (-static_cast<Vector3>(p_restore).normalized() * orig_out_length));
}
+
ur->commit_action();
break;
}
@@ -263,6 +249,7 @@ void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_res
ur->create_action(TTR("Set Curve Point Tilt"));
ur->add_do_method(c.ptr(), "set_point_tilt", idx, c->get_point_tilt(idx));
ur->add_undo_method(c.ptr(), "set_point_tilt", idx, p_restore);
+
ur->commit_action();
break;
}
@@ -275,7 +262,7 @@ void Path3DGizmo::redraw() {
Ref<StandardMaterial3D> path_material = gizmo_plugin->get_material("path_material", this);
Ref<StandardMaterial3D> path_thin_material = gizmo_plugin->get_material("path_thin_material", this);
Ref<StandardMaterial3D> path_tilt_material = gizmo_plugin->get_material("path_tilt_material", this);
- Ref<StandardMaterial3D> handles_material = gizmo_plugin->get_material("handles");
+ Ref<StandardMaterial3D> path_tilt_muted_material = gizmo_plugin->get_material("path_tilt_muted_material", this);
Ref<StandardMaterial3D> sec_handles_material = gizmo_plugin->get_material("sec_handles");
Ref<Curve3D> c = path->get_curve();
@@ -353,48 +340,57 @@ void Path3DGizmo::redraw() {
if (Path3DEditorPlugin::singleton->get_edited_path() == path) {
PackedVector3Array handle_lines;
PackedVector3Array tilt_handle_lines;
- PackedVector3Array primary_handle_points;
PackedVector3Array secondary_handle_points;
PackedInt32Array collected_secondary_handle_ids; // Avoid shadowing member on Node3DEditorGizmo.
_secondary_handles_info.resize(c->get_point_count() * 3);
for (int idx = 0; idx < c->get_point_count(); idx++) {
- // Collect primary-handles.
const Vector3 pos = c->get_point_position(idx);
- primary_handle_points.append(pos);
+ bool is_current_point_selected = is_subgizmo_selected(idx);
+ bool is_previous_point_selected = is_subgizmo_selected(idx - 1);
+ bool is_following_point_selected = is_subgizmo_selected(idx + 1);
HandleInfo info;
info.point_idx = idx;
// Collect in-handles except for the first point.
- if (idx > 0) {
- info.type = HandleType::HANDLE_TYPE_IN;
- const int handle_idx = idx * 3 + 0;
- collected_secondary_handle_ids.append(handle_idx);
- _secondary_handles_info.write[handle_idx] = info;
-
+ if (idx > 0 && (is_current_point_selected || is_previous_point_selected)) {
const Vector3 in = c->get_point_in(idx);
- secondary_handle_points.append(pos + in);
- handle_lines.append(pos);
- handle_lines.append(pos + in);
+
+ // Display in-handles only when they are "initialized".
+ if (in.length_squared() > 0) {
+ info.type = HandleType::HANDLE_TYPE_IN;
+ const int handle_idx = idx * 3 + 0;
+ collected_secondary_handle_ids.append(handle_idx);
+ _secondary_handles_info.write[handle_idx] = info;
+
+ secondary_handle_points.append(pos + in);
+ handle_lines.append(pos);
+ handle_lines.append(pos + in);
+ }
}
// Collect out-handles except for the last point.
- if (idx < c->get_point_count() - 1) {
- info.type = HandleType::HANDLE_TYPE_OUT;
- const int handle_idx = idx * 3 + 1;
- collected_secondary_handle_ids.append(handle_idx);
- _secondary_handles_info.write[handle_idx] = info;
-
+ if (idx < c->get_point_count() - 1 && (is_current_point_selected || is_following_point_selected)) {
const Vector3 out = c->get_point_out(idx);
- secondary_handle_points.append(pos + out);
- handle_lines.append(pos);
- handle_lines.append(pos + out);
+
+ // Display out-handles only when they are "initialized".
+ if (out.length_squared() > 0) {
+ info.type = HandleType::HANDLE_TYPE_OUT;
+ const int handle_idx = idx * 3 + 1;
+ collected_secondary_handle_ids.append(handle_idx);
+ _secondary_handles_info.write[handle_idx] = info;
+
+ secondary_handle_points.append(pos + out);
+ handle_lines.append(pos);
+ handle_lines.append(pos + out);
+ }
}
// Collect tilt-handles.
- {
+ if (is_current_point_selected || is_previous_point_selected || is_following_point_selected) {
+ // Tilt handle.
{
info.type = HandleType::HANDLE_TYPE_TILT;
const int handle_idx = idx * 3 + 2;
@@ -423,7 +419,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, is_current_point_selected ? path_tilt_material : path_tilt_muted_material, Mesh::PRIMITIVE_LINE_STRIP);
}
}
}
@@ -436,21 +432,27 @@ void Path3DGizmo::redraw() {
add_lines(tilt_handle_lines, path_tilt_material);
}
- if (primary_handle_points.size()) {
- add_handles(primary_handle_points, handles_material);
- }
if (secondary_handle_points.size()) {
add_handles(secondary_handle_points, sec_handles_material, collected_secondary_handle_ids, false, true);
}
+ // Draw the gizmo plugin manually, because handles are registered. In which case, the caller code skips drawing the gizmo plugin.
+ gizmo_plugin->redraw(this);
}
}
+void Path3DGizmo::_update_transform_gizmo() {
+ Node3DEditor::get_singleton()->update_transform_gizmo();
+}
+
Path3DGizmo::Path3DGizmo(Path3D *p_path, float p_disk_size) {
path = p_path;
disk_size = p_disk_size;
set_node_3d(p_path);
orig_in_length = 0;
orig_out_length = 0;
+
+ // 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));
}
EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
@@ -819,10 +821,130 @@ Ref<EditorNode3DGizmo> Path3DGizmoPlugin::create_gizmo(Node3D *p_spatial) {
return ref;
}
+bool Path3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
+ return Object::cast_to<Path3D>(p_spatial) != nullptr;
+}
+
String Path3DGizmoPlugin::get_gizmo_name() const {
return "Path3D";
}
+void Path3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
+ Path3D *path = Object::cast_to<Path3D>(p_gizmo->get_node_3d());
+ ERR_FAIL_NULL(path);
+
+ Ref<Curve3D> curve = path->get_curve();
+
+ Ref<StandardMaterial3D> handle_material = get_material("handles", p_gizmo);
+ PackedVector3Array handles;
+
+ for (int idx = 0; idx < curve->get_point_count(); ++idx) {
+ // Collect handles.
+ const Vector3 pos = curve->get_point_position(idx);
+
+ handles.append(pos);
+ }
+
+ if (handles.size()) {
+ p_gizmo->add_vertices(handles, handle_material, Mesh::PRIMITIVE_POINTS);
+ }
+}
+
+int Path3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const {
+ Path3D *path = Object::cast_to<Path3D>(p_gizmo->get_node_3d());
+ ERR_FAIL_NULL_V(path, -1);
+ Ref<Curve3D> curve = path->get_curve();
+ ERR_FAIL_COND_V(curve.is_null(), -1);
+
+ for (int idx = 0; idx < curve->get_point_count(); ++idx) {
+ Vector3 pos = path->get_global_transform().xform(curve->get_point_position(idx));
+ if (p_camera->unproject_position(pos).distance_to(p_point) < 20) {
+ return idx;
+ }
+ }
+ return -1;
+}
+
+Vector<int> Path3DGizmoPlugin::subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const {
+ Vector<int> contained_points;
+
+ Path3D *path = Object::cast_to<Path3D>(p_gizmo->get_node_3d());
+ ERR_FAIL_NULL_V(path, contained_points);
+ Ref<Curve3D> curve = path->get_curve();
+ ERR_FAIL_COND_V(curve.is_null(), contained_points);
+
+ for (int idx = 0; idx < curve->get_point_count(); ++idx) {
+ Vector3 pos = path->get_global_transform().xform(curve->get_point_position(idx));
+ bool is_contained_in_frustum = true;
+ for (int i = 0; i < p_frustum.size(); ++i) {
+ if (p_frustum[i].distance_to(pos) > 0) {
+ is_contained_in_frustum = false;
+ break;
+ }
+ }
+
+ if (is_contained_in_frustum) {
+ contained_points.push_back(idx);
+ }
+ }
+
+ return contained_points;
+}
+
+Transform3D Path3DGizmoPlugin::get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+ Path3D *path = Object::cast_to<Path3D>(p_gizmo->get_node_3d());
+ ERR_FAIL_NULL_V(path, Transform3D());
+ Ref<Curve3D> curve = path->get_curve();
+ ERR_FAIL_COND_V(curve.is_null(), Transform3D());
+ ERR_FAIL_INDEX_V(p_id, curve->get_point_count(), Transform3D());
+
+ Basis basis = transformation_locked_basis.has(p_id) ? transformation_locked_basis[p_id] : curve->get_point_baked_posture(p_id, true);
+ Vector3 pos = curve->get_point_position(p_id);
+
+ Transform3D t = Transform3D(basis, pos);
+ return t;
+}
+
+void Path3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) {
+ Path3D *path = Object::cast_to<Path3D>(p_gizmo->get_node_3d());
+ ERR_FAIL_NULL(path);
+ Ref<Curve3D> curve = path->get_curve();
+ ERR_FAIL_COND(curve.is_null());
+ ERR_FAIL_INDEX(p_id, curve->get_point_count());
+
+ if (!transformation_locked_basis.has(p_id)) {
+ transformation_locked_basis[p_id] = Basis(curve->get_point_baked_posture(p_id, true));
+ }
+ curve->set_point_position(p_id, p_transform.origin);
+}
+
+void Path3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) {
+ Path3D *path = Object::cast_to<Path3D>(p_gizmo->get_node_3d());
+ ERR_FAIL_NULL(path);
+ Ref<Curve3D> curve = path->get_curve();
+ ERR_FAIL_COND(curve.is_null());
+
+ transformation_locked_basis.clear();
+
+ if (p_cancel) {
+ for (int i = 0; i < p_ids.size(); ++i) {
+ curve->set_point_position(p_ids[i], p_restore[i].origin);
+ }
+ return;
+ }
+
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+
+ undo_redo->create_action(TTR("Set Curve Point Position"));
+
+ for (int i = 0; i < p_ids.size(); ++i) {
+ const int idx = p_ids[i];
+ undo_redo->add_do_method(curve.ptr(), "set_point_position", idx, curve->get_point_position(idx));
+ undo_redo->add_undo_method(curve.ptr(), "set_point_position", idx, p_restore[i].origin);
+ }
+ undo_redo->commit_action();
+}
+
int Path3DGizmoPlugin::get_priority() const {
return -1;
}
@@ -835,6 +957,7 @@ Path3DGizmoPlugin::Path3DGizmoPlugin(float p_disk_size) {
create_material("path_material", path_color);
create_material("path_thin_material", Color(0.6, 0.6, 0.6));
create_material("path_tilt_material", path_tilt_color);
+ create_material("path_tilt_muted_material", path_tilt_color * 0.7);
create_handle_material("handles", false, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("EditorPathSmoothHandle"), EditorStringName(EditorIcons)));
create_handle_material("sec_handles", false, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("EditorCurveHandle"), EditorStringName(EditorIcons)));
}
diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h
index 5a5f76b015..931ac7128c 100644
--- a/editor/plugins/path_3d_editor_plugin.h
+++ b/editor/plugins/path_3d_editor_plugin.h
@@ -63,6 +63,8 @@ class Path3DGizmo : public EditorNode3DGizmo {
// Cache information of secondary handles.
Vector<HandleInfo> _secondary_handles_info;
+ void _update_transform_gizmo();
+
public:
virtual String get_handle_name(int p_id, bool p_secondary) const override;
virtual Variant get_handle_value(int p_id, bool p_secondary) const override;
@@ -78,11 +80,25 @@ class Path3DGizmoPlugin : public EditorNode3DGizmoPlugin {
float disk_size = 0.8;
+ // Locking basis is meant to ensure a predictable behavior during translation of the curve points in "local space transform mode".
+ // Without the locking, the gizmo/point, in "local space transform mode", wouldn't follow a straight path and would curve and twitch in an unpredictable way.
+ HashMap<int, Basis> transformation_locked_basis;
+
protected:
Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial) override;
public:
+ virtual bool has_gizmo(Node3D *p_spatial) override;
String get_gizmo_name() const override;
+
+ virtual void redraw(EditorNode3DGizmo *p_gizmo) override;
+
+ virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const override;
+ virtual Vector<int> subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const override;
+ virtual Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
+ virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) override;
+ virtual void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false) override;
+
int get_priority() const override;
Path3DGizmoPlugin(float p_disk_size);
};
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 4750179473..acca5810a9 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -104,6 +104,7 @@ void VisualShaderNodePlugin::_bind_methods() {
///////////////////
VisualShaderGraphPlugin::VisualShaderGraphPlugin() {
+ vs_msdf_fonts_theme.instantiate();
}
void VisualShaderGraphPlugin::_bind_methods() {
@@ -358,6 +359,13 @@ void VisualShaderGraphPlugin::update_theme() {
vector_expanded_color[1] = editor->get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)); // green
vector_expanded_color[2] = editor->get_theme_color(SNAME("axis_z_color"), EditorStringName(Editor)); // blue
vector_expanded_color[3] = editor->get_theme_color(SNAME("axis_w_color"), EditorStringName(Editor)); // alpha
+
+ Ref<Font> label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", EditorStringName(EditorFonts));
+ Ref<Font> label_bold_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_bold_msdf", EditorStringName(EditorFonts));
+ vs_msdf_fonts_theme->set_font("font", "Label", label_font);
+ vs_msdf_fonts_theme->set_font("font", "GraphNodeTitleLabel", label_bold_font);
+ vs_msdf_fonts_theme->set_font("font", "LineEdit", label_font);
+ vs_msdf_fonts_theme->set_font("font", "Button", label_font);
}
bool VisualShaderGraphPlugin::is_node_has_parameter_instances_relatively(VisualShader::Type p_type, int p_node) const {
@@ -398,34 +406,35 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
Control *offset;
- static const Color type_color[] = {
- Color(0.38, 0.85, 0.96), // scalar (float)
- Color(0.49, 0.78, 0.94), // scalar (int)
- Color(0.20, 0.88, 0.67), // scalar (uint)
- Color(0.74, 0.57, 0.95), // vector2
- Color(0.84, 0.49, 0.93), // vector3
- Color(1.0, 0.125, 0.95), // vector4
- Color(0.55, 0.65, 0.94), // boolean
- Color(0.96, 0.66, 0.43), // transform
- Color(1.0, 1.0, 0.0), // sampler
+ const Color type_color[] = {
+ EDITOR_GET("editors/visual_editors/connection_colors/scalar_color"),
+ EDITOR_GET("editors/visual_editors/connection_colors/scalar_color"),
+ EDITOR_GET("editors/visual_editors/connection_colors/scalar_color"),
+ EDITOR_GET("editors/visual_editors/connection_colors/vector2_color"),
+ EDITOR_GET("editors/visual_editors/connection_colors/vector3_color"),
+ EDITOR_GET("editors/visual_editors/connection_colors/vector4_color"),
+ EDITOR_GET("editors/visual_editors/connection_colors/boolean_color"),
+ EDITOR_GET("editors/visual_editors/connection_colors/transform_color"),
+ EDITOR_GET("editors/visual_editors/connection_colors/sampler_color"),
};
- static const String vector_expanded_name[4] = {
- "red",
- "green",
- "blue",
- "alpha"
+ // Keep in sync with VisualShaderNode::Category.
+ const Color category_color[VisualShaderNode::Category::CATEGORY_MAX] = {
+ Color(0.0, 0.0, 0.0), // None (default, not used)
+ EDITOR_GET("editors/visual_editors/category_colors/output_color"),
+ EDITOR_GET("editors/visual_editors/category_colors/color_color"),
+ EDITOR_GET("editors/visual_editors/category_colors/conditional_color"),
+ EDITOR_GET("editors/visual_editors/category_colors/input_color"),
+ EDITOR_GET("editors/visual_editors/category_colors/scalar_color"),
+ EDITOR_GET("editors/visual_editors/category_colors/textures_color"),
+ EDITOR_GET("editors/visual_editors/category_colors/transform_color"),
+ EDITOR_GET("editors/visual_editors/category_colors/utility_color"),
+ EDITOR_GET("editors/visual_editors/category_colors/vector_color"),
+ EDITOR_GET("editors/visual_editors/category_colors/special_color"),
+ EDITOR_GET("editors/visual_editors/category_colors/particle_color"),
};
- // Visual shader specific theme for MSDF font.
- Ref<Theme> vstheme;
- vstheme.instantiate();
- Ref<Font> label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", EditorStringName(EditorFonts));
- Ref<Font> label_bold_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_bold_msdf", EditorStringName(EditorFonts));
- vstheme->set_font("font", "Label", label_font);
- vstheme->set_font("font", "GraphNodeTitleLabel", label_bold_font);
- vstheme->set_font("font", "LineEdit", label_font);
- vstheme->set_font("font", "Button", label_font);
+ static const String vector_expanded_name[4] = { "red", "green", "blue", "alpha" };
Ref<VisualShaderNode> vsnode = visual_shader->get_node(p_type, p_id);
@@ -457,7 +466,18 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
node->connect("delete_request", callable_mp(editor, &VisualShaderEditor::_delete_node_request).bind(p_type, p_id), CONNECT_DEFERRED);
}
graph->add_child(node);
- node->set_theme(vstheme);
+ node->set_theme(vs_msdf_fonts_theme);
+
+ // Set the node's titlebar color based on its category.
+ if (vsnode->get_category() != VisualShaderNode::CATEGORY_NONE) {
+ Ref<StyleBoxFlat> sb_colored = editor->get_theme_stylebox("titlebar", "GraphNode")->duplicate();
+ sb_colored->set_bg_color(category_color[vsnode->get_category()]);
+ node->add_theme_style_override("titlebar", sb_colored);
+
+ Ref<StyleBoxFlat> sb_colored_selected = editor->get_theme_stylebox("titlebar_selected", "GraphNode")->duplicate();
+ sb_colored_selected->set_bg_color(category_color[vsnode->get_category()].lightened(0.2));
+ node->add_theme_style_override("titlebar_selected", sb_colored_selected);
+ }
if (p_just_update) {
Link &link = links[p_id];
@@ -506,6 +526,11 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
port_offset += 1;
}
+ // Set the minimum width of a node based on the preview size to avoid a resize when toggling the preview.
+ Ref<StyleBoxFlat> graph_node_stylebox = graph->get_theme_stylebox("panel", "GraphNode");
+ int port_preview_size = EDITOR_GET("editors/visual_editors/visual_shader/port_preview_size");
+ node->set_custom_minimum_size(Size2((Math::ceil(graph_node_stylebox->get_minimum_size().width) + port_preview_size) * EDSCALE, 0));
+
Ref<VisualShaderNodeParticleEmit> emit = vsnode;
if (emit.is_valid()) {
node->set_custom_minimum_size(Size2(200 * EDSCALE, 0));
@@ -4313,7 +4338,9 @@ void VisualShaderEditor::_notification(int p_what) {
}
if (EditorSettings::get_singleton()->check_changed_settings_in_group("editors/visual_editors")) {
graph->set_minimap_opacity(EDITOR_GET("editors/visual_editors/minimap_opacity"));
+ graph->set_grid_pattern((GraphEdit::GridPattern) int(EDITOR_GET("editors/visual_editors/grid_pattern")));
graph->set_connection_lines_curvature(EDITOR_GET("editors/visual_editors/lines_curvature"));
+
_update_graph();
}
} break;
@@ -5424,6 +5451,9 @@ VisualShaderEditor::VisualShaderEditor() {
graph->get_menu_hbox()->set_h_size_flags(SIZE_EXPAND_FILL);
graph->set_v_size_flags(SIZE_EXPAND_FILL);
graph->set_h_size_flags(SIZE_EXPAND_FILL);
+ graph->set_grid_pattern(GraphEdit::GridPattern::GRID_PATTERN_DOTS);
+ int grid_pattern = EDITOR_GET("editors/visual_editors/grid_pattern");
+ graph->set_grid_pattern((GraphEdit::GridPattern)grid_pattern);
graph->set_show_zoom_label(true);
add_child(graph);
SET_DRAG_FORWARDING_GCD(graph, VisualShaderEditor);
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index 39e721f226..2575866b10 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -99,6 +99,9 @@ private:
Color vector_expanded_color[4];
+ // Visual shader specific theme for using MSDF fonts (on GraphNodes) which reduce aliasing at higher zoom levels.
+ Ref<Theme> vs_msdf_fonts_theme;
+
protected:
static void _bind_methods();
diff --git a/editor/themes/editor_theme_manager.cpp b/editor/themes/editor_theme_manager.cpp
index 4ceffcc98c..4a67bd6b31 100644
--- a/editor/themes/editor_theme_manager.cpp
+++ b/editor/themes/editor_theme_manager.cpp
@@ -39,6 +39,7 @@
#include "editor/themes/editor_icons.h"
#include "editor/themes/editor_scale.h"
#include "editor/themes/editor_theme.h"
+#include "scene/gui/graph_edit.h"
#include "scene/resources/image_texture.h"
#include "scene/resources/style_box_flat.h"
#include "scene/resources/style_box_line.h"
@@ -213,6 +214,7 @@ Ref<EditorTheme> EditorThemeManager::_create_base_theme(const Ref<EditorTheme> &
_populate_standard_styles(theme, config);
_populate_editor_styles(theme, config);
_populate_text_editor_styles(theme, config);
+ _populate_visual_shader_styles(theme, config);
OS::get_singleton()->benchmark_end_measure(get_benchmark_key(), "Create Base Theme");
return theme;
@@ -1465,13 +1467,22 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
p_theme->set_stylebox("panel", "GraphEdit", p_config.tree_panel_style);
p_theme->set_stylebox("menu_panel", "GraphEdit", make_flat_stylebox(p_config.dark_color_1 * Color(1, 1, 1, 0.6), 4, 2, 4, 2, 3));
- if (p_config.dark_theme) {
- p_theme->set_color("grid_major", "GraphEdit", Color(1.0, 1.0, 1.0, 0.1));
- p_theme->set_color("grid_minor", "GraphEdit", Color(1.0, 1.0, 1.0, 0.05));
- } else {
- p_theme->set_color("grid_major", "GraphEdit", Color(0.0, 0.0, 0.0, 0.15));
- p_theme->set_color("grid_minor", "GraphEdit", Color(0.0, 0.0, 0.0, 0.07));
+ float grid_base_brightness = p_config.dark_theme ? 1.0 : 0.0;
+ GraphEdit::GridPattern grid_pattern = (GraphEdit::GridPattern) int(EDITOR_GET("editors/visual_editors/grid_pattern"));
+ switch (grid_pattern) {
+ case GraphEdit::GRID_PATTERN_LINES:
+ p_theme->set_color("grid_major", "GraphEdit", Color(grid_base_brightness, grid_base_brightness, grid_base_brightness, 0.10));
+ p_theme->set_color("grid_minor", "GraphEdit", Color(grid_base_brightness, grid_base_brightness, grid_base_brightness, 0.05));
+ break;
+ case GraphEdit::GRID_PATTERN_DOTS:
+ p_theme->set_color("grid_major", "GraphEdit", Color(grid_base_brightness, grid_base_brightness, grid_base_brightness, 0.07));
+ p_theme->set_color("grid_minor", "GraphEdit", Color(grid_base_brightness, grid_base_brightness, grid_base_brightness, 0.07));
+ break;
+ default:
+ WARN_PRINT("Unknown grid pattern.");
+ break;
}
+
p_theme->set_color("selection_fill", "GraphEdit", p_theme->get_color(SNAME("box_selection_fill_color"), EditorStringName(Editor)));
p_theme->set_color("selection_stroke", "GraphEdit", p_theme->get_color(SNAME("box_selection_stroke_color"), EditorStringName(Editor)));
p_theme->set_color("activity", "GraphEdit", p_config.dark_theme ? Color(1, 1, 1) : Color(0, 0, 0));
@@ -1522,31 +1533,48 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
const int gn_margin_side = 2;
const int gn_margin_bottom = 2;
+ const int gn_corner_radius = 3;
+
const Color gn_bg_color = p_config.dark_theme ? p_config.dark_color_3 : p_config.dark_color_1.lerp(p_config.mono_color, 0.09);
- const Color gn_selected_border_color = gn_bg_color.lerp(p_config.accent_color, 0.275);
+ const Color gn_selected_border_color = p_config.dark_theme ? Color(1, 1, 1) : Color(0, 0, 0);
const Color gn_frame_bg = gn_bg_color.lerp(p_config.tree_panel_style->get_bg_color(), 0.3);
- Ref<StyleBoxFlat> gn_panel_style = make_flat_stylebox(gn_frame_bg, gn_margin_side, gn_margin_top, gn_margin_side, gn_margin_bottom, p_config.corner_radius);
- gn_panel_style->set_border_width_all(p_config.border_width);
- gn_panel_style->set_border_color(gn_bg_color);
- gn_panel_style->set_corner_radius_individual(0, 0, p_config.corner_radius * EDSCALE, p_config.corner_radius * EDSCALE);
- gn_panel_style->set_expand_margin(SIDE_TOP, 17 * EDSCALE);
+ const bool high_contrast_borders = p_config.draw_extra_borders && p_config.dark_theme;
- Ref<StyleBoxFlat> gn_panel_selected_style = make_flat_stylebox(gn_frame_bg, gn_margin_side, gn_margin_top, gn_margin_side, gn_margin_bottom, p_config.corner_radius);
- gn_panel_selected_style->set_border_width_all(2 * EDSCALE + p_config.border_width);
+ Ref<StyleBoxFlat> gn_panel_style = make_flat_stylebox(gn_frame_bg, gn_margin_side, gn_margin_top, gn_margin_side, gn_margin_bottom, p_config.corner_radius);
+ gn_panel_style->set_border_width(SIDE_BOTTOM, 2 * EDSCALE);
+ gn_panel_style->set_border_width(SIDE_LEFT, 2 * EDSCALE);
+ gn_panel_style->set_border_width(SIDE_RIGHT, 2 * EDSCALE);
+ gn_panel_style->set_border_color(high_contrast_borders ? gn_bg_color.lightened(0.2) : gn_bg_color.darkened(0.3));
+ gn_panel_style->set_corner_radius_individual(0, 0, gn_corner_radius * EDSCALE, gn_corner_radius * EDSCALE);
+ gn_panel_style->set_anti_aliased(true);
+
+ Ref<StyleBoxFlat> gn_panel_selected_style = gn_panel_style->duplicate();
+ gn_panel_selected_style->set_bg_color(p_config.dark_theme ? gn_bg_color.lightened(0.15) : gn_bg_color.darkened(0.15));
+ gn_panel_selected_style->set_border_width(SIDE_TOP, 0);
+ gn_panel_selected_style->set_border_width(SIDE_BOTTOM, 2 * EDSCALE);
+ gn_panel_selected_style->set_border_width(SIDE_LEFT, 2 * EDSCALE);
+ gn_panel_selected_style->set_border_width(SIDE_RIGHT, 2 * EDSCALE);
gn_panel_selected_style->set_border_color(gn_selected_border_color);
- gn_panel_selected_style->set_corner_radius_individual(0, 0, p_config.corner_radius * EDSCALE, p_config.corner_radius * EDSCALE);
- gn_panel_selected_style->set_expand_margin(SIDE_TOP, 17 * EDSCALE);
- const int gn_titlebar_margin_left = 12;
- const int gn_titlebar_margin_right = 4; // The rest is for the close button.
+ const int gn_titlebar_margin_top = 8;
+ const int gn_titlebar_margin_side = 12;
+ const int gn_titlebar_margin_bottom = 8;
- Ref<StyleBoxFlat> gn_titlebar_style = make_flat_stylebox(gn_bg_color, gn_titlebar_margin_left, gn_margin_top, gn_titlebar_margin_right, 0, p_config.corner_radius);
+ Ref<StyleBoxFlat> gn_titlebar_style = make_flat_stylebox(gn_bg_color, gn_titlebar_margin_side, gn_titlebar_margin_top, gn_titlebar_margin_side, gn_titlebar_margin_bottom, p_config.corner_radius);
+ gn_titlebar_style->set_border_width(SIDE_TOP, 2 * EDSCALE);
+ gn_titlebar_style->set_border_width(SIDE_LEFT, 2 * EDSCALE);
+ gn_titlebar_style->set_border_width(SIDE_RIGHT, 2 * EDSCALE);
+ gn_titlebar_style->set_border_color(high_contrast_borders ? gn_bg_color.lightened(0.2) : gn_bg_color.darkened(0.3));
gn_titlebar_style->set_expand_margin(SIDE_TOP, 2 * EDSCALE);
- gn_titlebar_style->set_corner_radius_individual(p_config.corner_radius * EDSCALE, p_config.corner_radius * EDSCALE, 0, 0);
-
- Ref<StyleBoxFlat> gn_titlebar_selected_style = make_flat_stylebox(gn_selected_border_color, gn_titlebar_margin_left, gn_margin_top, gn_titlebar_margin_right, 0, p_config.corner_radius);
- gn_titlebar_selected_style->set_corner_radius_individual(p_config.corner_radius * EDSCALE, p_config.corner_radius * EDSCALE, 0, 0);
+ gn_titlebar_style->set_corner_radius_individual(gn_corner_radius * EDSCALE, gn_corner_radius * EDSCALE, 0, 0);
+ gn_titlebar_style->set_anti_aliased(true);
+
+ Ref<StyleBoxFlat> gn_titlebar_selected_style = gn_titlebar_style->duplicate();
+ gn_titlebar_selected_style->set_border_color(gn_selected_border_color);
+ gn_titlebar_selected_style->set_border_width(SIDE_TOP, 2 * EDSCALE);
+ gn_titlebar_selected_style->set_border_width(SIDE_LEFT, 2 * EDSCALE);
+ gn_titlebar_selected_style->set_border_width(SIDE_RIGHT, 2 * EDSCALE);
gn_titlebar_selected_style->set_expand_margin(SIDE_TOP, 2 * EDSCALE);
Color gn_decoration_color = p_config.dark_color_1.inverted();
@@ -1573,7 +1601,7 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
p_theme->set_color("resizer_color", "GraphNode", gn_decoration_color);
- p_theme->set_constant("port_h_offset", "GraphNode", 0);
+ p_theme->set_constant("port_h_offset", "GraphNode", 1);
p_theme->set_constant("separation", "GraphNode", 1 * EDSCALE);
Ref<ImageTexture> port_icon = p_theme->get_icon(SNAME("GuiGraphNodePort"), EditorStringName(EditorIcons));
@@ -1584,7 +1612,11 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
// GraphNode's title Label.
p_theme->set_type_variation("GraphNodeTitleLabel", "Label");
p_theme->set_stylebox("normal", "GraphNodeTitleLabel", make_empty_stylebox(0, 0, 0, 0));
- p_theme->set_color("font_color", "GraphNodeTitleLabel", p_config.font_color);
+ p_theme->set_color("font_color", "GraphNodeTitleLabel", p_config.dark_theme ? p_config.font_color : Color(1, 1, 1)); // Also use a bright font color for light themes.
+ p_theme->set_color("font_shadow_color", "GraphNodeTitleLabel", Color(0, 0, 0, 0.35));
+ p_theme->set_constant("shadow_outline_size", "GraphNodeTitleLabel", 4);
+ p_theme->set_constant("shadow_offset_x", "GraphNodeTitleLabel", 0);
+ p_theme->set_constant("shadow_offset_y", "GraphNodeTitleLabel", 1);
p_theme->set_constant("line_spacing", "GraphNodeTitleLabel", 3 * EDSCALE);
}
}
@@ -2339,6 +2371,59 @@ void EditorThemeManager::_populate_text_editor_styles(const Ref<EditorTheme> &p_
/* clang-format on */
}
+void EditorThemeManager::_populate_visual_shader_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config) {
+ EditorSettings *ed_settings = EditorSettings::get_singleton();
+ String visual_shader_color_theme = ed_settings->get("editors/visual_editors/color_theme");
+ if (visual_shader_color_theme == "Default") {
+ // Connection type colors
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/scalar_color", Color(0.55, 0.55, 0.55), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/vector2_color", Color(0.44, 0.43, 0.64), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/vector3_color", Color(0.337, 0.314, 0.71), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/vector4_color", Color(0.7, 0.65, 0.147), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/boolean_color", Color(0.243, 0.612, 0.349), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/transform_color", Color(0.71, 0.357, 0.64), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/sampler_color", Color(0.659, 0.4, 0.137), true);
+
+ // Node category colors (used for the node headers)
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/output_color", Color(0.26, 0.10, 0.15), true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/color_color", Color(0.5, 0.5, 0.1), true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/conditional_color", Color(0.208, 0.522, 0.298), true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/input_color", Color(0.502, 0.2, 0.204), true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/scalar_color", Color(0.1, 0.5, 0.6), true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/textures_color", Color(0.5, 0.3, 0.1), true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/transform_color", Color(0.5, 0.3, 0.5), true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/utility_color", Color(0.2, 0.2, 0.2), true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/vector_color", Color(0.2, 0.2, 0.5), true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/special_color", Color(0.098, 0.361, 0.294), true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/particle_color", Color(0.12, 0.358, 0.8), true);
+
+ } else if (visual_shader_color_theme == "Legacy") {
+ // Connection type colors
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/scalar_color", Color(0.38, 0.85, 0.96), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/vector2_color", Color(0.74, 0.57, 0.95), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/vector3_color", Color(0.84, 0.49, 0.93), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/vector4_color", Color(1.0, 0.125, 0.95), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/boolean_color", Color(0.55, 0.65, 0.94), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/transform_color", Color(0.96, 0.66, 0.43), true);
+ ed_settings->set_initial_value("editors/visual_editors/connection_colors/sampler_color", Color(1.0, 1.0, 0.0), true);
+
+ // Node category colors (used for the node headers)
+ Ref<StyleBoxFlat> gn_panel_style = p_theme->get_stylebox("panel", "GraphNode");
+ Color gn_bg_color = gn_panel_style->get_bg_color();
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/output_color", gn_bg_color, true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/color_color", gn_bg_color, true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/conditional_color", gn_bg_color, true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/input_color", gn_bg_color, true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/scalar_color", gn_bg_color, true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/textures_color", gn_bg_color, true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/transform_color", gn_bg_color, true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/utility_color", gn_bg_color, true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/vector_color", gn_bg_color, true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/special_color", gn_bg_color, true);
+ ed_settings->set_initial_value("editors/visual_editors/category_colors/particle_color", gn_bg_color, true);
+ }
+}
+
void EditorThemeManager::_reset_dirty_flag() {
outdated_cache_dirty = true;
}
@@ -2381,6 +2466,7 @@ bool EditorThemeManager::is_generated_theme_outdated() {
EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/code_font") ||
EditorSettings::get_singleton()->check_changed_settings_in_group("interface/touchscreen/increase_scrollbar_touch_area") ||
EditorSettings::get_singleton()->check_changed_settings_in_group("interface/touchscreen/scale_gizmo_handles") ||
+ EditorSettings::get_singleton()->check_changed_settings_in_group("editors/visual_editors") ||
EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor/theme") ||
EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor/help/help") ||
EditorSettings::get_singleton()->check_changed_settings_in_group("docks/property_editor/subresource_hue_tint") ||
diff --git a/editor/themes/editor_theme_manager.h b/editor/themes/editor_theme_manager.h
index de088a1011..3eb1dd5ffd 100644
--- a/editor/themes/editor_theme_manager.h
+++ b/editor/themes/editor_theme_manager.h
@@ -156,6 +156,7 @@ class EditorThemeManager {
static void _generate_text_editor_defaults(ThemeConfiguration &p_config);
static void _populate_text_editor_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
+ static void _populate_visual_shader_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _reset_dirty_flag();
diff --git a/modules/basis_universal/image_compress_basisu.cpp b/modules/basis_universal/image_compress_basisu.cpp
index 12856f33c1..72e7977eef 100644
--- a/modules/basis_universal/image_compress_basisu.cpp
+++ b/modules/basis_universal/image_compress_basisu.cpp
@@ -158,6 +158,8 @@ Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size) {
bool s3tc_supported = RS::get_singleton()->has_os_feature("s3tc");
bool etc2_supported = RS::get_singleton()->has_os_feature("etc2");
+ bool needs_ra_rg_swap = false;
+
switch (*(uint32_t *)(src_ptr)) {
case BASIS_DECOMPRESS_RG: {
// RGTC transcoding is currently performed with RG_AS_RA, fail.
@@ -213,6 +215,7 @@ Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size) {
// No supported VRAM compression formats, decompress.
basisu_format = basist::transcoder_texture_format::cTFRGBA32;
image_format = Image::FORMAT_RGBA8;
+ needs_ra_rg_swap = true;
}
} break;
}
@@ -228,6 +231,7 @@ Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size) {
basist::basisu_image_info basisu_info;
transcoder.get_image_info(src_ptr, src_size, basisu_info, 0);
+ // Create the buffer for transcoded/decompressed data.
Vector<uint8_t> out_data;
out_data.resize(Image::get_image_data_size(basisu_info.m_width, basisu_info.m_height, image_format, basisu_info.m_total_levels > 1));
@@ -239,8 +243,10 @@ Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size) {
basist::basisu_image_level_info basisu_level;
transcoder.get_image_level_info(src_ptr, src_size, basisu_level, 0, i);
+ uint32_t mip_block_or_pixel_count = image_format >= Image::FORMAT_DXT1 ? basisu_level.m_total_blocks : basisu_level.m_orig_width * basisu_level.m_orig_height;
int ofs = Image::get_image_mipmap_offset(basisu_info.m_width, basisu_info.m_height, image_format, i);
- bool result = transcoder.transcode_image_level(src_ptr, src_size, 0, i, dst + ofs, basisu_level.m_total_blocks, basisu_format);
+
+ bool result = transcoder.transcode_image_level(src_ptr, src_size, 0, i, dst + ofs, mip_block_or_pixel_count, basisu_format);
if (!result) {
print_line(vformat("BasisUniversal cannot unpack level %d.", i));
@@ -250,6 +256,11 @@ Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size) {
image = Image::create_from_data(basisu_info.m_width, basisu_info.m_height, basisu_info.m_total_levels > 1, image_format, out_data);
+ if (needs_ra_rg_swap) {
+ // Swap uncompressed RA-as-RG texture's color channels.
+ image->convert_ra_rgba8_to_rg();
+ }
+
return image;
}
diff --git a/modules/gdscript/tests/gdscript_test_runner_suite.h b/modules/gdscript/tests/gdscript_test_runner_suite.h
index 5acf436e42..b2289ef9cc 100644
--- a/modules/gdscript/tests/gdscript_test_runner_suite.h
+++ b/modules/gdscript/tests/gdscript_test_runner_suite.h
@@ -37,6 +37,8 @@
namespace GDScriptTests {
+// TODO: Handle some cases failing on release builds. See: https://github.com/godotengine/godot/pull/88452
+#ifdef TOOLS_ENABLED
TEST_SUITE("[Modules][GDScript]") {
TEST_CASE("Script compilation and runtime") {
bool print_filenames = OS::get_singleton()->get_cmdline_args().find("--print-filenames") != nullptr;
@@ -68,6 +70,7 @@ func _init():
ref_counted->set_script(gdscript);
CHECK_MESSAGE(int(ref_counted->get_meta("result")) == 42, "The script should assign object metadata successfully.");
}
+#endif // TOOLS_ENABLED
TEST_CASE("[Modules][GDScript] Validate built-in API") {
GDScriptLanguage *lang = GDScriptLanguage::get_singleton();
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index c23d21775f..b7118d595f 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -52,6 +52,7 @@ constexpr int MINIMAP_PADDING = 5;
constexpr int MIN_DRAG_DISTANCE_FOR_VALID_CONNECTION = 20;
constexpr int MAX_CONNECTION_LINE_CURVE_TESSELATION_STAGES = 5;
constexpr int GRID_MINOR_STEPS_PER_MAJOR_LINE = 10;
+constexpr int GRID_MINOR_STEPS_PER_MAJOR_DOT = 5;
constexpr int GRID_MIN_SNAPPING_DISTANCE = 2;
constexpr int GRID_MAX_SNAPPING_DISTANCE = 100;
@@ -1349,13 +1350,13 @@ void GraphEdit::_draw_grid() {
} break;
case GRID_PATTERN_DOTS: {
Color transparent_grid_minor = theme_cache.grid_minor;
- transparent_grid_minor.a *= CLAMP(2 * (zoom - 0.4), 0, 1);
+ transparent_grid_minor.a *= CLAMP(1.0 * (zoom - 0.4), 0, 1);
for (int i = from_pos.x; i < from_pos.x + len.x; i++) {
for (int j = from_pos.y; j < from_pos.y + len.y; j++) {
Color color = transparent_grid_minor;
- if (ABS(i) % GRID_MINOR_STEPS_PER_MAJOR_LINE == 0 && ABS(j) % GRID_MINOR_STEPS_PER_MAJOR_LINE == 0) {
+ if (ABS(i) % GRID_MINOR_STEPS_PER_MAJOR_DOT == 0 && ABS(j) % GRID_MINOR_STEPS_PER_MAJOR_DOT == 0) {
color = theme_cache.grid_major;
}
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 218ca6322a..c7c2ddbb18 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -403,6 +403,11 @@ String VisualShaderNode::get_warning(Shader::Mode p_mode, VisualShader::Type p_t
return String();
}
+VisualShaderNode::Category VisualShaderNode::get_category() const {
+ WARN_PRINT(get_caption() + " is missing a category.");
+ return CATEGORY_NONE;
+}
+
bool VisualShaderNode::is_input_port_default(int p_port, Shader::Mode p_mode) const {
return false;
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index d4d77e7609..09ea9a8890 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -255,6 +255,37 @@ VARIANT_ENUM_CAST(VisualShader::VaryingType)
class VisualShaderNode : public Resource {
GDCLASS(VisualShaderNode, Resource);
+public:
+ enum PortType {
+ PORT_TYPE_SCALAR,
+ PORT_TYPE_SCALAR_INT,
+ PORT_TYPE_SCALAR_UINT,
+ PORT_TYPE_VECTOR_2D,
+ PORT_TYPE_VECTOR_3D,
+ PORT_TYPE_VECTOR_4D,
+ PORT_TYPE_BOOLEAN,
+ PORT_TYPE_TRANSFORM,
+ PORT_TYPE_SAMPLER,
+ PORT_TYPE_MAX,
+ };
+
+ enum Category {
+ CATEGORY_NONE,
+ CATEGORY_OUTPUT,
+ CATEGORY_COLOR,
+ CATEGORY_CONDITIONAL,
+ CATEGORY_INPUT,
+ CATEGORY_SCALAR,
+ CATEGORY_TEXTURES,
+ CATEGORY_TRANSFORM,
+ CATEGORY_UTILITY,
+ CATEGORY_VECTOR,
+ CATEGORY_SPECIAL,
+ CATEGORY_PARTICLE,
+ CATEGORY_MAX
+ };
+
+private:
int port_preview = -1;
HashMap<int, bool> connected_input_ports;
@@ -270,19 +301,6 @@ protected:
static void _bind_methods();
public:
- enum PortType {
- PORT_TYPE_SCALAR,
- PORT_TYPE_SCALAR_INT,
- PORT_TYPE_SCALAR_UINT,
- PORT_TYPE_VECTOR_2D,
- PORT_TYPE_VECTOR_3D,
- PORT_TYPE_VECTOR_4D,
- PORT_TYPE_BOOLEAN,
- PORT_TYPE_TRANSFORM,
- PORT_TYPE_SAMPLER,
- PORT_TYPE_MAX,
- };
-
bool is_simple_decl() const;
virtual String get_caption() const = 0;
@@ -348,6 +366,8 @@ public:
virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const;
+ virtual Category get_category() const;
+
VisualShaderNode();
};
@@ -507,6 +527,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_INPUT; }
+
VisualShaderNodeInput();
};
@@ -546,6 +568,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_OUTPUT; }
+
VisualShaderNodeOutput();
};
@@ -589,6 +613,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
+ virtual Category get_category() const override { return CATEGORY_INPUT; }
+
VisualShaderNodeParameter();
};
@@ -661,6 +687,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_INPUT; }
+
VisualShaderNodeParameterRef();
};
@@ -713,6 +741,8 @@ public:
void set_description(const String &p_description);
String get_description() const;
+ virtual Category get_category() const override { return CATEGORY_SPECIAL; }
+
VisualShaderNodeComment();
};
@@ -781,6 +811,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_SPECIAL; }
+
VisualShaderNodeGroupBase();
};
@@ -887,6 +919,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_OUTPUT; }
+
VisualShaderNodeVaryingSetter();
};
@@ -907,6 +941,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_INPUT; }
+
VisualShaderNodeVaryingGetter();
};
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 67e2c4633d..05c8fbd16c 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -76,6 +76,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_VECTOR; }
+
VisualShaderNodeVectorBase();
};
@@ -101,6 +103,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override = 0;
+ virtual Category get_category() const override { return CATEGORY_INPUT; }
+
VisualShaderNodeConstant();
};
@@ -437,6 +441,8 @@ public:
virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
+ virtual Category get_category() const override { return CATEGORY_TEXTURES; }
+
VisualShaderNodeTexture();
};
@@ -473,6 +479,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
virtual bool is_use_prop_slots() const override;
+ virtual Category get_category() const override { return CATEGORY_TEXTURES; }
+
VisualShaderNodeCurveTexture();
};
@@ -543,6 +551,8 @@ public:
virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
+ virtual Category get_category() const override { return CATEGORY_TEXTURES; }
+
VisualShaderNodeSample3D();
};
@@ -671,8 +681,11 @@ public:
virtual bool has_output_port_preview(int p_port) const override;
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_TEXTURES; }
+
VisualShaderNodeLinearSceneDepth();
};
@@ -695,6 +708,8 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_TEXTURES; }
+
VisualShaderNodeWorldPositionFromDepth();
};
@@ -717,6 +732,8 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_TEXTURES; }
+
VisualShaderNodeScreenNormalWorldSpace();
};
@@ -765,6 +782,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_SCALAR; }
+
VisualShaderNodeFloatOp();
};
@@ -957,6 +976,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_COLOR; }
+
VisualShaderNodeColorOp();
};
@@ -1006,6 +1027,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_TRANSFORM; }
+
VisualShaderNodeTransformOp();
};
@@ -1050,6 +1073,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_TRANSFORM; }
+
VisualShaderNodeTransformVecMult();
};
@@ -1122,6 +1147,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_SCALAR; }
+
VisualShaderNodeFloatFunc();
};
@@ -1166,6 +1193,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_SCALAR; }
+
VisualShaderNodeIntFunc();
};
@@ -1208,6 +1237,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_SCALAR; }
+
VisualShaderNodeUIntFunc();
};
@@ -1327,6 +1358,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_COLOR; }
+
VisualShaderNodeColorFunc();
};
@@ -1369,6 +1402,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_TRANSFORM; }
+
VisualShaderNodeTransformFunc();
};
@@ -1414,6 +1449,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_TEXTURES; }
+
VisualShaderNodeUVFunc();
};
@@ -1440,6 +1477,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_TEXTURES; }
+
VisualShaderNodeUVPolarCoord();
};
@@ -1620,6 +1659,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_UTILITY; }
+
VisualShaderNodeDerivativeFunc();
};
@@ -1669,6 +1710,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_TRANSFORM; }
+
VisualShaderNodeOuterProduct();
};
@@ -1714,6 +1757,14 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override {
+ if (op_type == OP_TYPE_SCALAR) {
+ return CATEGORY_SCALAR;
+ } else {
+ return CATEGORY_VECTOR;
+ }
+ }
+
VisualShaderNodeStep();
};
@@ -1761,6 +1812,14 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override {
+ if (op_type == OP_TYPE_SCALAR) {
+ return CATEGORY_SCALAR;
+ } else {
+ return CATEGORY_VECTOR;
+ }
+ }
+
VisualShaderNodeSmoothStep();
};
@@ -1852,6 +1911,14 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override {
+ if (op_type == OP_TYPE_SCALAR) {
+ return CATEGORY_SCALAR;
+ } else {
+ return CATEGORY_VECTOR;
+ }
+ }
+
VisualShaderNodeMix();
};
@@ -1898,6 +1965,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_TRANSFORM; }
+
VisualShaderNodeTransformCompose();
};
@@ -1921,6 +1990,8 @@ public:
virtual void set_op_type(OpType p_op_type) override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_VECTOR; }
+
VisualShaderNodeVectorDecompose();
};
@@ -1942,6 +2013,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_TRANSFORM; }
+
VisualShaderNodeTransformDecompose();
};
@@ -2584,6 +2657,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_CONDITIONAL; }
+
VisualShaderNodeIf();
};
@@ -2630,6 +2705,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_CONDITIONAL; }
+
VisualShaderNodeSwitch();
};
@@ -2698,6 +2775,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_CONDITIONAL; }
+
VisualShaderNodeIs();
};
@@ -2772,6 +2851,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
+ virtual Category get_category() const override { return CATEGORY_CONDITIONAL; }
+
VisualShaderNodeCompare();
};
@@ -2815,6 +2896,14 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override {
+ if (op_type == OP_TYPE_SCALAR) {
+ return CATEGORY_SCALAR;
+ } else {
+ return CATEGORY_VECTOR;
+ }
+ }
+
VisualShaderNodeMultiplyAdd();
};
@@ -2862,6 +2951,8 @@ public:
virtual Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_UTILITY; }
+
VisualShaderNodeBillboard();
};
@@ -2888,6 +2979,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_UTILITY; }
+
VisualShaderNodeDistanceFade();
};
@@ -2909,6 +3002,8 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_UTILITY; }
+
VisualShaderNodeProximityFade();
};
@@ -2929,6 +3024,8 @@ public:
virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_UTILITY; }
+
VisualShaderNodeRandomRange();
};
@@ -2948,6 +3045,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_UTILITY; }
+
VisualShaderNodeRemap();
};
@@ -2968,6 +3067,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_UTILITY; }
+
VisualShaderNodeRotationByAxis();
};
diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h
index 652b5dff03..23d06d4b7c 100644
--- a/scene/resources/visual_shader_particle_nodes.h
+++ b/scene/resources/visual_shader_particle_nodes.h
@@ -57,6 +57,8 @@ public:
virtual HashMap<StringName, String> get_editable_properties_names() const override;
bool is_show_prop_names() const override;
+ virtual Category get_category() const override { return CATEGORY_PARTICLE; }
+
VisualShaderNodeParticleEmitter();
};
@@ -73,6 +75,8 @@ public:
virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_PARTICLE; }
+
VisualShaderNodeParticleSphereEmitter();
};
@@ -90,6 +94,8 @@ public:
virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_PARTICLE; }
+
VisualShaderNodeParticleBoxEmitter();
};
@@ -106,6 +112,8 @@ public:
virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_PARTICLE; }
+
VisualShaderNodeParticleRingEmitter();
};
@@ -158,6 +166,8 @@ public:
HashMap<StringName, String> get_editable_properties_names() const override;
Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override;
+ virtual Category get_category() const override { return CATEGORY_PARTICLE; }
+
VisualShaderNodeParticleMeshEmitter();
};
@@ -187,6 +197,8 @@ public:
bool is_degrees_mode() const;
Vector<StringName> get_editable_properties() const override;
+ virtual Category get_category() const override { return CATEGORY_PARTICLE; }
+
VisualShaderNodeParticleMultiplyByAxisAngle();
};
@@ -207,6 +219,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_PARTICLE; }
+
VisualShaderNodeParticleConeVelocity();
};
@@ -248,6 +262,8 @@ public:
void set_op_type(OpType p_type);
OpType get_op_type() const;
+ virtual Category get_category() const override { return CATEGORY_PARTICLE; }
+
VisualShaderNodeParticleRandomness();
};
@@ -290,6 +306,8 @@ public:
void set_mode(Mode p_mode);
Mode get_mode() const;
+ virtual Category get_category() const override { return CATEGORY_PARTICLE; }
+
VisualShaderNodeParticleAccelerator();
};
@@ -352,6 +370,8 @@ public:
virtual bool is_input_port_default(int p_port, Shader::Mode p_mode) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual Category get_category() const override { return CATEGORY_PARTICLE; }
+
VisualShaderNodeParticleEmit();
};
diff --git a/tests/core/config/test_project_settings.h b/tests/core/config/test_project_settings.h
index 9bd072f511..8fc2489f8b 100644
--- a/tests/core/config/test_project_settings.h
+++ b/tests/core/config/test_project_settings.h
@@ -45,6 +45,8 @@ public:
namespace TestProjectSettings {
+// TODO: Handle some cases failing on release builds. See: https://github.com/godotengine/godot/pull/88452
+#ifdef TOOLS_ENABLED
TEST_CASE("[ProjectSettings] Get existing setting") {
CHECK(ProjectSettings::get_singleton()->has_setting("application/config/name"));
@@ -64,6 +66,7 @@ TEST_CASE("[ProjectSettings] Default value is ignored if setting exists") {
String name = variant;
CHECK_EQ(name, "GDScript Integration Test Suite");
}
+#endif // TOOLS_ENABLED
TEST_CASE("[ProjectSettings] Non existing setting is null") {
CHECK_FALSE(ProjectSettings::get_singleton()->has_setting("not_existing_setting"));
diff --git a/tests/core/io/test_image.h b/tests/core/io/test_image.h
index 945a7e1ba3..35d182f50c 100644
--- a/tests/core/io/test_image.h
+++ b/tests/core/io/test_image.h
@@ -88,11 +88,14 @@ TEST_CASE("[Image] Saving and loading") {
err == OK,
"The image should be saved successfully as a .png file.");
+ // Only available on editor builds.
+#ifdef TOOLS_ENABLED
// Save EXR
err = image->save_exr(save_path_exr, false);
CHECK_MESSAGE(
err == OK,
"The image should be saved successfully as an .exr file.");
+#endif // TOOLS_ENABLED
// Load using load()
Ref<Image> image_load = memnew(Image());
diff --git a/tests/core/os/test_os.h b/tests/core/os/test_os.h
index ef8216685f..1a5d360f57 100644
--- a/tests/core/os/test_os.h
+++ b/tests/core/os/test_os.h
@@ -93,6 +93,7 @@ TEST_CASE("[OS] Ticks") {
}
TEST_CASE("[OS] Feature tags") {
+#ifdef TOOLS_ENABLED
CHECK_MESSAGE(
OS::get_singleton()->has_feature("editor"),
"The binary has the \"editor\" feature tag.");
@@ -105,6 +106,29 @@ TEST_CASE("[OS] Feature tags") {
CHECK_MESSAGE(
!OS::get_singleton()->has_feature("template_release"),
"The binary does not have the \"template_release\" feature tag.");
+#else
+ CHECK_MESSAGE(
+ !OS::get_singleton()->has_feature("editor"),
+ "The binary does not have the \"editor\" feature tag.");
+ CHECK_MESSAGE(
+ OS::get_singleton()->has_feature("template"),
+ "The binary has the \"template\" feature tag.");
+#ifdef DEBUG_ENABLED
+ CHECK_MESSAGE(
+ OS::get_singleton()->has_feature("template_debug"),
+ "The binary has the \"template_debug\" feature tag.");
+ CHECK_MESSAGE(
+ !OS::get_singleton()->has_feature("template_release"),
+ "The binary does not have the \"template_release\" feature tag.");
+#else
+ CHECK_MESSAGE(
+ !OS::get_singleton()->has_feature("template_debug"),
+ "The binary does not have the \"template_debug\" feature tag.");
+ CHECK_MESSAGE(
+ OS::get_singleton()->has_feature("template_release"),
+ "The binary has the \"template_release\" feature tag.");
+#endif // DEBUG_ENABLED
+#endif // TOOLS_ENABLED
}
TEST_CASE("[OS] Process ID") {
diff --git a/tests/core/string/test_translation.h b/tests/core/string/test_translation.h
index bf9674d6b1..acdd851b29 100644
--- a/tests/core/string/test_translation.h
+++ b/tests/core/string/test_translation.h
@@ -129,6 +129,7 @@ TEST_CASE("[TranslationPO] Plural messages") {
CHECK(vformat(translation->get_plural_message("There are %d apples", "", 2), 2) == "Il y a 2 pommes");
}
+#ifdef TOOLS_ENABLED
TEST_CASE("[OptimizedTranslation] Generate from Translation and read messages") {
Ref<Translation> translation = memnew(Translation);
translation->set_locale("fr");
@@ -150,7 +151,6 @@ TEST_CASE("[OptimizedTranslation] Generate from Translation and read messages")
CHECK(messages.size() == 0);
}
-#ifdef TOOLS_ENABLED
TEST_CASE("[TranslationCSV] CSV import") {
Ref<ResourceImporterCSVTranslation> import_csv_translation = memnew(ResourceImporterCSVTranslation);