diff options
Diffstat (limited to 'scene/2d/particles_2d.cpp')
-rw-r--r-- | scene/2d/particles_2d.cpp | 1182 |
1 files changed, 209 insertions, 973 deletions
diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index 21d64c5d64..7c864c3430 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -28,903 +28,234 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "particles_2d.h" +#include "scene/3d/particles.h" #include "scene/scene_string_names.h" -void ParticleAttractor2D::_notification(int p_what) { - - switch (p_what) { - - case NOTIFICATION_ENTER_TREE: { - - _update_owner(); - - } break; - case NOTIFICATION_DRAW: { - - if (!get_tree()->is_editor_hint()) - return; - - Vector2 pv; - float dr = MIN(disable_radius, radius); - for (int i = 0; i <= 32; i++) { - Vector2 v(Math::sin(i / 32.0 * Math_PI * 2), Math::cos(i / 32.0 * Math_PI * 2)); - if (i > 0) { - draw_line(pv * radius, v * radius, Color(0, 0, 0.5, 0.9)); - if (dr > 0) { - draw_line(pv * dr, v * dr, Color(0.5, 0, 0.0, 0.9)); - } - } - pv = v; - } - - } break; - case NOTIFICATION_EXIT_TREE: { - if (owner) { - _set_owner(NULL); - } - - } break; - } -} - -void ParticleAttractor2D::_owner_exited() { - - ERR_FAIL_COND(!owner); - owner->attractors.erase(this); - owner = NULL; -} - -void ParticleAttractor2D::_update_owner() { - - if (!is_inside_tree() || !has_node(path)) { - _set_owner(NULL); - return; - } - - Node *n = get_node(path); - ERR_FAIL_COND(!n); - Particles2D *pn = n->cast_to<Particles2D>(); - if (!pn) { - _set_owner(NULL); - return; - } +void Particles2D::set_emitting(bool p_emitting) { - _set_owner(pn); + emitting = p_emitting; + VS::get_singleton()->particles_set_emitting(particles, emitting); } -void ParticleAttractor2D::_set_owner(Particles2D *p_owner) { - - if (owner == p_owner) - return; - - if (owner) { - owner->disconnect("tree_exited", this, "_owner_exited"); - owner->attractors.erase(this); - owner = NULL; - } - owner = p_owner; - - if (owner) { +void Particles2D::set_amount(int p_amount) { - owner->connect("tree_exited", this, "_owner_exited", varray(), CONNECT_ONESHOT); - owner->attractors.insert(this); - } + ERR_FAIL_COND(p_amount < 1); + amount = p_amount; + VS::get_singleton()->particles_set_amount(particles, amount); } +void Particles2D::set_lifetime(float p_lifetime) { -void ParticleAttractor2D::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &ParticleAttractor2D::set_enabled); - ClassDB::bind_method(D_METHOD("is_enabled"), &ParticleAttractor2D::is_enabled); - - ClassDB::bind_method(D_METHOD("set_radius", "radius"), &ParticleAttractor2D::set_radius); - ClassDB::bind_method(D_METHOD("get_radius"), &ParticleAttractor2D::get_radius); - - ClassDB::bind_method(D_METHOD("set_disable_radius", "radius"), &ParticleAttractor2D::set_disable_radius); - ClassDB::bind_method(D_METHOD("get_disable_radius"), &ParticleAttractor2D::get_disable_radius); - - ClassDB::bind_method(D_METHOD("set_gravity", "gravity"), &ParticleAttractor2D::set_gravity); - ClassDB::bind_method(D_METHOD("get_gravity"), &ParticleAttractor2D::get_gravity); - - ClassDB::bind_method(D_METHOD("set_absorption", "absorption"), &ParticleAttractor2D::set_absorption); - ClassDB::bind_method(D_METHOD("get_absorption"), &ParticleAttractor2D::get_absorption); - - ClassDB::bind_method(D_METHOD("set_particles_path", "path"), &ParticleAttractor2D::set_particles_path); - ClassDB::bind_method(D_METHOD("get_particles_path"), &ParticleAttractor2D::get_particles_path); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,16000,0.1"), "set_radius", "get_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "disable_radius", PROPERTY_HINT_RANGE, "0.1,16000,0.1"), "set_disable_radius", "get_disable_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-512,512,0.01"), "set_gravity", "get_gravity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "absorption", PROPERTY_HINT_RANGE, "0,512,0.01"), "set_absorption", "get_absorption"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "particles_path", PROPERTY_HINT_RESOURCE_TYPE, "Particles2D"), "set_particles_path", "get_particles_path"); + ERR_FAIL_COND(p_lifetime <= 0); + lifetime = p_lifetime; + VS::get_singleton()->particles_set_lifetime(particles, lifetime); } +void Particles2D::set_pre_process_time(float p_time) { -void ParticleAttractor2D::set_enabled(bool p_enabled) { - - enabled = p_enabled; + pre_process_time = p_time; + VS::get_singleton()->particles_set_pre_process_time(particles, pre_process_time); } +void Particles2D::set_explosiveness_ratio(float p_ratio) { -bool ParticleAttractor2D::is_enabled() const { - - return enabled; + explosiveness_ratio = p_ratio; + VS::get_singleton()->particles_set_explosiveness_ratio(particles, explosiveness_ratio); } +void Particles2D::set_randomness_ratio(float p_ratio) { -void ParticleAttractor2D::set_radius(float p_radius) { - - radius = p_radius; - update(); + randomness_ratio = p_ratio; + VS::get_singleton()->particles_set_randomness_ratio(particles, randomness_ratio); } +void Particles2D::set_visibility_rect(const Rect2 &p_aabb) { -float ParticleAttractor2D::get_radius() const { - - return radius; -} + visibility_rect = p_aabb; + Rect3 aabb; + aabb.position.x = p_aabb.position.x; + aabb.position.y = p_aabb.position.y; + aabb.size.x = p_aabb.size.x; + aabb.size.y = p_aabb.size.y; -void ParticleAttractor2D::set_disable_radius(float p_disable_radius) { + VS::get_singleton()->particles_set_custom_aabb(particles, aabb); - disable_radius = p_disable_radius; + _change_notify("visibility_rect"); update(); } -float ParticleAttractor2D::get_disable_radius() const { - - return disable_radius; -} - -void ParticleAttractor2D::set_gravity(float p_gravity) { - - gravity = p_gravity; -} -float ParticleAttractor2D::get_gravity() const { - - return gravity; -} - -void ParticleAttractor2D::set_absorption(float p_absorption) { - - absorption = p_absorption; -} -float ParticleAttractor2D::get_absorption() const { - - return absorption; -} - -void ParticleAttractor2D::set_particles_path(NodePath p_path) { - - path = p_path; - _update_owner(); - update_configuration_warning(); -} -NodePath ParticleAttractor2D::get_particles_path() const { - - return path; -} +void Particles2D::set_use_local_coordinates(bool p_enable) { -String ParticleAttractor2D::get_configuration_warning() const { - - if (!has_node(path) || !get_node(path) || !get_node(path)->cast_to<Particles2D>()) { - return TTR("Path property must point to a valid Particles2D node to work."); + local_coords = p_enable; + VS::get_singleton()->particles_set_use_local_coordinates(particles, local_coords); + set_notify_transform(!p_enable); + if (!p_enable) { + _update_particle_emission_transform(); } - - return String(); -} - -ParticleAttractor2D::ParticleAttractor2D() { - - owner = NULL; - radius = 50; - disable_radius = 0; - gravity = 100; - absorption = 0; - path = String(".."); - enabled = true; } -/****************************************/ +void Particles2D::_update_particle_emission_transform() { -_FORCE_INLINE_ static float _rand_from_seed(uint64_t *seed) { + Transform2D xf2d = get_global_transform(); + Transform xf; + xf.basis.set_axis(0, Vector3(xf2d.get_axis(0).x, xf2d.get_axis(0).y, 0)); + xf.basis.set_axis(1, Vector3(xf2d.get_axis(1).x, xf2d.get_axis(1).y, 0)); + xf.set_origin(Vector3(xf2d.get_origin().x, xf2d.get_origin().y, 0)); - uint32_t r = Math::rand_from_seed(seed); - return 2.0f * (float)r / (float)Math::RANDOM_MAX - 1.0f; + VS::get_singleton()->particles_set_emission_transform(particles, xf); } -void Particles2D::_process_particles(float p_delta) { - - if (particles.size() == 0 || lifetime == 0) - return; - - p_delta *= time_scale; - - float frame_time = p_delta; - - if (emit_timeout > 0) { - time_to_live -= frame_time; - if (time_to_live < 0) { - - emitting = false; - _change_notify("config/emitting"); - }; - }; - - float next_time = time + frame_time; - - if (next_time > lifetime) - next_time = Math::fmod(next_time, lifetime); - - Particle *pdata = &particles[0]; - int particle_count = particles.size(); - Transform2D xform; - if (!local_space) - xform = get_global_transform(); +void Particles2D::set_process_material(const Ref<Material> &p_material) { - active_count = 0; - - PoolVector<Point2>::Read r; - int emission_point_count = 0; - if (emission_points.size()) { - - emission_point_count = emission_points.size(); - r = emission_points.read(); - } - - int attractor_count = 0; - AttractorCache *attractor_ptr = NULL; - - if (attractors.size()) { - if (attractors.size() != attractor_cache.size()) { - attractor_cache.resize(attractors.size()); - } - - int idx = 0; - Transform2D m; - if (local_space) { - m = get_global_transform().affine_inverse(); - } - for (Set<ParticleAttractor2D *>::Element *E = attractors.front(); E; E = E->next()) { - - attractor_cache[idx].pos = m.xform(E->get()->get_global_position()); - attractor_cache[idx].attractor = E->get(); - idx++; - } - - attractor_ptr = attractor_cache.ptr(); - attractor_count = attractor_cache.size(); - } - - for (int i = 0; i < particle_count; i++) { - - Particle &p = pdata[i]; - - float restart_time = (i * lifetime / particle_count) * explosiveness; - - bool restart = false; - - if (next_time < time) { - - if (restart_time > time || restart_time < next_time) - restart = true; - - } else if (restart_time > time && restart_time < next_time) { - restart = true; - } - - if (restart) { - - if (emitting) { - - p.pos = emissor_offset; - if (emission_point_count) { - - Vector2 ep = r[Math::rand() % emission_point_count]; - if (!local_space) { - p.pos = xform.xform(p.pos + ep * extents); - } else { - p.pos += ep * extents; - } - } else { - if (!local_space) { - p.pos = xform.xform(p.pos + Vector2(Math::random(-extents.x, extents.x), Math::random(-extents.y, extents.y))); - } else { - p.pos += Vector2(Math::random(-extents.x, extents.x), Math::random(-extents.y, extents.y)); - } - } - p.seed = Math::rand() % 12345678; - uint64_t rand_seed = p.seed * (i + 1); - - float angle = Math::deg2rad(param[PARAM_DIRECTION] + _rand_from_seed(&rand_seed) * param[PARAM_SPREAD]); - - p.velocity = Vector2(Math::sin(angle), Math::cos(angle)); - if (!local_space) { - - p.velocity = xform.basis_xform(p.velocity).normalized(); - } - - p.velocity *= param[PARAM_LINEAR_VELOCITY] + param[PARAM_LINEAR_VELOCITY] * _rand_from_seed(&rand_seed) * randomness[PARAM_LINEAR_VELOCITY]; - p.velocity += initial_velocity; - p.active = true; - p.rot = Math::deg2rad(param[PARAM_INITIAL_ANGLE] + param[PARAM_INITIAL_ANGLE] * randomness[PARAM_INITIAL_ANGLE] * _rand_from_seed(&rand_seed)); - active_count++; - - p.frame = Math::fmod(param[PARAM_ANIM_INITIAL_POS] + randomness[PARAM_ANIM_INITIAL_POS] * _rand_from_seed(&rand_seed), 1.0f); - - } else { - - p.active = false; - } - - } else { - - if (!p.active) - continue; - - uint64_t rand_seed = p.seed * (i + 1); - - Vector2 force; - - //apply gravity - float gravity_dir = Math::deg2rad(param[PARAM_GRAVITY_DIRECTION] + 180 * randomness[PARAM_GRAVITY_DIRECTION] * _rand_from_seed(&rand_seed)); - force += Vector2(Math::sin(gravity_dir), Math::cos(gravity_dir)) * (param[PARAM_GRAVITY_STRENGTH] + param[PARAM_GRAVITY_STRENGTH] * randomness[PARAM_GRAVITY_STRENGTH] * _rand_from_seed(&rand_seed)); - //apply radial - Vector2 rvec = (p.pos - emissor_offset).normalized(); - force += rvec * (param[PARAM_RADIAL_ACCEL] + param[PARAM_RADIAL_ACCEL] * randomness[PARAM_RADIAL_ACCEL] * _rand_from_seed(&rand_seed)); - //apply orbit - float orbitvel = (param[PARAM_ORBIT_VELOCITY] + param[PARAM_ORBIT_VELOCITY] * randomness[PARAM_ORBIT_VELOCITY] * _rand_from_seed(&rand_seed)); - if (orbitvel != 0) { - Vector2 rel = p.pos - xform.elements[2]; - Transform2D rot(orbitvel * frame_time, Vector2()); - p.pos = rot.xform(rel) + xform.elements[2]; - } - - Vector2 tvec = rvec.tangent(); - force += tvec * (param[PARAM_TANGENTIAL_ACCEL] + param[PARAM_TANGENTIAL_ACCEL] * randomness[PARAM_TANGENTIAL_ACCEL] * _rand_from_seed(&rand_seed)); - - for (int j = 0; j < attractor_count; j++) { - - Vector2 vec = (attractor_ptr[j].pos - p.pos); - float vl = vec.length(); - - if (!attractor_ptr[j].attractor->enabled || vl == 0 || vl > attractor_ptr[j].attractor->radius) - continue; - - force += vec * attractor_ptr[j].attractor->gravity; - float fvl = p.velocity.length(); - if (fvl && attractor_ptr[j].attractor->absorption) { - Vector2 target = vec.normalized(); - p.velocity = p.velocity.normalized().linear_interpolate(target, MIN(frame_time * attractor_ptr[j].attractor->absorption, 1)) * fvl; - } - - if (attractor_ptr[j].attractor->disable_radius && vl < attractor_ptr[j].attractor->disable_radius) { - p.active = false; - } - } - - p.velocity += force * frame_time; - - if (param[PARAM_DAMPING]) { - float dmp = param[PARAM_DAMPING] + param[PARAM_DAMPING] * randomness[PARAM_DAMPING] * _rand_from_seed(&rand_seed); - float v = p.velocity.length(); - v -= dmp * frame_time; - if (v <= 0) { - p.velocity = Vector2(); - } else { - p.velocity = p.velocity.normalized() * v; - } - } - - p.pos += p.velocity * frame_time; - p.rot += Math::lerp(param[PARAM_SPIN_VELOCITY], param[PARAM_SPIN_VELOCITY] * randomness[PARAM_SPIN_VELOCITY] * _rand_from_seed(&rand_seed), randomness[PARAM_SPIN_VELOCITY]) * frame_time; - float anim_spd = param[PARAM_ANIM_SPEED_SCALE] + param[PARAM_ANIM_SPEED_SCALE] * randomness[PARAM_ANIM_SPEED_SCALE] * _rand_from_seed(&rand_seed); - p.frame = Math::fposmod(p.frame + (frame_time / lifetime) * anim_spd, 1.0f); - - active_count++; - } + process_material = p_material; + Ref<ParticlesMaterial> pm = p_material; + if (pm.is_valid() && !pm->get_flag(ParticlesMaterial::FLAG_DISABLE_Z) && pm->get_gravity() == Vector3(0, -9.8, 0)) { + //likely a new material, modify it! + pm->set_flag(ParticlesMaterial::FLAG_DISABLE_Z, true); + pm->set_gravity(Vector3(0, 98, 0)); } + RID material_rid; + if (process_material.is_valid()) + material_rid = process_material->get_rid(); + VS::get_singleton()->particles_set_process_material(particles, material_rid); - time = Math::fmod(time + frame_time, lifetime); - if (!emitting && active_count == 0) { - emit_signal(SceneStringNames::get_singleton()->emission_finished); - set_process(false); - set_fixed_process(false); - } - - update(); -} - -void Particles2D::_notification(int p_what) { - - switch (p_what) { - - case NOTIFICATION_PROCESS: { - - _process_particles(get_process_delta_time()); - } break; - - case NOTIFICATION_FIXED_PROCESS: { - - _process_particles(get_fixed_process_delta_time()); - } break; - - case NOTIFICATION_ENTER_TREE: { - - float ppt = preprocess; - while (ppt > 0) { - _process_particles(0.1); - ppt -= 0.1; - } - } break; - case NOTIFICATION_DRAW: { - - if (particles.size() == 0 || lifetime == 0) - return; - - RID ci = get_canvas_item(); - Size2 size(1, 1); - Point2 center; - int total_frames = 1; - - if (!texture.is_null()) { - size = texture->get_size(); - size.x /= h_frames; - size.y /= v_frames; - total_frames = h_frames * v_frames; - } - - float time_pos = (time / lifetime); - - Particle *pdata = &particles[0]; - int particle_count = particles.size(); - - RID texrid; - - if (texture.is_valid()) - texrid = texture->get_rid(); - - Transform2D invxform; - if (!local_space) - invxform = get_global_transform().affine_inverse(); - - int start_particle = (int)(time * (float)particle_count / lifetime); - - for (int id = 0; id < particle_count; ++id) { - int i = start_particle + id; - if (i >= particle_count) { - i -= particle_count; - } - - Particle &p = pdata[i]; - if (!p.active) - continue; - - float ptime = ((float)i / particle_count) * explosiveness; - - if (ptime < time_pos) - ptime = time_pos - ptime; - else - ptime = (1.0 - ptime) + time_pos; - - uint64_t rand_seed = p.seed * (i + 1); - - Color color; - - if (gradient.is_valid()) { - color = gradient->get_color_at_offset(ptime); - } else { - color = default_color; - } - - { - float huerand = _rand_from_seed(&rand_seed); - float huerot = param[PARAM_HUE_VARIATION] + randomness[PARAM_HUE_VARIATION] * huerand; - - if (Math::abs(huerot) > CMP_EPSILON) { - - float h = color.get_h(); - float s = color.get_s(); - float v = color.get_v(); - float a = color.a; - //float preh=h; - h += huerot; - h = Math::abs(Math::fposmod(h, 1.0f)); - //print_line("rand: "+rtos(randomness[PARAM_HUE_VARIATION])+" rand: "+rtos(huerand)); - //print_line(itos(i)+":hue: "+rtos(preh)+" + "+rtos(huerot)+" = "+rtos(h)); - color.set_hsv(h, s, v); - color.a = a; - } - } - - float initial_size = param[PARAM_INITIAL_SIZE] + param[PARAM_INITIAL_SIZE] * _rand_from_seed(&rand_seed) * randomness[PARAM_INITIAL_SIZE]; - float final_size = param[PARAM_FINAL_SIZE] + param[PARAM_FINAL_SIZE] * _rand_from_seed(&rand_seed) * randomness[PARAM_FINAL_SIZE]; - - float size_mult = initial_size * (1.0 - ptime) + final_size * ptime; - - //Size2 rectsize=size * size_mult; - //rectsize=rectsize.floor(); - - //Rect2 r = Rect2(Vecto,rectsize); - - Transform2D xform; - - if (p.rot) { - - xform.set_rotation(p.rot); - xform.translate(-size * size_mult / 2.0); - xform.elements[2] += p.pos; - } else { - xform.elements[2] = -size * size_mult / 2.0; - xform.elements[2] += p.pos; - } - - if (!local_space) { - xform = invxform * xform; - } - - xform.scale_basis(Size2(size_mult, size_mult)); - - VisualServer::get_singleton()->canvas_item_add_set_transform(ci, xform); - - if (texrid.is_valid()) { - - Rect2 src_rect; - src_rect.size = size; - - if (total_frames > 1) { - int frame = Math::fast_ftoi(Math::floor(p.frame * total_frames)) % total_frames; - src_rect.position.x = size.x * (frame % h_frames); - src_rect.position.y = size.y * (frame / h_frames); - } - Rect2 dst_rect(Point2(), size); - if (flip_h) - dst_rect.size.x = -dst_rect.size.x; - if (flip_v) - dst_rect.size.y = -dst_rect.size.y; - - texture->draw_rect_region(ci, dst_rect, src_rect, color); - //VisualServer::get_singleton()->canvas_item_add_texture_rect(ci,r,texrid,false,color); - } else { - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(), size), color); - } - } - - } break; - } + update_configuration_warning(); } -static const char *_particlesframe_property_names[Particles2D::PARAM_MAX] = { - "params/direction", - "params/spread", - "params/linear_velocity", - "params/spin_velocity", - "params/orbit_velocity", - "params/gravity_direction", - "params/gravity_strength", - "params/radial_accel", - "params/tangential_accel", - "params/damping", - "params/initial_angle", - "params/initial_size", - "params/final_size", - "params/hue_variation", - "params/anim_speed_scale", - "params/anim_initial_pos", -}; - -static const char *_particlesframe_property_rnames[Particles2D::PARAM_MAX] = { - "randomness/direction", - "randomness/spread", - "randomness/linear_velocity", - "randomness/spin_velocity", - "randomness/orbit_velocity", - "randomness/gravity_direction", - "randomness/gravity_strength", - "randomness/radial_accel", - "randomness/tangential_accel", - "randomness/damping", - "randomness/initial_angle", - "randomness/initial_size", - "randomness/final_size", - "randomness/hue_variation", - "randomness/anim_speed_scale", - "randomness/anim_initial_pos", -}; - -static const char *_particlesframe_property_ranges[Particles2D::PARAM_MAX] = { - "0,360,0.01", - "0,180,0.01", - "-1024,1024,0.01", - "-1024,1024,0.01", - "-1024,1024,0.01", - "0,360,0.01", - "0,1024,0.01", - "-128,128,0.01", - "-128,128,0.01", - "0,1024,0.001", - "0,360,0.01", - "0,1024,0.01", - "0,1024,0.01", - "0,1,0.01", - "0,128,0.01", - "0,1,0.01", -}; - -void Particles2D::set_emitting(bool p_emitting) { - - if (emitting == p_emitting) - return; - - if (p_emitting) { +void Particles2D::set_speed_scale(float p_scale) { - if (active_count == 0) - time = 0; - set_process(process_mode == PROCESS_IDLE); - set_fixed_process(process_mode == PROCESS_FIXED); - time_to_live = emit_timeout; - }; - emitting = p_emitting; - _change_notify("config/emitting"); + speed_scale = p_scale; + VS::get_singleton()->particles_set_speed_scale(particles, p_scale); } bool Particles2D::is_emitting() const { return emitting; } - -void Particles2D::set_process_mode(ProcessMode p_mode) { - - process_mode = p_mode; - const bool should_process = emitting || active_count != 0; - set_process(should_process && process_mode == PROCESS_IDLE); - set_fixed_process(should_process && process_mode == PROCESS_FIXED); -} - -Particles2D::ProcessMode Particles2D::get_process_mode() const { - - return process_mode; -} - -void Particles2D::set_amount(int p_amount) { - - ERR_FAIL_INDEX(p_amount, 1024 + 1); - - particles.resize(p_amount); -} int Particles2D::get_amount() const { - return particles.size(); -} - -void Particles2D::set_emit_timeout(float p_timeout) { - - emit_timeout = p_timeout; - time_to_live = p_timeout; -}; - -float Particles2D::get_emit_timeout() const { - - return emit_timeout; -}; - -void Particles2D::set_lifetime(float p_lifetime) { - - ERR_FAIL_INDEX(p_lifetime, 3600 + 1); - - lifetime = p_lifetime; + return amount; } float Particles2D::get_lifetime() const { return lifetime; } - -void Particles2D::set_time_scale(float p_time_scale) { - - time_scale = p_time_scale; -} -float Particles2D::get_time_scale() const { - - return time_scale; -} - -void Particles2D::set_pre_process_time(float p_pre_process_time) { - - preprocess = p_pre_process_time; -} - float Particles2D::get_pre_process_time() const { - return preprocess; -} - -void Particles2D::set_param(Parameter p_param, float p_value) { - - ERR_FAIL_INDEX(p_param, PARAM_MAX); - param[p_param] = p_value; -} -float Particles2D::get_param(Parameter p_param) const { - - ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); - return param[p_param]; -} - -void Particles2D::set_randomness(Parameter p_param, float p_value) { - - ERR_FAIL_INDEX(p_param, PARAM_MAX); - randomness[p_param] = p_value; -} -float Particles2D::get_randomness(Parameter p_param) const { - - ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); - return randomness[p_param]; -} - -void Particles2D::set_texture(const Ref<Texture> &p_texture) { - - texture = p_texture; -} - -Ref<Texture> Particles2D::get_texture() const { - - return texture; + return pre_process_time; } +float Particles2D::get_explosiveness_ratio() const { -void Particles2D::set_color(const Color &p_color) { - - default_color = p_color; + return explosiveness_ratio; } +float Particles2D::get_randomness_ratio() const { -Color Particles2D::get_color() const { - - return default_color; + return randomness_ratio; } +Rect2 Particles2D::get_visibility_rect() const { -void Particles2D::set_gradient(const Ref<Gradient> &p_gradient) { - - gradient = p_gradient; + return visibility_rect; } +bool Particles2D::get_use_local_coordinates() const { -Ref<Gradient> Particles2D::get_gradient() const { - - return gradient; + return local_coords; } +Ref<Material> Particles2D::get_process_material() const { -void Particles2D::set_emissor_offset(const Point2 &p_offset) { - - emissor_offset = p_offset; + return process_material; } -Point2 Particles2D::get_emissor_offset() const { +float Particles2D::get_speed_scale() const { - return emissor_offset; + return speed_scale; } -void Particles2D::set_use_local_space(bool p_use) { +void Particles2D::set_draw_order(DrawOrder p_order) { - local_space = p_use; + draw_order = p_order; + VS::get_singleton()->particles_set_draw_order(particles, VS::ParticlesDrawOrder(p_order)); } -bool Particles2D::is_using_local_space() const { +Particles2D::DrawOrder Particles2D::get_draw_order() const { - return local_space; + return draw_order; } -//Deprecated. Converts color phases to color ramp -void Particles2D::set_color_phases(int p_phases) { - - //Create color ramp if we have 2 or more phases. - //Otherwise first phase phase will be assigned to default color. - if (p_phases > 1 && gradient.is_null()) { - gradient = Ref<Gradient>(memnew(Gradient())); - } - if (gradient.is_valid()) { - gradient->get_points().resize(p_phases); - } +void Particles2D::set_fixed_fps(int p_count) { + fixed_fps = p_count; + VS::get_singleton()->particles_set_fixed_fps(particles, p_count); } -//Deprecated. -int Particles2D::get_color_phases() const { - - if (gradient.is_valid()) { - return gradient->get_points_count(); - } - return 0; +int Particles2D::get_fixed_fps() const { + return fixed_fps; } -//Deprecated. Converts color phases to color ramp -void Particles2D::set_color_phase_color(int p_phase, const Color &p_color) { - - ERR_FAIL_INDEX(p_phase, MAX_COLOR_PHASES); - if (gradient.is_valid()) { - if (gradient->get_points_count() > p_phase) - gradient->set_color(p_phase, p_color); - } else { - if (p_phase == 0) - default_color = p_color; - } +void Particles2D::set_fractional_delta(bool p_enable) { + fractional_delta = p_enable; + VS::get_singleton()->particles_set_fractional_delta(particles, p_enable); } -//Deprecated. -Color Particles2D::get_color_phase_color(int p_phase) const { - - ERR_FAIL_INDEX_V(p_phase, MAX_COLOR_PHASES, Color()); - if (gradient.is_valid()) { - return gradient->get_color(p_phase); - } - return Color(0, 0, 0, 1); +bool Particles2D::get_fractional_delta() const { + return fractional_delta; } -//Deprecated. Converts color phases to color ramp -void Particles2D::set_color_phase_pos(int p_phase, float p_pos) { - ERR_FAIL_INDEX(p_phase, MAX_COLOR_PHASES); - ERR_FAIL_COND(p_pos < 0.0 || p_pos > 1.0); - if (gradient.is_valid() && gradient->get_points_count() > p_phase) { - return gradient->set_offset(p_phase, p_pos); - } -} +String Particles2D::get_configuration_warning() const { -//Deprecated. -float Particles2D::get_color_phase_pos(int p_phase) const { + String warnings; - ERR_FAIL_INDEX_V(p_phase, MAX_COLOR_PHASES, 0); - if (gradient.is_valid()) { - return gradient->get_offset(p_phase); + if (process_material.is_null()) { + if (warnings != String()) + warnings += "\n"; + warnings += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted."); } - return 0; -} - -void Particles2D::set_emission_half_extents(const Vector2 &p_extents) { - extents = p_extents; + return warnings; } -Vector2 Particles2D::get_emission_half_extents() const { +Rect2 Particles2D::capture_rect() const { - return extents; + Rect3 aabb = VS::get_singleton()->particles_get_current_aabb(particles); + Rect2 r; + r.position.x = aabb.position.x; + r.position.y = aabb.position.y; + r.size.x = aabb.size.x; + r.size.y = aabb.size.y; + return r; } -void Particles2D::set_initial_velocity(const Vector2 &p_velocity) { - - initial_velocity = p_velocity; -} -Vector2 Particles2D::get_initial_velocity() const { - - return initial_velocity; +void Particles2D::set_texture(const Ref<Texture> &p_texture) { + texture = p_texture; + update(); } -void Particles2D::pre_process(float p_delta) { - - _process_particles(p_delta); +Ref<Texture> Particles2D::get_texture() const { + return texture; } -void Particles2D::set_explosiveness(float p_value) { +void Particles2D::set_normal_map(const Ref<Texture> &p_normal_map) { - explosiveness = p_value; + normal_map = p_normal_map; + update(); } -float Particles2D::get_explosiveness() const { - - return explosiveness; +Ref<Texture> Particles2D::get_normal_map() const { + return normal_map; } -void Particles2D::set_flip_h(bool p_flip) { - - flip_h = p_flip; +void Particles2D::_validate_property(PropertyInfo &property) const { } -bool Particles2D::is_flipped_h() const { +void Particles2D::set_v_frames(int p_count) { - return flip_h; + ERR_FAIL_COND(p_count < 1); + v_frames = p_count; + update(); } -void Particles2D::set_flip_v(bool p_flip) { - - flip_v = p_flip; -} -bool Particles2D::is_flipped_v() const { +int Particles2D::get_v_frames() const { - return flip_v; + return v_frames; } -void Particles2D::set_h_frames(int p_frames) { +void Particles2D::set_h_frames(int p_count) { - ERR_FAIL_COND(p_frames < 1); - h_frames = p_frames; + ERR_FAIL_COND(p_count < 1); + h_frames = p_count; + update(); } int Particles2D::get_h_frames() const { @@ -932,215 +263,120 @@ int Particles2D::get_h_frames() const { return h_frames; } -void Particles2D::set_v_frames(int p_frames) { - - ERR_FAIL_COND(p_frames < 1); - v_frames = p_frames; -} -int Particles2D::get_v_frames() const { - - return v_frames; -} +void Particles2D::_notification(int p_what) { -void Particles2D::set_emission_points(const PoolVector<Vector2> &p_points) { + if (p_what == NOTIFICATION_DRAW) { - emission_points = p_points; -} + RID texture_rid; + if (texture.is_valid()) + texture_rid = texture->get_rid(); + RID normal_rid; + if (normal_map.is_valid()) + normal_rid = texture->get_rid(); -PoolVector<Vector2> Particles2D::get_emission_points() const { + VS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid, normal_rid, h_frames, v_frames); - return emission_points; -} + if (get_tree()->is_editor_hint() && (this == get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->is_a_parent_of(this))) { -void Particles2D::reset() { + draw_rect(visibility_rect, Color(0, 0.7, 0.9, 0.4), false); + } + } - for (int i = 0; i < particles.size(); i++) { - particles[i].active = false; + if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { + _update_particle_emission_transform(); } - time = 0; - active_count = 0; } void Particles2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_emitting", "active"), &Particles2D::set_emitting); - ClassDB::bind_method(D_METHOD("is_emitting"), &Particles2D::is_emitting); - - ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Particles2D::set_process_mode); - ClassDB::bind_method(D_METHOD("get_process_mode"), &Particles2D::get_process_mode); - + 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("get_amount"), &Particles2D::get_amount); + ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &Particles2D::set_lifetime); + 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); + ClassDB::bind_method(D_METHOD("set_visibility_rect", "aabb"), &Particles2D::set_visibility_rect); + ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &Particles2D::set_use_local_coordinates); + ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &Particles2D::set_fixed_fps); + ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &Particles2D::set_fractional_delta); + ClassDB::bind_method(D_METHOD("set_process_material", "material:Material"), &Particles2D::set_process_material); + ClassDB::bind_method(D_METHOD("set_speed_scale", "scale"), &Particles2D::set_speed_scale); - ClassDB::bind_method(D_METHOD("set_lifetime", "lifetime"), &Particles2D::set_lifetime); + 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("set_time_scale", "time_scale"), &Particles2D::set_time_scale); - ClassDB::bind_method(D_METHOD("get_time_scale"), &Particles2D::get_time_scale); - - ClassDB::bind_method(D_METHOD("set_pre_process_time", "time"), &Particles2D::set_pre_process_time); ClassDB::bind_method(D_METHOD("get_pre_process_time"), &Particles2D::get_pre_process_time); - - ClassDB::bind_method(D_METHOD("set_emit_timeout", "value"), &Particles2D::set_emit_timeout); - ClassDB::bind_method(D_METHOD("get_emit_timeout"), &Particles2D::get_emit_timeout); - - ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &Particles2D::set_param); - ClassDB::bind_method(D_METHOD("get_param", "param"), &Particles2D::get_param); - - ClassDB::bind_method(D_METHOD("set_randomness", "param", "value"), &Particles2D::set_randomness); - ClassDB::bind_method(D_METHOD("get_randomness", "param"), &Particles2D::get_randomness); - - ClassDB::bind_method(D_METHOD("set_texture:Texture", "texture"), &Particles2D::set_texture); + ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &Particles2D::get_explosiveness_ratio); + ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &Particles2D::get_randomness_ratio); + ClassDB::bind_method(D_METHOD("get_visibility_rect"), &Particles2D::get_visibility_rect); + ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &Particles2D::get_use_local_coordinates); + ClassDB::bind_method(D_METHOD("get_fixed_fps"), &Particles2D::get_fixed_fps); + ClassDB::bind_method(D_METHOD("get_fractional_delta"), &Particles2D::get_fractional_delta); + ClassDB::bind_method(D_METHOD("get_process_material:Material"), &Particles2D::get_process_material); + ClassDB::bind_method(D_METHOD("get_speed_scale"), &Particles2D::get_speed_scale); + + ClassDB::bind_method(D_METHOD("set_draw_order", "order"), &Particles2D::set_draw_order); + ClassDB::bind_method(D_METHOD("get_draw_order"), &Particles2D::get_draw_order); + + ClassDB::bind_method(D_METHOD("set_texture", "texture:Texture"), &Particles2D::set_texture); ClassDB::bind_method(D_METHOD("get_texture:Texture"), &Particles2D::get_texture); - ClassDB::bind_method(D_METHOD("set_color", "color"), &Particles2D::set_color); - ClassDB::bind_method(D_METHOD("get_color"), &Particles2D::get_color); - - ClassDB::bind_method(D_METHOD("set_gradient:Gradient", "gradient"), &Particles2D::set_gradient); - ClassDB::bind_method(D_METHOD("get_gradient:Gradient"), &Particles2D::get_gradient); - - ClassDB::bind_method(D_METHOD("set_emissor_offset", "offset"), &Particles2D::set_emissor_offset); - ClassDB::bind_method(D_METHOD("get_emissor_offset"), &Particles2D::get_emissor_offset); - - ClassDB::bind_method(D_METHOD("set_flip_h", "enable"), &Particles2D::set_flip_h); - ClassDB::bind_method(D_METHOD("is_flipped_h"), &Particles2D::is_flipped_h); - - ClassDB::bind_method(D_METHOD("set_flip_v", "enable"), &Particles2D::set_flip_v); - ClassDB::bind_method(D_METHOD("is_flipped_v"), &Particles2D::is_flipped_v); + ClassDB::bind_method(D_METHOD("set_normal_map", "texture:Texture"), &Particles2D::set_normal_map); + ClassDB::bind_method(D_METHOD("get_normal_map:Texture"), &Particles2D::get_normal_map); - ClassDB::bind_method(D_METHOD("set_h_frames", "enable"), &Particles2D::set_h_frames); - ClassDB::bind_method(D_METHOD("get_h_frames"), &Particles2D::get_h_frames); + ClassDB::bind_method(D_METHOD("capture_rect"), &Particles2D::capture_rect); - ClassDB::bind_method(D_METHOD("set_v_frames", "enable"), &Particles2D::set_v_frames); + ClassDB::bind_method(D_METHOD("set_v_frames", "frames"), &Particles2D::set_v_frames); ClassDB::bind_method(D_METHOD("get_v_frames"), &Particles2D::get_v_frames); - ClassDB::bind_method(D_METHOD("set_emission_half_extents", "extents"), &Particles2D::set_emission_half_extents); - ClassDB::bind_method(D_METHOD("get_emission_half_extents"), &Particles2D::get_emission_half_extents); - - ClassDB::bind_method(D_METHOD("set_color_phases", "phases"), &Particles2D::set_color_phases); - ClassDB::bind_method(D_METHOD("get_color_phases"), &Particles2D::get_color_phases); - - ClassDB::bind_method(D_METHOD("set_color_phase_color", "phase", "color"), &Particles2D::set_color_phase_color); - ClassDB::bind_method(D_METHOD("get_color_phase_color", "phase"), &Particles2D::get_color_phase_color); - - ClassDB::bind_method(D_METHOD("set_color_phase_pos", "phase", "pos"), &Particles2D::set_color_phase_pos); - ClassDB::bind_method(D_METHOD("get_color_phase_pos", "phase"), &Particles2D::get_color_phase_pos); - - ClassDB::bind_method(D_METHOD("pre_process", "time"), &Particles2D::pre_process); - ClassDB::bind_method(D_METHOD("reset"), &Particles2D::reset); - - ClassDB::bind_method(D_METHOD("set_use_local_space", "enable"), &Particles2D::set_use_local_space); - ClassDB::bind_method(D_METHOD("is_using_local_space"), &Particles2D::is_using_local_space); - - ClassDB::bind_method(D_METHOD("set_initial_velocity", "velocity"), &Particles2D::set_initial_velocity); - ClassDB::bind_method(D_METHOD("get_initial_velocity"), &Particles2D::get_initial_velocity); - - ClassDB::bind_method(D_METHOD("set_explosiveness", "amount"), &Particles2D::set_explosiveness); - ClassDB::bind_method(D_METHOD("get_explosiveness"), &Particles2D::get_explosiveness); - - ClassDB::bind_method(D_METHOD("set_emission_points", "points"), &Particles2D::set_emission_points); - ClassDB::bind_method(D_METHOD("get_emission_points"), &Particles2D::get_emission_points); - - ADD_SIGNAL(MethodInfo("emission_finished")); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "config/amount", PROPERTY_HINT_EXP_RANGE, "1,1024"), "set_amount", "get_amount"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "config/lifetime", PROPERTY_HINT_EXP_RANGE, "0.1,3600,0.1"), "set_lifetime", "get_lifetime"); - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "config/time_scale", PROPERTY_HINT_EXP_RANGE, "0.01,128,0.01"), "set_time_scale", "get_time_scale"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "config/preprocess", PROPERTY_HINT_EXP_RANGE, "0,3600,0.1"), "set_pre_process_time", "get_pre_process_time"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "config/emit_timeout", PROPERTY_HINT_RANGE, "0,3600,0.1"), "set_emit_timeout", "get_emit_timeout"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "config/emitting"), "set_emitting", "is_emitting"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "config/process_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), "set_process_mode", "get_process_mode"); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "config/offset"), "set_emissor_offset", "get_emissor_offset"); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "config/half_extents"), "set_emission_half_extents", "get_emission_half_extents"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "config/local_space"), "set_use_local_space", "is_using_local_space"); - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "config/explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness", "get_explosiveness"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "config/flip_h"), "set_flip_h", "is_flipped_h"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "config/flip_v"), "set_flip_v", "is_flipped_v"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "config/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "config/h_frames", PROPERTY_HINT_RANGE, "1,512,1"), "set_h_frames", "get_h_frames"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "config/v_frames", PROPERTY_HINT_RANGE, "1,512,1"), "set_v_frames", "get_v_frames"); - - for (int i = 0; i < PARAM_MAX; i++) { - ADD_PROPERTYI(PropertyInfo(Variant::REAL, _particlesframe_property_names[i], PROPERTY_HINT_RANGE, _particlesframe_property_ranges[i]), "set_param", "get_param", i); - } - - for (int i = 0; i < PARAM_MAX; i++) { - ADD_PROPERTYINZ(PropertyInfo(Variant::REAL, _particlesframe_property_rnames[i], PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_randomness", "get_randomness", i); - } - - ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "color_phases/count", PROPERTY_HINT_RANGE, "0,4,1", 0), "set_color_phases", "get_color_phases"); - - //Backward compatibility. They will be converted to color ramp - for (int i = 0; i < MAX_COLOR_PHASES; i++) { - String phase = "phase_" + itos(i) + "/"; - ADD_PROPERTYI(PropertyInfo(Variant::REAL, phase + "pos", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_color_phase_pos", "get_color_phase_pos", i); - ADD_PROPERTYI(PropertyInfo(Variant::COLOR, phase + "color", PROPERTY_HINT_NONE, "", 0), "set_color_phase_color", "get_color_phase_color", i); - } + 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); - ADD_PROPERTYNO(PropertyInfo(Variant::COLOR, "color/color"), "set_color", "get_color"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "color/color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); - - ADD_PROPERTYNZ(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "emission_points", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_emission_points", "get_emission_points"); - - BIND_CONSTANT(PARAM_DIRECTION); - BIND_CONSTANT(PARAM_SPREAD); - BIND_CONSTANT(PARAM_LINEAR_VELOCITY); - BIND_CONSTANT(PARAM_SPIN_VELOCITY); - BIND_CONSTANT(PARAM_ORBIT_VELOCITY); - BIND_CONSTANT(PARAM_GRAVITY_DIRECTION); - BIND_CONSTANT(PARAM_GRAVITY_STRENGTH); - BIND_CONSTANT(PARAM_RADIAL_ACCEL); - BIND_CONSTANT(PARAM_TANGENTIAL_ACCEL); - BIND_CONSTANT(PARAM_DAMPING); - BIND_CONSTANT(PARAM_INITIAL_ANGLE); - BIND_CONSTANT(PARAM_INITIAL_SIZE); - BIND_CONSTANT(PARAM_FINAL_SIZE); - BIND_CONSTANT(PARAM_HUE_VARIATION); - BIND_CONSTANT(PARAM_ANIM_SPEED_SCALE); - BIND_CONSTANT(PARAM_ANIM_INITIAL_POS); - BIND_CONSTANT(PARAM_MAX); - - BIND_CONSTANT(MAX_COLOR_PHASES); + 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::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"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::RECT3, "visibility_rect"), "set_visibility_rect", "get_visibility_rect"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime"), "set_draw_order", "get_draw_order"); + ADD_GROUP("Process Material", "process_"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ParticlesMaterial,ShaderMaterial"), "set_process_material", "get_process_material"); + ADD_GROUP("Textures", ""); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "h_frames", PROPERTY_HINT_RANGE, "1,1024,1"), "set_h_frames", "get_h_frames"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "v_frames", PROPERTY_HINT_RANGE, "1,1024,1"), "set_v_frames", "get_v_frames"); + + BIND_CONSTANT(DRAW_ORDER_INDEX); + BIND_CONSTANT(DRAW_ORDER_LIFETIME); } Particles2D::Particles2D() { - for (int i = 0; i < PARAM_MAX; i++) { - - param[i] = 0; - randomness[i] = 0; - } + particles = VS::get_singleton()->particles_create(); - set_param(PARAM_SPREAD, 10); - set_param(PARAM_LINEAR_VELOCITY, 20); - set_param(PARAM_GRAVITY_STRENGTH, 9.8); - set_param(PARAM_RADIAL_ACCEL, 0); - set_param(PARAM_TANGENTIAL_ACCEL, 0); - set_param(PARAM_INITIAL_ANGLE, 0.0); - set_param(PARAM_INITIAL_SIZE, 1.0); - set_param(PARAM_FINAL_SIZE, 1.0); - set_param(PARAM_ANIM_SPEED_SCALE, 1.0); - - set_color(Color(1, 1, 1, 1)); - - time = 0; - lifetime = 2; - emitting = false; - particles.resize(32); - active_count = -1; set_emitting(true); - process_mode = PROCESS_IDLE; - local_space = true; - preprocess = 0; - time_scale = 1.0; - - flip_h = false; - flip_v = false; - - v_frames = 1; + set_amount(8); + set_lifetime(1); + set_fixed_fps(0); + set_fractional_delta(true); + set_pre_process_time(0); + set_explosiveness_ratio(0); + set_randomness_ratio(0); + set_visibility_rect(Rect2(Vector2(-100, -100), Vector2(200, 200))); + set_use_local_coordinates(true); + set_speed_scale(1); h_frames = 1; + v_frames = 1; +} + +Particles2D::~Particles2D() { - emit_timeout = 0; - time_to_live = 0; - explosiveness = 1.0; + VS::get_singleton()->free(particles); } |