Skip to content

Commit

Permalink
Add quad mesh to material preview
Browse files Browse the repository at this point in the history
  • Loading branch information
tetrapod00 committed Sep 15, 2024
1 parent 6681f25 commit 1dc30dc
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 17 deletions.
1 change: 1 addition & 0 deletions editor/icons/MaterialPreviewQuad.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 75 additions & 17 deletions editor/plugins/material_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,14 @@ void MaterialEditor::gui_input(const Ref<InputEvent> &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.
// Magic numbers so that the range is a bit less than 90 degrees in either direction.
rot.x = CLAMP(rot.x, -Math_PI / 2.2, Math_PI / 2.2);
rot.y = CLAMP(rot.y, -Math_PI / 2.2, Math_PI / 2.2);
} else {
rot.x = CLAMP(rot.x, -Math_PI / 2, Math_PI / 2);
}
_update_rotation();
}
}
Expand All @@ -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"));
}
Expand All @@ -82,6 +89,7 @@ void MaterialEditor::_notification(int p_what) {

sphere_switch->set_icon(theme_cache.sphere_icon);
box_switch->set_icon(theme_cache.box_icon);
quad_switch->set_icon(theme_cache.quad_icon);

error_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
} break;
Expand All @@ -95,11 +103,20 @@ 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();
}

void MaterialEditor::_update_rotation() {
Transform3D t;
t.basis.rotate(Vector3(0, 1, 0), -rot.y);
t.basis.rotate(Vector3(1, 0, 0), -rot.x);
rotation->set_transform(t);
// Store the rotation so it can persist when switching between materials.
Vector2 rotation_degrees = Vector2(Math::rad_to_deg(rot.x),Math::rad_to_deg(rot.y);

Check failure on line 118 in editor/plugins/material_editor_plugin.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor w/ Mono (target=editor)

expected primary-expression before '(' token

Check failure on line 118 in editor/plugins/material_editor_plugin.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor w/ Mono (target=editor)

expected ')' before ';' token

Check failure on line 118 in editor/plugins/material_editor_plugin.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with doubles and GCC sanitizers (target=editor, tests=yes, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=gold)

expected primary-expression before '(' token

Check failure on line 118 in editor/plugins/material_editor_plugin.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with doubles and GCC sanitizers (target=editor, tests=yes, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=gold)

expected ')' before ';' token

Check failure on line 118 in editor/plugins/material_editor_plugin.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)

expected ')'

Check failure on line 118 in editor/plugins/material_editor_plugin.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Editor (target=editor, tests=yes)

syntax error: missing ')' before ';'

Check failure on line 118 in editor/plugins/material_editor_plugin.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with ThreadSanitizer (target=editor, tests=yes, dev_build=yes, use_tsan=yes, use_llvm=yes, linker=lld)

expected ')'
EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_rotation", rotation_degrees);
}

void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &p_env) {
Expand All @@ -124,6 +141,7 @@ void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &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();
Expand All @@ -136,10 +154,6 @@ void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &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() {
Expand All @@ -151,19 +165,36 @@ void MaterialEditor::_on_light_2_switch_pressed() {
}

void MaterialEditor::_on_sphere_switch_pressed() {
box_instance->hide();
sphere_instance->show();
box_switch->set_pressed(false);
box_instance->hide();
quad_instance->hide();
sphere_switch->set_pressed(true);
EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", true);
box_switch->set_pressed(false);
quad_switch->set_pressed(false);
_set_rotation(-15.0, 30.0);
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_instance->show();
quad_instance->hide();
sphere_switch->set_pressed(false);
box_switch->set_pressed(true);
quad_switch->set_pressed(false);
_set_rotation(-15.0, 30.0);
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);
EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", false);
box_switch->set_pressed(false);
quad_switch->set_pressed(true);
_set_rotation(0.0, 0.0);
EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_mesh", "quad");
}

MaterialEditor::MaterialEditor() {
Expand Down Expand Up @@ -213,15 +244,15 @@ MaterialEditor::MaterialEditor() {
viewport = memnew(SubViewport);
Ref<World3D> 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);
viewport->set_msaa_3d(Viewport::MSAA_4X);

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();
Expand Down Expand Up @@ -249,13 +280,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.25);

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);

Expand All @@ -280,6 +317,13 @@ MaterialEditor::MaterialEditor() {
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);
quad_switch->set_pressed(false);
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);
Expand All @@ -299,14 +343,28 @@ 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();
} else if (shape == "box") {
sphere_instance->hide();
box_instance->show();
quad_instance->hide();
sphere_switch->set_pressed(false);
box_switch->set_pressed(true);
quad_switch->set_pressed(false);
} else {
sphere_instance->hide();
box_instance->hide();
quad_instance->show();
sphere_switch->set_pressed(false);
box_switch->set_pressed(false);
quad_switch->set_pressed(true);
}

Vector2 stored_rot = EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_rotation", Vector2());
_set_rotation(stored_rot.x, stored_rot.y);
}

///////////////////////
Expand Down
6 changes: 6 additions & 0 deletions editor/plugins/material_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@ 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;
Ref<CameraAttributesPractical> camera_attributes;

Ref<SphereMesh> sphere_mesh;
Ref<BoxMesh> box_mesh;
Ref<QuadMesh> quad_mesh;

VBoxContainer *layout_error = nullptr;
Label *error_label = nullptr;
Expand All @@ -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;

Expand All @@ -88,18 +91,21 @@ class MaterialEditor : public Control {
Ref<Texture2D> light_2_icon;
Ref<Texture2D> sphere_icon;
Ref<Texture2D> box_icon;
Ref<Texture2D> quad_icon;
Ref<Texture2D> checkerboard;
} theme_cache;

void _on_light_1_switch_pressed();
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<InputEvent> &p_event) override;
void _set_rotation(real_t p_x_degrees, real_t p_y_degrees);
void _update_rotation();

public:
Expand Down
2 changes: 2 additions & 0 deletions editor/themes/editor_color_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down

0 comments on commit 1dc30dc

Please sign in to comment.