Ability to restart particle system with a function call

This commit is contained in:
Juan Linietsky 2017-06-25 08:01:15 -03:00
parent 87fd71244b
commit 83ae9a5e28
12 changed files with 115 additions and 6 deletions

View file

@ -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());

View file

@ -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);

View file

@ -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));

View file

@ -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 {

View file

@ -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);

View file

@ -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();

View file

@ -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);

View file

@ -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();

View file

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

View file

@ -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)

View file

@ -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)

View file

@ -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,