mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-11-21 16:37:20 +01:00
Renamed Particle to GPUParticle and Particle2D to GPUParticle2D pt4.
This commit is contained in:
parent
a97a334ebd
commit
85cddb07b4
@ -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"
|
||||
@ -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)));
|
||||
@ -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)));
|
||||
|
Before Width: | Height: | Size: 470 B After Width: | Height: | Size: 470 B |
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 448 B |
@ -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"
|
||||
|
||||
@ -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") {
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
@ -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() {
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ class Panel;
|
||||
class SceneTreeDialog;
|
||||
class Spatial;
|
||||
class SpinBox;
|
||||
class GPUParticles;
|
||||
struct Vector3;
|
||||
|
||||
class ParticlesEditorBase : public Control {
|
||||
@ -79,4 +80,58 @@ public:
|
||||
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
|
||||
|
@ -7186,6 +7186,7 @@ void SpatialEditor::_register_all_gizmos() {
|
||||
add_gizmo_plugin(Ref<SpringArmSpatialGizmoPlugin>(memnew(SpringArmSpatialGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<VehicleWheelSpatialGizmoPlugin>(memnew(VehicleWheelSpatialGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<VisibilityNotifierGizmoPlugin>(memnew(VisibilityNotifierGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<GPUParticlesGizmoPlugin>(memnew(GPUParticlesGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<CPUParticlesGizmoPlugin>(memnew(CPUParticlesGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin)));
|
||||
|
@ -82,6 +82,7 @@
|
||||
#include "scene/3d/sprite_3d.h"
|
||||
#include "scene/3d/vehicle_body.h"
|
||||
#include "scene/3d/visibility_notifier.h"
|
||||
#include "scene/3d/gpu_particles.h"
|
||||
#include "scene/main/control.h"
|
||||
#include "scene/main/node.h"
|
||||
#include "scene/main/scene_tree.h"
|
||||
@ -2661,6 +2662,169 @@ void CPUParticlesGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
|
||||
|
||||
////
|
||||
|
||||
GPUParticlesGizmoPlugin::GPUParticlesGizmoPlugin() {
|
||||
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particles", Color(0.8, 0.7, 0.4));
|
||||
create_material("particles_material", gizmo_color);
|
||||
gizmo_color.a = 0.1;
|
||||
create_material("particles_solid_material", gizmo_color);
|
||||
create_icon_material("particles_icon", SpatialEditor::get_singleton()->get_theme_icon("GizmoParticles", "EditorIcons"));
|
||||
create_handle_material("handles");
|
||||
}
|
||||
|
||||
bool GPUParticlesGizmoPlugin::has_gizmo(Spatial *p_spatial) {
|
||||
return Object::cast_to<GPUParticles>(p_spatial) != nullptr;
|
||||
}
|
||||
|
||||
String GPUParticlesGizmoPlugin::get_gizmo_name() const {
|
||||
return "GPUParticles";
|
||||
}
|
||||
|
||||
int GPUParticlesGizmoPlugin::get_priority() const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool GPUParticlesGizmoPlugin::is_selectable_when_hidden() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
String GPUParticlesGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary) const {
|
||||
switch (p_id) {
|
||||
case 0:
|
||||
return "Size X";
|
||||
case 1:
|
||||
return "Size Y";
|
||||
case 2:
|
||||
return "Size Z";
|
||||
case 3:
|
||||
return "Pos X";
|
||||
case 4:
|
||||
return "Pos Y";
|
||||
case 5:
|
||||
return "Pos Z";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
Variant GPUParticlesGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary) const {
|
||||
GPUParticles *particles = Object::cast_to<GPUParticles>(p_gizmo->get_spatial_node());
|
||||
return particles->get_visibility_aabb();
|
||||
}
|
||||
void GPUParticlesGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary, Camera *p_camera, const Point2 &p_point) {
|
||||
GPUParticles *particles = Object::cast_to<GPUParticles>(p_gizmo->get_spatial_node());
|
||||
|
||||
Transform gt = particles->get_global_transform();
|
||||
Transform gi = gt.affine_inverse();
|
||||
|
||||
bool move = p_id >= 3;
|
||||
p_id = p_id % 3;
|
||||
|
||||
AABB aabb = particles->get_visibility_aabb();
|
||||
Vector3 ray_from = p_camera->project_ray_origin(p_point);
|
||||
Vector3 ray_dir = p_camera->project_ray_normal(p_point);
|
||||
|
||||
Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
|
||||
|
||||
Vector3 ofs = aabb.position + aabb.size * 0.5;
|
||||
|
||||
Vector3 axis;
|
||||
axis[p_id] = 1.0;
|
||||
|
||||
if (move) {
|
||||
Vector3 ra, rb;
|
||||
Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb);
|
||||
|
||||
float d = ra[p_id];
|
||||
if (SpatialEditor::get_singleton()->is_snap_enabled()) {
|
||||
d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap());
|
||||
}
|
||||
|
||||
aabb.position[p_id] = d - 1.0 - aabb.size[p_id] * 0.5;
|
||||
particles->set_visibility_aabb(aabb);
|
||||
|
||||
} else {
|
||||
Vector3 ra, rb;
|
||||
Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb);
|
||||
|
||||
float d = ra[p_id] - ofs[p_id];
|
||||
if (SpatialEditor::get_singleton()->is_snap_enabled()) {
|
||||
d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap());
|
||||
}
|
||||
|
||||
if (d < 0.001) {
|
||||
d = 0.001;
|
||||
}
|
||||
//resize
|
||||
aabb.position[p_id] = (aabb.position[p_id] + aabb.size[p_id] * 0.5) - d;
|
||||
aabb.size[p_id] = d * 2;
|
||||
particles->set_visibility_aabb(aabb);
|
||||
}
|
||||
}
|
||||
|
||||
void GPUParticlesGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
|
||||
GPUParticles *particles = Object::cast_to<GPUParticles>(p_gizmo->get_spatial_node());
|
||||
|
||||
if (p_cancel) {
|
||||
particles->set_visibility_aabb(p_restore);
|
||||
return;
|
||||
}
|
||||
|
||||
UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
|
||||
ur->create_action(TTR("Change Particles AABB"));
|
||||
ur->add_do_method(particles, "set_visibility_aabb", particles->get_visibility_aabb());
|
||||
ur->add_undo_method(particles, "set_visibility_aabb", p_restore);
|
||||
ur->commit_action();
|
||||
}
|
||||
|
||||
void GPUParticlesGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
|
||||
GPUParticles *particles = Object::cast_to<GPUParticles>(p_gizmo->get_spatial_node());
|
||||
|
||||
p_gizmo->clear();
|
||||
|
||||
Vector<Vector3> lines;
|
||||
AABB aabb = particles->get_visibility_aabb();
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
Vector3 a, b;
|
||||
aabb.get_edge(i, a, b);
|
||||
lines.push_back(a);
|
||||
lines.push_back(b);
|
||||
}
|
||||
|
||||
Vector<Vector3> handles;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Vector3 ax;
|
||||
ax[i] = aabb.position[i] + aabb.size[i];
|
||||
ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
|
||||
ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
|
||||
handles.push_back(ax);
|
||||
}
|
||||
|
||||
Vector3 center = aabb.position + aabb.size * 0.5;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Vector3 ax;
|
||||
ax[i] = 1.0;
|
||||
handles.push_back(center + ax);
|
||||
lines.push_back(center);
|
||||
lines.push_back(center + ax);
|
||||
}
|
||||
|
||||
Ref<Material> material = get_material("particles_material", p_gizmo);
|
||||
Ref<Material> icon = get_material("particles_icon", p_gizmo);
|
||||
|
||||
p_gizmo->add_lines(lines, material);
|
||||
|
||||
if (p_gizmo->is_selected()) {
|
||||
Ref<Material> solid_material = get_material("particles_solid_material", p_gizmo);
|
||||
p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_position() + aabb.get_size() / 2.0);
|
||||
}
|
||||
|
||||
p_gizmo->add_handles(handles, get_material("handles"));
|
||||
p_gizmo->add_unscaled_billboard(icon, 0.05);
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
ReflectionProbeGizmoPlugin::ReflectionProbeGizmoPlugin() {
|
||||
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/reflection_probe", Color(0.6, 1, 0.5));
|
||||
|
||||
|
@ -436,6 +436,24 @@ public:
|
||||
CPUParticlesGizmoPlugin();
|
||||
};
|
||||
|
||||
class GPUParticlesGizmoPlugin : public EditorSpatialGizmoPlugin {
|
||||
GDCLASS(GPUParticlesGizmoPlugin, EditorSpatialGizmoPlugin);
|
||||
|
||||
public:
|
||||
bool has_gizmo(Spatial *p_spatial);
|
||||
String get_gizmo_name() const;
|
||||
int get_priority() const;
|
||||
bool is_selectable_when_hidden() const;
|
||||
void redraw(EditorSpatialGizmo *p_gizmo);
|
||||
|
||||
String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary) const;
|
||||
Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary) const;
|
||||
void set_handle(EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary, Camera *p_camera, const Point2 &p_point);
|
||||
void commit_handle(EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false);
|
||||
|
||||
GPUParticlesGizmoPlugin();
|
||||
};
|
||||
|
||||
class ReflectionProbeGizmoPlugin : public EditorSpatialGizmoPlugin {
|
||||
GDCLASS(ReflectionProbeGizmoPlugin, EditorSpatialGizmoPlugin);
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "core/os/os.h"
|
||||
|
||||
#include "scene/main/canvas_item.h"
|
||||
#include "scene/2d/gpu_particles_2d.h"
|
||||
#include "scene/resources/material/particles_material.h"
|
||||
#include "scene/resources/texture.h"
|
||||
#include "servers/rendering_server.h"
|
||||
@ -1282,6 +1283,86 @@ void CPUParticles2D::_notification(int p_what) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void CPUParticles2D::convert_from_particles(Node *p_particles) {
|
||||
GPUParticles2D *particles = Object::cast_to<GPUParticles2D>(p_particles);
|
||||
ERR_FAIL_COND_MSG(!particles, "Only GPUParticles2D nodes can be converted to CPUParticles2D.");
|
||||
|
||||
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_texture(particles->get_texture());
|
||||
|
||||
Ref<Material> mat = particles->get_material();
|
||||
if (mat.is_valid()) {
|
||||
set_material(mat);
|
||||
}
|
||||
|
||||
Ref<ParticlesMaterial> material = particles->get_process_material();
|
||||
if (material.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 dir = material->get_direction();
|
||||
set_direction(Vector2(dir.x, dir.y));
|
||||
set_spread(material->get_spread());
|
||||
|
||||
set_color(material->get_color());
|
||||
|
||||
Ref<GradientTexture> gt = material->get_color_ramp();
|
||||
if (gt.is_valid()) {
|
||||
set_color_ramp(gt->get_gradient());
|
||||
}
|
||||
|
||||
Ref<GradientTexture> gti = material->get_color_initial_ramp();
|
||||
if (gti.is_valid()) {
|
||||
set_color_initial_ramp(gti->get_gradient());
|
||||
}
|
||||
|
||||
set_particle_flag(FLAG_ALIGN_Y_TO_VELOCITY, material->get_flag(ParticlesMaterial::FLAG_ALIGN_Y_TO_VELOCITY));
|
||||
|
||||
set_emission_shape(EmissionShape(material->get_emission_shape()));
|
||||
set_emission_sphere_radius(material->get_emission_sphere_radius());
|
||||
Vector2 rect_extents = Vector2(material->get_emission_box_extents().x, material->get_emission_box_extents().y);
|
||||
set_emission_rect_extents(rect_extents);
|
||||
|
||||
Vector2 gravity = Vector2(material->get_gravity().x, material->get_gravity().y);
|
||||
set_gravity(gravity);
|
||||
set_lifetime_randomness(material->get_lifetime_randomness());
|
||||
|
||||
#define CONVERT_PARAM(m_param) \
|
||||
set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \
|
||||
{ \
|
||||
Ref<CurveTexture> 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 CPUParticles2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &CPUParticles2D::set_emitting);
|
||||
ClassDB::bind_method(D_METHOD("set_amount", "amount"), &CPUParticles2D::set_amount);
|
||||
@ -1393,6 +1474,8 @@ void CPUParticles2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_gravity"), &CPUParticles2D::get_gravity);
|
||||
ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &CPUParticles2D::set_gravity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_update_render_thread"), &CPUParticles2D::_update_render_thread);
|
||||
ClassDB::bind_method(D_METHOD("_texture_changed"), &CPUParticles2D::_texture_changed);
|
||||
|
||||
|
@ -356,6 +356,8 @@ public:
|
||||
|
||||
void restart();
|
||||
|
||||
void convert_from_particles(Node *p_particles);
|
||||
|
||||
CPUParticles2D();
|
||||
~CPUParticles2D();
|
||||
};
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "visibility_notifier_2d.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "gpu_particles_2d.h"
|
||||
#include "scene/2d/animated_sprite.h"
|
||||
#include "scene/2d/physics_body_2d.h"
|
||||
#include "scene/animation/animation_player.h"
|
||||
@ -215,6 +216,13 @@ void VisibilityEnabler2D::_find_nodes(Node *p_node) {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
GPUParticles2D *ps = Object::cast_to<GPUParticles2D>(p_node);
|
||||
if (ps) {
|
||||
add = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (add) {
|
||||
p_node->connect(SceneStringNames::get_singleton()->tree_exiting, this, "_node_removed", varray(p_node), CONNECT_ONESHOT);
|
||||
nodes[p_node] = meta;
|
||||
@ -309,6 +317,14 @@ void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (enabler[ENABLER_PAUSE_PARTICLES]) {
|
||||
GPUParticles2D *ps = Object::cast_to<GPUParticles2D>(p_node);
|
||||
|
||||
if (ps) {
|
||||
ps->set_emitting(p_enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VisibilityEnabler2D::_node_removed(Node *p_node) {
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "core/os/os.h"
|
||||
#include "scene/3d/camera.h"
|
||||
#include "scene/3d/gpu_particles.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "scene/resources/curve.h"
|
||||
#include "scene/resources/gradient.h"
|
||||
@ -1313,6 +1314,85 @@ void CPUParticles::_notification(int p_what) {
|
||||
}
|
||||
}
|
||||
|
||||
void CPUParticles::convert_from_particles(Node *p_particles) {
|
||||
GPUParticles *particles = Object::cast_to<GPUParticles>(p_particles);
|
||||
ERR_FAIL_COND_MSG(!particles, "Only GPUParticles nodes can be converted to CPUParticles.");
|
||||
|
||||
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<ParticlesMaterial> material = particles->get_process_material();
|
||||
if (material.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
set_direction(material->get_direction());
|
||||
set_spread(material->get_spread());
|
||||
set_flatness(material->get_flatness());
|
||||
|
||||
set_color(material->get_color());
|
||||
|
||||
Ref<GradientTexture> gt = material->get_color_ramp();
|
||||
if (gt.is_valid()) {
|
||||
set_color_ramp(gt->get_gradient());
|
||||
}
|
||||
|
||||
Ref<GradientTexture> gti = material->get_color_initial_ramp();
|
||||
if (gti.is_valid()) {
|
||||
set_color_initial_ramp(gti->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_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_emission_ring_height(material->get_emission_ring_height());
|
||||
set_emission_ring_inner_radius(material->get_emission_ring_inner_radius());
|
||||
set_emission_ring_radius(material->get_emission_ring_radius());
|
||||
set_emission_ring_axis(material->get_emission_ring_axis());
|
||||
|
||||
set_gravity(material->get_gravity());
|
||||
set_lifetime_randomness(material->get_lifetime_randomness());
|
||||
|
||||
#define CONVERT_PARAM(m_param) \
|
||||
set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \
|
||||
{ \
|
||||
Ref<CurveTexture> 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);
|
||||
ClassDB::bind_method(D_METHOD("set_amount", "amount"), &CPUParticles::set_amount);
|
||||
@ -1435,6 +1515,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_");
|
||||
|
@ -357,6 +357,8 @@ public:
|
||||
|
||||
void restart();
|
||||
|
||||
void convert_from_particles(Node *p_particles);
|
||||
|
||||
CPUParticles();
|
||||
~CPUParticles();
|
||||
};
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "room_group.h"
|
||||
#include "scene/3d/camera.h"
|
||||
#include "scene/3d/light.h"
|
||||
#include "scene/3d/gpu_particles.h"
|
||||
#include "scene/3d/sprite_3d.h"
|
||||
#include "scene/resources/mesh/multimesh.h"
|
||||
#include "scene/resources/world_3d.h"
|
||||
@ -1869,13 +1870,11 @@ bool RoomManager::_bound_findpoints_geom_instance(GeometryInstance *p_gi, Vector
|
||||
}
|
||||
|
||||
// Particles have a "visibility aabb" we can use for this
|
||||
/*
|
||||
Particles *particles = Object::cast_to<Particles>(p_gi);
|
||||
GPUParticles *particles = Object::cast_to<GPUParticles>(p_gi);
|
||||
if (particles) {
|
||||
r_aabb = particles->get_global_transform().xform(particles->get_visibility_aabb());
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
// Fallback path for geometry that is not recognised
|
||||
// (including CPUParticles, which will need to rely on an expansion margin)
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "scene/2d/navigation_polygon_instance.h"
|
||||
#include "scene/2d/parallax_background.h"
|
||||
#include "scene/2d/parallax_layer.h"
|
||||
#include "scene/2d/gpu_particles_2d.h"
|
||||
#include "scene/2d/path_2d.h"
|
||||
#include "scene/2d/physics_body_2d.h"
|
||||
#include "scene/2d/polygon_2d.h"
|
||||
@ -213,6 +214,7 @@
|
||||
#include "scene/3d/navigation_obstacle.h"
|
||||
#include "scene/3d/occluder.h"
|
||||
#include "scene/3d/path.h"
|
||||
#include "scene/3d/gpu_particles.h"
|
||||
#include "scene/3d/physics_body.h"
|
||||
#include "scene/3d/physics_joint.h"
|
||||
#include "scene/3d/portal.h"
|
||||
@ -460,6 +462,7 @@ void register_scene_types() {
|
||||
ClassDB::register_class<OmniLight>();
|
||||
ClassDB::register_class<SpotLight>();
|
||||
ClassDB::register_class<ReflectionProbe>();
|
||||
ClassDB::register_class<GPUParticles>();
|
||||
ClassDB::register_class<BakedLightmap>();
|
||||
ClassDB::register_class<BakedLightmapData>();
|
||||
ClassDB::register_class<CPUParticles>();
|
||||
@ -536,6 +539,7 @@ void register_scene_types() {
|
||||
CanvasItemMaterial::init_shaders();
|
||||
ClassDB::register_class<Node2D>();
|
||||
ClassDB::register_class<CPUParticles2D>();
|
||||
ClassDB::register_class<GPUParticles2D>();
|
||||
//ClassDB::register_class<ParticleAttractor2D>();
|
||||
ClassDB::register_class<Sprite>();
|
||||
//ClassDB::register_type<ViewportSprite>();
|
||||
|
Loading…
Reference in New Issue
Block a user