diff options
Diffstat (limited to 'scene/2d')
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; } } |