From 6454ea4606293fee236f51f8ea5e81d9a6a2ca79 Mon Sep 17 00:00:00 2001
From: tetrapod00 <145553014+tetrapod00@users.noreply.github.com>
Date: Sat, 14 Sep 2024 19:38:17 -0700
Subject: [PATCH] Add quad mesh to material preview
---
editor/icons/MaterialPreviewQuad.svg | 1 +
editor/plugins/material_editor_plugin.cpp | 97 ++++++++++++++++++-----
editor/plugins/material_editor_plugin.h | 7 ++
editor/themes/editor_color_map.cpp | 2 +
4 files changed, 85 insertions(+), 22 deletions(-)
create mode 100644 editor/icons/MaterialPreviewQuad.svg
diff --git a/editor/icons/MaterialPreviewQuad.svg b/editor/icons/MaterialPreviewQuad.svg
new file mode 100644
index 00000000000..9765a15df77
--- /dev/null
+++ b/editor/icons/MaterialPreviewQuad.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index be44d573765..8bdc763ebef 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -56,9 +56,15 @@ void MaterialEditor::gui_input(const Ref &p_event) {
if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
rot.x -= mm->get_relative().y * 0.01;
rot.y -= mm->get_relative().x * 0.01;
-
- rot.x = CLAMP(rot.x, -Math_PI / 2, Math_PI / 2);
+ if (quad_instance->is_visible()) {
+ // Clamp rotation so the quad is always visible.
+ const real_t limit = Math::deg_to_rad(80.0);
+ rot = rot.clampf(-limit, limit);
+ } else {
+ rot.x = CLAMP(rot.x, -Math_PI / 2, Math_PI / 2);
+ }
_update_rotation();
+ _store_rotation_metadata();
}
}
@@ -70,6 +76,7 @@ void MaterialEditor::_update_theme_item_cache() {
theme_cache.sphere_icon = get_editor_theme_icon(SNAME("MaterialPreviewSphere"));
theme_cache.box_icon = get_editor_theme_icon(SNAME("MaterialPreviewCube"));
+ theme_cache.quad_icon = get_editor_theme_icon(SNAME("MaterialPreviewQuad"));
theme_cache.checkerboard = get_editor_theme_icon(SNAME("Checkerboard"));
}
@@ -82,6 +89,7 @@ void MaterialEditor::_notification(int p_what) {
sphere_switch->set_button_icon(theme_cache.sphere_icon);
box_switch->set_button_icon(theme_cache.box_icon);
+ quad_switch->set_button_icon(theme_cache.quad_icon);
error_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
} break;
@@ -95,6 +103,18 @@ void MaterialEditor::_notification(int p_what) {
}
}
+void MaterialEditor::_set_rotation(real_t p_x_degrees, real_t p_y_degrees) {
+ rot.x = Math::deg_to_rad(p_x_degrees);
+ rot.y = Math::deg_to_rad(p_y_degrees);
+ _update_rotation();
+}
+
+// Store the rotation so it can persist when switching between materials.
+void MaterialEditor::_store_rotation_metadata() {
+ Vector2 rotation_degrees = Vector2(Math::rad_to_deg(rot.x), Math::rad_to_deg(rot.y));
+ EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_rotation", rotation_degrees);
+}
+
void MaterialEditor::_update_rotation() {
Transform3D t;
t.basis.rotate(Vector3(0, 1, 0), -rot.y);
@@ -124,6 +144,7 @@ void MaterialEditor::edit(Ref p_material, const Ref &p_en
vc->show();
sphere_instance->set_material_override(material);
box_instance->set_material_override(material);
+ quad_instance->set_material_override(material);
break;
default:
layout_error->show();
@@ -136,10 +157,6 @@ void MaterialEditor::edit(Ref p_material, const Ref &p_en
} else {
hide();
}
-
- rot.x = Math::deg_to_rad(-15.0);
- rot.y = Math::deg_to_rad(30.0);
- _update_rotation();
}
void MaterialEditor::_on_light_1_switch_pressed() {
@@ -151,19 +168,36 @@ void MaterialEditor::_on_light_2_switch_pressed() {
}
void MaterialEditor::_on_sphere_switch_pressed() {
- box_instance->hide();
sphere_instance->show();
+ box_instance->hide();
+ quad_instance->hide();
box_switch->set_pressed(false);
- sphere_switch->set_pressed(true);
- EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", true);
+ quad_switch->set_pressed(false);
+ _set_rotation(-15.0, 30.0);
+ _store_rotation_metadata();
+ EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_mesh", "sphere");
}
void MaterialEditor::_on_box_switch_pressed() {
- box_instance->show();
sphere_instance->hide();
- box_switch->set_pressed(true);
+ box_instance->show();
+ quad_instance->hide();
sphere_switch->set_pressed(false);
- EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", false);
+ quad_switch->set_pressed(false);
+ _set_rotation(-15.0, 30.0);
+ _store_rotation_metadata();
+ EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_mesh", "box");
+}
+
+void MaterialEditor::_on_quad_switch_pressed() {
+ sphere_instance->hide();
+ box_instance->hide();
+ quad_instance->show();
+ sphere_switch->set_pressed(false);
+ box_switch->set_pressed(false);
+ _set_rotation(0.0, 0.0);
+ _store_rotation_metadata();
+ EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_mesh", "quad");
}
MaterialEditor::MaterialEditor() {
@@ -213,7 +247,7 @@ MaterialEditor::MaterialEditor() {
viewport = memnew(SubViewport);
Ref world_3d;
world_3d.instantiate();
- viewport->set_world_3d(world_3d); //use own world
+ viewport->set_world_3d(world_3d); // Use own world.
vc->add_child(viewport);
viewport->set_disable_input(true);
viewport->set_transparent_background(true);
@@ -221,7 +255,7 @@ MaterialEditor::MaterialEditor() {
camera = memnew(Camera3D);
camera->set_transform(Transform3D(Basis(), Vector3(0, 0, 1.1)));
- // Use low field of view so the sphere/box is fully encompassed within the preview,
+ // Use low field of view so the sphere/box/quad is fully encompassed within the preview,
// without much distortion.
camera->set_perspective(20, 0.1, 10);
camera->make_current();
@@ -249,13 +283,19 @@ MaterialEditor::MaterialEditor() {
box_instance = memnew(MeshInstance3D);
rotation->add_child(box_instance);
- box_instance->set_transform(Transform3D() * 0.25);
+ quad_instance = memnew(MeshInstance3D);
+ rotation->add_child(quad_instance);
+
sphere_instance->set_transform(Transform3D() * 0.375);
+ box_instance->set_transform(Transform3D() * 0.25);
+ quad_instance->set_transform(Transform3D() * 0.375);
sphere_mesh.instantiate();
sphere_instance->set_mesh(sphere_mesh);
box_mesh.instantiate();
box_instance->set_mesh(box_mesh);
+ quad_mesh.instantiate();
+ quad_instance->set_mesh(quad_mesh);
set_custom_minimum_size(Size2(1, 150) * EDSCALE);
@@ -269,17 +309,21 @@ MaterialEditor::MaterialEditor() {
sphere_switch = memnew(Button);
sphere_switch->set_theme_type_variation("PreviewLightButton");
sphere_switch->set_toggle_mode(true);
- sphere_switch->set_pressed(true);
vb_shape->add_child(sphere_switch);
sphere_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_sphere_switch_pressed));
box_switch = memnew(Button);
box_switch->set_theme_type_variation("PreviewLightButton");
box_switch->set_toggle_mode(true);
- box_switch->set_pressed(false);
vb_shape->add_child(box_switch);
box_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_box_switch_pressed));
+ quad_switch = memnew(Button);
+ quad_switch->set_theme_type_variation("PreviewLightButton");
+ quad_switch->set_toggle_mode(true);
+ vb_shape->add_child(quad_switch);
+ quad_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_quad_switch_pressed));
+
layout_3d->add_spacer();
VBoxContainer *vb_light = memnew(VBoxContainer);
@@ -299,14 +343,23 @@ MaterialEditor::MaterialEditor() {
vb_light->add_child(light_2_switch);
light_2_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_light_2_switch_pressed));
- if (EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_on_sphere", true)) {
+ String shape = EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_mesh", "sphere");
+ if (shape == "sphere") {
box_instance->hide();
- } else {
- box_instance->show();
+ quad_instance->hide();
+ sphere_switch->set_pressed_no_signal(true);
+ } else if (shape == "box") {
sphere_instance->hide();
- box_switch->set_pressed(true);
- sphere_switch->set_pressed(false);
+ quad_instance->hide();
+ box_switch->set_pressed_no_signal(true);
+ } else {
+ sphere_instance->hide();
+ box_instance->hide();
+ quad_switch->set_pressed_no_signal(true);
}
+
+ Vector2 stored_rot = EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_rotation", Vector2());
+ _set_rotation(stored_rot.x, stored_rot.y);
}
///////////////////////
diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h
index 28c59d27dba..c1b37a5831b 100644
--- a/editor/plugins/material_editor_plugin.h
+++ b/editor/plugins/material_editor_plugin.h
@@ -62,6 +62,7 @@ class MaterialEditor : public Control {
Node3D *rotation = nullptr;
MeshInstance3D *sphere_instance = nullptr;
MeshInstance3D *box_instance = nullptr;
+ MeshInstance3D *quad_instance = nullptr;
DirectionalLight3D *light1 = nullptr;
DirectionalLight3D *light2 = nullptr;
Camera3D *camera = nullptr;
@@ -69,6 +70,7 @@ class MaterialEditor : public Control {
Ref sphere_mesh;
Ref box_mesh;
+ Ref quad_mesh;
VBoxContainer *layout_error = nullptr;
Label *error_label = nullptr;
@@ -80,6 +82,7 @@ class MaterialEditor : public Control {
Button *sphere_switch = nullptr;
Button *box_switch = nullptr;
+ Button *quad_switch = nullptr;
Button *light_1_switch = nullptr;
Button *light_2_switch = nullptr;
@@ -88,6 +91,7 @@ class MaterialEditor : public Control {
Ref light_2_icon;
Ref sphere_icon;
Ref box_icon;
+ Ref quad_icon;
Ref checkerboard;
} theme_cache;
@@ -95,11 +99,14 @@ class MaterialEditor : public Control {
void _on_light_2_switch_pressed();
void _on_sphere_switch_pressed();
void _on_box_switch_pressed();
+ void _on_quad_switch_pressed();
protected:
virtual void _update_theme_item_cache() override;
void _notification(int p_what);
void gui_input(const Ref &p_event) override;
+ void _set_rotation(real_t p_x_degrees, real_t p_y_degrees);
+ void _store_rotation_metadata();
void _update_rotation();
public:
diff --git a/editor/themes/editor_color_map.cpp b/editor/themes/editor_color_map.cpp
index 9046a8b688f..3c3d755586d 100644
--- a/editor/themes/editor_color_map.cpp
+++ b/editor/themes/editor_color_map.cpp
@@ -173,6 +173,8 @@ void EditorColorMap::create() {
add_conversion_exception("OverbrightIndicator");
add_conversion_exception("MaterialPreviewCube");
add_conversion_exception("MaterialPreviewSphere");
+ add_conversion_exception("MaterialPreviewQuad");
+
add_conversion_exception("MaterialPreviewLight1");
add_conversion_exception("MaterialPreviewLight2");