diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/editor_node.cpp | 2 | ||||
-rw-r--r-- | editor/icons/icon_c_p_u_particles.svg | 60 | ||||
-rw-r--r-- | editor/plugins/cpu_particles_editor_plugin.cpp | 114 | ||||
-rw-r--r-- | editor/plugins/cpu_particles_editor_plugin.h | 55 | ||||
-rw-r--r-- | editor/plugins/particles_editor_plugin.cpp | 410 | ||||
-rw-r--r-- | editor/plugins/particles_editor_plugin.h | 34 |
6 files changed, 480 insertions, 195 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 2ac0364778..8d039f8cc0 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -79,6 +79,7 @@ #include "editor/plugins/collision_polygon_2d_editor_plugin.h" #include "editor/plugins/collision_polygon_editor_plugin.h" #include "editor/plugins/collision_shape_2d_editor_plugin.h" +#include "editor/plugins/cpu_particles_editor_plugin.h" #include "editor/plugins/cube_grid_theme_editor_plugin.h" #include "editor/plugins/curve_editor_plugin.h" #include "editor/plugins/editor_preview_plugins.h" @@ -5383,6 +5384,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(SpriteEditorPlugin(this))); add_editor_plugin(memnew(Skeleton2DEditorPlugin(this))); add_editor_plugin(memnew(ParticlesEditorPlugin(this))); + add_editor_plugin(memnew(CPUParticlesEditorPlugin(this))); add_editor_plugin(memnew(ResourcePreloaderEditorPlugin(this))); add_editor_plugin(memnew(ItemListEditorPlugin(this))); add_editor_plugin(memnew(Polygon3DEditorPlugin(this))); diff --git a/editor/icons/icon_c_p_u_particles.svg b/editor/icons/icon_c_p_u_particles.svg new file mode 100644 index 0000000000..00d79cafd2 --- /dev/null +++ b/editor/icons/icon_c_p_u_particles.svg @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg6" + sodipodi:docname="icon_c_p_u_particles.svg" + inkscape:version="0.92.3 (2405546, 2018-03-11)"> + <metadata + id="metadata12"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs10" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1741" + inkscape:window-height="753" + id="namedview8" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="8.1355932" + inkscape:cy="7.7288136" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg6" /> + <path + style="fill:#fc9c9c;fill-opacity:0.99607843" + d="m 4.5587261,0.60940813 c -0.4226244,0 -0.7617187,0.3410473 -0.7617187,0.76367177 v 0.5078126 c 0,0.1028478 0.020058,0.199689 0.056641,0.2890624 H 2.6602887 c -0.4226245,0 -0.7617188,0.3390944 -0.7617188,0.7617188 v 0.921875 C 1.8581419,3.8469787 1.821771,3.8301112 1.7794293,3.8301112 H 1.2716168 c -0.42262448,0 -0.76367188,0.3410475 -0.76367188,0.7636719 v 0.3730468 c 0,0.4226245 0.3410474,0.7617188 0.76367188,0.7617188 h 0.5078125 c 0.042396,0 0.078663,-0.016851 0.1191406,-0.023437 v 4.4531248 c -0.040428,-0.0066 -0.076799,-0.02344 -0.1191406,-0.02344 H 1.2716168 c -0.42262448,0 -0.76367188,0.341047 -0.76367188,0.763672 v 0.373047 c 0,0.422625 0.3410474,0.761718 0.76367188,0.761718 h 0.5078125 c 0.042396,0 0.078663,-0.01685 0.1191406,-0.02344 v 1.125 c 0,0.422624 0.3390944,0.763672 0.7617188,0.763672 h 1.1367187 v 0.457031 c 0,0.422624 0.3390943,0.763672 0.7617187,0.763672 H 4.931773 c 0.4226244,0 0.7636719,-0.341048 0.7636719,-0.763672 v -0.457031 h 4.4062501 v 0.457031 c 0,0.422624 0.339094,0.763672 0.761719,0.763672 h 0.373047 c 0.422624,0 0.763671,-0.341048 0.763671,-0.763672 v -0.457031 h 1.269532 c 0.422625,0 0.763672,-0.341048 0.763672,-0.763672 v -1.111328 c 0.01774,0.0012 0.03272,0.0098 0.05078,0.0098 h 0.507812 c 0.422624,0 0.763672,-0.339093 0.763672,-0.761718 v -0.373047 c 0,-0.422624 -0.341048,-0.763672 -0.763672,-0.763672 h -0.507812 c -0.01803,0 -0.03307,0.0085 -0.05078,0.0098 V 5.7187831 c 0.01774,0.00122 0.03272,0.00977 0.05078,0.00977 h 0.507812 c 0.422624,0 0.763672,-0.3390943 0.763672,-0.7617188 V 4.5937831 c 0,-0.4226244 -0.341048,-0.7636719 -0.763672,-0.7636719 h -0.507812 c -0.01803,0 -0.03307,0.00855 -0.05078,0.00977 V 2.9316737 c 0,-0.4226244 -0.341047,-0.7617187 -0.763672,-0.7617188 h -1.328125 c 0.03658,-0.089375 0.05859,-0.1862118 0.05859,-0.2890624 V 1.3730799 c 0,-0.42262437 -0.341047,-0.76367177 -0.763671,-0.76367177 h -0.373047 c -0.422625,0 -0.761719,0.3410474 -0.761719,0.76367177 v 0.5078126 c 0,0.1028478 0.02006,0.1996891 0.05664,0.2890624 H 5.6368511 C 5.6734361,2.08058 5.6954449,1.9837431 5.6954449,1.8808925 V 1.3730799 c 0,-0.42262437 -0.3410475,-0.76367177 -0.7636719,-0.76367177 z M 7.7970074,2.9668299 A 3.279661,3.6440678 0 0 1 11.009898,5.9062831 2.1864407,2.1864407 0 0 1 12.89857,8.0683925 2.1864407,2.1864407 0 0 1 10.71107,10.25394 H 4.8809918 A 2.1864407,2.1864407 0 0 1 2.6954449,8.0683925 2.1864407,2.1864407 0 0 1 4.5802105,5.9043299 3.279661,3.6440678 0 0 1 7.7970074,2.9668299 Z M 4.8809918,10.982455 A 0.72881355,0.72881355 0 0 1 5.6095074,11.710971 0.72881355,0.72881355 0 0 1 4.8809918,12.44144 0.72881355,0.72881355 0 0 1 4.1524761,11.710971 0.72881355,0.72881355 0 0 1 4.8809918,10.982455 Z m 5.8300782,0 A 0.72881355,0.72881355 0 0 1 11.441539,11.710971 0.72881355,0.72881355 0 0 1 10.71107,12.44144 0.72881355,0.72881355 0 0 1 9.9825543,11.710971 0.72881355,0.72881355 0 0 1 10.71107,10.982455 Z M 7.7970074,11.710971 A 0.72881355,0.72881355 0 0 1 8.525523,12.44144 0.72881355,0.72881355 0 0 1 7.7970074,13.169955 0.72881355,0.72881355 0 0 1 7.0684918,12.44144 0.72881355,0.72881355 0 0 1 7.7970074,11.710971 Z" + id="rect822" + inkscape:connector-curvature="0" /> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="Layer 1" /> +</svg> diff --git a/editor/plugins/cpu_particles_editor_plugin.cpp b/editor/plugins/cpu_particles_editor_plugin.cpp new file mode 100644 index 0000000000..b32f927249 --- /dev/null +++ b/editor/plugins/cpu_particles_editor_plugin.cpp @@ -0,0 +1,114 @@ +#include "cpu_particles_editor_plugin.h" +#include "editor/plugins/spatial_editor_plugin.h" + +void CPUParticlesEditor::_node_removed(Node *p_node) { + + if (p_node == node) { + node = NULL; + hide(); + } +} + +void CPUParticlesEditor::_notification(int p_notification) { + + if (p_notification == NOTIFICATION_ENTER_TREE) { + options->set_icon(options->get_popup()->get_icon("CPUParticles", "EditorIcons")); + } +} + +void CPUParticlesEditor::_menu_option(int p_option) { + + switch (p_option) { + + case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH: { + + emission_file_dialog->popup_centered_ratio(); + + } break; + + case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: { + + emission_tree_dialog->popup_centered_ratio(); + + } break; + } +} + +void CPUParticlesEditor::edit(CPUParticles *p_particles) { + + base_node = p_particles; + node = p_particles; +} + +void CPUParticlesEditor::_generate_emission_points() { + + /// hacer codigo aca + PoolVector<Vector3> points; + PoolVector<Vector3> normals; + + if (!_generate(points, normals)) { + return; + } + + if (normals.size() == 0) { + node->set_emission_shape(CPUParticles::EMISSION_SHAPE_POINTS); + node->set_emission_points(points); + } else { + node->set_emission_shape(CPUParticles::EMISSION_SHAPE_DIRECTED_POINTS); + node->set_emission_points(points); + node->set_emission_normals(normals); + } +} + +void CPUParticlesEditor::_bind_methods() { + + ClassDB::bind_method("_menu_option", &CPUParticlesEditor::_menu_option); +} + +CPUParticlesEditor::CPUParticlesEditor() { + + particles_editor_hb = memnew(HBoxContainer); + SpatialEditor::get_singleton()->add_control_to_menu_panel(particles_editor_hb); + options = memnew(MenuButton); + particles_editor_hb->add_child(options); + particles_editor_hb->hide(); + + options->set_text(TTR("CPUParticles")); + 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()->connect("id_pressed", this, "_menu_option"); +} + +void CPUParticlesEditorPlugin::edit(Object *p_object) { + + particles_editor->edit(Object::cast_to<CPUParticles>(p_object)); +} + +bool CPUParticlesEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("CPUParticles"); +} + +void CPUParticlesEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + particles_editor->show(); + particles_editor->particles_editor_hb->show(); + } else { + particles_editor->particles_editor_hb->hide(); + particles_editor->hide(); + particles_editor->edit(NULL); + } +} + +CPUParticlesEditorPlugin::CPUParticlesEditorPlugin(EditorNode *p_node) { + + editor = p_node; + particles_editor = memnew(CPUParticlesEditor); + editor->get_viewport()->add_child(particles_editor); + + particles_editor->hide(); +} + +CPUParticlesEditorPlugin::~CPUParticlesEditorPlugin() { +} diff --git a/editor/plugins/cpu_particles_editor_plugin.h b/editor/plugins/cpu_particles_editor_plugin.h new file mode 100644 index 0000000000..f47d17104d --- /dev/null +++ b/editor/plugins/cpu_particles_editor_plugin.h @@ -0,0 +1,55 @@ +#ifndef CPU_PARTICLES_EDITOR_PLUGIN_H +#define CPU_PARTICLES_EDITOR_PLUGIN_H + +#include "editor/plugins/particles_editor_plugin.h" +#include "scene/3d/cpu_particles.h" + +class CPUParticlesEditor : public ParticlesEditorBase { + + GDCLASS(CPUParticlesEditor, ParticlesEditorBase); + + enum Menu { + + MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE, + MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH, + MENU_OPTION_CLEAR_EMISSION_VOLUME, + + }; + + CPUParticles *node; + + void _menu_option(int); + + friend class CPUParticlesEditorPlugin; + + virtual void _generate_emission_points(); + +protected: + void _notification(int p_notification); + void _node_removed(Node *p_node); + static void _bind_methods(); + +public: + void edit(CPUParticles *p_particles); + CPUParticlesEditor(); +}; + +class CPUParticlesEditorPlugin : public EditorPlugin { + + GDCLASS(CPUParticlesEditorPlugin, EditorPlugin); + + CPUParticlesEditor *particles_editor; + EditorNode *editor; + +public: + virtual String get_name() const { return "CPUParticles"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_object); + virtual bool handles(Object *p_object) const; + virtual void make_visible(bool p_visible); + + CPUParticlesEditorPlugin(EditorNode *p_node); + ~CPUParticlesEditorPlugin(); +}; + +#endif // CPU_PARTICLES_EDITOR_PLUGIN_H diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp index 7728995a99..e0325702a8 100644 --- a/editor/plugins/particles_editor_plugin.cpp +++ b/editor/plugins/particles_editor_plugin.cpp @@ -31,130 +31,10 @@ #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<Vector3> &points, PoolVector<Vector3> &normals) { -void ParticlesEditor::_node_removed(Node *p_node) { - - if (p_node == node) { - node = NULL; - hide(); - } -} - -void ParticlesEditor::_node_selected(const NodePath &p_path) { - - Node *sel = get_node(p_path); - if (!sel) - return; - - VisualInstance *vi = Object::cast_to<VisualInstance>(sel); - if (!vi) { - - err_dialog->set_text(TTR("Node does not contain geometry.")); - err_dialog->popup_centered_minsize(); - return; - } - - geometry = vi->get_faces(VisualInstance::FACES_SOLID); - - if (geometry.size() == 0) { - - err_dialog->set_text(TTR("Node does not contain geometry (faces).")); - err_dialog->popup_centered_minsize(); - return; - } - - Transform geom_xform = node->get_global_transform().affine_inverse() * vi->get_global_transform(); - - int gc = geometry.size(); - PoolVector<Face3>::Write w = geometry.write(); - - for (int i = 0; i < gc; i++) { - for (int j = 0; j < 3; j++) { - w[i].vertex[j] = geom_xform.xform(w[i].vertex[j]); - } - } - - w = PoolVector<Face3>::Write(); - - emission_dialog->popup_centered(Size2(300, 130)); -} - -void ParticlesEditor::_notification(int p_notification) { - - if (p_notification == NOTIFICATION_ENTER_TREE) { - options->set_icon(options->get_popup()->get_icon("Particles", "EditorIcons")); - } -} - -void ParticlesEditor::_menu_option(int p_option) { - - switch (p_option) { - - case MENU_OPTION_GENERATE_AABB: { - generate_aabb->popup_centered_minsize(); - } break; - case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH: { - - Ref<ParticlesMaterial> material = node->get_process_material(); - if (material.is_null()) { - EditorNode::get_singleton()->show_warning(TTR("A processor material of type 'ParticlesMaterial' is required.")); - return; - } - emission_file_dialog->popup_centered_ratio(); - - } break; - - case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: { - Ref<ParticlesMaterial> material = node->get_process_material(); - if (material.is_null()) { - EditorNode::get_singleton()->show_warning(TTR("A processor material of type 'ParticlesMaterial' is required.")); - return; - } - - emission_tree_dialog->popup_centered_ratio(); - - } break; - } -} - -void ParticlesEditor::_generate_aabb() { - - float time = generate_seconds->get_value(); - - float running = 0.0; - - EditorProgress ep("gen_aabb", TTR("Generating AABB"), int(time)); - - AABB rect; - while (running < time) { - - uint64_t ticks = OS::get_singleton()->get_ticks_usec(); - ep.step("Generating...", int(running), true); - OS::get_singleton()->delay_usec(1000); - - AABB capture = node->capture_aabb(); - if (rect == AABB()) - rect = capture; - else - rect.merge_with(capture); - - running += (OS::get_singleton()->get_ticks_usec() - ticks) / 1000000.0; - } - - node->set_visibility_aabb(rect); -} - -void ParticlesEditor::edit(Particles *p_particles) { - - node = p_particles; -} - -void ParticlesEditor::_generate_emission_points() { - - /// hacer codigo aca - PoolVector<float> points; bool use_normals = emission_fill->get_selected() == 1; - PoolVector<float> normals; if (emission_fill->get_selected() < 2) { @@ -175,7 +55,7 @@ void ParticlesEditor::_generate_emission_points() { err_dialog->set_text(TTR("Faces contain no area!")); err_dialog->popup_centered_minsize(); - return; + return false; } int emissor_count = emission_amount->get_value(); @@ -185,9 +65,9 @@ void ParticlesEditor::_generate_emission_points() { float areapos = Math::random(0.0f, area_accum); Map<float, int>::Element *E = triangle_area_map.find_closest(areapos); - ERR_FAIL_COND(!E) + ERR_FAIL_COND_V(!E, false) int index = E->get(); - ERR_FAIL_INDEX(index, geometry.size()); + ERR_FAIL_INDEX_V(index, geometry.size(), false); // ok FINALLY get face Face3 face = geometry[index]; @@ -195,15 +75,11 @@ void ParticlesEditor::_generate_emission_points() { Vector3 pos = face.get_random_point_inside(); - points.push_back(pos.x); - points.push_back(pos.y); - points.push_back(pos.z); + points.push_back(pos); if (use_normals) { Vector3 normal = face.get_plane().normal; - normals.push_back(normal.x); - normals.push_back(normal.y); - normals.push_back(normal.z); + normals.push_back(normal); } } } else { @@ -214,7 +90,7 @@ void ParticlesEditor::_generate_emission_points() { err_dialog->set_text(TTR("No faces!")); err_dialog->popup_centered_minsize(); - return; + return false; } PoolVector<Face3>::Read r = geometry.read(); @@ -276,15 +152,210 @@ void ParticlesEditor::_generate_emission_points() { Vector3 point = ofs + dir * val; - points.push_back(point.x); - points.push_back(point.y); - points.push_back(point.z); + points.push_back(point); break; } } } - int point_count = points.size() / 3; + return true; +} + +void ParticlesEditorBase::_node_selected(const NodePath &p_path) { + + Node *sel = get_node(p_path); + if (!sel) + return; + + VisualInstance *vi = Object::cast_to<VisualInstance>(sel); + if (!vi) { + + err_dialog->set_text(TTR("Node does not contain geometry.")); + err_dialog->popup_centered_minsize(); + return; + } + + geometry = vi->get_faces(VisualInstance::FACES_SOLID); + + if (geometry.size() == 0) { + + err_dialog->set_text(TTR("Node does not contain geometry (faces).")); + err_dialog->popup_centered_minsize(); + return; + } + + Transform geom_xform = base_node->get_global_transform().affine_inverse() * vi->get_global_transform(); + + int gc = geometry.size(); + PoolVector<Face3>::Write w = geometry.write(); + + for (int i = 0; i < gc; i++) { + for (int j = 0; j < 3; j++) { + w[i].vertex[j] = geom_xform.xform(w[i].vertex[j]); + } + } + + w = PoolVector<Face3>::Write(); + + emission_dialog->popup_centered(Size2(300, 130)); +} + +void ParticlesEditorBase::_bind_methods() { + + ClassDB::bind_method("_node_selected", &ParticlesEditorBase::_node_selected); + ClassDB::bind_method("_generate_emission_points", &ParticlesEditorBase::_generate_emission_points); +} + +ParticlesEditorBase::ParticlesEditorBase() { + + emission_dialog = memnew(ConfirmationDialog); + emission_dialog->set_title(TTR("Create Emitter")); + add_child(emission_dialog); + VBoxContainer *emd_vb = memnew(VBoxContainer); + emission_dialog->add_child(emd_vb); + + emission_amount = memnew(SpinBox); + emission_amount->set_min(1); + emission_amount->set_max(100000); + emission_amount->set_value(512); + emd_vb->add_margin_child(TTR("Emission Points:"), emission_amount); + + emission_fill = memnew(OptionButton); + emission_fill->add_item(TTR("Surface Points")); + emission_fill->add_item(TTR("Surface Points+Normal (Directed)")); + emission_fill->add_item(TTR("Volume")); + emd_vb->add_margin_child(TTR("Emission Source: "), emission_fill); + + emission_dialog->get_ok()->set_text(TTR("Create")); + emission_dialog->connect("confirmed", this, "_generate_emission_points"); + + err_dialog = memnew(ConfirmationDialog); + add_child(err_dialog); + + emission_file_dialog = memnew(EditorFileDialog); + add_child(emission_file_dialog); + emission_file_dialog->connect("file_selected", this, "_resource_seleted"); + emission_tree_dialog = memnew(SceneTreeDialog); + add_child(emission_tree_dialog); + emission_tree_dialog->connect("selected", this, "_node_selected"); + + List<String> extensions; + ResourceLoader::get_recognized_extensions_for_type("Mesh", &extensions); + + emission_file_dialog->clear_filters(); + for (int i = 0; i < extensions.size(); i++) { + + emission_file_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); + } + + emission_file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); +} + +void ParticlesEditor::_node_removed(Node *p_node) { + + if (p_node == node) { + node = NULL; + hide(); + } +} + +void ParticlesEditor::_notification(int p_notification) { + + if (p_notification == NOTIFICATION_ENTER_TREE) { + options->set_icon(options->get_popup()->get_icon("Particles", "EditorIcons")); + } +} + +void ParticlesEditor::_menu_option(int p_option) { + + switch (p_option) { + + case MENU_OPTION_GENERATE_AABB: { + generate_aabb->popup_centered_minsize(); + } break; + case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH: { + + Ref<ParticlesMaterial> material = node->get_process_material(); + if (material.is_null()) { + EditorNode::get_singleton()->show_warning(TTR("A processor material of type 'ParticlesMaterial' is required.")); + return; + } + emission_file_dialog->popup_centered_ratio(); + + } break; + + case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: { + Ref<ParticlesMaterial> material = node->get_process_material(); + if (material.is_null()) { + EditorNode::get_singleton()->show_warning(TTR("A processor material of type 'ParticlesMaterial' is required.")); + return; + } + + 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; + } +} + +void ParticlesEditor::_generate_aabb() { + + float time = generate_seconds->get_value(); + + float running = 0.0; + + EditorProgress ep("gen_aabb", TTR("Generating AABB"), int(time)); + + AABB rect; + while (running < time) { + + uint64_t ticks = OS::get_singleton()->get_ticks_usec(); + ep.step("Generating...", int(running), true); + OS::get_singleton()->delay_usec(1000); + + AABB capture = node->capture_aabb(); + if (rect == AABB()) + rect = capture; + else + rect.merge_with(capture); + + running += (OS::get_singleton()->get_ticks_usec() - ticks) / 1000000.0; + } + + node->set_visibility_aabb(rect); +} + +void ParticlesEditor::edit(Particles *p_particles) { + + base_node = p_particles; + node = p_particles; +} + +void ParticlesEditor::_generate_emission_points() { + + /// hacer codigo aca + PoolVector<Vector3> points; + PoolVector<Vector3> normals; + + if (!_generate(points, normals)) { + return; + } + + int point_count = points.size(); int w = 2048; int h = (point_count / 2048) + 1; @@ -295,8 +366,13 @@ void ParticlesEditor::_generate_emission_points() { { PoolVector<uint8_t>::Write iw = point_img.write(); zeromem(iw.ptr(), w * h * 3 * sizeof(float)); - PoolVector<float>::Read r = points.read(); - copymem(iw.ptr(), r.ptr(), point_count * sizeof(float) * 3); + PoolVector<Vector3>::Read r = points.read(); + float *wf = (float *)iw.ptr(); + for (int i = 0; i < point_count; i++) { + wf[i * 3 + 0] = r[i].x; + wf[i * 3 + 1] = r[i].y; + wf[i * 3 + 2] = r[i].z; + } } Ref<Image> image = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img)); @@ -308,7 +384,7 @@ void ParticlesEditor::_generate_emission_points() { Ref<ParticlesMaterial> material = node->get_process_material(); ERR_FAIL_COND(material.is_null()); - if (use_normals) { + if (normals.size() > 0) { material->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_DIRECTED_POINTS); material->set_emission_point_count(point_count); @@ -320,8 +396,13 @@ void ParticlesEditor::_generate_emission_points() { { PoolVector<uint8_t>::Write iw = point_img2.write(); zeromem(iw.ptr(), w * h * 3 * sizeof(float)); - PoolVector<float>::Read r = normals.read(); - copymem(iw.ptr(), r.ptr(), point_count * sizeof(float) * 3); + PoolVector<Vector3>::Read r = normals.read(); + float *wf = (float *)iw.ptr(); + for (int i = 0; i < point_count; i++) { + wf[i * 3 + 0] = r[i].x; + wf[i * 3 + 1] = r[i].y; + wf[i * 3 + 2] = r[i].z; + } } Ref<Image> image2 = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img2)); @@ -342,8 +423,6 @@ void ParticlesEditor::_generate_emission_points() { void ParticlesEditor::_bind_methods() { ClassDB::bind_method("_menu_option", &ParticlesEditor::_menu_option); - ClassDB::bind_method("_node_selected", &ParticlesEditor::_node_selected); - ClassDB::bind_method("_generate_emission_points", &ParticlesEditor::_generate_emission_points); ClassDB::bind_method("_generate_aabb", &ParticlesEditor::_generate_aabb); } @@ -360,49 +439,10 @@ 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()->connect("id_pressed", this, "_menu_option"); - - emission_dialog = memnew(ConfirmationDialog); - emission_dialog->set_title(TTR("Create Emitter")); - add_child(emission_dialog); - VBoxContainer *emd_vb = memnew(VBoxContainer); - emission_dialog->add_child(emd_vb); - - emission_amount = memnew(SpinBox); - emission_amount->set_min(1); - emission_amount->set_max(100000); - emission_amount->set_value(512); - emd_vb->add_margin_child(TTR("Emission Points:"), emission_amount); - - emission_fill = memnew(OptionButton); - emission_fill->add_item(TTR("Surface Points")); - emission_fill->add_item(TTR("Surface Points+Normal (Directed)")); - emission_fill->add_item(TTR("Volume")); - emd_vb->add_margin_child(TTR("Emission Source: "), emission_fill); - - emission_dialog->get_ok()->set_text(TTR("Create")); - emission_dialog->connect("confirmed", this, "_generate_emission_points"); - - err_dialog = memnew(ConfirmationDialog); - add_child(err_dialog); - - emission_file_dialog = memnew(EditorFileDialog); - add_child(emission_file_dialog); - emission_file_dialog->connect("file_selected", this, "_resource_seleted"); - emission_tree_dialog = memnew(SceneTreeDialog); - add_child(emission_tree_dialog); - emission_tree_dialog->connect("selected", this, "_node_selected"); - - List<String> extensions; - ResourceLoader::get_recognized_extensions_for_type("Mesh", &extensions); - - emission_file_dialog->clear_filters(); - for (int i = 0; i < extensions.size(); i++) { - - emission_file_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); - } + options->get_popup()->add_separator(); + options->get_popup()->add_item(TTR("Convert to CPUParticles"), MENU_OPTION_CONVERT_TO_CPU_PARTICLES); - emission_file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); + options->get_popup()->connect("id_pressed", this, "_menu_option"); generate_aabb = memnew(ConfirmationDialog); generate_aabb->set_title(TTR("Generate Visibility AABB")); diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h index 013b6e7e30..622ce6e8a9 100644 --- a/editor/plugins/particles_editor_plugin.h +++ b/editor/plugins/particles_editor_plugin.h @@ -40,14 +40,14 @@ @author Juan Linietsky <reduzio@gmail.com> */ -class ParticlesEditor : public Control { - - GDCLASS(ParticlesEditor, Control); +class ParticlesEditorBase : public Control { + GDCLASS(ParticlesEditorBase, Control) +protected: + Spatial *base_node; Panel *panel; MenuButton *options; HBoxContainer *particles_editor_hb; - Particles *node; EditorFileDialog *emission_file_dialog; SceneTreeDialog *emission_tree_dialog; @@ -58,8 +58,25 @@ class ParticlesEditor : public Control { SpinBox *emission_amount; OptionButton *emission_fill; + PoolVector<Face3> geometry; + + bool _generate(PoolVector<Vector3> &points, PoolVector<Vector3> &normals); + virtual void _generate_emission_points() = 0; + void _node_selected(const NodePath &p_path); + + static void _bind_methods(); + +public: + ParticlesEditorBase(); +}; + +class ParticlesEditor : public ParticlesEditorBase { + + GDCLASS(ParticlesEditor, ParticlesEditorBase); + ConfirmationDialog *generate_aabb; SpinBox *generate_seconds; + Particles *node; enum Menu { @@ -67,21 +84,18 @@ class ParticlesEditor : public Control { 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, }; - PoolVector<Face3> geometry; - void _generate_aabb(); - void _generate_emission_points(); - void _node_selected(const NodePath &p_path); void _menu_option(int); - void _populate(); - friend class ParticlesEditorPlugin; + virtual void _generate_emission_points(); + protected: void _notification(int p_notification); void _node_removed(Node *p_node); |