فهرست منبع

Merge pull request #100571 from KoBeWi/emission_mission

Add UndoRedo support to Load Emission Mask/Points
Thaddeus Crews 9 ماه پیش
والد
کامیت
8fb7a1f357
1فایلهای تغییر یافته به همراه69 افزوده شده و 31 حذف شده
  1. 69 31
      editor/plugins/particles_editor_plugin.cpp

+ 69 - 31
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<GPUParticles2D>(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<GPUParticles2D>(edited_node);
 	Ref<ParticleProcessMaterial> 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<uint8_t> texdata;
 
 	int vpc = valid_positions.size();
@@ -428,8 +435,10 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
 	Ref<Image> 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<uint8_t> 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<uint8_t> 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<ParticleProcessMaterial> 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<uint8_t> point_img2;
 		point_img2.resize(w * h * 3 * sizeof(float));
@@ -916,16 +942,21 @@ void GPUParticles3DEditorPlugin::_generate_emission_points() {
 		}
 
 		Ref<Image> 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");
 }