summaryrefslogtreecommitdiff
path: root/scene/2d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d')
-rw-r--r--scene/2d/animated_sprite_2d.cpp13
-rw-r--r--scene/2d/audio_listener_2d.cpp1
-rw-r--r--scene/2d/audio_stream_player_2d.cpp113
-rw-r--r--scene/2d/camera_2d.cpp40
-rw-r--r--scene/2d/camera_2d.h1
-rw-r--r--scene/2d/canvas_modulate.cpp43
-rw-r--r--scene/2d/collision_object_2d.cpp5
-rw-r--r--scene/2d/collision_object_2d.h2
-rw-r--r--scene/2d/collision_polygon_2d.cpp28
-rw-r--r--scene/2d/collision_shape_2d.cpp30
-rw-r--r--scene/2d/cpu_particles_2d.cpp48
-rw-r--r--scene/2d/cpu_particles_2d.h1
-rw-r--r--scene/2d/gpu_particles_2d.cpp308
-rw-r--r--scene/2d/gpu_particles_2d.h16
-rw-r--r--scene/2d/joint_2d.cpp18
-rw-r--r--scene/2d/light_2d.cpp33
-rw-r--r--scene/2d/light_occluder_2d.cpp68
-rw-r--r--scene/2d/line_2d.cpp19
-rw-r--r--scene/2d/mesh_instance_2d.cpp11
-rw-r--r--scene/2d/multimesh_instance_2d.cpp11
-rw-r--r--scene/2d/navigation_agent_2d.cpp5
-rw-r--r--scene/2d/navigation_obstacle_2d.cpp12
-rw-r--r--scene/2d/navigation_region_2d.cpp14
-rw-r--r--scene/2d/navigation_region_2d.h4
-rw-r--r--scene/2d/node_2d.cpp5
-rw-r--r--scene/2d/parallax_background.cpp3
-rw-r--r--scene/2d/parallax_layer.cpp1
-rw-r--r--scene/2d/path_2d.cpp45
-rw-r--r--scene/2d/physics_body_2d.cpp106
-rw-r--r--scene/2d/physics_body_2d.h20
-rw-r--r--scene/2d/polygon_2d.cpp15
-rw-r--r--scene/2d/position_2d.cpp48
-rw-r--r--scene/2d/ray_cast_2d.cpp47
-rw-r--r--scene/2d/ray_cast_2d.h6
-rw-r--r--scene/2d/remote_transform_2d.cpp3
-rw-r--r--scene/2d/shape_cast_2d.cpp38
-rw-r--r--scene/2d/shape_cast_2d.h7
-rw-r--r--scene/2d/skeleton_2d.cpp372
-rw-r--r--scene/2d/sprite_2d.cpp5
-rw-r--r--scene/2d/tile_map.cpp49
-rw-r--r--scene/2d/tile_map.h3
-rw-r--r--scene/2d/touch_screen_button.cpp54
-rw-r--r--scene/2d/touch_screen_button.h6
-rw-r--r--scene/2d/visible_on_screen_notifier_2d.cpp31
44 files changed, 910 insertions, 798 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index 4916eb573c..257e334873 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -158,14 +158,14 @@ void AnimatedSprite2D::_notification(int p_what) {
return;
}
- double speed = frames->get_animation_speed(animation) * speed_scale;
- if (speed == 0) {
- return; //do nothing
- }
-
double remaining = get_process_delta_time();
while (remaining) {
+ double speed = frames->get_animation_speed(animation) * speed_scale;
+ if (speed == 0) {
+ return; // Do nothing.
+ }
+
if (timeout <= 0) {
timeout = _get_frame_duration();
@@ -247,7 +247,6 @@ void AnimatedSprite2D::_notification(int p_what) {
}
texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false);
-
} break;
}
}
@@ -417,7 +416,7 @@ void AnimatedSprite2D::_reset_timeout() {
void AnimatedSprite2D::set_animation(const StringName &p_animation) {
ERR_FAIL_COND_MSG(frames == nullptr, vformat("There is no animation with name '%s'.", p_animation));
- ERR_FAIL_COND_MSG(frames->get_animation_names().find(p_animation) == -1, vformat("There is no animation with name '%s'.", p_animation));
+ ERR_FAIL_COND_MSG(!frames->get_animation_names().has(p_animation), vformat("There is no animation with name '%s'.", p_animation));
if (animation == p_animation) {
return;
diff --git a/scene/2d/audio_listener_2d.cpp b/scene/2d/audio_listener_2d.cpp
index 8fae339756..eb463864e1 100644
--- a/scene/2d/audio_listener_2d.cpp
+++ b/scene/2d/audio_listener_2d.cpp
@@ -67,6 +67,7 @@ void AudioListener2D::_notification(int p_what) {
make_current();
}
} break;
+
case NOTIFICATION_EXIT_TREE: {
if (!get_tree()->is_node_being_edited(this)) {
if (is_current()) {
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index a761d0d1ec..c1328badfb 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -33,72 +33,75 @@
#include "scene/2d/area_2d.h"
#include "scene/2d/audio_listener_2d.h"
#include "scene/main/window.h"
+#include "scene/resources/world_2d.h"
void AudioStreamPlayer2D::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- AudioServer::get_singleton()->add_listener_changed_callback(_listener_changed_cb, this);
- if (autoplay && !Engine::get_singleton()->is_editor_hint()) {
- play();
- }
- }
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ AudioServer::get_singleton()->add_listener_changed_callback(_listener_changed_cb, this);
+ if (autoplay && !Engine::get_singleton()->is_editor_hint()) {
+ play();
+ }
+ } break;
- if (p_what == NOTIFICATION_EXIT_TREE) {
- stop();
- AudioServer::get_singleton()->remove_listener_changed_callback(_listener_changed_cb, this);
- }
+ case NOTIFICATION_EXIT_TREE: {
+ stop();
+ AudioServer::get_singleton()->remove_listener_changed_callback(_listener_changed_cb, this);
+ } break;
- if (p_what == NOTIFICATION_PAUSED) {
- if (!can_process()) {
- // Node can't process so we start fading out to silence
- set_stream_paused(true);
- }
- }
+ case NOTIFICATION_PAUSED: {
+ if (!can_process()) {
+ // Node can't process so we start fading out to silence.
+ set_stream_paused(true);
+ }
+ } break;
- if (p_what == NOTIFICATION_UNPAUSED) {
- set_stream_paused(false);
- }
+ case NOTIFICATION_UNPAUSED: {
+ set_stream_paused(false);
+ } break;
- if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
- //update anything related to position first, if possible of course
- if (setplay.get() > 0 || (active.is_set() && last_mix_count != AudioServer::get_singleton()->get_mix_count())) {
- _update_panning();
- }
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+ // Update anything related to position first, if possible of course.
+ if (setplay.get() > 0 || (active.is_set() && last_mix_count != AudioServer::get_singleton()->get_mix_count())) {
+ _update_panning();
+ }
- if (setplay.get() >= 0 && stream.is_valid()) {
- active.set();
- Ref<AudioStreamPlayback> new_playback = stream->instance_playback();
- ERR_FAIL_COND_MSG(new_playback.is_null(), "Failed to instantiate playback.");
- AudioServer::get_singleton()->start_playback_stream(new_playback, _get_actual_bus(), volume_vector, setplay.get(), pitch_scale);
- stream_playbacks.push_back(new_playback);
- setplay.set(-1);
- }
+ if (setplay.get() >= 0 && stream.is_valid()) {
+ active.set();
+ Ref<AudioStreamPlayback> new_playback = stream->instance_playback();
+ ERR_FAIL_COND_MSG(new_playback.is_null(), "Failed to instantiate playback.");
+ AudioServer::get_singleton()->start_playback_stream(new_playback, _get_actual_bus(), volume_vector, setplay.get(), pitch_scale);
+ stream_playbacks.push_back(new_playback);
+ setplay.set(-1);
+ }
- if (!stream_playbacks.is_empty() && active.is_set()) {
- // Stop playing if no longer active.
- Vector<Ref<AudioStreamPlayback>> playbacks_to_remove;
- for (Ref<AudioStreamPlayback> &playback : stream_playbacks) {
- if (playback.is_valid() && !AudioServer::get_singleton()->is_playback_active(playback) && !AudioServer::get_singleton()->is_playback_paused(playback)) {
- playbacks_to_remove.push_back(playback);
+ if (!stream_playbacks.is_empty() && active.is_set()) {
+ // Stop playing if no longer active.
+ Vector<Ref<AudioStreamPlayback>> playbacks_to_remove;
+ for (Ref<AudioStreamPlayback> &playback : stream_playbacks) {
+ if (playback.is_valid() && !AudioServer::get_singleton()->is_playback_active(playback) && !AudioServer::get_singleton()->is_playback_paused(playback)) {
+ playbacks_to_remove.push_back(playback);
+ }
+ }
+ // Now go through and remove playbacks that have finished. Removing elements from a Vector in a range based for is asking for trouble.
+ for (Ref<AudioStreamPlayback> &playback : playbacks_to_remove) {
+ stream_playbacks.erase(playback);
+ }
+ if (!playbacks_to_remove.is_empty() && stream_playbacks.is_empty()) {
+ // This node is no longer actively playing audio.
+ active.clear();
+ set_physics_process_internal(false);
+ }
+ if (!playbacks_to_remove.is_empty()) {
+ emit_signal(SNAME("finished"));
}
}
- // Now go through and remove playbacks that have finished. Removing elements from a Vector in a range based for is asking for trouble.
- for (Ref<AudioStreamPlayback> &playback : playbacks_to_remove) {
- stream_playbacks.erase(playback);
- }
- if (!playbacks_to_remove.is_empty() && stream_playbacks.is_empty()) {
- // This node is no longer actively playing audio.
- active.clear();
- set_physics_process_internal(false);
- }
- if (!playbacks_to_remove.is_empty()) {
- emit_signal(SNAME("finished"));
- }
- }
- while (stream_playbacks.size() > max_polyphony) {
- AudioServer::get_singleton()->stop_playback_stream(stream_playbacks[0]);
- stream_playbacks.remove_at(0);
- }
+ while (stream_playbacks.size() > max_polyphony) {
+ AudioServer::get_singleton()->stop_playback_stream(stream_playbacks[0]);
+ stream_playbacks.remove_at(0);
+ }
+ } break;
}
}
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index f4c0665f36..efde8d8a2b 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -30,6 +30,7 @@
#include "camera_2d.h"
+#include "core/config/project_settings.h"
#include "scene/main/window.h"
void Camera2D::_update_scroll() {
@@ -78,6 +79,7 @@ void Camera2D::set_zoom(const Vector2 &p_zoom) {
ERR_FAIL_COND_MSG(Math::is_zero_approx(p_zoom.x) || Math::is_zero_approx(p_zoom.y), "Zoom level must be different from 0 (can be negative).");
zoom = p_zoom;
+ zoom_scale = Vector2(1, 1) / zoom;
Point2 old_smoothed_camera_pos = smoothed_camera_pos;
_update_scroll();
smoothed_camera_pos = old_smoothed_camera_pos;
@@ -102,8 +104,8 @@ Transform2D Camera2D::get_camera_transform() {
if (!first) {
if (anchor_mode == ANCHOR_MODE_DRAG_CENTER) {
if (drag_horizontal_enabled && !Engine::get_singleton()->is_editor_hint() && !drag_horizontal_offset_changed) {
- camera_pos.x = MIN(camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * zoom.x * drag_margin[SIDE_LEFT]));
- camera_pos.x = MAX(camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * zoom.x * drag_margin[SIDE_RIGHT]));
+ camera_pos.x = MIN(camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * zoom_scale.x * drag_margin[SIDE_LEFT]));
+ camera_pos.x = MAX(camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * zoom_scale.x * drag_margin[SIDE_RIGHT]));
} else {
if (drag_horizontal_offset < 0) {
camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[SIDE_RIGHT] * drag_horizontal_offset;
@@ -115,8 +117,8 @@ Transform2D Camera2D::get_camera_transform() {
}
if (drag_vertical_enabled && !Engine::get_singleton()->is_editor_hint() && !drag_vertical_offset_changed) {
- camera_pos.y = MIN(camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * zoom.y * drag_margin[SIDE_TOP]));
- camera_pos.y = MAX(camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * zoom.y * drag_margin[SIDE_BOTTOM]));
+ camera_pos.y = MIN(camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * zoom_scale.y * drag_margin[SIDE_TOP]));
+ camera_pos.y = MAX(camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * zoom_scale.y * drag_margin[SIDE_BOTTOM]));
} else {
if (drag_vertical_offset < 0) {
@@ -132,8 +134,8 @@ Transform2D Camera2D::get_camera_transform() {
camera_pos = new_camera_pos;
}
- Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2());
- Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom);
+ Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom_scale) : Point2());
+ Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom_scale);
if (limit_smoothing_enabled) {
if (screen_rect.position.x < limit[SIDE_LEFT]) {
@@ -167,14 +169,14 @@ Transform2D Camera2D::get_camera_transform() {
first = false;
}
- Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2());
+ Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom_scale) : Point2());
real_t angle = get_global_rotation();
if (rotating) {
screen_offset = screen_offset.rotated(angle);
}
- Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom);
+ Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom_scale);
if (!smoothing_enabled || !limit_smoothing_enabled) {
if (screen_rect.position.x < limit[SIDE_LEFT]) {
@@ -201,19 +203,11 @@ Transform2D Camera2D::get_camera_transform() {
camera_screen_center = screen_rect.get_center();
Transform2D xform;
- xform.scale_basis(zoom);
+ xform.scale_basis(zoom_scale);
if (rotating) {
xform.set_rotation(angle);
}
- xform.set_origin(screen_rect.position /*.floor()*/);
-
- /*
- if (0) {
- xform = get_global_transform() * xform;
- } else {
- xform.elements[2]+=get_global_transform().get_origin();
- }
-*/
+ xform.set_origin(screen_rect.position);
return (xform).affine_inverse();
}
@@ -223,14 +217,14 @@ void Camera2D::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PROCESS:
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
_update_scroll();
-
} break;
+
case NOTIFICATION_TRANSFORM_CHANGED: {
if (!is_processing_internal() && !is_physics_processing_internal()) {
_update_scroll();
}
-
} break;
+
case NOTIFICATION_ENTER_TREE: {
ERR_FAIL_COND(!is_inside_tree());
if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) {
@@ -255,8 +249,8 @@ void Camera2D::_notification(int p_what) {
_update_process_callback();
_update_scroll();
first = true;
-
} break;
+
case NOTIFICATION_EXIT_TREE: {
if (is_current()) {
if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) {
@@ -268,8 +262,8 @@ void Camera2D::_notification(int p_what) {
remove_from_group(group_name);
remove_from_group(canvas_group_name);
viewport = nullptr;
-
} break;
+
#ifdef TOOLS_ENABLED
case NOTIFICATION_DRAW: {
if (!is_inside_tree() || !Engine::get_singleton()->is_editor_hint()) {
@@ -530,7 +524,7 @@ Point2 Camera2D::get_camera_screen_center() const {
Size2 Camera2D::_get_camera_screen_size() const {
// special case if the camera2D is in the root viewport
if (Engine::get_singleton()->is_editor_hint() && get_viewport()->get_parent_viewport() == get_tree()->get_root()) {
- return Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
+ return Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height"));
}
return get_viewport_rect().size;
}
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 662bee3612..294a6fcb80 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -61,6 +61,7 @@ protected:
RID canvas;
Vector2 offset;
Vector2 zoom = Vector2(1, 1);
+ Vector2 zoom_scale = Vector2(1, 1);
AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER;
bool rotating = false;
bool current = false;
diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp
index d0abed4a0c..7f7eae51a6 100644
--- a/scene/2d/canvas_modulate.cpp
+++ b/scene/2d/canvas_modulate.cpp
@@ -31,27 +31,32 @@
#include "canvas_modulate.h"
void CanvasModulate::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_CANVAS) {
- if (is_visible_in_tree()) {
- RS::get_singleton()->canvas_set_modulate(get_canvas(), color);
- add_to_group("_canvas_modulate_" + itos(get_canvas().get_id()));
- }
+ switch (p_what) {
+ case NOTIFICATION_ENTER_CANVAS: {
+ if (is_visible_in_tree()) {
+ RS::get_singleton()->canvas_set_modulate(get_canvas(), color);
+ add_to_group("_canvas_modulate_" + itos(get_canvas().get_id()));
+ }
+ } break;
- } else if (p_what == NOTIFICATION_EXIT_CANVAS) {
- if (is_visible_in_tree()) {
- RS::get_singleton()->canvas_set_modulate(get_canvas(), Color(1, 1, 1, 1));
- remove_from_group("_canvas_modulate_" + itos(get_canvas().get_id()));
- }
- } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- if (is_visible_in_tree()) {
- RS::get_singleton()->canvas_set_modulate(get_canvas(), color);
- add_to_group("_canvas_modulate_" + itos(get_canvas().get_id()));
- } else {
- RS::get_singleton()->canvas_set_modulate(get_canvas(), Color(1, 1, 1, 1));
- remove_from_group("_canvas_modulate_" + itos(get_canvas().get_id()));
- }
+ case NOTIFICATION_EXIT_CANVAS: {
+ if (is_visible_in_tree()) {
+ RS::get_singleton()->canvas_set_modulate(get_canvas(), Color(1, 1, 1, 1));
+ remove_from_group("_canvas_modulate_" + itos(get_canvas().get_id()));
+ }
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ if (is_visible_in_tree()) {
+ RS::get_singleton()->canvas_set_modulate(get_canvas(), color);
+ add_to_group("_canvas_modulate_" + itos(get_canvas().get_id()));
+ } else {
+ RS::get_singleton()->canvas_set_modulate(get_canvas(), Color(1, 1, 1, 1));
+ remove_from_group("_canvas_modulate_" + itos(get_canvas().get_id()));
+ }
- update_configuration_warnings();
+ update_configuration_warnings();
+ } break;
}
}
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 0f4e3c8bed..fbfe1d7eff 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -30,6 +30,7 @@
#include "collision_object_2d.h"
+#include "scene/resources/world_2d.h"
#include "scene/scene_string_names.h"
void CollisionObject2D::_notification(int p_what) {
@@ -268,7 +269,7 @@ uint32_t CollisionObject2D::create_shape_owner(Object *p_owner) {
id = shapes.back()->key() + 1;
}
- sd.owner = p_owner;
+ sd.owner_id = p_owner ? p_owner->get_instance_id() : ObjectID();
shapes[id] = sd;
@@ -382,7 +383,7 @@ Transform2D CollisionObject2D::shape_owner_get_transform(uint32_t p_owner) const
Object *CollisionObject2D::shape_owner_get_owner(uint32_t p_owner) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), nullptr);
- return shapes[p_owner].owner;
+ return ObjectDB::get_instance(shapes[p_owner].owner_id);
}
void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape) {
diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h
index 9463b2c429..f2b7eecc7b 100644
--- a/scene/2d/collision_object_2d.h
+++ b/scene/2d/collision_object_2d.h
@@ -59,7 +59,7 @@ private:
PhysicsServer2D::BodyMode body_mode = PhysicsServer2D::BODY_MODE_STATIC;
struct ShapeData {
- Object *owner = nullptr;
+ ObjectID owner_id;
Transform2D xform;
struct Shape {
Ref<Shape2D> shape;
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 9bc3226851..e3939130ec 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -102,26 +102,20 @@ void CollisionPolygon2D::_notification(int p_what) {
_build_polygon();
_update_in_shape_owner();
}
-
- /*if (Engine::get_singleton()->is_editor_hint()) {
- //display above all else
- set_z_as_relative(false);
- set_z_index(RS::CANVAS_ITEM_Z_MAX - 1);
- }*/
-
} break;
+
case NOTIFICATION_ENTER_TREE: {
if (parent) {
_update_in_shape_owner();
}
-
} break;
+
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
if (parent) {
_update_in_shape_owner(true);
}
-
} break;
+
case NOTIFICATION_UNPARENTED: {
if (parent) {
parent->remove_shape_owner(owner_id);
@@ -164,15 +158,15 @@ void CollisionPolygon2D::_notification(int p_what) {
dcol.a = 1.0;
Vector2 line_to(0, 20);
draw_line(Vector2(), line_to, dcol, 3);
- Vector<Vector2> pts;
real_t tsize = 8;
- pts.push_back(line_to + (Vector2(0, tsize)));
- pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0)));
- pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0)));
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(dcol);
- }
+
+ Vector<Vector2> pts = {
+ line_to + Vector2(0, tsize),
+ line_to + Vector2(Math_SQRT12 * tsize, 0),
+ line_to + Vector2(-Math_SQRT12 * tsize, 0)
+ };
+
+ Vector<Color> cols{ dcol, dcol, dcol };
draw_primitive(pts, cols, Vector<Vector2>()); //small arrow
}
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index 18426c088d..db9a745436 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -59,34 +59,28 @@ void CollisionShape2D::_notification(int p_what) {
}
_update_in_shape_owner();
}
-
- /*if (Engine::get_singleton()->is_editor_hint()) {
- //display above all else
- set_z_as_relative(false);
- set_z_index(RS::CANVAS_ITEM_Z_MAX - 1);
- }*/
-
} break;
+
case NOTIFICATION_ENTER_TREE: {
if (parent) {
_update_in_shape_owner();
}
-
} break;
+
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
if (parent) {
_update_in_shape_owner(true);
}
-
} break;
+
case NOTIFICATION_UNPARENTED: {
if (parent) {
parent->remove_shape_owner(owner_id);
}
owner_id = 0;
parent = nullptr;
-
} break;
+
case NOTIFICATION_DRAW: {
ERR_FAIL_COND(!is_inside_tree());
@@ -121,15 +115,15 @@ void CollisionShape2D::_notification(int p_what) {
}
Vector2 line_to(0, 20);
draw_line(Vector2(), line_to, draw_col, 2);
- Vector<Vector2> pts;
real_t tsize = 8;
- pts.push_back(line_to + (Vector2(0, tsize)));
- pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0)));
- pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0)));
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(draw_col);
- }
+
+ Vector<Vector2> pts{
+ line_to + Vector2(0, tsize),
+ line_to + Vector2(Math_SQRT12 * tsize, 0),
+ line_to + Vector2(-Math_SQRT12 * tsize, 0)
+ };
+
+ Vector<Color> cols{ draw_col, draw_col, draw_col };
draw_primitive(pts, cols, Vector<Vector2>());
}
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index f62e7f24e3..dd9df3c485 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -152,11 +152,14 @@ void CPUParticles2D::_update_mesh_texture() {
} else {
tex_size = Size2(1, 1);
}
- Vector<Vector2> vertices;
- vertices.push_back(-tex_size * 0.5);
- vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, 0));
- vertices.push_back(-tex_size * 0.5 + tex_size);
- vertices.push_back(-tex_size * 0.5 + Vector2(0, tex_size.y));
+
+ Vector<Vector2> vertices = {
+ -tex_size * 0.5,
+ -tex_size * 0.5 + Vector2(tex_size.x, 0),
+ -tex_size * 0.5 + tex_size,
+ -tex_size * 0.5 + Vector2(0, tex_size.y)
+ };
+
Vector<Vector2> uvs;
AtlasTexture *atlas_texure = Object::cast_to<AtlasTexture>(*texture);
if (atlas_texure && atlas_texure->get_atlas().is_valid()) {
@@ -172,18 +175,15 @@ void CPUParticles2D::_update_mesh_texture() {
uvs.push_back(Vector2(1, 1));
uvs.push_back(Vector2(0, 1));
}
- Vector<Color> colors;
- colors.push_back(Color(1, 1, 1, 1));
- colors.push_back(Color(1, 1, 1, 1));
- colors.push_back(Color(1, 1, 1, 1));
- colors.push_back(Color(1, 1, 1, 1));
- Vector<int> indices;
- indices.push_back(0);
- indices.push_back(1);
- indices.push_back(2);
- indices.push_back(2);
- indices.push_back(3);
- indices.push_back(0);
+
+ Vector<Color> colors = {
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1)
+ };
+
+ Vector<int> indices = { 0, 1, 2, 2, 3, 0 };
Array arr;
arr.resize(RS::ARRAY_MAX);
@@ -500,7 +500,7 @@ bool CPUParticles2D::get_split_scale() {
}
void CPUParticles2D::_validate_property(PropertyInfo &property) const {
- if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) {
+ if (property.name == "emission_sphere_radius" && (emission_shape != EMISSION_SHAPE_SPHERE && emission_shape != EMISSION_SHAPE_SPHERE_SURFACE)) {
property.usage = PROPERTY_USAGE_NONE;
}
@@ -762,6 +762,11 @@ void CPUParticles2D::_particles_process(double p_delta) {
//do none
} break;
case EMISSION_SHAPE_SPHERE: {
+ real_t t = Math_TAU * Math::randf();
+ real_t radius = emission_sphere_radius * Math::randf();
+ p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius;
+ } break;
+ case EMISSION_SHAPE_SPHERE_SURFACE: {
real_t s = Math::randf(), t = Math_TAU * Math::randf();
real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius;
@@ -1091,9 +1096,11 @@ void CPUParticles2D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
set_process_internal(emitting);
} break;
+
case NOTIFICATION_EXIT_TREE: {
_set_redraw(false);
} break;
+
case NOTIFICATION_DRAW: {
// first update before rendering to avoid one frame delay after emitting starts
if (emitting && (time == 0)) {
@@ -1111,9 +1118,11 @@ void CPUParticles2D::_notification(int p_what) {
RS::get_singleton()->canvas_item_add_multimesh(get_canvas_item(), multimesh, texrid);
} break;
+
case NOTIFICATION_INTERNAL_PROCESS: {
_update_internal();
} break;
+
case NOTIFICATION_TRANSFORM_CHANGED: {
inv_emission_transform = get_global_transform().affine_inverse();
@@ -1353,7 +1362,7 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles);
ADD_GROUP("Emission Shape", "emission_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Sphere Surface,Box,Points,Directed Points", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "emission_rect_extents"), "set_emission_rect_extents", "get_emission_rect_extents");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_points"), "set_emission_points", "get_emission_points");
@@ -1443,6 +1452,7 @@ void CPUParticles2D::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE);
+ BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE_SURFACE);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_RECTANGLE);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS);
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 8c8f161d74..7ae51e3966 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -69,6 +69,7 @@ public:
enum EmissionShape {
EMISSION_SHAPE_POINT,
EMISSION_SHAPE_SPHERE,
+ EMISSION_SHAPE_SPHERE_SURFACE,
EMISSION_SHAPE_RECTANGLE,
EMISSION_SHAPE_POINTS,
EMISSION_SHAPE_DIRECTED_POINTS,
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index 8c8f794298..8b0840e7c8 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -335,153 +335,199 @@ Ref<Texture2D> GPUParticles2D::get_texture() const {
void GPUParticles2D::_validate_property(PropertyInfo &property) const {
}
-void GPUParticles2D::restart() {
- RS::get_singleton()->particles_restart(particles);
- RS::get_singleton()->particles_set_emitting(particles, true);
+void GPUParticles2D::emit_particle(const Transform2D &p_transform2d, const Vector2 &p_velocity2d, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
+ Transform3D transform;
+ transform.basis.set_axis(0, Vector3(p_transform2d.get_axis(0).x, p_transform2d.get_axis(0).y, 0));
+ transform.basis.set_axis(1, Vector3(p_transform2d.get_axis(1).x, p_transform2d.get_axis(1).y, 0));
+ transform.set_origin(Vector3(p_transform2d.get_origin().x, p_transform2d.get_origin().y, 0));
+ Vector3 velocity = Vector3(p_velocity2d.x, p_velocity2d.y, 0);
+
+ RS::get_singleton()->particles_emit(particles, transform, velocity, p_color, p_custom, p_emit_flags);
+}
+
+void GPUParticles2D::_attach_sub_emitter() {
+ Node *n = get_node_or_null(sub_emitter);
+ if (n) {
+ GPUParticles2D *sen = Object::cast_to<GPUParticles2D>(n);
+ if (sen && sen != this) {
+ RS::get_singleton()->particles_set_subemitter(particles, sen->particles);
+ }
+ }
}
-void GPUParticles2D::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW) {
- RID texture_rid;
- Size2 size;
- if (texture.is_valid()) {
- texture_rid = texture->get_rid();
- size = texture->get_size();
- } else {
- size = Size2(1, 1);
- }
+void GPUParticles2D::set_sub_emitter(const NodePath &p_path) {
+ if (is_inside_tree()) {
+ RS::get_singleton()->particles_set_subemitter(particles, RID());
+ }
- if (trail_enabled) {
- RS::get_singleton()->mesh_clear(mesh);
- PackedVector2Array points;
- PackedVector2Array uvs;
- PackedInt32Array bone_indices;
- PackedFloat32Array bone_weights;
- PackedInt32Array indices;
+ sub_emitter = p_path;
- int total_segments = trail_sections * trail_section_subdivisions;
- real_t depth = size.height * trail_sections;
+ if (is_inside_tree() && sub_emitter != NodePath()) {
+ _attach_sub_emitter();
+ }
+}
- for (int j = 0; j <= total_segments; j++) {
- real_t v = j;
- v /= total_segments;
+NodePath GPUParticles2D::get_sub_emitter() const {
+ return sub_emitter;
+}
- real_t y = depth * v;
- y = (depth * 0.5) - y;
+void GPUParticles2D::restart() {
+ RS::get_singleton()->particles_restart(particles);
+ RS::get_singleton()->particles_set_emitting(particles, true);
+}
- int bone = j / trail_section_subdivisions;
- real_t blend = 1.0 - real_t(j % trail_section_subdivisions) / real_t(trail_section_subdivisions);
+void GPUParticles2D::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+ RID texture_rid;
+ Size2 size;
+ if (texture.is_valid()) {
+ texture_rid = texture->get_rid();
+ size = texture->get_size();
+ } else {
+ size = Size2(1, 1);
+ }
- real_t s = size.width;
+ if (trail_enabled) {
+ RS::get_singleton()->mesh_clear(mesh);
+ PackedVector2Array points;
+ PackedVector2Array uvs;
+ PackedInt32Array bone_indices;
+ PackedFloat32Array bone_weights;
+ PackedInt32Array indices;
+
+ int total_segments = trail_sections * trail_section_subdivisions;
+ real_t depth = size.height * trail_sections;
+
+ for (int j = 0; j <= total_segments; j++) {
+ real_t v = j;
+ v /= total_segments;
+
+ real_t y = depth * v;
+ y = (depth * 0.5) - y;
+
+ int bone = j / trail_section_subdivisions;
+ real_t blend = 1.0 - real_t(j % trail_section_subdivisions) / real_t(trail_section_subdivisions);
+
+ real_t s = size.width;
+
+ points.push_back(Vector2(-s * 0.5, 0));
+ points.push_back(Vector2(+s * 0.5, 0));
+
+ uvs.push_back(Vector2(0, v));
+ uvs.push_back(Vector2(1, v));
+
+ for (int i = 0; i < 2; i++) {
+ bone_indices.push_back(bone);
+ bone_indices.push_back(MIN(trail_sections, bone + 1));
+ bone_indices.push_back(0);
+ bone_indices.push_back(0);
+
+ bone_weights.push_back(blend);
+ bone_weights.push_back(1.0 - blend);
+ bone_weights.push_back(0);
+ bone_weights.push_back(0);
+ }
+
+ if (j > 0) {
+ int base = j * 2 - 2;
+ indices.push_back(base + 0);
+ indices.push_back(base + 1);
+ indices.push_back(base + 2);
+
+ indices.push_back(base + 1);
+ indices.push_back(base + 3);
+ indices.push_back(base + 2);
+ }
+ }
- points.push_back(Vector2(-s * 0.5, 0));
- points.push_back(Vector2(+s * 0.5, 0));
+ Array arr;
+ arr.resize(RS::ARRAY_MAX);
+ arr[RS::ARRAY_VERTEX] = points;
+ arr[RS::ARRAY_TEX_UV] = uvs;
+ arr[RS::ARRAY_BONES] = bone_indices;
+ arr[RS::ARRAY_WEIGHTS] = bone_weights;
+ arr[RS::ARRAY_INDEX] = indices;
+
+ RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
+
+ Vector<Transform3D> xforms;
+ for (int i = 0; i <= trail_sections; i++) {
+ Transform3D xform;
+ /*
+ xform.origin.y = depth / 2.0 - size.height * real_t(i);
+ xform.origin.y = -xform.origin.y; //bind is an inverse transform, so negate y */
+ xforms.push_back(xform);
+ }
- uvs.push_back(Vector2(0, v));
- uvs.push_back(Vector2(1, v));
+ RS::get_singleton()->particles_set_trail_bind_poses(particles, xforms);
- for (int i = 0; i < 2; i++) {
- bone_indices.push_back(bone);
- bone_indices.push_back(MIN(trail_sections, bone + 1));
- bone_indices.push_back(0);
- bone_indices.push_back(0);
+ } else {
+ RS::get_singleton()->mesh_clear(mesh);
- bone_weights.push_back(blend);
- bone_weights.push_back(1.0 - blend);
- bone_weights.push_back(0);
- bone_weights.push_back(0);
- }
+ Vector<Vector2> points = {
+ Vector2(-size.x / 2.0, -size.y / 2.0),
+ Vector2(size.x / 2.0, -size.y / 2.0),
+ Vector2(size.x / 2.0, size.y / 2.0),
+ Vector2(-size.x / 2.0, size.y / 2.0)
+ };
- if (j > 0) {
- int base = j * 2 - 2;
- indices.push_back(base + 0);
- indices.push_back(base + 1);
- indices.push_back(base + 2);
+ Vector<Vector2> uvs = {
+ Vector2(0, 0),
+ Vector2(1, 0),
+ Vector2(1, 1),
+ Vector2(0, 1)
+ };
- indices.push_back(base + 1);
- indices.push_back(base + 3);
- indices.push_back(base + 2);
- }
- }
+ Vector<int> indices = { 0, 1, 2, 0, 2, 3 };
- Array arr;
- arr.resize(RS::ARRAY_MAX);
- arr[RS::ARRAY_VERTEX] = points;
- arr[RS::ARRAY_TEX_UV] = uvs;
- arr[RS::ARRAY_BONES] = bone_indices;
- arr[RS::ARRAY_WEIGHTS] = bone_weights;
- arr[RS::ARRAY_INDEX] = indices;
-
- RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
-
- Vector<Transform3D> xforms;
- for (int i = 0; i <= trail_sections; i++) {
- Transform3D xform;
- /*
- xform.origin.y = depth / 2.0 - size.height * real_t(i);
- xform.origin.y = -xform.origin.y; //bind is an inverse transform, so negate y */
- xforms.push_back(xform);
- }
+ Array arr;
+ arr.resize(RS::ARRAY_MAX);
+ arr[RS::ARRAY_VERTEX] = points;
+ arr[RS::ARRAY_TEX_UV] = uvs;
+ arr[RS::ARRAY_INDEX] = indices;
- RS::get_singleton()->particles_set_trail_bind_poses(particles, xforms);
-
- } else {
- RS::get_singleton()->mesh_clear(mesh);
- Vector<Vector2> points;
- points.resize(4);
- points.write[0] = Vector2(-size.x / 2.0, -size.y / 2.0);
- points.write[1] = Vector2(size.x / 2.0, -size.y / 2.0);
- points.write[2] = Vector2(size.x / 2.0, size.y / 2.0);
- points.write[3] = Vector2(-size.x / 2.0, size.y / 2.0);
- Vector<Vector2> uvs;
- uvs.resize(4);
- uvs.write[0] = Vector2(0, 0);
- uvs.write[1] = Vector2(1, 0);
- uvs.write[2] = Vector2(1, 1);
- uvs.write[3] = Vector2(0, 1);
- Vector<int> indices;
- indices.resize(6);
- indices.write[0] = 0;
- indices.write[1] = 1;
- indices.write[2] = 2;
- indices.write[3] = 0;
- indices.write[4] = 2;
- indices.write[5] = 3;
- Array arr;
- arr.resize(RS::ARRAY_MAX);
- arr[RS::ARRAY_VERTEX] = points;
- arr[RS::ARRAY_TEX_UV] = uvs;
- arr[RS::ARRAY_INDEX] = indices;
-
- RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
- RS::get_singleton()->particles_set_trail_bind_poses(particles, Vector<Transform3D>());
- }
- RS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid);
+ RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
+ RS::get_singleton()->particles_set_trail_bind_poses(particles, Vector<Transform3D>());
+ }
+ RS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid);
#ifdef TOOLS_ENABLED
- if (show_visibility_rect) {
- draw_rect(visibility_rect, Color(0, 0.7, 0.9, 0.4), false);
- }
+ if (show_visibility_rect) {
+ draw_rect(visibility_rect, Color(0, 0.7, 0.9, 0.4), false);
+ }
#endif
- }
+ } break;
- if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) {
- if (can_process()) {
- RS::get_singleton()->particles_set_speed_scale(particles, speed_scale);
- } else {
- RS::get_singleton()->particles_set_speed_scale(particles, 0);
- }
- }
+ case NOTIFICATION_ENTER_TREE: {
+ if (sub_emitter != NodePath()) {
+ _attach_sub_emitter();
+ }
+ } break;
+
+ case NOTIFICATION_EXIT_TREE: {
+ RS::get_singleton()->particles_set_subemitter(particles, RID());
+ } break;
+
+ case NOTIFICATION_PAUSED:
+ case NOTIFICATION_UNPAUSED: {
+ if (can_process()) {
+ RS::get_singleton()->particles_set_speed_scale(particles, speed_scale);
+ } else {
+ RS::get_singleton()->particles_set_speed_scale(particles, 0);
+ }
+ } break;
- if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
- _update_particle_emission_transform();
- }
+ case NOTIFICATION_TRANSFORM_CHANGED: {
+ _update_particle_emission_transform();
+ } break;
- if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
- if (one_shot && !is_emitting()) {
- notify_property_list_changed();
- set_process_internal(false);
- }
+ case NOTIFICATION_INTERNAL_PROCESS: {
+ if (one_shot && !is_emitting()) {
+ notify_property_list_changed();
+ set_process_internal(false);
+ }
+ } break;
}
}
@@ -526,6 +572,11 @@ void GPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("restart"), &GPUParticles2D::restart);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter", "path"), &GPUParticles2D::set_sub_emitter);
+ ClassDB::bind_method(D_METHOD("get_sub_emitter"), &GPUParticles2D::get_sub_emitter);
+
+ ClassDB::bind_method(D_METHOD("emit_particle", "xform", "velocity", "color", "custom", "flags"), &GPUParticles2D::emit_particle);
+
ClassDB::bind_method(D_METHOD("set_trail_enabled", "enabled"), &GPUParticles2D::set_trail_enabled);
ClassDB::bind_method(D_METHOD("set_trail_length", "secs"), &GPUParticles2D::set_trail_length);
@@ -541,6 +592,7 @@ void GPUParticles2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting");
ADD_PROPERTY_DEFAULT("emitting", true); // Workaround for doctool in headless mode, as dummy rasterizer always returns false.
ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1000000,1,exp"), "set_amount", "get_amount");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "sub_emitter", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GPUParticles2D"), "set_sub_emitter", "get_sub_emitter");
ADD_GROUP("Time", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot");
@@ -569,6 +621,12 @@ void GPUParticles2D::_bind_methods() {
BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX);
BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME);
BIND_ENUM_CONSTANT(DRAW_ORDER_REVERSE_LIFETIME);
+
+ BIND_ENUM_CONSTANT(EMIT_FLAG_POSITION);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_ROTATION_SCALE);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_VELOCITY);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_COLOR);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_CUSTOM);
}
GPUParticles2D::GPUParticles2D() {
diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h
index aa9a8da129..fc95ae27b2 100644
--- a/scene/2d/gpu_particles_2d.h
+++ b/scene/2d/gpu_particles_2d.h
@@ -79,6 +79,8 @@ private:
RID mesh;
+ void _attach_sub_emitter();
+
protected:
static void _bind_methods();
virtual void _validate_property(PropertyInfo &property) const override;
@@ -139,6 +141,19 @@ public:
TypedArray<String> get_configuration_warnings() const override;
+ void set_sub_emitter(const NodePath &p_path);
+ NodePath get_sub_emitter() const;
+
+ enum EmitFlags {
+ EMIT_FLAG_POSITION = RS::PARTICLES_EMIT_FLAG_POSITION,
+ EMIT_FLAG_ROTATION_SCALE = RS::PARTICLES_EMIT_FLAG_ROTATION_SCALE,
+ EMIT_FLAG_VELOCITY = RS::PARTICLES_EMIT_FLAG_VELOCITY,
+ EMIT_FLAG_COLOR = RS::PARTICLES_EMIT_FLAG_COLOR,
+ EMIT_FLAG_CUSTOM = RS::PARTICLES_EMIT_FLAG_CUSTOM
+ };
+
+ void emit_particle(const Transform2D &p_transform, const Vector2 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags);
+
void restart();
Rect2 capture_rect() const;
GPUParticles2D();
@@ -146,5 +161,6 @@ public:
};
VARIANT_ENUM_CAST(GPUParticles2D::DrawOrder)
+VARIANT_ENUM_CAST(GPUParticles2D::EmitFlags)
#endif // PARTICLES_2D_H
diff --git a/scene/2d/joint_2d.cpp b/scene/2d/joint_2d.cpp
index 62a77fb969..c2773191ea 100644
--- a/scene/2d/joint_2d.cpp
+++ b/scene/2d/joint_2d.cpp
@@ -128,7 +128,7 @@ void Joint2D::set_node_a(const NodePath &p_node_a) {
return;
}
- if (joint.is_valid()) {
+ if (is_configured()) {
_disconnect_signals();
}
@@ -145,7 +145,7 @@ void Joint2D::set_node_b(const NodePath &p_node_b) {
return;
}
- if (joint.is_valid()) {
+ if (is_configured()) {
_disconnect_signals();
}
@@ -159,14 +159,18 @@ NodePath Joint2D::get_node_b() const {
void Joint2D::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_READY: {
+ case NOTIFICATION_POST_ENTER_TREE: {
+ if (is_configured()) {
+ _disconnect_signals();
+ }
_update_joint();
} break;
+
case NOTIFICATION_EXIT_TREE: {
- if (joint.is_valid()) {
+ if (is_configured()) {
_disconnect_signals();
- _update_joint(true);
}
+ _update_joint(true);
} break;
}
}
@@ -186,7 +190,9 @@ void Joint2D::set_exclude_nodes_from_collision(bool p_enable) {
if (exclude_from_collision == p_enable) {
return;
}
-
+ if (is_configured()) {
+ _disconnect_signals();
+ }
_update_joint(true);
exclude_from_collision = p_enable;
_update_joint();
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index f496e1aac2..ba168eeb86 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -192,21 +192,24 @@ Light2D::BlendMode Light2D::get_blend_mode() const {
}
void Light2D::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, get_canvas());
- _update_light_visibility();
- }
-
- if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
- RS::get_singleton()->canvas_light_set_transform(canvas_light, get_global_transform());
- }
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- _update_light_visibility();
- }
-
- if (p_what == NOTIFICATION_EXIT_TREE) {
- RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, RID());
- _update_light_visibility();
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, get_canvas());
+ _update_light_visibility();
+ } break;
+
+ case NOTIFICATION_TRANSFORM_CHANGED: {
+ RS::get_singleton()->canvas_light_set_transform(canvas_light, get_global_transform());
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ _update_light_visibility();
+ } break;
+
+ case NOTIFICATION_EXIT_TREE: {
+ RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, RID());
+ _update_light_visibility();
+ } break;
}
}
diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp
index 0a7e4c8841..0310817592 100644
--- a/scene/2d/light_occluder_2d.cpp
+++ b/scene/2d/light_occluder_2d.cpp
@@ -29,9 +29,9 @@
/*************************************************************************/
#include "light_occluder_2d.h"
-#include "core/math/geometry_2d.h"
#include "core/config/engine.h"
+#include "core/math/geometry_2d.h"
#define LINE_GRAB_WIDTH 8
@@ -158,42 +158,46 @@ void LightOccluder2D::_poly_changed() {
}
void LightOccluder2D::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_CANVAS) {
- RS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder, get_canvas());
- RS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform());
- RS::get_singleton()->canvas_light_occluder_set_enabled(occluder, is_visible_in_tree());
- }
- if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
- RS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform());
- }
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- RS::get_singleton()->canvas_light_occluder_set_enabled(occluder, is_visible_in_tree());
- }
-
- if (p_what == NOTIFICATION_DRAW) {
- if (Engine::get_singleton()->is_editor_hint()) {
- if (occluder_polygon.is_valid()) {
- Vector<Vector2> poly = occluder_polygon->get_polygon();
-
- if (poly.size()) {
- if (occluder_polygon->is_closed()) {
- Vector<Color> color;
- color.push_back(Color(0, 0, 0, 0.6));
- draw_polygon(Variant(poly), color);
- } else {
- int ps = poly.size();
- const Vector2 *r = poly.ptr();
- for (int i = 0; i < ps - 1; i++) {
- draw_line(r[i], r[i + 1], Color(0, 0, 0, 0.6), 3);
+ switch (p_what) {
+ case NOTIFICATION_ENTER_CANVAS: {
+ RS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder, get_canvas());
+ RS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform());
+ RS::get_singleton()->canvas_light_occluder_set_enabled(occluder, is_visible_in_tree());
+ } break;
+
+ case NOTIFICATION_TRANSFORM_CHANGED: {
+ RS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform());
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ RS::get_singleton()->canvas_light_occluder_set_enabled(occluder, is_visible_in_tree());
+ } break;
+
+ case NOTIFICATION_DRAW: {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ if (occluder_polygon.is_valid()) {
+ Vector<Vector2> poly = occluder_polygon->get_polygon();
+
+ if (poly.size()) {
+ if (occluder_polygon->is_closed()) {
+ Vector<Color> color;
+ color.push_back(Color(0, 0, 0, 0.6));
+ draw_polygon(Variant(poly), color);
+ } else {
+ int ps = poly.size();
+ const Vector2 *r = poly.ptr();
+ for (int i = 0; i < ps - 1; i++) {
+ draw_line(r[i], r[i + 1], Color(0, 0, 0, 0.6), 3);
+ }
}
}
}
}
- }
- }
+ } break;
- if (p_what == NOTIFICATION_EXIT_CANVAS) {
- RS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder, RID());
+ case NOTIFICATION_EXIT_CANVAS: {
+ RS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder, RID());
+ } break;
}
}
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index 1a6aaecaa8..8cbcc9acf6 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -133,7 +133,7 @@ int Line2D::get_point_count() const {
void Line2D::clear_points() {
int count = _points.size();
if (count > 0) {
- _points.resize(0);
+ _points.clear();
update();
}
}
@@ -228,9 +228,9 @@ Line2D::LineCapMode Line2D::get_end_cap_mode() const {
void Line2D::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_DRAW:
+ case NOTIFICATION_DRAW: {
_draw();
- break;
+ } break;
}
}
@@ -247,10 +247,7 @@ float Line2D::get_sharp_limit() const {
}
void Line2D::set_round_precision(int p_precision) {
- if (p_precision < 1) {
- p_precision = 1;
- }
- _round_precision = p_precision;
+ _round_precision = MAX(1, p_precision);
update();
}
@@ -268,15 +265,15 @@ bool Line2D::get_antialiased() const {
}
void Line2D::_draw() {
- if (_points.size() <= 1 || _width == 0.f) {
+ int len = _points.size();
+ if (len <= 1 || _width == 0.f) {
return;
}
// TODO Is this really needed?
// Copy points for faster access
Vector<Vector2> points;
- points.resize(_points.size());
- int len = points.size();
+ points.resize(len);
{
const Vector2 *points_read = _points.ptr();
for (int i = 0; i < len; ++i) {
@@ -409,7 +406,7 @@ void Line2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "end_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_end_cap_mode", "get_end_cap_mode");
ADD_GROUP("Border", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sharp_limit"), "set_sharp_limit", "get_sharp_limit");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "round_precision"), "set_round_precision", "get_round_precision");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "round_precision", PROPERTY_HINT_RANGE, "1,32,1"), "set_round_precision", "get_round_precision");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "get_antialiased");
BIND_ENUM_CONSTANT(LINE_JOINT_SHARP);
diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp
index 5f8a46ad2e..178addd62d 100644
--- a/scene/2d/mesh_instance_2d.cpp
+++ b/scene/2d/mesh_instance_2d.cpp
@@ -29,13 +29,16 @@
/*************************************************************************/
#include "mesh_instance_2d.h"
+
#include "scene/scene_string_names.h"
void MeshInstance2D::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW) {
- if (mesh.is_valid()) {
- draw_mesh(mesh, texture);
- }
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+ if (mesh.is_valid()) {
+ draw_mesh(mesh, texture);
+ }
+ } break;
}
}
diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp
index e1af99d931..8f72ff1757 100644
--- a/scene/2d/multimesh_instance_2d.cpp
+++ b/scene/2d/multimesh_instance_2d.cpp
@@ -29,13 +29,16 @@
/*************************************************************************/
#include "multimesh_instance_2d.h"
+
#include "scene/scene_string_names.h"
void MultiMeshInstance2D::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW) {
- if (multimesh.is_valid()) {
- draw_multimesh(multimesh, texture);
- }
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+ if (multimesh.is_valid()) {
+ draw_multimesh(multimesh, texture);
+ }
+ } break;
}
}
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 00d0996e08..78b5a39e9a 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -31,6 +31,7 @@
#include "navigation_agent_2d.h"
#include "core/math/geometry_2d.h"
+#include "scene/resources/world_2d.h"
#include "servers/navigation_server_2d.h"
void NavigationAgent2D::_bind_methods() {
@@ -96,10 +97,12 @@ void NavigationAgent2D::_notification(int p_what) {
}
set_physics_process_internal(true);
} break;
+
case NOTIFICATION_EXIT_TREE: {
agent_parent = nullptr;
set_physics_process_internal(false);
} break;
+
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (agent_parent) {
NavigationServer2D::get_singleton()->agent_set_position(agent, agent_parent->get_global_position());
@@ -241,7 +244,7 @@ TypedArray<String> NavigationAgent2D::get_configuration_warnings() const {
TypedArray<String> warnings = Node::get_configuration_warnings();
if (!Object::cast_to<Node2D>(get_parent())) {
- warnings.push_back(TTR("The NavigationAgent2D can be used only under a Node2D node"));
+ warnings.push_back(TTR("The NavigationAgent2D can be used only under a Node2D node."));
}
return warnings;
diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp
index e5df089771..65f7adb7a6 100644
--- a/scene/2d/navigation_obstacle_2d.cpp
+++ b/scene/2d/navigation_obstacle_2d.cpp
@@ -31,6 +31,7 @@
#include "navigation_obstacle_2d.h"
#include "scene/2d/collision_shape_2d.h"
+#include "scene/resources/world_2d.h"
#include "servers/navigation_server_2d.h"
void NavigationObstacle2D::_bind_methods() {
@@ -53,26 +54,30 @@ void NavigationObstacle2D::_validate_property(PropertyInfo &p_property) const {
void NavigationObstacle2D::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_READY: {
- initialize_agent();
+ case NOTIFICATION_ENTER_TREE: {
parent_node2d = Object::cast_to<Node2D>(get_parent());
+ reevaluate_agent_radius();
if (parent_node2d != nullptr) {
// place agent on navigation map first or else the RVO agent callback creation fails silently later
NavigationServer2D::get_singleton()->agent_set_map(get_rid(), parent_node2d->get_world_2d()->get_navigation_map());
}
set_physics_process_internal(true);
} break;
+
case NOTIFICATION_EXIT_TREE: {
parent_node2d = nullptr;
set_physics_process_internal(false);
} break;
+
case NOTIFICATION_PARENTED: {
parent_node2d = Object::cast_to<Node2D>(get_parent());
reevaluate_agent_radius();
} break;
+
case NOTIFICATION_UNPARENTED: {
parent_node2d = nullptr;
} break;
+
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (parent_node2d) {
NavigationServer2D::get_singleton()->agent_set_position(agent, parent_node2d->get_global_position());
@@ -83,6 +88,7 @@ void NavigationObstacle2D::_notification(int p_what) {
NavigationObstacle2D::NavigationObstacle2D() {
agent = NavigationServer2D::get_singleton()->agent_create();
+ initialize_agent();
}
NavigationObstacle2D::~NavigationObstacle2D() {
@@ -110,7 +116,7 @@ void NavigationObstacle2D::initialize_agent() {
void NavigationObstacle2D::reevaluate_agent_radius() {
if (!estimate_radius) {
NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
- } else if (parent_node2d) {
+ } else if (parent_node2d && parent_node2d->is_inside_tree()) {
NavigationServer2D::get_singleton()->agent_set_radius(agent, estimate_agent_radius());
}
}
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index 34f5830d8d..34ac02a82a 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -33,6 +33,7 @@
#include "core/core_string_names.h"
#include "core/math/geometry_2d.h"
#include "core/os/mutex.h"
+#include "scene/resources/world_2d.h"
#include "servers/navigation_server_2d.h"
#include "thirdparty/misc/polypartition.h"
@@ -104,8 +105,8 @@ void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array
}
}
-Array NavigationPolygon::_get_polygons() const {
- Array ret;
+TypedArray<Vector<int32_t>> NavigationPolygon::_get_polygons() const {
+ TypedArray<Vector<int32_t>> ret;
ret.resize(polygons.size());
for (int i = 0; i < ret.size(); i++) {
ret[i] = polygons[i].indices;
@@ -122,8 +123,8 @@ void NavigationPolygon::_set_outlines(const TypedArray<Vector<Vector2>> &p_array
rect_cache_dirty = true;
}
-Array NavigationPolygon::_get_outlines() const {
- Array ret;
+TypedArray<Vector<Vector2>> NavigationPolygon::_get_outlines() const {
+ TypedArray<Vector<Vector2>> ret;
ret.resize(outlines.size());
for (int i = 0; i < ret.size(); i++) {
ret[i] = outlines[i];
@@ -299,7 +300,7 @@ void NavigationPolygon::make_polygons_from_outlines() {
}
polygons.clear();
- vertices.resize(0);
+ vertices.clear();
Map<Vector2, int> points;
for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) {
@@ -405,15 +406,18 @@ void NavigationRegion2D::_notification(int p_what) {
NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
} break;
+
case NOTIFICATION_TRANSFORM_CHANGED: {
NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform());
} break;
+
case NOTIFICATION_EXIT_TREE: {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
if (enabled) {
NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
} break;
+
case NOTIFICATION_DRAW: {
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) {
Vector<Vector2> verts = navpoly->get_vertices();
diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h
index 012debb584..487a578401 100644
--- a/scene/2d/navigation_region_2d.h
+++ b/scene/2d/navigation_region_2d.h
@@ -55,10 +55,10 @@ protected:
static void _bind_methods();
void _set_polygons(const TypedArray<Vector<int32_t>> &p_array);
- Array _get_polygons() const;
+ TypedArray<Vector<int32_t>> _get_polygons() const;
void _set_outlines(const TypedArray<Vector<Vector2>> &p_array);
- Array _get_outlines() const;
+ TypedArray<Vector<Vector2>> _get_outlines() const;
public:
#ifdef TOOLS_ENABLED
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index 9331340e1b..dd88bda304 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -244,10 +244,9 @@ Point2 Node2D::get_global_position() const {
}
void Node2D::set_global_position(const Point2 &p_pos) {
- Transform2D inv;
CanvasItem *pi = get_parent_item();
if (pi) {
- inv = pi->get_global_transform().affine_inverse();
+ Transform2D inv = pi->get_global_transform().affine_inverse();
set_position(inv.xform(p_pos));
} else {
set_position(p_pos);
@@ -413,7 +412,7 @@ void Node2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_relative_transform_to_parent", "parent"), &Node2D::get_relative_transform_to_parent);
ADD_GROUP("Transform", "");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_RANGE, "-99999,99999,0,or_lesser,or_greater,noslider,suffix:px"), "set_position", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_lesser,or_greater,noslider,suffix:px"), "set_position", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians"), "set_skew", "get_skew");
diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp
index f75baaab0f..dcbb6507f5 100644
--- a/scene/2d/parallax_background.cpp
+++ b/scene/2d/parallax_background.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "parallax_background.h"
+
#include "parallax_layer.h"
void ParallaxBackground::_notification(int p_what) {
@@ -36,8 +37,8 @@ void ParallaxBackground::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
group_name = "__cameras_" + itos(get_viewport().get_id());
add_to_group(group_name);
-
} break;
+
case NOTIFICATION_EXIT_TREE: {
remove_from_group(group_name);
} break;
diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp
index ff572c9b9a..849412a7ae 100644
--- a/scene/2d/parallax_layer.cpp
+++ b/scene/2d/parallax_layer.cpp
@@ -99,6 +99,7 @@ void ParallaxLayer::_notification(int p_what) {
orig_scale = get_scale();
_update_mirroring();
} break;
+
case NOTIFICATION_EXIT_TREE: {
if (Engine::get_singleton()->is_editor_hint()) {
break;
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index 4f24b0e004..d001652ca3 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -86,32 +86,41 @@ bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
#endif
void Path2D::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW && curve.is_valid()) {
- //draw the curve!!
+ switch (p_what) {
+ // Draw the curve if navigation debugging is enabled.
+ case NOTIFICATION_DRAW: {
+ if (!curve.is_valid()) {
+ break;
+ }
- if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) {
- return;
- }
+ if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) {
+ return;
+ }
+
+ if (curve->get_point_count() < 2) {
+ return;
+ }
#ifdef TOOLS_ENABLED
- const real_t line_width = 2 * EDSCALE;
+ const real_t line_width = 2 * EDSCALE;
#else
- const real_t line_width = 2;
+ const real_t line_width = 2;
#endif
- const Color color = Color(0.5, 0.6, 1.0, 0.7);
+ const Color color = Color(0.5, 0.6, 1.0, 0.7);
- _cached_draw_pts.resize(curve->get_point_count() * 8);
- int count = 0;
+ _cached_draw_pts.resize(curve->get_point_count() * 8);
+ int count = 0;
- for (int i = 0; i < curve->get_point_count(); i++) {
- for (int j = 0; j < 8; j++) {
- real_t frac = j * (1.0 / 8.0);
- Vector2 p = curve->interpolate(i, frac);
- _cached_draw_pts.set(count++, p);
+ for (int i = 0; i < curve->get_point_count(); i++) {
+ for (int j = 0; j < 8; j++) {
+ real_t frac = j * (1.0 / 8.0);
+ Vector2 p = curve->interpolate(i, frac);
+ _cached_draw_pts.set(count++, p);
+ }
}
- }
- draw_polyline(_cached_draw_pts, color, line_width, true);
+ draw_polyline(_cached_draw_pts, color, line_width, true);
+ } break;
}
}
@@ -222,8 +231,8 @@ void PathFollow2D::_notification(int p_what) {
if (path) {
_update_transform();
}
-
} break;
+
case NOTIFICATION_EXIT_TREE: {
path = nullptr;
} break;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index b2cc8164b6..eb4d9d6445 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -34,8 +34,8 @@
#include "scene/scene_string_names.h"
void PhysicsBody2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move_and_collide", "linear_velocity", "test_only", "safe_margin"), &PhysicsBody2D::_move, DEFVAL(false), DEFVAL(0.08));
- ClassDB::bind_method(D_METHOD("test_move", "from", "linear_velocity", "collision", "safe_margin"), &PhysicsBody2D::test_move, DEFVAL(Variant()), DEFVAL(0.08));
+ ClassDB::bind_method(D_METHOD("move_and_collide", "distance", "test_only", "safe_margin"), &PhysicsBody2D::_move, DEFVAL(false), DEFVAL(0.08));
+ ClassDB::bind_method(D_METHOD("test_move", "from", "distance", "collision", "safe_margin"), &PhysicsBody2D::test_move, DEFVAL(Variant()), DEFVAL(0.08));
ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody2D::get_collision_exceptions);
ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody2D::add_collision_exception_with);
@@ -54,11 +54,8 @@ PhysicsBody2D::~PhysicsBody2D() {
}
}
-Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_linear_velocity, bool p_test_only, real_t p_margin) {
- // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
- double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
-
- PhysicsServer2D::MotionParameters parameters(get_global_transform(), p_linear_velocity * delta, p_margin);
+Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_distance, bool p_test_only, real_t p_margin) {
+ PhysicsServer2D::MotionParameters parameters(get_global_transform(), p_distance, p_margin);
PhysicsServer2D::MotionResult result;
if (move_and_collide(parameters, result, p_test_only)) {
@@ -129,7 +126,7 @@ bool PhysicsBody2D::move_and_collide(const PhysicsServer2D::MotionParameters &p_
return colliding;
}
-bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_linear_velocity, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) {
+bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_distance, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) {
ERR_FAIL_COND_V(!is_inside_tree(), false);
PhysicsServer2D::MotionResult *r = nullptr;
@@ -141,10 +138,7 @@ bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_linear
r = &temp_result;
}
- // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
- double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
-
- PhysicsServer2D::MotionParameters parameters(p_from, p_linear_velocity * delta, p_margin);
+ PhysicsServer2D::MotionParameters parameters(p_from, p_distance, p_margin);
bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), parameters, r);
@@ -912,7 +906,7 @@ void RigidDynamicBody2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
if (Engine::get_singleton()->is_editor_hint()) {
- set_notify_local_transform(true); //used for warnings and only in editor
+ set_notify_local_transform(true); // Used for warnings and only in editor.
}
} break;
@@ -1162,7 +1156,7 @@ bool CharacterBody2D::move_and_slide() {
if (motion_mode == MOTION_MODE_GROUNDED) {
_move_and_slide_grounded(delta, was_on_floor);
} else {
- _move_and_slide_free(delta);
+ _move_and_slide_floating(delta);
}
// Compute real velocity.
@@ -1174,7 +1168,7 @@ bool CharacterBody2D::move_and_slide() {
if (moving_platform_apply_velocity_on_leave == PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY && current_platform_velocity.dot(up_direction) < 0) {
current_platform_velocity = current_platform_velocity.slide(up_direction);
}
- motion_velocity += current_platform_velocity;
+ velocity += current_platform_velocity;
}
}
@@ -1182,7 +1176,7 @@ bool CharacterBody2D::move_and_slide() {
}
void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_floor) {
- Vector2 motion = motion_velocity * p_delta;
+ Vector2 motion = velocity * p_delta;
Vector2 motion_slide_up = motion.slide(up_direction);
Vector2 prev_floor_normal = floor_normal;
@@ -1200,7 +1194,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
// If the platform's ceiling push down the body.
bool apply_ceiling_velocity = false;
bool first_slide = true;
- bool vel_dir_facing_up = motion_velocity.dot(up_direction) > 0;
+ bool vel_dir_facing_up = velocity.dot(up_direction) > 0;
Vector2 last_travel;
for (int iteration = 0; iteration < max_slides; ++iteration) {
@@ -1217,26 +1211,26 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
motion_results.push_back(result);
_set_collision_direction(result);
- // If we hit a ceiling platform, we set the vertical motion_velocity to at least the platform one.
+ // If we hit a ceiling platform, we set the vertical velocity to at least the platform one.
if (on_ceiling && result.collider_velocity != Vector2() && result.collider_velocity.dot(up_direction) < 0) {
// If ceiling sliding is on, only apply when the ceiling is flat or when the motion is upward.
if (!slide_on_ceiling || motion.dot(up_direction) < 0 || (result.collision_normal + up_direction).length() < 0.01) {
apply_ceiling_velocity = true;
Vector2 ceiling_vertical_velocity = up_direction * up_direction.dot(result.collider_velocity);
- Vector2 motion_vertical_velocity = up_direction * up_direction.dot(motion_velocity);
+ Vector2 motion_vertical_velocity = up_direction * up_direction.dot(velocity);
if (motion_vertical_velocity.dot(up_direction) > 0 || ceiling_vertical_velocity.length_squared() > motion_vertical_velocity.length_squared()) {
- motion_velocity = ceiling_vertical_velocity + motion_velocity.slide(up_direction);
+ velocity = ceiling_vertical_velocity + velocity.slide(up_direction);
}
}
}
- if (on_floor && floor_stop_on_slope && (motion_velocity.normalized() + up_direction).length() < 0.01) {
+ if (on_floor && floor_stop_on_slope && (velocity.normalized() + up_direction).length() < 0.01) {
Transform2D gt = get_global_transform();
if (result.travel.length() <= margin + CMP_EPSILON) {
gt.elements[2] -= result.travel;
}
set_global_transform(gt);
- motion_velocity = Vector2();
+ velocity = Vector2();
last_motion = Vector2();
motion = Vector2();
break;
@@ -1260,7 +1254,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
}
// Determines if you are on the ground.
_snap_on_floor(true, false);
- motion_velocity = Vector2();
+ velocity = Vector2();
last_motion = Vector2();
motion = Vector2();
break;
@@ -1282,7 +1276,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
// Regular sliding, the last part of the test handle the case when you don't want to slide on the ceiling.
else if ((sliding_enabled || !on_floor) && (!on_ceiling || slide_on_ceiling || !vel_dir_facing_up) && !apply_ceiling_velocity) {
Vector2 slide_motion = result.remainder.slide(result.collision_normal);
- if (slide_motion.dot(motion_velocity) > 0.0) {
+ if (slide_motion.dot(velocity) > 0.0) {
motion = slide_motion;
} else {
motion = Vector2();
@@ -1290,10 +1284,10 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
if (slide_on_ceiling && on_ceiling) {
// Apply slide only in the direction of the input motion, otherwise just stop to avoid jittering when moving against a wall.
if (vel_dir_facing_up) {
- motion_velocity = motion_velocity.slide(result.collision_normal);
+ velocity = velocity.slide(result.collision_normal);
} else {
// Avoid acceleration in slope when falling.
- motion_velocity = up_direction * up_direction.dot(motion_velocity);
+ velocity = up_direction * up_direction.dot(velocity);
}
}
}
@@ -1301,7 +1295,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
else {
motion = result.remainder;
if (on_ceiling && !slide_on_ceiling && vel_dir_facing_up) {
- motion_velocity = motion_velocity.slide(up_direction);
+ velocity = velocity.slide(up_direction);
motion = motion.slide(up_direction);
}
}
@@ -1335,23 +1329,23 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
// Scales the horizontal velocity according to the wall slope.
if (is_on_wall_only() && motion_slide_up.dot(motion_results.get(0).collision_normal) < 0) {
- Vector2 slide_motion = motion_velocity.slide(motion_results.get(0).collision_normal);
+ Vector2 slide_motion = velocity.slide(motion_results.get(0).collision_normal);
if (motion_slide_up.dot(slide_motion) < 0) {
- motion_velocity = up_direction * up_direction.dot(motion_velocity);
+ velocity = up_direction * up_direction.dot(velocity);
} else {
- // Keeps the vertical motion from motion_velocity and add the horizontal motion of the projection.
- motion_velocity = up_direction * up_direction.dot(motion_velocity) + slide_motion.slide(up_direction);
+ // Keeps the vertical motion from velocity and add the horizontal motion of the projection.
+ velocity = up_direction * up_direction.dot(velocity) + slide_motion.slide(up_direction);
}
}
// Reset the gravity accumulation when touching the ground.
if (on_floor && !vel_dir_facing_up) {
- motion_velocity = motion_velocity.slide(up_direction);
+ velocity = velocity.slide(up_direction);
}
}
-void CharacterBody2D::_move_and_slide_free(double p_delta) {
- Vector2 motion = motion_velocity * p_delta;
+void CharacterBody2D::_move_and_slide_floating(double p_delta) {
+ Vector2 motion = velocity * p_delta;
platform_rid = RID();
platform_object_id = ObjectID();
@@ -1376,7 +1370,7 @@ void CharacterBody2D::_move_and_slide_free(double p_delta) {
break;
}
- if (free_mode_min_slide_angle != 0 && result.get_angle(-motion_velocity.normalized()) < free_mode_min_slide_angle + FLOOR_ANGLE_THRESHOLD) {
+ if (wall_min_slide_angle != 0 && result.get_angle(-velocity.normalized()) < wall_min_slide_angle + FLOOR_ANGLE_THRESHOLD) {
motion = Vector2();
} else if (first_slide) {
Vector2 motion_slide_norm = result.remainder.slide(result.collision_normal).normalized();
@@ -1385,7 +1379,7 @@ void CharacterBody2D::_move_and_slide_free(double p_delta) {
motion = result.remainder.slide(result.collision_normal);
}
- if (motion.dot(motion_velocity) <= 0.0) {
+ if (motion.dot(velocity) <= 0.0) {
motion = Vector2();
}
}
@@ -1477,12 +1471,12 @@ void CharacterBody2D::_set_platform_data(const PhysicsServer2D::MotionResult &p_
platform_layer = PhysicsServer2D::get_singleton()->body_get_collision_layer(platform_rid);
}
-const Vector2 &CharacterBody2D::get_motion_velocity() const {
- return motion_velocity;
+const Vector2 &CharacterBody2D::get_velocity() const {
+ return velocity;
}
-void CharacterBody2D::set_motion_velocity(const Vector2 &p_velocity) {
- motion_velocity = p_velocity;
+void CharacterBody2D::set_velocity(const Vector2 &p_velocity) {
+ velocity = p_velocity;
}
bool CharacterBody2D::is_on_floor() const {
@@ -1668,12 +1662,12 @@ void CharacterBody2D::set_floor_snap_length(real_t p_floor_snap_length) {
floor_snap_length = p_floor_snap_length;
}
-real_t CharacterBody2D::get_free_mode_min_slide_angle() const {
- return free_mode_min_slide_angle;
+real_t CharacterBody2D::get_wall_min_slide_angle() const {
+ return wall_min_slide_angle;
}
-void CharacterBody2D::set_free_mode_min_slide_angle(real_t p_radians) {
- free_mode_min_slide_angle = p_radians;
+void CharacterBody2D::set_wall_min_slide_angle(real_t p_radians) {
+ wall_min_slide_angle = p_radians;
}
const Vector2 &CharacterBody2D::get_up_direction() const {
@@ -1681,7 +1675,7 @@ const Vector2 &CharacterBody2D::get_up_direction() const {
}
void CharacterBody2D::set_up_direction(const Vector2 &p_up_direction) {
- ERR_FAIL_COND_MSG(p_up_direction == Vector2(), "up_direction can't be equal to Vector2.ZERO, consider using Free motion mode instead.");
+ ERR_FAIL_COND_MSG(p_up_direction == Vector2(), "up_direction can't be equal to Vector2.ZERO, consider using Floating motion mode instead.");
up_direction = p_up_direction.normalized();
}
@@ -1703,8 +1697,8 @@ void CharacterBody2D::_notification(int p_what) {
void CharacterBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody2D::move_and_slide);
- ClassDB::bind_method(D_METHOD("set_motion_velocity", "motion_velocity"), &CharacterBody2D::set_motion_velocity);
- ClassDB::bind_method(D_METHOD("get_motion_velocity"), &CharacterBody2D::get_motion_velocity);
+ ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &CharacterBody2D::set_velocity);
+ ClassDB::bind_method(D_METHOD("get_velocity"), &CharacterBody2D::get_velocity);
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &CharacterBody2D::set_safe_margin);
ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody2D::get_safe_margin);
@@ -1728,8 +1722,8 @@ void CharacterBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_floor_max_angle", "radians"), &CharacterBody2D::set_floor_max_angle);
ClassDB::bind_method(D_METHOD("get_floor_snap_length"), &CharacterBody2D::get_floor_snap_length);
ClassDB::bind_method(D_METHOD("set_floor_snap_length", "floor_snap_length"), &CharacterBody2D::set_floor_snap_length);
- ClassDB::bind_method(D_METHOD("get_free_mode_min_slide_angle"), &CharacterBody2D::get_free_mode_min_slide_angle);
- ClassDB::bind_method(D_METHOD("set_free_mode_min_slide_angle", "radians"), &CharacterBody2D::set_free_mode_min_slide_angle);
+ ClassDB::bind_method(D_METHOD("get_wall_min_slide_angle"), &CharacterBody2D::get_wall_min_slide_angle);
+ ClassDB::bind_method(D_METHOD("set_wall_min_slide_angle", "radians"), &CharacterBody2D::set_wall_min_slide_angle);
ClassDB::bind_method(D_METHOD("get_up_direction"), &CharacterBody2D::get_up_direction);
ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody2D::set_up_direction);
ClassDB::bind_method(D_METHOD("set_motion_mode", "mode"), &CharacterBody2D::set_motion_mode);
@@ -1754,14 +1748,12 @@ void CharacterBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &CharacterBody2D::_get_slide_collision);
ClassDB::bind_method(D_METHOD("get_last_slide_collision"), &CharacterBody2D::_get_last_slide_collision);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Free", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Floating", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "up_direction"), "set_up_direction", "get_up_direction");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_motion_velocity", "get_motion_velocity");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_velocity", "get_velocity");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_max_slides", "get_max_slides");
-
- ADD_GROUP("Free Mode", "free_mode_");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "free_mode_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_free_mode_min_slide_angle", "get_free_mode_min_slide_angle");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wall_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_wall_min_slide_angle", "get_wall_min_slide_angle");
ADD_GROUP("Floor", "floor_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "floor_stop_on_slope"), "set_floor_stop_on_slope_enabled", "is_floor_stop_on_slope_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "floor_constant_speed"), "set_floor_constant_speed_enabled", "is_floor_constant_speed_enabled");
@@ -1775,7 +1767,7 @@ void CharacterBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
BIND_ENUM_CONSTANT(MOTION_MODE_GROUNDED);
- BIND_ENUM_CONSTANT(MOTION_MODE_FREE);
+ BIND_ENUM_CONSTANT(MOTION_MODE_FLOATING);
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_ALWAYS);
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY);
@@ -1783,12 +1775,12 @@ void CharacterBody2D::_bind_methods() {
}
void CharacterBody2D::_validate_property(PropertyInfo &property) const {
- if (motion_mode == MOTION_MODE_FREE) {
+ if (motion_mode == MOTION_MODE_FLOATING) {
if (property.name.begins_with("floor_") || property.name == "up_direction" || property.name == "slide_on_ceiling") {
property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL;
}
} else {
- if (property.name == "free_mode_min_slide_angle") {
+ if (property.name == "wall_min_slide_angle") {
property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL;
}
}
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 649d67d759..8d9e31d4dd 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -47,11 +47,11 @@ protected:
Ref<KinematicCollision2D> motion_cache;
- Ref<KinematicCollision2D> _move(const Vector2 &p_linear_velocity, bool p_test_only = false, real_t p_margin = 0.08);
+ Ref<KinematicCollision2D> _move(const Vector2 &p_distance, bool p_test_only = false, real_t p_margin = 0.08);
public:
bool move_and_collide(const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult &r_result, bool p_test_only = false, bool p_cancel_sliding = true);
- bool test_move(const Transform2D &p_from, const Vector2 &p_linear_velocity, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
+ bool test_move(const Transform2D &p_from, const Vector2 &p_distance, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
TypedArray<PhysicsBody2D> get_collision_exceptions();
void add_collision_exception_with(Node *p_node); //must be physicsbody
@@ -328,7 +328,7 @@ class CharacterBody2D : public PhysicsBody2D {
public:
enum MotionMode {
MOTION_MODE_GROUNDED,
- MOTION_MODE_FREE,
+ MOTION_MODE_FLOATING,
};
enum MovingPlatformApplyVelocityOnLeave {
PLATFORM_VEL_ON_LEAVE_ALWAYS,
@@ -337,8 +337,8 @@ public:
};
bool move_and_slide();
- const Vector2 &get_motion_velocity() const;
- void set_motion_velocity(const Vector2 &p_velocity);
+ const Vector2 &get_velocity() const;
+ void set_velocity(const Vector2 &p_velocity);
bool is_on_floor() const;
bool is_on_floor_only() const;
@@ -374,11 +374,11 @@ private:
int platform_layer = 0;
real_t floor_max_angle = Math::deg2rad((real_t)45.0);
real_t floor_snap_length = 1;
- real_t free_mode_min_slide_angle = Math::deg2rad((real_t)15.0);
+ real_t wall_min_slide_angle = Math::deg2rad((real_t)15.0);
Vector2 up_direction = Vector2(0.0, -1.0);
uint32_t moving_platform_floor_layers = UINT32_MAX;
uint32_t moving_platform_wall_layers = 0;
- Vector2 motion_velocity;
+ Vector2 velocity;
Vector2 floor_normal;
Vector2 platform_velocity;
@@ -420,8 +420,8 @@ private:
real_t get_floor_snap_length();
void set_floor_snap_length(real_t p_floor_snap_length);
- real_t get_free_mode_min_slide_angle() const;
- void set_free_mode_min_slide_angle(real_t p_radians);
+ real_t get_wall_min_slide_angle() const;
+ void set_wall_min_slide_angle(real_t p_radians);
uint32_t get_moving_platform_floor_layers() const;
void set_moving_platform_floor_layers(const uint32_t p_exclude_layer);
@@ -435,7 +435,7 @@ private:
void set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_velocity);
MovingPlatformApplyVelocityOnLeave get_moving_platform_apply_velocity_on_leave() const;
- void _move_and_slide_free(double p_delta);
+ void _move_and_slide_floating(double p_delta);
void _move_and_slide_grounded(double p_delta, bool p_was_on_floor);
Ref<KinematicCollision2D> _get_slide_collision(int p_bounce);
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index 5451d95be9..f9986c2f30 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -295,14 +295,14 @@ void Polygon2D::_notification(int p_what) {
}
Vector<Color> colors;
+ colors.resize(len);
+
if (vertex_colors.size() == points.size()) {
- colors.resize(len);
const Color *color_r = vertex_colors.ptr();
for (int i = 0; i < len; i++) {
colors.write[i] = color_r[i];
}
} else {
- colors.resize(len);
for (int i = 0; i < len; i++) {
colors.write[i] = color;
}
@@ -428,15 +428,6 @@ Vector<Color> Polygon2D::get_vertex_colors() const {
void Polygon2D::set_texture(const Ref<Texture2D> &p_texture) {
texture = p_texture;
-
- /*if (texture.is_valid()) {
- uint32_t flags=texture->get_flags();
- flags&=~Texture::FLAG_REPEAT;
- if (tex_tile)
- flags|=Texture::FLAG_REPEAT;
-
- texture->set_flags(flags);
- }*/
update();
}
@@ -662,7 +653,7 @@ void Polygon2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons"), "set_polygons", "get_polygons");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "_set_bones", "_get_bones");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "_set_bones", "_get_bones");
ADD_PROPERTY(PropertyInfo(Variant::INT, "internal_vertex_count", PROPERTY_HINT_RANGE, "0,1000"), "set_internal_vertex_count", "get_internal_vertex_count");
}
diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp
index 28aeff98ca..518593cee1 100644
--- a/scene/2d/position_2d.cpp
+++ b/scene/2d/position_2d.cpp
@@ -36,37 +36,41 @@ void Position2D::_draw_cross() {
const real_t extents = get_gizmo_extents();
// Add more points to create a "hard stop" in the color gradient.
- PackedVector2Array points_x;
- points_x.push_back(Point2(+extents, 0));
- points_x.push_back(Point2());
- points_x.push_back(Point2());
- points_x.push_back(Point2(-extents, 0));
-
- PackedVector2Array points_y;
- points_y.push_back(Point2(0, +extents));
- points_y.push_back(Point2());
- points_y.push_back(Point2());
- points_y.push_back(Point2(0, -extents));
+ PackedVector2Array points_x = {
+ Point2(+extents, 0),
+ Point2(),
+ Point2(),
+ Point2(-extents, 0)
+ };
+
+ PackedVector2Array points_y = {
+ Point2(0, +extents),
+ Point2(),
+ Point2(),
+ Point2(0, -extents)
+ };
// Use the axis color which is brighter for the positive axis.
// Use a darkened axis color for the negative axis.
// This makes it possible to see in which direction the Position3D node is rotated
// (which can be important depending on how it's used).
// Axis colors are taken from `axis_x_color` and `axis_y_color` (defined in `editor/editor_themes.cpp`).
- PackedColorArray colors_x;
const Color color_x = Color(0.96, 0.20, 0.32);
- colors_x.push_back(color_x);
- colors_x.push_back(color_x);
- colors_x.push_back(color_x.lerp(Color(0, 0, 0), 0.5));
- colors_x.push_back(color_x.lerp(Color(0, 0, 0), 0.5));
+ PackedColorArray colors_x = {
+ color_x,
+ color_x,
+ color_x.lerp(Color(0, 0, 0), 0.5),
+ color_x.lerp(Color(0, 0, 0), 0.5)
+ };
draw_multiline_colors(points_x, colors_x);
- PackedColorArray colors_y;
const Color color_y = Color(0.53, 0.84, 0.01);
- colors_y.push_back(color_y);
- colors_y.push_back(color_y);
- colors_y.push_back(color_y.lerp(Color(0, 0, 0), 0.5));
- colors_y.push_back(color_y.lerp(Color(0, 0, 0), 0.5));
+ PackedColorArray colors_y = {
+ color_y,
+ color_y,
+ color_y.lerp(Color(0, 0, 0), 0.5),
+ color_y.lerp(Color(0, 0, 0), 0.5)
+ };
draw_multiline_colors(points_y, colors_y);
}
@@ -86,6 +90,7 @@ void Position2D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
update();
} break;
+
case NOTIFICATION_DRAW: {
if (!is_inside_tree()) {
break;
@@ -93,7 +98,6 @@ void Position2D::_notification(int p_what) {
if (Engine::get_singleton()->is_editor_hint()) {
_draw_cross();
}
-
} break;
}
}
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 33090fbacc..37db9211e1 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -31,6 +31,7 @@
#include "ray_cast_2d.h"
#include "collision_object_2d.h"
+#include "scene/resources/world_2d.h"
void RayCast2D::set_target_position(const Vector2 &p_point) {
target_position = p_point;
@@ -149,11 +150,11 @@ void RayCast2D::_notification(int p_what) {
}
}
} break;
+
case NOTIFICATION_EXIT_TREE: {
if (enabled) {
set_physics_process_internal(false);
}
-
} break;
case NOTIFICATION_DRAW: {
@@ -162,16 +163,13 @@ void RayCast2D::_notification(int p_what) {
break;
}
_draw_debug_shape();
-
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (!enabled) {
break;
}
-
_update_raycast_state();
-
} break;
}
}
@@ -244,15 +242,13 @@ void RayCast2D::_draw_debug_shape() {
xf.rotate(target_position.angle());
xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0));
- Vector<Vector2> pts;
- pts.push_back(xf.xform(Vector2(arrow_size, 0)));
- pts.push_back(xf.xform(Vector2(0, 0.5 * arrow_size)));
- pts.push_back(xf.xform(Vector2(0, -0.5 * arrow_size)));
+ Vector<Vector2> pts = {
+ xf.xform(Vector2(arrow_size, 0)),
+ xf.xform(Vector2(0, 0.5 * arrow_size)),
+ xf.xform(Vector2(0, -0.5 * arrow_size))
+ };
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(draw_col);
- }
+ Vector<Color> cols = { draw_col, draw_col, draw_col };
draw_primitive(pts, cols, Vector<Vector2>());
}
@@ -265,30 +261,29 @@ void RayCast2D::add_exception_rid(const RID &p_rid) {
exclude.insert(p_rid);
}
-void RayCast2D::add_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject2D *co = Object::cast_to<CollisionObject2D>(p_object);
- if (!co) {
- return;
- }
- add_exception_rid(co->get_rid());
+void RayCast2D::add_exception(const CollisionObject2D *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject2D.");
+ add_exception_rid(p_node->get_rid());
}
void RayCast2D::remove_exception_rid(const RID &p_rid) {
exclude.erase(p_rid);
}
-void RayCast2D::remove_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject2D *co = Object::cast_to<CollisionObject2D>(p_object);
- if (!co) {
- return;
- }
- remove_exception_rid(co->get_rid());
+void RayCast2D::remove_exception(const CollisionObject2D *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject2D.");
+ remove_exception_rid(p_node->get_rid());
}
void RayCast2D::clear_exceptions() {
exclude.clear();
+
+ if (exclude_parent_body && is_inside_tree()) {
+ CollisionObject2D *parent = Object::cast_to<CollisionObject2D>(get_parent());
+ if (parent) {
+ exclude.insert(parent->get_rid());
+ }
+ }
}
void RayCast2D::set_collide_with_areas(bool p_enabled) {
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index a1015c6ce0..2c6f2d5c00 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -33,6 +33,8 @@
#include "scene/2d/node_2d.h"
+class CollisionObject2D;
+
class RayCast2D : public Node2D {
GDCLASS(RayCast2D, Node2D);
@@ -94,9 +96,9 @@ public:
Vector2 get_collision_normal() const;
void add_exception_rid(const RID &p_rid);
- void add_exception(const Object *p_object);
+ void add_exception(const CollisionObject2D *p_node);
void remove_exception_rid(const RID &p_rid);
- void remove_exception(const Object *p_object);
+ void remove_exception(const CollisionObject2D *p_node);
void clear_exceptions();
RayCast2D();
diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp
index e9431efde3..429f0f6f6f 100644
--- a/scene/2d/remote_transform_2d.cpp
+++ b/scene/2d/remote_transform_2d.cpp
@@ -115,8 +115,8 @@ void RemoteTransform2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
_update_cache();
-
} break;
+
case NOTIFICATION_TRANSFORM_CHANGED: {
if (!is_inside_tree()) {
break;
@@ -125,7 +125,6 @@ void RemoteTransform2D::_notification(int p_what) {
if (cache.is_valid()) {
_update_remote();
}
-
} break;
}
}
diff --git a/scene/2d/shape_cast_2d.cpp b/scene/2d/shape_cast_2d.cpp
index 7fc1992e96..a2c5d73b59 100644
--- a/scene/2d/shape_cast_2d.cpp
+++ b/scene/2d/shape_cast_2d.cpp
@@ -201,6 +201,7 @@ void ShapeCast2D::_notification(int p_what) {
}
}
} break;
+
case NOTIFICATION_EXIT_TREE: {
if (enabled) {
set_physics_process_internal(false);
@@ -239,19 +240,22 @@ void ShapeCast2D::_notification(int p_what) {
xf.translate(Vector2(target_position.length(), 0));
draw_line(Vector2(), target_position, draw_col, 2);
- Vector<Vector2> pts;
+
float tsize = 8;
- pts.push_back(xf.xform(Vector2(tsize, 0)));
- pts.push_back(xf.xform(Vector2(0, Math_SQRT12 * tsize)));
- pts.push_back(xf.xform(Vector2(0, -Math_SQRT12 * tsize)));
- Vector<Color> cols;
- for (int i = 0; i < 3; i++)
- cols.push_back(draw_col);
+
+ Vector<Vector2> pts = {
+ xf.xform(Vector2(tsize, 0)),
+ xf.xform(Vector2(0, Math_SQRT12 * tsize)),
+ xf.xform(Vector2(0, -Math_SQRT12 * tsize))
+ };
+
+ Vector<Color> cols = { draw_col, draw_col, draw_col };
draw_primitive(pts, cols, Vector<Vector2>());
}
#endif
} break;
+
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (!enabled) {
break;
@@ -320,26 +324,18 @@ void ShapeCast2D::add_exception_rid(const RID &p_rid) {
exclude.insert(p_rid);
}
-void ShapeCast2D::add_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject2D *co = Object::cast_to<CollisionObject2D>(p_object);
- if (!co) {
- return;
- }
- add_exception_rid(co->get_rid());
+void ShapeCast2D::add_exception(const CollisionObject2D *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject2D.");
+ add_exception_rid(p_node->get_rid());
}
void ShapeCast2D::remove_exception_rid(const RID &p_rid) {
exclude.erase(p_rid);
}
-void ShapeCast2D::remove_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject2D *co = Object::cast_to<CollisionObject2D>(p_object);
- if (!co) {
- return;
- }
- remove_exception_rid(co->get_rid());
+void ShapeCast2D::remove_exception(const CollisionObject2D *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject2D.");
+ remove_exception_rid(p_node->get_rid());
}
void ShapeCast2D::clear_exceptions() {
diff --git a/scene/2d/shape_cast_2d.h b/scene/2d/shape_cast_2d.h
index 7e1ebeb315..15436d6e3d 100644
--- a/scene/2d/shape_cast_2d.h
+++ b/scene/2d/shape_cast_2d.h
@@ -33,6 +33,9 @@
#include "scene/2d/node_2d.h"
#include "scene/resources/shape_2d.h"
+#include "scene/resources/world_2d.h"
+
+class CollisionObject2D;
class ShapeCast2D : public Node2D {
GDCLASS(ShapeCast2D, Node2D);
@@ -109,9 +112,9 @@ public:
real_t get_closest_collision_unsafe_fraction() const;
void add_exception_rid(const RID &p_rid);
- void add_exception(const Object *p_object);
+ void add_exception(const CollisionObject2D *p_node);
void remove_exception_rid(const RID &p_rid);
- void remove_exception(const Object *p_object);
+ void remove_exception(const CollisionObject2D *p_node);
void clear_exceptions();
TypedArray<String> get_configuration_warnings() const override;
diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp
index 2270926ea7..360650c724 100644
--- a/scene/2d/skeleton_2d.cpp
+++ b/scene/2d/skeleton_2d.cpp
@@ -31,6 +31,7 @@
#include "skeleton_2d.h"
#ifdef TOOLS_ENABLED
+#include "editor/editor_data.h"
#include "editor/editor_settings.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#endif //TOOLS_ENABLED
@@ -92,223 +93,228 @@ void Bone2D::_get_property_list(List<PropertyInfo> *p_list) const {
}
void Bone2D::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- Node *parent = get_parent();
- parent_bone = Object::cast_to<Bone2D>(parent);
- skeleton = nullptr;
- while (parent) {
- skeleton = Object::cast_to<Skeleton2D>(parent);
- if (skeleton) {
- break;
- }
- if (!Object::cast_to<Bone2D>(parent)) {
- break; //skeletons must be chained to Bone2Ds.
- }
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ Node *parent = get_parent();
+ parent_bone = Object::cast_to<Bone2D>(parent);
+ skeleton = nullptr;
+ while (parent) {
+ skeleton = Object::cast_to<Skeleton2D>(parent);
+ if (skeleton) {
+ break;
+ }
+ if (!Object::cast_to<Bone2D>(parent)) {
+ break; //skeletons must be chained to Bone2Ds.
+ }
- parent = parent->get_parent();
- }
+ parent = parent->get_parent();
+ }
- if (skeleton) {
- Skeleton2D::Bone bone;
- bone.bone = this;
- skeleton->bones.push_back(bone);
- skeleton->_make_bone_setup_dirty();
- }
+ if (skeleton) {
+ Skeleton2D::Bone bone;
+ bone.bone = this;
+ skeleton->bones.push_back(bone);
+ skeleton->_make_bone_setup_dirty();
+ }
- cache_transform = get_transform();
- copy_transform_to_cache = true;
+ cache_transform = get_transform();
+ copy_transform_to_cache = true;
#ifdef TOOLS_ENABLED
- // Only draw the gizmo in the editor!
- if (Engine::get_singleton()->is_editor_hint() == false) {
- return;
- }
+ // Only draw the gizmo in the editor!
+ if (Engine::get_singleton()->is_editor_hint() == false) {
+ return;
+ }
- update();
+ update();
#endif // TOOLS_ENABLED
- }
+ } break;
- else if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
- if (skeleton) {
- skeleton->_make_transform_dirty();
- }
- if (copy_transform_to_cache) {
- cache_transform = get_transform();
- }
+ case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
+ if (skeleton) {
+ skeleton->_make_transform_dirty();
+ }
+ if (copy_transform_to_cache) {
+ cache_transform = get_transform();
+ }
#ifdef TOOLS_ENABLED
- // Only draw the gizmo in the editor!
- if (Engine::get_singleton()->is_editor_hint() == false) {
- return;
- }
+ // Only draw the gizmo in the editor!
+ if (Engine::get_singleton()->is_editor_hint() == false) {
+ return;
+ }
- update();
+ update();
- if (get_parent()) {
- Bone2D *parent_bone = Object::cast_to<Bone2D>(get_parent());
- if (parent_bone) {
- parent_bone->update();
+ if (get_parent()) {
+ Bone2D *parent_bone = Object::cast_to<Bone2D>(get_parent());
+ if (parent_bone) {
+ parent_bone->update();
+ }
}
- }
#endif // TOOLS_ENABLED
- }
+ } break;
- else if (p_what == NOTIFICATION_MOVED_IN_PARENT) {
- if (skeleton) {
- skeleton->_make_bone_setup_dirty();
- }
- if (copy_transform_to_cache) {
- cache_transform = get_transform();
- }
- }
+ case NOTIFICATION_MOVED_IN_PARENT: {
+ if (skeleton) {
+ skeleton->_make_bone_setup_dirty();
+ }
+ if (copy_transform_to_cache) {
+ cache_transform = get_transform();
+ }
+ } break;
- else if (p_what == NOTIFICATION_EXIT_TREE) {
- if (skeleton) {
- for (int i = 0; i < skeleton->bones.size(); i++) {
- if (skeleton->bones[i].bone == this) {
- skeleton->bones.remove_at(i);
- break;
+ case NOTIFICATION_EXIT_TREE: {
+ if (skeleton) {
+ for (int i = 0; i < skeleton->bones.size(); i++) {
+ if (skeleton->bones[i].bone == this) {
+ skeleton->bones.remove_at(i);
+ break;
+ }
}
+ skeleton->_make_bone_setup_dirty();
+ skeleton = nullptr;
}
- skeleton->_make_bone_setup_dirty();
- skeleton = nullptr;
- }
- parent_bone = nullptr;
- set_transform(cache_transform);
- }
+ parent_bone = nullptr;
+ set_transform(cache_transform);
+ } break;
+
+ case NOTIFICATION_READY: {
+ if (autocalculate_length_and_angle) {
+ calculate_length_and_rotation();
+ }
+ } break;
- else if (p_what == NOTIFICATION_READY) {
- if (autocalculate_length_and_angle) {
- calculate_length_and_rotation();
- }
- }
#ifdef TOOLS_ENABLED
- else if (p_what == NOTIFICATION_EDITOR_PRE_SAVE || p_what == NOTIFICATION_EDITOR_POST_SAVE) {
- Transform2D tmp_trans = get_transform();
- set_transform(cache_transform);
- cache_transform = tmp_trans;
- }
- // Bone2D Editor gizmo drawing:
+ case NOTIFICATION_EDITOR_PRE_SAVE:
+ case NOTIFICATION_EDITOR_POST_SAVE: {
+ Transform2D tmp_trans = get_transform();
+ set_transform(cache_transform);
+ cache_transform = tmp_trans;
+ } break;
+
+ // Bone2D Editor gizmo drawing:
#ifndef _MSC_VER
#warning TODO Bone2D gizmo drawing needs to be moved to an editor plugin
#endif
- else if (p_what == NOTIFICATION_DRAW) {
- // Only draw the gizmo in the editor!
- if (Engine::get_singleton()->is_editor_hint() == false) {
- return;
- }
-
- if (editor_gizmo_rid.is_null()) {
- editor_gizmo_rid = RenderingServer::get_singleton()->canvas_item_create();
- RenderingServer::get_singleton()->canvas_item_set_parent(editor_gizmo_rid, get_canvas_item());
- RenderingServer::get_singleton()->canvas_item_set_z_as_relative_to_parent(editor_gizmo_rid, true);
- RenderingServer::get_singleton()->canvas_item_set_z_index(editor_gizmo_rid, 10);
- }
- RenderingServer::get_singleton()->canvas_item_clear(editor_gizmo_rid);
-
- if (!_editor_show_bone_gizmo) {
- return;
- }
-
- // Undo scaling
- Transform2D editor_gizmo_trans = Transform2D();
- editor_gizmo_trans.set_scale(Vector2(1, 1) / get_global_scale());
- RenderingServer::get_singleton()->canvas_item_set_transform(editor_gizmo_rid, editor_gizmo_trans);
-
- Color bone_color1 = EditorSettings::get_singleton()->get("editors/2d/bone_color1");
- Color bone_color2 = EditorSettings::get_singleton()->get("editors/2d/bone_color2");
- Color bone_ik_color = EditorSettings::get_singleton()->get("editors/2d/bone_ik_color");
- Color bone_outline_color = EditorSettings::get_singleton()->get("editors/2d/bone_outline_color");
- Color bone_selected_color = EditorSettings::get_singleton()->get("editors/2d/bone_selected_color");
-
- bool Bone2D_found = false;
- for (int i = 0; i < get_child_count(); i++) {
- Bone2D *child_node = nullptr;
- child_node = Object::cast_to<Bone2D>(get_child(i));
- if (!child_node) {
- continue;
+ case NOTIFICATION_DRAW: {
+ // Only draw the gizmo in the editor!
+ if (Engine::get_singleton()->is_editor_hint() == false) {
+ return;
}
- Bone2D_found = true;
-
- Vector<Vector2> bone_shape;
- Vector<Vector2> bone_shape_outline;
- _editor_get_bone_shape(&bone_shape, &bone_shape_outline, child_node);
-
- Vector<Color> colors;
- if (has_meta("_local_pose_override_enabled_")) {
- colors.push_back(bone_ik_color);
- colors.push_back(bone_ik_color);
- colors.push_back(bone_ik_color);
- colors.push_back(bone_ik_color);
- } else {
- colors.push_back(bone_color1);
- colors.push_back(bone_color2);
- colors.push_back(bone_color1);
- colors.push_back(bone_color2);
+ if (editor_gizmo_rid.is_null()) {
+ editor_gizmo_rid = RenderingServer::get_singleton()->canvas_item_create();
+ RenderingServer::get_singleton()->canvas_item_set_parent(editor_gizmo_rid, get_canvas_item());
+ RenderingServer::get_singleton()->canvas_item_set_z_as_relative_to_parent(editor_gizmo_rid, true);
+ RenderingServer::get_singleton()->canvas_item_set_z_index(editor_gizmo_rid, 10);
}
+ RenderingServer::get_singleton()->canvas_item_clear(editor_gizmo_rid);
- Vector<Color> outline_colors;
- if (CanvasItemEditor::get_singleton()->editor_selection->is_selected(this)) {
- outline_colors.push_back(bone_selected_color);
- outline_colors.push_back(bone_selected_color);
- outline_colors.push_back(bone_selected_color);
- outline_colors.push_back(bone_selected_color);
- outline_colors.push_back(bone_selected_color);
- outline_colors.push_back(bone_selected_color);
- } else {
- outline_colors.push_back(bone_outline_color);
- outline_colors.push_back(bone_outline_color);
- outline_colors.push_back(bone_outline_color);
- outline_colors.push_back(bone_outline_color);
- outline_colors.push_back(bone_outline_color);
- outline_colors.push_back(bone_outline_color);
+ if (!_editor_show_bone_gizmo) {
+ return;
}
- RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape_outline, outline_colors);
- RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape, colors);
- }
-
- if (!Bone2D_found) {
- Vector<Vector2> bone_shape;
- Vector<Vector2> bone_shape_outline;
+ // Undo scaling
+ Transform2D editor_gizmo_trans = Transform2D();
+ editor_gizmo_trans.set_scale(Vector2(1, 1) / get_global_scale());
+ RenderingServer::get_singleton()->canvas_item_set_transform(editor_gizmo_rid, editor_gizmo_trans);
+
+ Color bone_color1 = EditorSettings::get_singleton()->get("editors/2d/bone_color1");
+ Color bone_color2 = EditorSettings::get_singleton()->get("editors/2d/bone_color2");
+ Color bone_ik_color = EditorSettings::get_singleton()->get("editors/2d/bone_ik_color");
+ Color bone_outline_color = EditorSettings::get_singleton()->get("editors/2d/bone_outline_color");
+ Color bone_selected_color = EditorSettings::get_singleton()->get("editors/2d/bone_selected_color");
+
+ bool Bone2D_found = false;
+ for (int i = 0; i < get_child_count(); i++) {
+ Bone2D *child_node = nullptr;
+ child_node = Object::cast_to<Bone2D>(get_child(i));
+ if (!child_node) {
+ continue;
+ }
+ Bone2D_found = true;
+
+ Vector<Vector2> bone_shape;
+ Vector<Vector2> bone_shape_outline;
+
+ _editor_get_bone_shape(&bone_shape, &bone_shape_outline, child_node);
+
+ Vector<Color> colors;
+ if (has_meta("_local_pose_override_enabled_")) {
+ colors.push_back(bone_ik_color);
+ colors.push_back(bone_ik_color);
+ colors.push_back(bone_ik_color);
+ colors.push_back(bone_ik_color);
+ } else {
+ colors.push_back(bone_color1);
+ colors.push_back(bone_color2);
+ colors.push_back(bone_color1);
+ colors.push_back(bone_color2);
+ }
- _editor_get_bone_shape(&bone_shape, &bone_shape_outline, nullptr);
+ Vector<Color> outline_colors;
+ if (CanvasItemEditor::get_singleton()->editor_selection->is_selected(this)) {
+ outline_colors.push_back(bone_selected_color);
+ outline_colors.push_back(bone_selected_color);
+ outline_colors.push_back(bone_selected_color);
+ outline_colors.push_back(bone_selected_color);
+ outline_colors.push_back(bone_selected_color);
+ outline_colors.push_back(bone_selected_color);
+ } else {
+ outline_colors.push_back(bone_outline_color);
+ outline_colors.push_back(bone_outline_color);
+ outline_colors.push_back(bone_outline_color);
+ outline_colors.push_back(bone_outline_color);
+ outline_colors.push_back(bone_outline_color);
+ outline_colors.push_back(bone_outline_color);
+ }
- Vector<Color> colors;
- if (has_meta("_local_pose_override_enabled_")) {
- colors.push_back(bone_ik_color);
- colors.push_back(bone_ik_color);
- colors.push_back(bone_ik_color);
- colors.push_back(bone_ik_color);
- } else {
- colors.push_back(bone_color1);
- colors.push_back(bone_color2);
- colors.push_back(bone_color1);
- colors.push_back(bone_color2);
+ RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape_outline, outline_colors);
+ RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape, colors);
}
- Vector<Color> outline_colors;
- if (CanvasItemEditor::get_singleton()->editor_selection->is_selected(this)) {
- outline_colors.push_back(bone_selected_color);
- outline_colors.push_back(bone_selected_color);
- outline_colors.push_back(bone_selected_color);
- outline_colors.push_back(bone_selected_color);
- outline_colors.push_back(bone_selected_color);
- outline_colors.push_back(bone_selected_color);
- } else {
- outline_colors.push_back(bone_outline_color);
- outline_colors.push_back(bone_outline_color);
- outline_colors.push_back(bone_outline_color);
- outline_colors.push_back(bone_outline_color);
- outline_colors.push_back(bone_outline_color);
- outline_colors.push_back(bone_outline_color);
- }
+ if (!Bone2D_found) {
+ Vector<Vector2> bone_shape;
+ Vector<Vector2> bone_shape_outline;
+
+ _editor_get_bone_shape(&bone_shape, &bone_shape_outline, nullptr);
+
+ Vector<Color> colors;
+ if (has_meta("_local_pose_override_enabled_")) {
+ colors.push_back(bone_ik_color);
+ colors.push_back(bone_ik_color);
+ colors.push_back(bone_ik_color);
+ colors.push_back(bone_ik_color);
+ } else {
+ colors.push_back(bone_color1);
+ colors.push_back(bone_color2);
+ colors.push_back(bone_color1);
+ colors.push_back(bone_color2);
+ }
- RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape_outline, outline_colors);
- RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape, colors);
- }
+ Vector<Color> outline_colors;
+ if (CanvasItemEditor::get_singleton()->editor_selection->is_selected(this)) {
+ outline_colors.push_back(bone_selected_color);
+ outline_colors.push_back(bone_selected_color);
+ outline_colors.push_back(bone_selected_color);
+ outline_colors.push_back(bone_selected_color);
+ outline_colors.push_back(bone_selected_color);
+ outline_colors.push_back(bone_selected_color);
+ } else {
+ outline_colors.push_back(bone_outline_color);
+ outline_colors.push_back(bone_outline_color);
+ outline_colors.push_back(bone_outline_color);
+ outline_colors.push_back(bone_outline_color);
+ outline_colors.push_back(bone_outline_color);
+ outline_colors.push_back(bone_outline_color);
+ }
+
+ RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape_outline, outline_colors);
+ RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape, colors);
+ }
+ } break;
+#endif // TOOLS_ENABLED
}
-#endif // TOOLS_ENALBED
}
#ifdef TOOLS_ENABLED
diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp
index 389fa0388f..facd164a0e 100644
--- a/scene/2d/sprite_2d.cpp
+++ b/scene/2d/sprite_2d.cpp
@@ -122,11 +122,6 @@ void Sprite2D::_notification(int p_what) {
RID ci = get_canvas_item();
- /*
- texture->draw(ci,Point2());
- break;
- */
-
Rect2 src_rect, dst_rect;
bool filter_clip_enabled;
_get_rects(src_rect, dst_rect, filter_clip_enabled);
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 62dc4d1c15..db33e6561a 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -31,7 +31,7 @@
#include "tile_map.h"
#include "core/io/marshalls.h"
-
+#include "scene/resources/world_2d.h"
#include "servers/navigation_server_2d.h"
Map<Vector2i, TileSet::CellNeighbor> TileMap::TerrainConstraint::get_overlapping_coords_and_peering_bits() const {
@@ -489,6 +489,7 @@ void TileMap::_notification(int p_what) {
_clear_internals();
_recreate_internals();
} break;
+
case NOTIFICATION_EXIT_TREE: {
_clear_internals();
} break;
@@ -980,7 +981,7 @@ void TileMap::_recompute_rect_cache() {
void TileMap::_rendering_notification(int p_what) {
switch (p_what) {
- case CanvasItem::NOTIFICATION_VISIBILITY_CHANGED: {
+ case NOTIFICATION_VISIBILITY_CHANGED: {
bool visible = is_visible_in_tree();
for (int layer = 0; layer < (int)layers.size(); layer++) {
for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) {
@@ -997,7 +998,8 @@ void TileMap::_rendering_notification(int p_what) {
}
}
} break;
- case CanvasItem::NOTIFICATION_TRANSFORM_CHANGED: {
+
+ case NOTIFICATION_TRANSFORM_CHANGED: {
if (!is_inside_tree()) {
return;
}
@@ -1016,7 +1018,8 @@ void TileMap::_rendering_notification(int p_what) {
}
}
} break;
- case CanvasItem::NOTIFICATION_DRAW: {
+
+ case NOTIFICATION_DRAW: {
if (tile_set.is_valid()) {
RenderingServer::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), is_y_sort_enabled());
}
@@ -1119,7 +1122,7 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
if (q.runtime_tile_data_cache.has(E_cell.value)) {
tile_data = q.runtime_tile_data_cache[E_cell.value];
} else {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
+ tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
Ref<ShaderMaterial> mat = tile_data->get_material();
@@ -1311,7 +1314,7 @@ void TileMap::draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSe
}
// Get tile data.
- const TileData *tile_data = p_tile_data_override ? p_tile_data_override : Object::cast_to<TileData>(atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile));
+ const TileData *tile_data = p_tile_data_override ? p_tile_data_override : atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile);
// Get the tile modulation.
Color modulate = tile_data->get_modulate() * p_modulation;
@@ -1369,7 +1372,7 @@ void TileMap::draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSe
void TileMap::_physics_notification(int p_what) {
switch (p_what) {
- case CanvasItem::NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
bool in_editor = false;
#ifdef TOOLS_ENABLED
in_editor = Engine::get_singleton()->is_editor_hint();
@@ -1382,7 +1385,8 @@ void TileMap::_physics_notification(int p_what) {
set_notify_local_transform(true);
}
} break;
- case CanvasItem::NOTIFICATION_TRANSFORM_CHANGED: {
+
+ case NOTIFICATION_TRANSFORM_CHANGED: {
bool in_editor = false;
#ifdef TOOLS_ENABLED
in_editor = Engine::get_singleton()->is_editor_hint();
@@ -1404,6 +1408,7 @@ void TileMap::_physics_notification(int p_what) {
}
}
} break;
+
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
bool in_editor = false;
#ifdef TOOLS_ENABLED
@@ -1474,7 +1479,7 @@ void TileMap::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r
if (q.runtime_tile_data_cache.has(E_cell->get())) {
tile_data = q.runtime_tile_data_cache[E_cell->get()];
} else {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
+ tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
for (int tile_set_physics_layer = 0; tile_set_physics_layer < tile_set->get_physics_layers_count(); tile_set_physics_layer++) {
Ref<PhysicsMaterial> physics_material = tile_set->get_physics_layer_physics_material(tile_set_physics_layer);
@@ -1600,7 +1605,7 @@ void TileMap::_physics_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
void TileMap::_navigation_notification(int p_what) {
switch (p_what) {
- case CanvasItem::NOTIFICATION_TRANSFORM_CHANGED: {
+ case NOTIFICATION_TRANSFORM_CHANGED: {
if (is_inside_tree()) {
for (int layer = 0; layer < (int)layers.size(); layer++) {
Transform2D tilemap_xform = get_global_transform();
@@ -1671,7 +1676,7 @@ void TileMap::_navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
if (q.runtime_tile_data_cache.has(E_cell->get())) {
tile_data = q.runtime_tile_data_cache[E_cell->get()];
} else {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
+ tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
q.navigation_regions[E_cell->get()].resize(tile_set->get_navigation_layers_count());
@@ -1760,7 +1765,7 @@ void TileMap::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
if (p_quadrant->runtime_tile_data_cache.has(E_cell->get())) {
tile_data = p_quadrant->runtime_tile_data_cache[E_cell->get()];
} else {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
+ tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
Transform2D xform;
@@ -1809,7 +1814,7 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_
// Clear the scenes.
for (const KeyValue<Vector2i, String> &E : q.scenes) {
- Node *node = get_node(E.value);
+ Node *node = get_node_or_null(E.value);
if (node) {
node->queue_delete();
}
@@ -1857,7 +1862,7 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_
void TileMap::_scenes_cleanup_quadrant(TileMapQuadrant *p_quadrant) {
// Clear the scenes.
for (const KeyValue<Vector2i, String> &E : p_quadrant->scenes) {
- Node *node = get_node(E.value);
+ Node *node = get_node_or_null(E.value);
if (node) {
node->queue_delete();
}
@@ -1992,6 +1997,10 @@ void TileMap::set_cell(int p_layer, const Vector2i &p_coords, int p_source_id, c
}
}
+void TileMap::erase_cell(int p_layer, const Vector2i &p_coords) {
+ set_cell(p_layer, p_coords, TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
+}
+
int TileMap::get_cell_source_id(int p_layer, const Vector2i &p_coords, bool p_use_proxies) const {
ERR_FAIL_INDEX_V(p_layer, (int)layers.size(), TileSet::INVALID_SOURCE);
@@ -2204,7 +2213,7 @@ Set<TileMap::TerrainConstraint> TileMap::get_terrain_constraints_from_removed_ce
Ref<TileSetSource> source = tile_set->get_source(neighbor_cell.source_id);
Ref<TileSetAtlasSource> atlas_source = source;
if (atlas_source.is_valid()) {
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(neighbor_cell.get_atlas_coords(), neighbor_cell.alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(neighbor_cell.get_atlas_coords(), neighbor_cell.alternative_tile);
if (tile_data && tile_data->get_terrain_set() == p_terrain_set) {
neighbor_tile_data = tile_data;
}
@@ -2580,7 +2589,7 @@ void TileMap::_build_runtime_update_tile_data(SelfList<TileMapQuadrant>::List &r
if (atlas_source) {
bool ret = false;
if (GDVIRTUAL_CALL(_use_tile_data_runtime_update, q.layer, E_cell.value, ret) && ret) {
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
// Create the runtime TileData.
TileData *tile_data_runtime_use = tile_data->duplicate();
@@ -2725,7 +2734,7 @@ void TileMap::_get_property_list(List<PropertyInfo> *p_list) const {
}
Vector2 TileMap::map_to_world(const Vector2i &p_pos) const {
- // SHOULD RETURN THE CENTER OF THE TILE
+ // SHOULD RETURN THE CENTER OF THE CELL
ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2());
Vector2 ret = p_pos;
@@ -3617,7 +3626,8 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_navigation_visibility_mode", "navigation_visibility_mode"), &TileMap::set_navigation_visibility_mode);
ClassDB::bind_method(D_METHOD("get_navigation_visibility_mode"), &TileMap::get_navigation_visibility_mode);
- ClassDB::bind_method(D_METHOD("set_cell", "layer", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMap::set_cell, DEFVAL(TileSet::INVALID_SOURCE), DEFVAL(TileSetSource::INVALID_ATLAS_COORDS), DEFVAL(TileSetSource::INVALID_TILE_ALTERNATIVE));
+ ClassDB::bind_method(D_METHOD("set_cell", "layer", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMap::set_cell, DEFVAL(TileSet::INVALID_SOURCE), DEFVAL(TileSetSource::INVALID_ATLAS_COORDS), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("erase_cell", "layer", "coords"), &TileMap::erase_cell);
ClassDB::bind_method(D_METHOD("get_cell_source_id", "layer", "coords", "use_proxies"), &TileMap::get_cell_source_id);
ClassDB::bind_method(D_METHOD("get_cell_atlas_coords", "layer", "coords", "use_proxies"), &TileMap::get_cell_atlas_coords);
ClassDB::bind_method(D_METHOD("get_cell_alternative_tile", "layer", "coords", "use_proxies"), &TileMap::get_cell_alternative_tile);
@@ -3648,9 +3658,6 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_dirty_quadrants"), &TileMap::_update_dirty_quadrants);
- ClassDB::bind_method(D_METHOD("_set_tile_data", "layer", "data"), &TileMap::_set_tile_data);
- ClassDB::bind_method(D_METHOD("_get_tile_data", "layer"), &TileMap::_get_tile_data);
-
ClassDB::bind_method(D_METHOD("_tile_set_changed_deferred_update"), &TileMap::_tile_set_changed_deferred_update);
GDVIRTUAL_BIND(_use_tile_data_runtime_update, "layer", "coords");
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 0da04bfeae..a0655dea2a 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -321,7 +321,8 @@ public:
VisibilityMode get_navigation_visibility_mode();
// Cells accessors.
- void set_cell(int p_layer, const Vector2i &p_coords, int p_source_id = -1, const Vector2i p_atlas_coords = TileSetSource::INVALID_ATLAS_COORDS, int p_alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE);
+ void set_cell(int p_layer, const Vector2i &p_coords, int p_source_id = -1, const Vector2i p_atlas_coords = TileSetSource::INVALID_ATLAS_COORDS, int p_alternative_tile = 0);
+ void erase_cell(int p_layer, const Vector2i &p_coords);
int get_cell_source_id(int p_layer, const Vector2i &p_coords, bool p_use_proxies = false) const;
Vector2i get_cell_atlas_coords(int p_layer, const Vector2i &p_coords, bool p_use_proxies = false) const;
int get_cell_alternative_tile(int p_layer, const Vector2i &p_coords, bool p_use_proxies = false) const;
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index 77e6ad44c6..9a68c17269 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -32,13 +32,13 @@
#include "scene/main/window.h"
-void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) {
- texture = p_texture;
+void TouchScreenButton::set_texture_normal(const Ref<Texture2D> &p_texture) {
+ texture_normal = p_texture;
update();
}
-Ref<Texture2D> TouchScreenButton::get_texture() const {
- return texture;
+Ref<Texture2D> TouchScreenButton::get_texture_normal() const {
+ return texture_normal;
}
void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pressed) {
@@ -107,13 +107,13 @@ void TouchScreenButton::_notification(int p_what) {
if (finger_pressed != -1) {
if (texture_pressed.is_valid()) {
draw_texture(texture_pressed, Point2());
- } else if (texture.is_valid()) {
- draw_texture(texture, Point2());
+ } else if (texture_normal.is_valid()) {
+ draw_texture(texture_normal, Point2());
}
} else {
- if (texture.is_valid()) {
- draw_texture(texture, Point2());
+ if (texture_normal.is_valid()) {
+ draw_texture(texture_normal, Point2());
}
}
@@ -127,15 +127,15 @@ void TouchScreenButton::_notification(int p_what) {
Color draw_col = get_tree()->get_debug_collisions_color();
Vector2 pos;
- if (shape_centered && texture.is_valid()) {
- pos = texture->get_size() * 0.5;
+ if (shape_centered && texture_normal.is_valid()) {
+ pos = texture_normal->get_size() * 0.5;
}
draw_set_transform_matrix(get_canvas_transform().translated(pos));
shape->draw(get_canvas_item(), draw_col);
}
-
} break;
+
case NOTIFICATION_ENTER_TREE: {
if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())) && visibility == VISIBILITY_TOUCHSCREEN_ONLY) {
return;
@@ -145,13 +145,14 @@ void TouchScreenButton::_notification(int p_what) {
if (!Engine::get_singleton()->is_editor_hint()) {
set_process_input(is_visible_in_tree());
}
-
} break;
+
case NOTIFICATION_EXIT_TREE: {
if (is_pressed()) {
_release(true);
}
} break;
+
case NOTIFICATION_VISIBILITY_CHANGED: {
if (Engine::get_singleton()->is_editor_hint()) {
break;
@@ -165,6 +166,7 @@ void TouchScreenButton::_notification(int p_what) {
}
}
} break;
+
case NOTIFICATION_PAUSED: {
if (is_pressed()) {
_release();
@@ -254,8 +256,8 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
check_rect = false;
Vector2 pos;
- if (shape_centered && texture.is_valid()) {
- pos = texture->get_size() * 0.5;
+ if (shape_centered && texture_normal.is_valid()) {
+ pos = texture_normal->get_size() * 0.5;
}
touched = shape->collide(Transform2D().translated(pos), unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5)));
@@ -271,8 +273,8 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
}
if (!touched && check_rect) {
- if (texture.is_valid()) {
- touched = Rect2(Size2(), texture->get_size()).has_point(coord);
+ if (texture_normal.is_valid()) {
+ touched = Rect2(Size2(), texture_normal->get_size()).has_point(coord);
}
}
@@ -317,24 +319,24 @@ void TouchScreenButton::_release(bool p_exiting_tree) {
#ifdef TOOLS_ENABLED
Rect2 TouchScreenButton::_edit_get_rect() const {
- if (texture.is_null()) {
+ if (texture_normal.is_null()) {
return CanvasItem::_edit_get_rect();
}
- return Rect2(Size2(), texture->get_size());
+ return Rect2(Size2(), texture_normal->get_size());
}
bool TouchScreenButton::_edit_use_rect() const {
- return !texture.is_null();
+ return !texture_normal.is_null();
}
#endif
Rect2 TouchScreenButton::get_anchorable_rect() const {
- if (texture.is_null()) {
+ if (texture_normal.is_null()) {
return CanvasItem::get_anchorable_rect();
}
- return Rect2(Size2(), texture->get_size());
+ return Rect2(Size2(), texture_normal->get_size());
}
void TouchScreenButton::set_visibility_mode(VisibilityMode p_mode) {
@@ -355,10 +357,10 @@ bool TouchScreenButton::is_passby_press_enabled() const {
}
void TouchScreenButton::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_texture", "texture"), &TouchScreenButton::set_texture);
- ClassDB::bind_method(D_METHOD("get_texture"), &TouchScreenButton::get_texture);
+ ClassDB::bind_method(D_METHOD("set_texture_normal", "texture"), &TouchScreenButton::set_texture_normal);
+ ClassDB::bind_method(D_METHOD("get_texture_normal"), &TouchScreenButton::get_texture_normal);
- ClassDB::bind_method(D_METHOD("set_texture_pressed", "texture_pressed"), &TouchScreenButton::set_texture_pressed);
+ ClassDB::bind_method(D_METHOD("set_texture_pressed", "texture"), &TouchScreenButton::set_texture_pressed);
ClassDB::bind_method(D_METHOD("get_texture_pressed"), &TouchScreenButton::get_texture_pressed);
ClassDB::bind_method(D_METHOD("set_bitmask", "bitmask"), &TouchScreenButton::set_bitmask);
@@ -384,8 +386,8 @@ void TouchScreenButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_pressed"), &TouchScreenButton::is_pressed);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_pressed", "get_texture_pressed");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_normal", "get_texture_normal");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_pressed", "get_texture_pressed");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "bitmask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_bitmask", "get_bitmask");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_centered"), "set_shape_centered", "is_shape_centered");
diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h
index 6ed9ba8dc7..e7f6da9f50 100644
--- a/scene/2d/touch_screen_button.h
+++ b/scene/2d/touch_screen_button.h
@@ -46,7 +46,7 @@ public:
};
private:
- Ref<Texture2D> texture;
+ Ref<Texture2D> texture_normal;
Ref<Texture2D> texture_pressed;
Ref<BitMap> bitmask;
Ref<Shape2D> shape;
@@ -78,8 +78,8 @@ public:
virtual bool _edit_use_rect() const override;
#endif
- void set_texture(const Ref<Texture2D> &p_texture);
- Ref<Texture2D> get_texture() const;
+ void set_texture_normal(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture_normal() const;
void set_texture_pressed(const Ref<Texture2D> &p_texture_pressed);
Ref<Texture2D> get_texture_pressed() const;
diff --git a/scene/2d/visible_on_screen_notifier_2d.cpp b/scene/2d/visible_on_screen_notifier_2d.cpp
index a7c2ae5bb1..4bceaf71c6 100644
--- a/scene/2d/visible_on_screen_notifier_2d.cpp
+++ b/scene/2d/visible_on_screen_notifier_2d.cpp
@@ -75,15 +75,16 @@ Rect2 VisibleOnScreenNotifier2D::get_rect() const {
void VisibleOnScreenNotifier2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- //get_world_2d()->
on_screen = false;
RS::get_singleton()->canvas_item_set_visibility_notifier(get_canvas_item(), true, rect, callable_mp(this, &VisibleOnScreenNotifier2D::_visibility_enter), callable_mp(this, &VisibleOnScreenNotifier2D::_visibility_exit));
} break;
+
case NOTIFICATION_DRAW: {
if (Engine::get_singleton()->is_editor_hint()) {
draw_rect(rect, Color(1, 0.5, 1, 0.2));
}
} break;
+
case NOTIFICATION_EXIT_TREE: {
on_screen = false;
RS::get_singleton()->canvas_item_set_visibility_notifier(get_canvas_item(), false, Rect2(), Callable(), Callable());
@@ -169,21 +170,23 @@ void VisibleOnScreenEnabler2D::_update_enable_mode(bool p_enable) {
}
}
void VisibleOnScreenEnabler2D::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- if (Engine::get_singleton()->is_editor_hint()) {
- return;
- }
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ return;
+ }
- node_id = ObjectID();
- Node *node = get_node(enable_node_path);
- if (node) {
- node_id = node->get_instance_id();
- node->set_process_mode(PROCESS_MODE_DISABLED);
- }
- }
+ node_id = ObjectID();
+ Node *node = get_node(enable_node_path);
+ if (node) {
+ node_id = node->get_instance_id();
+ node->set_process_mode(PROCESS_MODE_DISABLED);
+ }
+ } break;
- if (p_what == NOTIFICATION_EXIT_TREE) {
- node_id = ObjectID();
+ case NOTIFICATION_EXIT_TREE: {
+ node_id = ObjectID();
+ } break;
}
}