From 9682496d72b1027237ced2dc3979e2a066a886f2 Mon Sep 17 00:00:00 2001 From: kobewi Date: Wed, 18 Dec 2024 18:29:00 +0100 Subject: [PATCH] Add UndoRedo support to Load Emission Mask/Points --- editor/plugins/particles_editor_plugin.cpp | 100 ++++++++++++++------- 1 file changed, 69 insertions(+), 31 deletions(-) diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp index 59a05546fc1b..a4ac07651b34 100644 --- a/editor/plugins/particles_editor_plugin.cpp +++ b/editor/plugins/particles_editor_plugin.cpp @@ -364,6 +364,12 @@ void GPUParticles2DEditorPlugin::_notification(int p_what) { void Particles2DEditorPlugin::_menu_callback(int p_idx) { if (p_idx == MENU_LOAD_EMISSION_MASK) { + GPUParticles2D *particles = Object::cast_to(edited_node); + if (particles && particles->get_process_material().is_null()) { + EditorNode::get_singleton()->show_warning(TTR("Loading emission mask requires ParticleProcessMaterial.")); + return; + } + file->popup_file_dialog(); } else { ParticlesEditorPlugin::_menu_callback(p_idx); @@ -390,10 +396,7 @@ Node *GPUParticles2DEditorPlugin::_convert_particles() { void GPUParticles2DEditorPlugin::_generate_emission_mask() { GPUParticles2D *particles = Object::cast_to(edited_node); Ref pm = particles->get_process_material(); - if (pm.is_null()) { - EditorNode::get_singleton()->show_warning(TTR("Can only set point into a ParticleProcessMaterial process material")); - return; - } + ERR_FAIL_COND(pm.is_null()); PackedVector2Array valid_positions; PackedVector2Array valid_normals; @@ -403,6 +406,10 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() { ERR_FAIL_COND_MSG(valid_positions.is_empty(), "No pixels with transparency > 128 in image..."); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Load Emission Mask")); + ParticleProcessMaterial *pmptr = pm.ptr(); + Vector texdata; int vpc = valid_positions.size(); @@ -428,8 +435,10 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() { Ref img; img.instantiate(); img->set_data(w, h, false, Image::FORMAT_RGF, texdata); - pm->set_emission_point_texture(ImageTexture::create_from_image(img)); - pm->set_emission_point_count(vpc); + undo_redo->add_do_property(pmptr, "emission_point_texture", ImageTexture::create_from_image(img)); + undo_redo->add_undo_property(pmptr, "emission_point_texture", pm->get_emission_point_texture()); + undo_redo->add_do_property(pmptr, "emission_point_count", vpc); + undo_redo->add_undo_property(pmptr, "emission_point_count", pm->get_emission_point_count()); if (emission_colors->is_pressed()) { Vector colordata; @@ -444,10 +453,13 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() { img.instantiate(); img->set_data(w, h, false, Image::FORMAT_RGBA8, colordata); - pm->set_emission_color_texture(ImageTexture::create_from_image(img)); + undo_redo->add_do_property(pmptr, "emission_color_texture", ImageTexture::create_from_image(img)); + undo_redo->add_undo_property(pmptr, "emission_color_texture", pm->get_emission_color_texture()); } if (valid_normals.size()) { + undo_redo->add_do_property(pmptr, "emission_shape", ParticleProcessMaterial::EMISSION_SHAPE_DIRECTED_POINTS); + undo_redo->add_undo_property(pmptr, "emission_shape", pm->get_emission_shape()); pm->set_emission_shape(ParticleProcessMaterial::EMISSION_SHAPE_DIRECTED_POINTS); Vector normdata; @@ -464,15 +476,17 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() { img.instantiate(); img->set_data(w, h, false, Image::FORMAT_RGF, normdata); - pm->set_emission_normal_texture(ImageTexture::create_from_image(img)); - + undo_redo->add_do_property(pmptr, "emission_normal_texture", ImageTexture::create_from_image(img)); + undo_redo->add_undo_property(pmptr, "emission_normal_texture", pm->get_emission_normal_texture()); } else { - pm->set_emission_shape(ParticleProcessMaterial::EMISSION_SHAPE_POINTS); + undo_redo->add_do_property(pmptr, "emission_shape", ParticleProcessMaterial::EMISSION_SHAPE_POINTS); + undo_redo->add_undo_property(pmptr, "emission_shape", pm->get_emission_shape()); } + undo_redo->commit_action(); } GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin() { - handled_type = "GPUParticles2D"; // TTR("GPUParticles2D") + handled_type = TTRC("GPUParticles2D"); conversion_option_name = TTR("Convert to CPUParticles2D"); generate_visibility_rect = memnew(ConfirmationDialog); @@ -515,6 +529,9 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() { ERR_FAIL_COND_MSG(valid_positions.is_empty(), "No pixels with transparency > 128 in image..."); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Load Emission Mask")); + int vpc = valid_positions.size(); if (emission_colors->is_pressed()) { PackedColorArray pca; @@ -528,20 +545,24 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() { color.a = valid_colors[i * 4 + 3] / 255.0f; pcaw[i] = color; } - particles->set_emission_colors(pca); + undo_redo->add_do_property(particles, "emission_colors", pca); + undo_redo->add_undo_property(particles, "emission_colors", particles->get_emission_colors()); } if (valid_normals.size()) { - particles->set_emission_shape(CPUParticles2D::EMISSION_SHAPE_DIRECTED_POINTS); + undo_redo->add_do_property(particles, "emission_shape", CPUParticles2D::EMISSION_SHAPE_DIRECTED_POINTS); + undo_redo->add_undo_property(particles, "emission_shape", particles->get_emission_shape()); PackedVector2Array norms; norms.resize(valid_normals.size()); Vector2 *normsw = norms.ptrw(); for (int i = 0; i < valid_normals.size(); i += 1) { normsw[i] = valid_normals[i]; } - particles->set_emission_normals(norms); + undo_redo->add_do_property(particles, "emission_normals", norms); + undo_redo->add_undo_property(particles, "emission_normals", particles->get_emission_normals()); } else { - particles->set_emission_shape(CPUParticles2D::EMISSION_SHAPE_POINTS); + undo_redo->add_do_property(particles, "emission_shape", CPUParticles2D::EMISSION_SHAPE_POINTS); + undo_redo->add_undo_property(particles, "emission_shape", particles->get_emission_shape()); } { @@ -556,12 +577,14 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() { for (int i = 0; i < valid_positions.size(); i += 1) { pointsw[i] = valid_positions[i] + offset; } - particles->set_emission_points(points); + undo_redo->add_do_property(particles, "emission_points", points); + undo_redo->add_undo_property(particles, "emission_shape", particles->get_emission_points()); } + undo_redo->commit_action(); } CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin() { - handled_type = "CPUParticles2D"; // TTR("CPUParticles2D") + handled_type = TTRC("CPUParticles2D"); conversion_option_name = TTR("Convert to GPUParticles2D"); } @@ -895,10 +918,13 @@ void GPUParticles3DEditorPlugin::_generate_emission_points() { Ref mat = particles->get_process_material(); ERR_FAIL_COND(mat.is_null()); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Create Emission Points")); + ParticleProcessMaterial *matptr = mat.ptr(); + if (normals.size() > 0) { - mat->set_emission_shape(ParticleProcessMaterial::EMISSION_SHAPE_DIRECTED_POINTS); - mat->set_emission_point_count(point_count); - mat->set_emission_point_texture(tex); + undo_redo->add_do_property(matptr, "emission_shape", ParticleProcessMaterial::EMISSION_SHAPE_DIRECTED_POINTS); + undo_redo->add_undo_property(matptr, "emission_shape", matptr->get_emission_shape()); Vector point_img2; point_img2.resize(w * h * 3 * sizeof(float)); @@ -916,16 +942,21 @@ void GPUParticles3DEditorPlugin::_generate_emission_points() { } Ref image2 = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img2)); - mat->set_emission_normal_texture(ImageTexture::create_from_image(image2)); + undo_redo->add_do_property(matptr, "emission_normal_texture", image2); + undo_redo->add_undo_property(matptr, "emission_normal_texture", matptr->get_emission_normal_texture()); } else { - mat->set_emission_shape(ParticleProcessMaterial::EMISSION_SHAPE_POINTS); - mat->set_emission_point_count(point_count); - mat->set_emission_point_texture(tex); + undo_redo->add_do_property(matptr, "emission_shape", ParticleProcessMaterial::EMISSION_SHAPE_POINTS); + undo_redo->add_undo_property(matptr, "emission_shape", matptr->get_emission_shape()); } + undo_redo->add_do_property(matptr, "emission_point_count", point_count); + undo_redo->add_undo_property(matptr, "emission_point_count", matptr->get_emission_point_count()); + undo_redo->add_do_property(matptr, "emission_point_texture", tex); + undo_redo->add_undo_property(matptr, "emission_point_texture", matptr->get_emission_point_texture()); + undo_redo->commit_action(); } GPUParticles3DEditorPlugin::GPUParticles3DEditorPlugin() { - handled_type = "GPUParticles3D"; // TTR("GPUParticles3D") + handled_type = TTRC("GPUParticles3D"); conversion_option_name = TTR("Convert to CPUParticles3D"); } @@ -952,17 +983,24 @@ void CPUParticles3DEditorPlugin::_generate_emission_points() { return; } + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Create Emission Points")); + if (normals.is_empty()) { - particles->set_emission_shape(CPUParticles3D::EMISSION_SHAPE_POINTS); - particles->set_emission_points(points); + undo_redo->add_do_property(particles, "emission_shape", ParticleProcessMaterial::EMISSION_SHAPE_POINTS); + undo_redo->add_undo_property(particles, "emission_shape", particles->get_emission_shape()); } else { - particles->set_emission_shape(CPUParticles3D::EMISSION_SHAPE_DIRECTED_POINTS); - particles->set_emission_points(points); - particles->set_emission_normals(normals); + undo_redo->add_do_property(particles, "emission_shape", ParticleProcessMaterial::EMISSION_SHAPE_DIRECTED_POINTS); + undo_redo->add_undo_property(particles, "emission_shape", particles->get_emission_shape()); + undo_redo->add_do_property(particles, "emission_normals", normals); + undo_redo->add_undo_property(particles, "emission_normals", particles->get_emission_normals()); } + undo_redo->add_do_property(particles, "emission_points", points); + undo_redo->add_undo_property(particles, "emission_points", particles->get_emission_points()); + undo_redo->commit_action(); } CPUParticles3DEditorPlugin::CPUParticles3DEditorPlugin() { - handled_type = "CPUParticles3D"; // TTR("CPUParticles3D") + handled_type = TTRC("CPUParticles3D"); conversion_option_name = TTR("Convert to GPUParticles3D"); }