diff options
Diffstat (limited to 'scene/2d')
-rw-r--r-- | scene/2d/animated_sprite.cpp | 8 | ||||
-rw-r--r-- | scene/2d/canvas_item.cpp | 31 | ||||
-rw-r--r-- | scene/2d/canvas_item.h | 3 | ||||
-rw-r--r-- | scene/2d/cpu_particles_2d.cpp | 151 | ||||
-rw-r--r-- | scene/2d/cpu_particles_2d.h | 1 | ||||
-rw-r--r-- | scene/2d/joints_2d.cpp | 6 | ||||
-rw-r--r-- | scene/2d/navigation_2d.cpp | 12 | ||||
-rw-r--r-- | scene/2d/sprite.cpp | 4 |
8 files changed, 132 insertions, 84 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 20ec06f033..9d02408641 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -604,10 +604,14 @@ bool AnimatedSprite::_is_playing() const { void AnimatedSprite::play(const StringName &p_animation, const bool p_backwards) { - if (p_animation) + backwards = p_backwards; + + if (p_animation) { set_animation(p_animation); + if (backwards && get_frame() == 0) + set_frame(frames->get_frame_count(p_animation) - 1); + } - backwards = p_backwards; _set_playing(true); } diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index b38fbfe981..fa23e3fd39 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -360,6 +360,10 @@ bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tole } } +Transform2D CanvasItem::_edit_get_transform() const { + return Transform2D(_edit_get_rotation(), _edit_get_position() + _edit_get_pivot()); +} + bool CanvasItem::is_visible_in_tree() const { if (!is_inside_tree()) @@ -735,6 +739,19 @@ void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vect VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width, p_antialiased); } +void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width, bool p_antialiased) { + + Vector<Point2> points; + points.resize(p_point_count); + const float delta_angle = p_end_angle - p_start_angle; + for (int i = 0; i < p_point_count; i++) { + float theta = (i / (p_point_count - 1.0f)) * delta_angle + p_start_angle; + points.set(i, p_center + Vector2(Math::cos(theta), Math::sin(theta)) * p_radius); + } + + draw_polyline(points, p_color, p_width, p_antialiased); +} + void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -777,29 +794,29 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil VisualServer::get_singleton()->canvas_item_add_line( canvas_item, - p_rect.position + Point2(-offset, 0), + p_rect.position + Size2(-offset, 0), p_rect.position + Size2(p_rect.size.width + offset, 0), p_color, p_width, p_antialiased); VisualServer::get_singleton()->canvas_item_add_line( canvas_item, - p_rect.position + Point2(0, offset), - p_rect.position + Size2(0, p_rect.size.height - offset), + p_rect.position + Size2(p_rect.size.width, offset), + p_rect.position + Size2(p_rect.size.width, p_rect.size.height - offset), p_color, p_width, p_antialiased); VisualServer::get_singleton()->canvas_item_add_line( canvas_item, - p_rect.position + Point2(-offset, p_rect.size.height), p_rect.position + Size2(p_rect.size.width + offset, p_rect.size.height), + p_rect.position + Size2(-offset, p_rect.size.height), p_color, p_width, p_antialiased); VisualServer::get_singleton()->canvas_item_add_line( canvas_item, - p_rect.position + Point2(p_rect.size.width, offset), - p_rect.position + Size2(p_rect.size.width, p_rect.size.height - offset), + p_rect.position + Size2(0, p_rect.size.height - offset), + p_rect.position + Size2(0, offset), p_color, p_width, p_antialiased); @@ -1120,6 +1137,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("_edit_set_pivot", "pivot"), &CanvasItem::_edit_set_pivot); ClassDB::bind_method(D_METHOD("_edit_get_pivot"), &CanvasItem::_edit_get_pivot); ClassDB::bind_method(D_METHOD("_edit_use_pivot"), &CanvasItem::_edit_use_pivot); + ClassDB::bind_method(D_METHOD("_edit_get_transform"), &CanvasItem::_edit_get_transform); ClassDB::bind_method(D_METHOD("get_canvas_item"), &CanvasItem::get_canvas_item); @@ -1152,6 +1170,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw_arc", "center", "radius", "start_angle", "end_angle", "point_count", "color", "width", "antialiased"), &CanvasItem::draw_arc, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width", "antialiased"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(1.0), DEFVAL(false)); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 9c6799a441..e51ee601e2 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -281,6 +281,8 @@ public: virtual void _edit_set_pivot(const Point2 &p_pivot){}; virtual Point2 _edit_get_pivot() const { return Point2(); }; + virtual Transform2D _edit_get_transform() const; + /* VISIBILITY */ void set_visible(bool p_visible); @@ -305,6 +307,7 @@ public: void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); + void draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, float p_width = 1.0, bool p_antialiased = false); diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 85c423964b..372d8f614b 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -37,6 +37,9 @@ void CPUParticles2D::set_emitting(bool p_emitting) { + if (emitting == p_emitting) + return; + emitting = p_emitting; if (emitting) set_process_internal(true); @@ -257,8 +260,7 @@ void CPUParticles2D::restart() { inactive_time = 0; frame_remainder = 0; cycle = 0; - - set_emitting(true); + emitting = false; { int pc = particles.size(); @@ -268,6 +270,8 @@ void CPUParticles2D::restart() { w[i].active = false; } } + + set_emitting(true); } void CPUParticles2D::set_direction(Vector2 p_direction) { @@ -535,6 +539,74 @@ static float rand_from_seed(uint32_t &seed) { return float(seed % uint32_t(65536)) / 65535.0; } +void CPUParticles2D::_update_internal() { + + if (particles.size() == 0 || !is_visible_in_tree()) { + _set_redraw(false); + return; + } + + float delta = get_process_delta_time(); + if (emitting) { + inactive_time = 0; + } else { + inactive_time += delta; + if (inactive_time > lifetime * 1.2) { + set_process_internal(false); + _set_redraw(false); + + //reset variables + time = 0; + inactive_time = 0; + frame_remainder = 0; + cycle = 0; + return; + } + } + _set_redraw(true); + + if (time == 0 && pre_process_time > 0.0) { + + float frame_time; + if (fixed_fps > 0) + frame_time = 1.0 / fixed_fps; + else + frame_time = 1.0 / 30.0; + + float todo = pre_process_time; + + while (todo >= 0) { + _particles_process(frame_time); + todo -= frame_time; + } + } + + if (fixed_fps > 0) { + float frame_time = 1.0 / fixed_fps; + float decr = frame_time; + + float ldelta = delta; + if (ldelta > 0.1) { //avoid recursive stalls if fps goes below 10 + ldelta = 0.1; + } else if (ldelta <= 0.0) { //unlikely but.. + ldelta = 0.001; + } + float todo = frame_remainder + ldelta; + + while (todo >= frame_time) { + _particles_process(frame_time); + todo -= decr; + } + + frame_remainder = todo; + + } else { + _particles_process(delta); + } + + _update_particle_data_buffer(); +} + void CPUParticles2D::_particles_process(float p_delta) { p_delta *= speed_scale; @@ -965,7 +1037,9 @@ void CPUParticles2D::_set_redraw(bool p_redraw) { VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); } else { - VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); + if (VS::get_singleton()->is_connected("frame_pre_draw", this, "_update_render_thread")) { + VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); + } VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); @@ -1000,6 +1074,10 @@ void CPUParticles2D::_notification(int p_what) { } if (p_what == NOTIFICATION_DRAW) { + // first update before rendering to avoid one frame delay after emitting starts + if (emitting && (time == 0)) + _update_internal(); + if (!redraw) return; // don't add to render list @@ -1017,71 +1095,7 @@ void CPUParticles2D::_notification(int p_what) { } if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - - if (particles.size() == 0 || !is_visible_in_tree()) { - _set_redraw(false); - return; - } - - float delta = get_process_delta_time(); - if (emitting) { - inactive_time = 0; - } else { - inactive_time += delta; - if (inactive_time > lifetime * 1.2) { - set_process_internal(false); - _set_redraw(false); - - //reset variables - time = 0; - inactive_time = 0; - frame_remainder = 0; - cycle = 0; - return; - } - } - _set_redraw(true); - - if (time == 0 && pre_process_time > 0.0) { - - float frame_time; - if (fixed_fps > 0) - frame_time = 1.0 / fixed_fps; - else - frame_time = 1.0 / 30.0; - - float todo = pre_process_time; - - while (todo >= 0) { - _particles_process(frame_time); - todo -= frame_time; - } - } - - if (fixed_fps > 0) { - float frame_time = 1.0 / fixed_fps; - float decr = frame_time; - - float ldelta = delta; - if (ldelta > 0.1) { //avoid recursive stalls if fps goes below 10 - ldelta = 0.1; - } else if (ldelta <= 0.0) { //unlikely but.. - ldelta = 0.001; - } - float todo = frame_remainder + ldelta; - - while (todo >= frame_time) { - _particles_process(frame_time); - todo -= decr; - } - - frame_remainder = todo; - - } else { - _particles_process(delta); - } - - _update_particle_data_buffer(); + _update_internal(); } if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { @@ -1411,6 +1425,7 @@ CPUParticles2D::CPUParticles2D() { frame_remainder = 0; cycle = 0; redraw = false; + emitting = false; mesh = VisualServer::get_singleton()->mesh_create(); multimesh = VisualServer::get_singleton()->multimesh_create(); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index da668664b9..47b4568dd4 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -174,6 +174,7 @@ private: Vector2 gravity; + void _update_internal(); void _particles_process(float p_delta); void _update_particle_data_buffer(); diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 12fb18cedc..847d08b025 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -37,8 +37,8 @@ void Joint2D::_update_joint(bool p_only_free) { if (joint.is_valid()) { - if (ba.is_valid() && bb.is_valid()) - Physics2DServer::get_singleton()->body_remove_collision_exception(ba, bb); + if (ba.is_valid() && bb.is_valid() && exclude_from_collision) + Physics2DServer::get_singleton()->joint_disable_collisions_between_bodies(joint, false); Physics2DServer::get_singleton()->free(joint); joint = RID(); @@ -131,6 +131,8 @@ void Joint2D::set_exclude_nodes_from_collision(bool p_enable) { if (exclude_from_collision == p_enable) return; + + _update_joint(true); exclude_from_collision = p_enable; _update_joint(); } diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp index 5cf28d6c89..c7d2dabbae 100644 --- a/scene/2d/navigation_2d.cpp +++ b/scene/2d/navigation_2d.cpp @@ -541,7 +541,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect if (CLOCK_TANGENT(apex_point, portal_left, left) >= 0) { //process - if (Math::is_zero_approx(portal_left.distance_squared_to(apex_point)) || CLOCK_TANGENT(apex_point, left, portal_right) > 0) { + if (portal_left.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, left, portal_right) > 0) { left_poly = p; portal_left = left; } else { @@ -551,7 +551,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect left_poly = p; portal_left = apex_point; portal_right = apex_point; - if (!path.size() || path[path.size() - 1] != apex_point) + if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point)) path.push_back(apex_point); skip = true; } @@ -559,7 +559,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect if (!skip && CLOCK_TANGENT(apex_point, portal_right, right) <= 0) { //process - if (Math::is_zero_approx(portal_right.distance_squared_to(apex_point)) || CLOCK_TANGENT(apex_point, right, portal_left) < 0) { + if (portal_right.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, right, portal_left) < 0) { right_poly = p; portal_right = right; } else { @@ -569,7 +569,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect right_poly = p; portal_right = apex_point; portal_left = apex_point; - if (!path.size() || path[path.size() - 1] != apex_point) + if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point)) path.push_back(apex_point); } } @@ -595,7 +595,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect } } - if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_squared_to(begin_point))) { + if (!path.size() || !path[path.size() - 1].is_equal_approx(begin_point)) { path.push_back(begin_point); // Add the begin point } else { path.write[path.size() - 1] = begin_point; // Replace first midpoint by the exact begin point @@ -603,7 +603,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect path.invert(); - if (path.size() <= 1 || !Math::is_zero_approx(path[path.size() - 1].distance_squared_to(end_point))) { + if (path.size() <= 1 || !path[path.size() - 1].is_equal_approx(end_point)) { path.push_back(end_point); // Add the end point } else { path.write[path.size() - 1] = end_point; // Replace last midpoint by the exact end point diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index d2e1e494e3..8cdfceea52 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -387,6 +387,10 @@ void Sprite::_validate_property(PropertyInfo &property) const { property.hint_string = "0," + itos(vframes * hframes - 1) + ",1"; property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS; } + + if (property.name == "frame_coords") { + property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS; + } } void Sprite::_texture_changed() { |