Moved "Update From Scene" button to multimesh item inspector
parent
414d1ce2b8
commit
90dbf9418e
|
@ -52,12 +52,8 @@ void VoxelInstanceLibraryEditorPlugin::_notification(int p_what) {
|
|||
// otherwise `add_inspector_plugin` causes ANOTHER editor plugin to leak on exit... Oo
|
||||
add_inspector_plugin(_inspector_plugin);
|
||||
|
||||
_multimesh_item_inspector_plugin.instantiate();
|
||||
add_inspector_plugin(_multimesh_item_inspector_plugin);
|
||||
|
||||
} else if (p_what == NOTIFICATION_EXIT_TREE) {
|
||||
remove_inspector_plugin(_inspector_plugin);
|
||||
remove_inspector_plugin(_multimesh_item_inspector_plugin);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,15 +84,6 @@ void VoxelInstanceLibraryEditorPlugin::_on_button_pressed(int id) {
|
|||
ur.commit_action();
|
||||
} break;
|
||||
|
||||
case VoxelInstanceLibraryInspectorPlugin::BUTTON_UPDATE_MULTIMESH_ITEM_FROM_SCENE: {
|
||||
ERR_FAIL_COND(_library.is_null());
|
||||
const int item_id = try_get_selected_item_id();
|
||||
if (item_id != -1) {
|
||||
_item_id_to_update = item_id;
|
||||
_open_scene_dialog->popup_centered_ratio();
|
||||
}
|
||||
} break;
|
||||
|
||||
case VoxelInstanceLibraryInspectorPlugin::BUTTON_ADD_SCENE_ITEM: {
|
||||
_open_scene_dialog->popup_centered_ratio();
|
||||
} break;
|
||||
|
@ -161,10 +148,6 @@ void VoxelInstanceLibraryEditorPlugin::_on_open_scene_dialog_file_selected(Strin
|
|||
add_scene_item(fpath);
|
||||
break;
|
||||
|
||||
case VoxelInstanceLibraryInspectorPlugin::BUTTON_UPDATE_MULTIMESH_ITEM_FROM_SCENE:
|
||||
update_multimesh_item_from_scene(fpath, _item_id_to_update);
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR_PRINT("Invalid menu option");
|
||||
break;
|
||||
|
@ -196,33 +179,6 @@ void VoxelInstanceLibraryEditorPlugin::add_scene_item(String fpath) {
|
|||
ur.commit_action();
|
||||
}
|
||||
|
||||
void VoxelInstanceLibraryEditorPlugin::update_multimesh_item_from_scene(String fpath, int item_id) {
|
||||
ERR_FAIL_COND(_library.is_null());
|
||||
|
||||
Ref<PackedScene> scene = ResourceLoader::load(fpath);
|
||||
ERR_FAIL_COND(scene.is_null());
|
||||
|
||||
Ref<VoxelInstanceLibraryItem> item_base = _library->get_item(item_id);
|
||||
ERR_FAIL_COND_MSG(item_base.is_null(), "Item not found");
|
||||
Ref<VoxelInstanceLibraryMultiMeshItem> item = item_base;
|
||||
ERR_FAIL_COND_MSG(item.is_null(), "Item not using multimeshes");
|
||||
|
||||
Node *node = scene->instantiate();
|
||||
ERR_FAIL_COND(node == nullptr);
|
||||
|
||||
Variant data_before = item->serialize_multimesh_item_properties();
|
||||
item->setup_from_template(node);
|
||||
Variant data_after = item->serialize_multimesh_item_properties();
|
||||
|
||||
memdelete(node);
|
||||
|
||||
UndoRedo &ur = get_undo_redo();
|
||||
ur.create_action("Update Multimesh Item From Scene");
|
||||
ur.add_do_method(item.ptr(), "_deserialize_multimesh_item_properties", data_after);
|
||||
ur.add_undo_method(item.ptr(), "_deserialize_multimesh_item_properties", data_before);
|
||||
ur.commit_action();
|
||||
}
|
||||
|
||||
void VoxelInstanceLibraryEditorPlugin::_bind_methods() {
|
||||
// ClassDB::bind_method(D_METHOD("_on_button_pressed", "id"),
|
||||
// &VoxelInstanceLibraryEditorPlugin::_on_button_pressed); ClassDB::bind_method(
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "../../terrain/instancing/voxel_instance_library.h"
|
||||
#include "voxel_instance_library_inspector_plugin.h"
|
||||
#include "voxel_instance_library_multimesh_item_inspector_plugin.h"
|
||||
#include <editor/editor_plugin.h>
|
||||
|
||||
class Control;
|
||||
|
@ -31,7 +30,6 @@ private:
|
|||
|
||||
int try_get_selected_item_id();
|
||||
void add_scene_item(String fpath);
|
||||
void update_multimesh_item_from_scene(String fpath, int item_id);
|
||||
|
||||
void _on_remove_item_confirmed();
|
||||
void _on_open_scene_dialog_file_selected(String fpath);
|
||||
|
@ -47,7 +45,6 @@ private:
|
|||
|
||||
Ref<VoxelInstanceLibrary> _library;
|
||||
Ref<VoxelInstanceLibraryInspectorPlugin> _inspector_plugin;
|
||||
Ref<VoxelInstanceLibraryMultiMeshItemInspectorPlugin> _multimesh_item_inspector_plugin;
|
||||
};
|
||||
|
||||
} // namespace zylann::voxel
|
||||
|
|
|
@ -46,14 +46,6 @@ void VoxelInstanceLibraryInspectorPlugin::add_buttons() {
|
|||
spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
hb->add_child(spacer);
|
||||
|
||||
Button *button_update = memnew(Button);
|
||||
// TODO Move this to multimesh items?
|
||||
button_update->set_text(TTR("Update From Scene..."));
|
||||
button_update->connect("pressed",
|
||||
callable_mp(button_listener, &VoxelInstanceLibraryEditorPlugin::_on_button_pressed)
|
||||
.bind(BUTTON_UPDATE_MULTIMESH_ITEM_FROM_SCENE));
|
||||
hb->add_child(button_update);
|
||||
|
||||
add_custom_control(hb);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,8 @@ class VoxelInstanceLibraryEditorPlugin;
|
|||
class VoxelInstanceLibraryInspectorPlugin : public EditorInspectorPlugin {
|
||||
GDCLASS(VoxelInstanceLibraryInspectorPlugin, EditorInspectorPlugin)
|
||||
public:
|
||||
enum Buttons {
|
||||
enum Buttons { //
|
||||
BUTTON_ADD_MULTIMESH_ITEM,
|
||||
BUTTON_UPDATE_MULTIMESH_ITEM_FROM_SCENE,
|
||||
BUTTON_ADD_SCENE_ITEM,
|
||||
BUTTON_REMOVE_ITEM
|
||||
};
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
#include "voxel_instance_library_multimesh_item_editor_plugin.h"
|
||||
#include <editor/editor_file_dialog.h>
|
||||
|
||||
namespace zylann::voxel {
|
||||
|
||||
VoxelInstanceLibraryMultiMeshItemEditorPlugin::VoxelInstanceLibraryMultiMeshItemEditorPlugin() {
|
||||
Control *base_control = get_editor_interface()->get_base_control();
|
||||
|
||||
_open_scene_dialog = memnew(EditorFileDialog);
|
||||
List<String> extensions;
|
||||
ResourceLoader::get_recognized_extensions_for_type(PackedScene::get_class_static(), &extensions);
|
||||
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
|
||||
_open_scene_dialog->add_filter("*." + E->get());
|
||||
}
|
||||
_open_scene_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
|
||||
base_control->add_child(_open_scene_dialog);
|
||||
_open_scene_dialog->connect("file_selected",
|
||||
callable_mp(this, &VoxelInstanceLibraryMultiMeshItemEditorPlugin::_on_open_scene_dialog_file_selected));
|
||||
}
|
||||
|
||||
bool VoxelInstanceLibraryMultiMeshItemEditorPlugin::handles(Object *p_object) const {
|
||||
// TODO Making a plugin handling sub-resources of `VoxelInstanceLibrary` breaks the inspector.
|
||||
// There are also some caveats when using multiple sub-inspectors. To keep supporting multiple sub-inspectors open
|
||||
// inside a library, we cannot rely on `edit` giving us edited resources.
|
||||
// See https://github.com/godotengine/godot/issues/64700
|
||||
return false;
|
||||
// const VoxelInstanceLibraryMultiMeshItem *item = Object::cast_to<VoxelInstanceLibraryMultiMeshItem>(p_object);
|
||||
// return item != nullptr;
|
||||
}
|
||||
|
||||
void VoxelInstanceLibraryMultiMeshItemEditorPlugin::edit(Object *p_object) {
|
||||
// VoxelInstanceLibraryMultiMeshItem *item = Object::cast_to<VoxelInstanceLibraryMultiMeshItem>(p_object);
|
||||
// _item.reference_ptr(item);
|
||||
}
|
||||
|
||||
void VoxelInstanceLibraryMultiMeshItemEditorPlugin::make_visible(bool visible) {
|
||||
// if (!visible) {
|
||||
// _item.unref();
|
||||
// }
|
||||
}
|
||||
|
||||
void VoxelInstanceLibraryMultiMeshItemEditorPlugin::_notification(int p_what) {
|
||||
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||
_inspector_plugin.instantiate();
|
||||
_inspector_plugin->listener = this;
|
||||
add_inspector_plugin(_inspector_plugin);
|
||||
|
||||
} else if (p_what == NOTIFICATION_EXIT_TREE) {
|
||||
remove_inspector_plugin(_inspector_plugin);
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelInstanceLibraryMultiMeshItemEditorPlugin::_on_update_from_scene_button_pressed(
|
||||
VoxelInstanceLibraryMultiMeshItem *item) {
|
||||
_item.reference_ptr(item);
|
||||
ERR_FAIL_COND(_item.is_null());
|
||||
_open_scene_dialog->popup_centered_ratio();
|
||||
}
|
||||
|
||||
static void update_multimesh_item_from_scene(
|
||||
VoxelInstanceLibraryMultiMeshItem &item, String scene_file_path, UndoRedo &ur) {
|
||||
Ref<PackedScene> scene = ResourceLoader::load(scene_file_path);
|
||||
ERR_FAIL_COND(scene.is_null());
|
||||
|
||||
Node *node = scene->instantiate();
|
||||
ERR_FAIL_COND(node == nullptr);
|
||||
|
||||
Variant data_before = item.serialize_multimesh_item_properties();
|
||||
item.setup_from_template(node);
|
||||
Variant data_after = item.serialize_multimesh_item_properties();
|
||||
|
||||
memdelete(node);
|
||||
|
||||
ur.create_action("Update Multimesh Item From Scene");
|
||||
ur.add_do_method(&item, "_deserialize_multimesh_item_properties", data_after);
|
||||
ur.add_undo_method(&item, "_deserialize_multimesh_item_properties", data_before);
|
||||
ur.commit_action();
|
||||
}
|
||||
|
||||
void VoxelInstanceLibraryMultiMeshItemEditorPlugin::_on_open_scene_dialog_file_selected(String fpath) {
|
||||
ERR_FAIL_COND(_item.is_null());
|
||||
update_multimesh_item_from_scene(**_item, fpath, get_undo_redo());
|
||||
// We are done with this item
|
||||
_item.unref();
|
||||
}
|
||||
|
||||
} // namespace zylann::voxel
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef VOXEL_INSTANCE_LIBRARY_MULTIMESH_ITEM_EDITOR_PLUGIN_H
|
||||
#define VOXEL_INSTANCE_LIBRARY_MULTIMESH_ITEM_EDITOR_PLUGIN_H
|
||||
|
||||
#include "../../terrain/instancing/voxel_instance_library_multimesh_item.h"
|
||||
#include "voxel_instance_library_multimesh_item_inspector_plugin.h"
|
||||
#include <editor/editor_plugin.h>
|
||||
|
||||
namespace zylann::voxel {
|
||||
|
||||
class VoxelInstanceLibraryMultiMeshItemEditorPlugin : public EditorPlugin {
|
||||
GDCLASS(VoxelInstanceLibraryMultiMeshItemEditorPlugin, EditorPlugin)
|
||||
public:
|
||||
VoxelInstanceLibraryMultiMeshItemEditorPlugin();
|
||||
|
||||
bool handles(Object *p_object) const override;
|
||||
void edit(Object *p_object) override;
|
||||
void make_visible(bool visible) override;
|
||||
|
||||
void _on_update_from_scene_button_pressed(VoxelInstanceLibraryMultiMeshItem *item);
|
||||
|
||||
private:
|
||||
void _notification(int p_what);
|
||||
|
||||
void _on_open_scene_dialog_file_selected(String fpath);
|
||||
|
||||
EditorFileDialog *_open_scene_dialog = nullptr;
|
||||
Ref<VoxelInstanceLibraryMultiMeshItem> _item;
|
||||
Ref<VoxelInstanceLibraryMultiMeshItemInspectorPlugin> _inspector_plugin;
|
||||
};
|
||||
|
||||
} // namespace zylann::voxel
|
||||
|
||||
#endif // VOXEL_INSTANCE_LIBRARY_MULTIMESH_ITEM_EDITOR_PLUGIN_H
|
|
@ -1,5 +1,7 @@
|
|||
#include "voxel_instance_library_multimesh_item_inspector_plugin.h"
|
||||
#include "../../terrain/instancing/voxel_instance_library_multimesh_item.h"
|
||||
#include "voxel_instance_library_editor_plugin.h"
|
||||
#include "voxel_instance_library_multimesh_item_editor_plugin.h"
|
||||
|
||||
namespace zylann::voxel {
|
||||
|
||||
|
@ -11,6 +13,20 @@ void VoxelInstanceLibraryMultiMeshItemInspectorPlugin::parse_group(Object *p_obj
|
|||
const VoxelInstanceLibraryMultiMeshItem *item = Object::cast_to<VoxelInstanceLibraryMultiMeshItem>(p_object);
|
||||
ERR_FAIL_COND(item == nullptr);
|
||||
if (item->get_scene().is_null()) {
|
||||
ERR_FAIL_COND(listener == nullptr);
|
||||
// TODO I preferred this at the end of the group, but Godot doesn't expose anything to do it.
|
||||
// This is a legacy workflow, we'll see if it can be removed later.
|
||||
Button *button = memnew(Button);
|
||||
button->set_tooltip(TTR("Set properties based on an existing scene. This might copy mesh and material data if "
|
||||
"the scene embeds them. Properties will not update if the scene changes later."));
|
||||
button->set_text(TTR("Update from scene..."));
|
||||
// Using a bind() instead of relying on "currently edited" item in the editor plugin allows to support multiple
|
||||
// sub-inspectors. Plugins are not instanced per-inspected-object, but custom controls are.
|
||||
button->connect("pressed",
|
||||
callable_mp(
|
||||
listener, &VoxelInstanceLibraryMultiMeshItemEditorPlugin::_on_update_from_scene_button_pressed)
|
||||
.bind(item));
|
||||
add_custom_control(button);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -20,7 +36,7 @@ void VoxelInstanceLibraryMultiMeshItemInspectorPlugin::parse_group(Object *p_obj
|
|||
add_custom_control(label);
|
||||
}
|
||||
// TODO Button to open scene in editor, since Godot doesn't have that in its resource picker menu?
|
||||
// Perhaps it should rather be a feature request to Godot
|
||||
// Perhaps it should rather be a feature request to Godot.
|
||||
// else if (p_group == VoxelInstanceLibraryMultiMeshItem::SCENE_SETTINGS_GROUP_NAME) {
|
||||
// ERR_FAIL_COND(listener == nullptr);
|
||||
// Button *button = memnew(Button);
|
||||
|
|
|
@ -5,9 +5,13 @@
|
|||
|
||||
namespace zylann::voxel {
|
||||
|
||||
class VoxelInstanceLibraryMultiMeshItemEditorPlugin;
|
||||
|
||||
class VoxelInstanceLibraryMultiMeshItemInspectorPlugin : public EditorInspectorPlugin {
|
||||
GDCLASS(VoxelInstanceLibraryMultiMeshItemInspectorPlugin, EditorInspectorPlugin)
|
||||
public:
|
||||
VoxelInstanceLibraryMultiMeshItemEditorPlugin *listener = nullptr;
|
||||
|
||||
bool can_handle(Object *p_object) override;
|
||||
void parse_group(Object *p_object, const String &p_group) override;
|
||||
bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint,
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "editor/fast_noise_lite/fast_noise_lite_editor_plugin.h"
|
||||
#include "editor/graph/voxel_graph_editor_plugin.h"
|
||||
#include "editor/instance_library/voxel_instance_library_editor_plugin.h"
|
||||
#include "editor/instance_library/voxel_instance_library_multimesh_item_editor_plugin.h"
|
||||
#include "editor/instancer/voxel_instancer_editor_plugin.h"
|
||||
#include "editor/mesh_sdf/voxel_mesh_sdf_editor_plugin.h"
|
||||
#include "editor/terrain/voxel_terrain_editor_plugin.h"
|
||||
|
@ -258,6 +259,7 @@ void initialize_voxel_module(ModuleInitializationLevel p_level) {
|
|||
EditorPlugins::add_by_type<VoxelGraphEditorPlugin>();
|
||||
EditorPlugins::add_by_type<VoxelTerrainEditorPlugin>();
|
||||
EditorPlugins::add_by_type<VoxelInstanceLibraryEditorPlugin>();
|
||||
EditorPlugins::add_by_type<VoxelInstanceLibraryMultiMeshItemEditorPlugin>();
|
||||
EditorPlugins::add_by_type<ZN_FastNoiseLiteEditorPlugin>();
|
||||
EditorPlugins::add_by_type<magica::VoxEditorPlugin>();
|
||||
EditorPlugins::add_by_type<VoxelInstancerEditorPlugin>();
|
||||
|
|
Loading…
Reference in New Issue