diff options
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 31 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 7 | ||||
-rw-r--r-- | editor/import/resource_importer_texture.cpp | 2 | ||||
-rw-r--r-- | scene/2d/canvas_item.cpp | 19 | ||||
-rw-r--r-- | scene/2d/particles_2d.cpp | 23 | ||||
-rw-r--r-- | scene/2d/particles_2d.h | 4 | ||||
-rw-r--r-- | scene/3d/particles.cpp | 22 | ||||
-rw-r--r-- | scene/3d/particles.h | 5 | ||||
-rw-r--r-- | servers/visual/rasterizer.h | 2 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.h | 2 | ||||
-rw-r--r-- | servers/visual/visual_server_wrap_mt.h | 2 | ||||
-rw-r--r-- | servers/visual_server.h | 2 |
12 files changed, 115 insertions, 6 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index f7e1fdee9d..24a57b772b 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -5068,6 +5068,14 @@ void RasterizerStorageGLES3::particles_set_lifetime(RID p_particles, float p_lif ERR_FAIL_COND(!particles); particles->lifetime = p_lifetime; } + +void RasterizerStorageGLES3::particles_set_one_shot(RID p_particles, bool p_one_shot) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + particles->one_shot = p_one_shot; +} + void RasterizerStorageGLES3::particles_set_pre_process_time(RID p_particles, float p_time) { Particles *particles = particles_owner.getornull(p_particles); @@ -5199,6 +5207,14 @@ void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles, int p particles->draw_passes[p_pass] = p_mesh; } +void RasterizerStorageGLES3::particles_restart(RID p_particles) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + + particles->restart_request = true; +} + void RasterizerStorageGLES3::particles_request_process(RID p_particles) { Particles *particles = particles_owner.getornull(p_particles); @@ -5290,6 +5306,10 @@ void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_de particles->cycle_number = 0; particles->random_seed = Math::rand(); } else if (new_phase < particles->phase) { + if (particles->one_shot) { + particles->emitting = false; + shaders.particles.set_uniform(ParticlesShaderGLES3::EMITTING, false); + } particles->cycle_number++; } @@ -5356,6 +5376,17 @@ void RasterizerStorageGLES3::update_particles() { Particles *particles = particle_update_list.first()->self(); + if (particles->restart_request) { + particles->emitting = true; //restart from zero + particles->prev_ticks = 0; + particles->phase = 0; + particles->prev_phase = 0; + particles->clear = true; + particles->particle_valid_histories[0] = false; + particles->particle_valid_histories[1] = false; + particles->restart_request = false; + } + if (particles->inactive && !particles->emitting) { particle_update_list.remove(particle_update_list.first()); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 79abebae5b..2ef47fe2cb 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -1036,11 +1036,13 @@ public: bool inactive; float inactive_time; bool emitting; + bool one_shot; int amount; float lifetime; float pre_process_time; float explosiveness; float randomness; + bool restart_request; Rect3 custom_aabb; bool use_local_coords; RID process_material; @@ -1080,6 +1082,7 @@ public: : particle_element(this) { cycle_number = 0; emitting = false; + one_shot = false; amount = 0; lifetime = 1.0; pre_process_time = 0.0; @@ -1093,6 +1096,8 @@ public: speed_scale = 1.0; random_seed = 0; + restart_request = false; + custom_aabb = Rect3(Vector3(-4, -4, -4), Vector3(8, 8, 8)); draw_order = VS::PARTICLES_DRAW_ORDER_INDEX; @@ -1131,6 +1136,7 @@ public: virtual void particles_set_emitting(RID p_particles, bool p_emitting); virtual void particles_set_amount(RID p_particles, int p_amount); virtual void particles_set_lifetime(RID p_particles, float p_lifetime); + virtual void particles_set_one_shot(RID p_particles, bool p_one_shot); virtual void particles_set_pre_process_time(RID p_particles, float p_time); virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio); virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio); @@ -1140,6 +1146,7 @@ public: virtual void particles_set_process_material(RID p_particles, RID p_material); virtual void particles_set_fixed_fps(RID p_particles, int p_fps); virtual void particles_set_fractional_delta(RID p_particles, bool p_enable); + virtual void particles_restart(RID p_particles); virtual void particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order); diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 41b2353ed3..3834e52fab 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -202,7 +202,7 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options, r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/anisotropic"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/srgb", PROPERTY_HINT_ENUM, "Disable,Enable,Detect"), 2)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/fix_alpha_border"), p_preset != PRESET_3D ? true : false)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/HDR_as_SRGB"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "stream"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0)); diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 57d178abe3..4a80aba355 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -96,8 +96,8 @@ void CanvasItemMaterial::_update_shader() { switch (light_mode) { case LIGHT_MODE_NORMAL: break; - case LIGHT_MODE_UNSHADED: code += "unshaded"; break; - case LIGHT_MODE_LIGHT_ONLY: code += "light_only"; break; + case LIGHT_MODE_UNSHADED: code += ",unshaded"; break; + case LIGHT_MODE_LIGHT_ONLY: code += ",light_only"; break; } code += ";\n"; //thats it. @@ -367,7 +367,9 @@ Transform2D CanvasItem::get_global_transform_with_canvas() const { } Transform2D CanvasItem::get_global_transform() const { - +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!is_inside_tree(), get_transform()); +#endif if (global_invalid) { const CanvasItem *pi = get_parent_item(); @@ -765,8 +767,9 @@ float CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const void CanvasItem::_notify_transform(CanvasItem *p_node) { - if (/*p_node->xform_change.in_list() &&*/ p_node->global_invalid) + if (/*p_node->xform_change.in_list() &&*/ p_node->global_invalid) { return; //nothing to do + } p_node->global_invalid = true; @@ -1067,7 +1070,15 @@ bool CanvasItem::is_local_transform_notification_enabled() const { } void CanvasItem::set_notify_transform(bool p_enable) { + if (notify_transform == p_enable) + return; + notify_transform = p_enable; + + if (notify_transform && is_inside_tree()) { + //this ensures that invalid globals get resolved, so notifications can be received + get_global_transform(); + } } bool CanvasItem::is_transform_notification_enabled() const { diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index beff247264..ba795d58f4 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -50,6 +50,12 @@ void Particles2D::set_lifetime(float p_lifetime) { lifetime = p_lifetime; VS::get_singleton()->particles_set_lifetime(particles, lifetime); } + +void Particles2D::set_one_shot(bool p_enable) { + + one_shot = p_enable; + VS::get_singleton()->particles_set_one_shot(particles, one_shot); +} void Particles2D::set_pre_process_time(float p_time) { pre_process_time = p_time; @@ -84,7 +90,7 @@ void Particles2D::set_use_local_coordinates(bool p_enable) { local_coords = p_enable; VS::get_singleton()->particles_set_use_local_coordinates(particles, local_coords); set_notify_transform(!p_enable); - if (!p_enable) { + if (!p_enable && is_inside_tree()) { _update_particle_emission_transform(); } } @@ -135,6 +141,11 @@ float Particles2D::get_lifetime() const { return lifetime; } + +bool Particles2D::get_one_shot() const { + + return one_shot; +} float Particles2D::get_pre_process_time() const { return pre_process_time; @@ -264,6 +275,10 @@ int Particles2D::get_h_frames() const { return h_frames; } +void Particles2D::restart() { + VS::get_singleton()->particles_restart(particles); +} + void Particles2D::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { @@ -295,6 +310,7 @@ void Particles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &Particles2D::set_emitting); ClassDB::bind_method(D_METHOD("set_amount", "amount"), &Particles2D::set_amount); ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &Particles2D::set_lifetime); + ClassDB::bind_method(D_METHOD("set_one_shot", "secs"), &Particles2D::set_one_shot); ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &Particles2D::set_pre_process_time); ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &Particles2D::set_explosiveness_ratio); ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &Particles2D::set_randomness_ratio); @@ -308,6 +324,7 @@ void Particles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_emitting"), &Particles2D::is_emitting); ClassDB::bind_method(D_METHOD("get_amount"), &Particles2D::get_amount); ClassDB::bind_method(D_METHOD("get_lifetime"), &Particles2D::get_lifetime); + ClassDB::bind_method(D_METHOD("get_one_shot"), &Particles2D::get_one_shot); ClassDB::bind_method(D_METHOD("get_pre_process_time"), &Particles2D::get_pre_process_time); ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &Particles2D::get_explosiveness_ratio); ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &Particles2D::get_randomness_ratio); @@ -335,10 +352,13 @@ void Particles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_h_frames", "frames"), &Particles2D::set_h_frames); ClassDB::bind_method(D_METHOD("get_h_frames"), &Particles2D::get_h_frames); + ClassDB::bind_method(D_METHOD("restart"), &Particles2D::restart); + ADD_GROUP("Parameters", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,100000,1"), "set_amount", "get_amount"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); @@ -365,6 +385,7 @@ Particles2D::Particles2D() { particles = VS::get_singleton()->particles_create(); set_emitting(true); + set_one_shot(false); set_amount(8); set_lifetime(1); set_fixed_fps(0); diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h index ab7dcb1464..23278ce746 100644 --- a/scene/2d/particles_2d.h +++ b/scene/2d/particles_2d.h @@ -48,6 +48,7 @@ private: RID particles; bool emitting; + bool one_shot; int amount; float lifetime; float pre_process_time; @@ -79,6 +80,7 @@ public: void set_emitting(bool p_emitting); void set_amount(int p_amount); void set_lifetime(float p_lifetime); + void set_one_shot(bool p_enabled); void set_pre_process_time(float p_time); void set_explosiveness_ratio(float p_ratio); void set_randomness_ratio(float p_ratio); @@ -90,6 +92,7 @@ public: bool is_emitting() const; int get_amount() const; float get_lifetime() const; + bool get_one_shot() const; float get_pre_process_time() const; float get_explosiveness_ratio() const; float get_randomness_ratio() const; @@ -121,6 +124,7 @@ public: void set_h_frames(int p_count); int get_h_frames() const; + void restart(); Rect2 capture_rect() const; Particles2D(); ~Particles2D(); diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index 722b698b75..0d4735fc7f 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -58,6 +58,13 @@ void Particles::set_lifetime(float p_lifetime) { lifetime = p_lifetime; VS::get_singleton()->particles_set_lifetime(particles, lifetime); } + +void Particles::set_one_shot(bool p_one_shot) { + + one_shot = p_one_shot; + VS::get_singleton()->particles_set_one_shot(particles, one_shot); +} + void Particles::set_pre_process_time(float p_time) { pre_process_time = p_time; @@ -114,6 +121,11 @@ float Particles::get_lifetime() const { return lifetime; } +bool Particles::get_one_shot() const { + + return one_shot; +} + float Particles::get_pre_process_time() const { return pre_process_time; @@ -233,6 +245,11 @@ String Particles::get_configuration_warning() const { return warnings; } +void Particles::restart() { + + VisualServer::get_singleton()->particles_restart(particles); +} + Rect3 Particles::capture_aabb() const { return VS::get_singleton()->particles_get_current_aabb(particles); @@ -254,6 +271,7 @@ void Particles::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &Particles::set_emitting); ClassDB::bind_method(D_METHOD("set_amount", "amount"), &Particles::set_amount); ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &Particles::set_lifetime); + ClassDB::bind_method(D_METHOD("set_one_shot", "enable"), &Particles::set_one_shot); ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &Particles::set_pre_process_time); ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &Particles::set_explosiveness_ratio); ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &Particles::set_randomness_ratio); @@ -267,6 +285,7 @@ void Particles::_bind_methods() { ClassDB::bind_method(D_METHOD("is_emitting"), &Particles::is_emitting); ClassDB::bind_method(D_METHOD("get_amount"), &Particles::get_amount); ClassDB::bind_method(D_METHOD("get_lifetime"), &Particles::get_lifetime); + ClassDB::bind_method(D_METHOD("get_one_shot"), &Particles::get_one_shot); ClassDB::bind_method(D_METHOD("get_pre_process_time"), &Particles::get_pre_process_time); ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &Particles::get_explosiveness_ratio); ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &Particles::get_randomness_ratio); @@ -287,12 +306,14 @@ void Particles::_bind_methods() { ClassDB::bind_method(D_METHOD("get_draw_passes"), &Particles::get_draw_passes); ClassDB::bind_method(D_METHOD("get_draw_pass_mesh:Mesh", "pass"), &Particles::get_draw_pass_mesh); + ClassDB::bind_method(D_METHOD("restart"), &Particles::restart); ClassDB::bind_method(D_METHOD("capture_aabb"), &Particles::capture_aabb); ADD_GROUP("Parameters", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,100000,1"), "set_amount", "get_amount"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); @@ -322,6 +343,7 @@ Particles::Particles() { particles = VS::get_singleton()->particles_create(); set_base(particles); set_emitting(true); + set_one_shot(false); set_amount(8); set_lifetime(1); set_fixed_fps(0); diff --git a/scene/3d/particles.h b/scene/3d/particles.h index dad8ed4585..0549eb4c09 100644 --- a/scene/3d/particles.h +++ b/scene/3d/particles.h @@ -58,6 +58,7 @@ private: RID particles; bool emitting; + bool one_shot; int amount; float lifetime; float pre_process_time; @@ -86,6 +87,7 @@ public: void set_emitting(bool p_emitting); void set_amount(int p_amount); void set_lifetime(float p_lifetime); + void set_one_shot(bool p_enabled); void set_pre_process_time(float p_time); void set_explosiveness_ratio(float p_ratio); void set_randomness_ratio(float p_ratio); @@ -97,6 +99,7 @@ public: bool is_emitting() const; int get_amount() const; float get_lifetime() const; + bool get_one_shot() const; float get_pre_process_time() const; float get_explosiveness_ratio() const; float get_randomness_ratio() const; @@ -122,6 +125,8 @@ public: virtual String get_configuration_warning() const; + void restart(); + Rect3 capture_aabb() const; Particles(); ~Particles(); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 2ce83e6c64..5b60a46ade 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -448,6 +448,7 @@ public: virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0; virtual void particles_set_amount(RID p_particles, int p_amount) = 0; virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0; + virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) = 0; virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0; virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0; virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0; @@ -457,6 +458,7 @@ public: virtual void particles_set_process_material(RID p_particles, RID p_material) = 0; virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0; virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0; + virtual void particles_restart(RID p_particles) = 0; virtual void particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order) = 0; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 03af60dcd5..e201f6a8c0 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -862,6 +862,7 @@ public: BIND2(particles_set_emitting, RID, bool) BIND2(particles_set_amount, RID, int) BIND2(particles_set_lifetime, RID, float) + BIND2(particles_set_one_shot, RID, bool) BIND2(particles_set_pre_process_time, RID, float) BIND2(particles_set_explosiveness_ratio, RID, float) BIND2(particles_set_randomness_ratio, RID, float) @@ -871,6 +872,7 @@ public: BIND2(particles_set_process_material, RID, RID) BIND2(particles_set_fixed_fps, RID, int) BIND2(particles_set_fractional_delta, RID, bool) + BIND1(particles_restart, RID) BIND2(particles_set_draw_order, RID, VS::ParticlesDrawOrder) diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 79a7805472..9f49377fa8 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -306,6 +306,7 @@ public: FUNC2(particles_set_emitting, RID, bool) FUNC2(particles_set_amount, RID, int) FUNC2(particles_set_lifetime, RID, float) + FUNC2(particles_set_one_shot, RID, bool) FUNC2(particles_set_pre_process_time, RID, float) FUNC2(particles_set_explosiveness_ratio, RID, float) FUNC2(particles_set_randomness_ratio, RID, float) @@ -315,6 +316,7 @@ public: FUNC2(particles_set_process_material, RID, RID) FUNC2(particles_set_fixed_fps, RID, int) FUNC2(particles_set_fractional_delta, RID, bool) + FUNC1(particles_restart, RID) FUNC2(particles_set_draw_order, RID, VS::ParticlesDrawOrder) diff --git a/servers/visual_server.h b/servers/visual_server.h index bc72c8a5a1..4d2a983751 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -478,6 +478,7 @@ public: virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0; virtual void particles_set_amount(RID p_particles, int p_amount) = 0; virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0; + virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) = 0; virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0; virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0; virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0; @@ -487,6 +488,7 @@ public: virtual void particles_set_process_material(RID p_particles, RID p_material) = 0; virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0; virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0; + virtual void particles_restart(RID p_particles) = 0; enum ParticlesDrawOrder { PARTICLES_DRAW_ORDER_INDEX, |