Skip to content

Commit

Permalink
Renamed Particle to GPUParticle and Particle2D to GPUParticle2D pt4.
Browse files Browse the repository at this point in the history
  • Loading branch information
Relintai committed Jul 16, 2024
1 parent a97a334 commit 85cddb0
Show file tree
Hide file tree
Showing 17 changed files with 705 additions and 5 deletions.
4 changes: 4 additions & 0 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@
#include "editor/plugins/navigation_obstacle_2d_editor_plugin.h"
#include "editor/plugins/navigation_obstacle_3d_editor_plugin.h"
#include "editor/plugins/packed_scene_editor_plugin.h"
#include "editor/plugins/gpu_particles_2d_editor_plugin.h"
#include "editor/plugins/particles_editor_plugin.h"
#include "editor/plugins/path_2d_editor_plugin.h"
#include "editor/plugins/path_editor_plugin.h"
#include "editor/plugins/polygon_2d_editor_plugin.h"
Expand Down Expand Up @@ -7164,6 +7166,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(AnimationTreeEditorPlugin(this)));
add_editor_plugin(memnew(StyleBoxEditorPlugin(this)));
add_editor_plugin(memnew(SpriteEditorPlugin(this)));
add_editor_plugin(memnew(GPUParticlesEditorPlugin(this)));
add_editor_plugin(memnew(CPUParticles2DEditorPlugin(this)));
add_editor_plugin(memnew(CPUParticlesEditorPlugin(this)));
add_editor_plugin(memnew(ResourcePreloaderEditorPlugin(this)));
Expand All @@ -7173,6 +7176,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(SpriteFramesEditorPlugin(this)));
add_editor_plugin(memnew(TextureRegionEditorPlugin(this)));
add_editor_plugin(memnew(BakedLightmapEditorPlugin(this)));
add_editor_plugin(memnew(GPUParticles2DEditorPlugin(this)));
add_editor_plugin(memnew(RoomManagerEditorPlugin(this)));
add_editor_plugin(memnew(RoomEditorPlugin(this)));
add_editor_plugin(memnew(OccluderEditorPlugin(this)));
Expand Down
File renamed without changes
File renamed without changes
3 changes: 3 additions & 0 deletions editor/plugins/canvas_item_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "editor/scene_tree_dock.h"
#include "editor/script_editor_debugger.h"
#include "scene/2d/light_2d.h"
#include "scene/2d/gpu_particles_2d.h"
#include "scene/2d/polygon_2d.h"
#include "scene/main/node_2d.h"

Expand Down Expand Up @@ -6141,6 +6142,8 @@ void CanvasItemEditorViewport::_perform_drop_data() {
Node *child;
if (default_type == "Light2D") {
child = memnew(Light2D);
} else if (default_type == "GPUParticles2D") {
child = memnew(GPUParticles2D);
} else if (default_type == "Polygon2D") {
child = memnew(Polygon2D);
} else if (default_type == "TouchScreenButton") {
Expand Down
3 changes: 1 addition & 2 deletions editor/plugins/gpu_particles_2d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ void GPUParticles2DEditorPlugin::_menu_callback(int p_idx) {
} break;
case MENU_OPTION_CONVERT_TO_CPU_PARTICLES: {
CPUParticles2D *cpu_particles = memnew(CPUParticles2D);
//TODO
//cpu_particles->convert_from_particles(particles);
cpu_particles->convert_from_particles(particles);
cpu_particles->set_name(particles->get_name());
cpu_particles->set_transform(particles->get_transform());
cpu_particles->set_visible(particles->is_visible());
Expand Down
268 changes: 268 additions & 0 deletions editor/plugins/particles_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,13 @@
#include "scene/gui/dialogs.h"
#include "scene/gui/option_button.h"
#include "scene/gui/spin_box.h"
#include "scene/gui/popup_menu.h"
#include "scene/main/node.h"
#include "scene/main/spatial.h"
#include "scene/3d/gpu_particles.h"
#include "scene/3d/cpu_particles.h"
#include "scene/resources/material/particles_material.h"
#include "editor/plugins/spatial_editor_plugin.h"

bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vector3> &normals) {
bool use_normals = emission_fill->get_selected() == 1;
Expand Down Expand Up @@ -261,3 +266,266 @@ ParticlesEditorBase::ParticlesEditorBase() {

emission_file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
}

void GPUParticlesEditor::_node_removed(Node *p_node) {
if (p_node == node) {
node = nullptr;
hide();
}
}

void GPUParticlesEditor::_notification(int p_notification) {
if (p_notification == NOTIFICATION_ENTER_TREE) {
options->set_icon(options->get_popup()->get_theme_icon("GPUParticles", "EditorIcons"));
get_tree()->connect("node_removed", this, "_node_removed");
}
}

void GPUParticlesEditor::_menu_option(int p_option) {
switch (p_option) {
case MENU_OPTION_GENERATE_AABB: {
// Add one second to the default generation lifetime, since the progress is updated every second.
generate_seconds->set_value(MAX(1.0, trunc(node->get_lifetime()) + 1.0));

if (generate_seconds->get_value() >= 11.0 + CMP_EPSILON) {
// Only pop up the time dialog if the particle's lifetime is long enough to warrant shortening it.
generate_aabb->popup_centered_minsize();
} else {
// Generate the visibility AABB immediately.
_generate_aabb();
}
} 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: {
CPUParticles *cpu_particles = memnew(CPUParticles);
cpu_particles->convert_from_particles(node);
cpu_particles->set_name(node->get_name());
cpu_particles->set_transform(node->get_transform());
cpu_particles->set_visible(node->is_visible());
cpu_particles->set_pause_mode(node->get_pause_mode());

UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Convert to CPUParticles"));
ur->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock(), "replace_node", node, cpu_particles, true, false);
ur->add_do_reference(cpu_particles);
ur->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock(), "replace_node", cpu_particles, node, false, false);
ur->add_undo_reference(node);
ur->commit_action();

} break;
case MENU_OPTION_RESTART: {
node->restart();

} break;
}
}

void GPUParticlesEditor::_generate_aabb() {
float time = generate_seconds->get_value();

float running = 0.0;

EditorProgress ep("gen_aabb", TTR("Generating Visibility AABB (Waiting for Particle Simulation)"), int(time));

bool was_emitting = node->is_emitting();
if (!was_emitting) {
node->set_emitting(true);
OS::get_singleton()->delay_usec(1000);
}

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;
}

if (!was_emitting) {
node->set_emitting(false);
}

UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Generate Visibility AABB"));
ur->add_do_method(node, "set_visibility_aabb", rect);
ur->add_undo_method(node, "set_visibility_aabb", node->get_visibility_aabb());
ur->commit_action();
}

void GPUParticlesEditor::edit(GPUParticles *p_particles) {
base_node = p_particles;
node = p_particles;
}

void GPUParticlesEditor::_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;

PoolVector<uint8_t> point_img;
point_img.resize(w * h * 3 * sizeof(float));

{
PoolVector<uint8_t>::Write iw = point_img.write();
memset(iw.ptr(), 0, w * h * 3 * sizeof(float));
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));

Ref<ImageTexture> tex;
tex.instance();
tex->create_from_image(image, Texture::FLAG_FILTER);

Ref<ParticlesMaterial> material = node->get_process_material();
ERR_FAIL_COND(material.is_null());

if (normals.size() > 0) {
material->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_DIRECTED_POINTS);
material->set_emission_point_count(point_count);
material->set_emission_point_texture(tex);

PoolVector<uint8_t> point_img2;
point_img2.resize(w * h * 3 * sizeof(float));

{
PoolVector<uint8_t>::Write iw = point_img2.write();
memset(iw.ptr(), 0, w * h * 3 * sizeof(float));
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));

Ref<ImageTexture> tex2;
tex2.instance();
tex2->create_from_image(image2, Texture::FLAG_FILTER);

material->set_emission_normal_texture(tex2);
} else {
material->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_POINTS);
material->set_emission_point_count(point_count);
material->set_emission_point_texture(tex);
}
}

void GPUParticlesEditor::_bind_methods() {
ClassDB::bind_method("_menu_option", &GPUParticlesEditor::_menu_option);
ClassDB::bind_method("_generate_aabb", &GPUParticlesEditor::_generate_aabb);
ClassDB::bind_method("_node_removed", &GPUParticlesEditor::_node_removed);
}

GPUParticlesEditor::GPUParticlesEditor() {
node = nullptr;
particles_editor_hb = memnew(HBoxContainer);
SpatialEditor::get_singleton()->add_control_to_menu_panel(particles_editor_hb);
options = memnew(MenuButton);
options->set_switch_on_hover(true);
particles_editor_hb->add_child(options);
particles_editor_hb->hide();

options->set_text(TTR("GPUParticles"));
options->get_popup()->add_item(TTR("Generate Visibility AABB"), MENU_OPTION_GENERATE_AABB);
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()->add_separator();
options->get_popup()->add_item(TTR("Restart"), MENU_OPTION_RESTART);

options->get_popup()->connect("id_pressed", this, "_menu_option");

generate_aabb = memnew(ConfirmationDialog);
generate_aabb->set_title(TTR("Generate Visibility AABB"));
VBoxContainer *genvb = memnew(VBoxContainer);
generate_aabb->add_child(genvb);
generate_seconds = memnew(SpinBox);
genvb->add_margin_child(TTR("Generation Time (sec):"), generate_seconds);
generate_seconds->set_min(0.1);
generate_seconds->set_max(25);
generate_seconds->set_value(2);

add_child(generate_aabb);

generate_aabb->connect("confirmed", this, "_generate_aabb");
}

void GPUParticlesEditorPlugin::edit(Object *p_object) {
particles_editor->edit(Object::cast_to<GPUParticles>(p_object));
}

bool GPUParticlesEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("GPUParticles");
}

void GPUParticlesEditorPlugin::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(nullptr);
}
}

GPUParticlesEditorPlugin::GPUParticlesEditorPlugin(EditorNode *p_node) {
editor = p_node;
particles_editor = memnew(GPUParticlesEditor);
editor->get_viewport()->add_child(particles_editor);

particles_editor->hide();
}

GPUParticlesEditorPlugin::~GPUParticlesEditorPlugin() {
}

55 changes: 55 additions & 0 deletions editor/plugins/particles_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Panel;
class SceneTreeDialog;
class Spatial;
class SpinBox;
class GPUParticles;
struct Vector3;

class ParticlesEditorBase : public Control {
Expand Down Expand Up @@ -79,4 +80,58 @@ class ParticlesEditorBase : public Control {
ParticlesEditorBase();
};

class GPUParticlesEditor : public ParticlesEditorBase {
GDCLASS(GPUParticlesEditor, ParticlesEditorBase);

ConfirmationDialog *generate_aabb;
SpinBox *generate_seconds;
GPUParticles *node;

enum Menu {

MENU_OPTION_GENERATE_AABB,
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,
MENU_OPTION_RESTART,

};

void _generate_aabb();

void _menu_option(int);

friend class GPUParticlesEditorPlugin;

virtual void _generate_emission_points();

protected:
void _notification(int p_notification);
void _node_removed(Node *p_node);
static void _bind_methods();

public:
void edit(GPUParticles *p_particles);
GPUParticlesEditor();
};

class GPUParticlesEditorPlugin : public EditorPlugin {
GDCLASS(GPUParticlesEditorPlugin, EditorPlugin);

GPUParticlesEditor *particles_editor;
EditorNode *editor;

public:
virtual String get_name() const { return "GPUParticles"; }
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);

GPUParticlesEditorPlugin(EditorNode *p_node);
~GPUParticlesEditorPlugin();
};


#endif // PARTICLES_EDITOR_PLUGIN_H
Loading

0 comments on commit 85cddb0

Please sign in to comment.