diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp index 91b307293ba..e0325702a8d 100644 --- a/editor/plugins/particles_editor_plugin.cpp +++ b/editor/plugins/particles_editor_plugin.cpp @@ -31,7 +31,7 @@ #include "particles_editor_plugin.h" #include "editor/plugins/spatial_editor_plugin.h" #include "io/resource_loader.h" - +#include "scene/3d/cpu_particles.h" bool ParticlesEditorBase::_generate(PoolVector &points, PoolVector &normals) { bool use_normals = emission_fill->get_selected() == 1; @@ -294,6 +294,21 @@ void ParticlesEditor::_menu_option(int p_option) { emission_tree_dialog->popup_centered_ratio(); } break; + case MENU_OPTION_CONVERT_TO_CPU_PARTICLES: { + + UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + CPUParticles *cpu_particles = memnew(CPUParticles); + cpu_particles->convert_from_particles(node); + + undo_redo->create_action("Replace Particles by CPUParticles"); + undo_redo->add_do_method(node, "replace_by", cpu_particles); + undo_redo->add_undo_method(cpu_particles, "replace_by", node); + undo_redo->add_do_reference(cpu_particles); + undo_redo->add_undo_reference(node); + undo_redo->commit_action(); + + } break; } } @@ -424,6 +439,9 @@ ParticlesEditor::ParticlesEditor() { options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Emission Points From Mesh"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH); options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE); + options->get_popup()->add_separator(); + options->get_popup()->add_item(TTR("Convert to CPUParticles"), MENU_OPTION_CONVERT_TO_CPU_PARTICLES); + options->get_popup()->connect("id_pressed", this, "_menu_option"); generate_aabb = memnew(ConfirmationDialog); diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h index d1fef1fbc17..622ce6e8a94 100644 --- a/editor/plugins/particles_editor_plugin.h +++ b/editor/plugins/particles_editor_plugin.h @@ -84,6 +84,7 @@ class ParticlesEditor : public ParticlesEditorBase { MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE, MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH, MENU_OPTION_CLEAR_EMISSION_VOLUME, + MENU_OPTION_CONVERT_TO_CPU_PARTICLES, }; diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index fa20ed0d4cf..2e897c1c73b 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -1,5 +1,6 @@ #include "cpu_particles.h" +#include "particles.h" #include "scene/3d/camera.h" #include "scene/main/viewport.h" #include "scene/resources/surface_tool.h" @@ -1072,6 +1073,74 @@ void CPUParticles::_notification(int p_what) { } } +void CPUParticles::convert_from_particles(Node *p_particles) { + + Particles *particles = Object::cast_to(p_particles); + ERR_FAIL_COND(!particles); + + set_emitting(particles->is_emitting()); + set_amount(particles->get_amount()); + set_lifetime(particles->get_lifetime()); + set_one_shot(particles->get_one_shot()); + set_pre_process_time(particles->get_pre_process_time()); + set_explosiveness_ratio(particles->get_explosiveness_ratio()); + set_randomness_ratio(particles->get_randomness_ratio()); + set_use_local_coordinates(particles->get_use_local_coordinates()); + set_fixed_fps(particles->get_fixed_fps()); + set_fractional_delta(particles->get_fractional_delta()); + set_speed_scale(particles->get_speed_scale()); + set_draw_order(DrawOrder(particles->get_draw_order())); + set_mesh(particles->get_draw_pass_mesh(0)); + + Ref material = particles->get_process_material(); + if (material.is_null()) + return; + + set_spread(material->get_spread()); + set_flatness(material->get_flatness()); + + set_color(material->get_color()); + + Ref gt = material->get_color_ramp(); + if (gt.is_valid()) { + set_color_ramp(gt->get_gradient()); + } + + set_particle_flag(FLAG_ALIGN_Y_TO_VELOCITY, material->get_flag(ParticlesMaterial::FLAG_ALIGN_Y_TO_VELOCITY)); + set_particle_flag(FLAG_ROTATE_Y, material->get_flag(ParticlesMaterial::FLAG_ROTATE_Y)); + set_particle_flag(FLAG_DISABLE_Z, material->get_flag(ParticlesMaterial::FLAG_DISABLE_Z)); + set_particle_flag(FLAG_ANIM_LOOP, material->get_flag(ParticlesMaterial::FLAG_ANIM_LOOP)); + + set_emission_shape(EmissionShape(material->get_emission_shape())); + set_emission_sphere_radius(material->get_emission_sphere_radius()); + set_emission_box_extents(material->get_emission_box_extents()); + + set_gravity(material->get_gravity()); + +#define CONVERT_PARAM(m_param) \ + set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \ + { \ + Ref ctex = material->get_param_texture(ParticlesMaterial::m_param); \ + if (ctex.is_valid()) set_param_curve(m_param, ctex->get_curve()); \ + } \ + set_param_randomness(m_param, material->get_param_randomness(ParticlesMaterial::m_param)); + + CONVERT_PARAM(PARAM_INITIAL_LINEAR_VELOCITY); + CONVERT_PARAM(PARAM_ANGULAR_VELOCITY); + // CONVERT_PARAM(PARAM_ORBIT_VELOCITY); + CONVERT_PARAM(PARAM_LINEAR_ACCEL); + CONVERT_PARAM(PARAM_RADIAL_ACCEL); + CONVERT_PARAM(PARAM_TANGENTIAL_ACCEL); + CONVERT_PARAM(PARAM_DAMPING); + CONVERT_PARAM(PARAM_ANGLE); + CONVERT_PARAM(PARAM_SCALE); + CONVERT_PARAM(PARAM_HUE_VARIATION); + CONVERT_PARAM(PARAM_ANIM_SPEED); + CONVERT_PARAM(PARAM_ANIM_OFFSET); + +#undef CONVERT_PARAM +} + void CPUParticles::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &CPUParticles::set_emitting); @@ -1174,6 +1243,8 @@ void CPUParticles::_bind_methods() { ClassDB::bind_method(D_METHOD("get_gravity"), &CPUParticles::get_gravity); ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &CPUParticles::set_gravity); + ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles::convert_from_particles); + ClassDB::bind_method(D_METHOD("_update_render_thread"), &CPUParticles::_update_render_thread); ADD_GROUP("Emission Shape", "emission_"); diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h index 2ed75058637..1ee709719d1 100644 --- a/scene/3d/cpu_particles.h +++ b/scene/3d/cpu_particles.h @@ -244,6 +244,8 @@ public: void restart(); + void convert_from_particles(Node *p_particles); + CPUParticles(); ~CPUParticles(); };