diff options
Diffstat (limited to 'scene/2d')
75 files changed, 1824 insertions, 2541 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index fc34f967ce..0f98fad824 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -31,11 +31,9 @@ #include "animated_sprite_2d.h" #include "core/os/os.h" +#include "scene/main/viewport.h" #include "scene/scene_string_names.h" -#define NORMAL_SUFFIX "_normal" -#define SPECULAR_SUFFIX "_specular" - #ifdef TOOLS_ENABLED Dictionary AnimatedSprite2D::_edit_get_state() const { Dictionary state = Node2D::_edit_get_state(); @@ -70,8 +68,9 @@ bool AnimatedSprite2D::_edit_use_rect() const { return false; } Ref<Texture2D> t; - if (animation) + if (animation) { t = frames->get_frame(animation, frame); + } return t.is_valid(); } #endif @@ -86,31 +85,35 @@ Rect2 AnimatedSprite2D::_get_rect() const { } Ref<Texture2D> t; - if (animation) + if (animation) { t = frames->get_frame(animation, frame); - if (t.is_null()) + } + if (t.is_null()) { return Rect2(); + } Size2 s = t->get_size(); Point2 ofs = offset; - if (centered) + if (centered) { ofs -= Size2(s) / 2; + } - if (s == Size2(0, 0)) + if (s == Size2(0, 0)) { s = Size2(1, 1); + } return Rect2(ofs, s); } void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos) { - Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist."); - if (p_at_pos >= 0 && p_at_pos < E->get().frames.size()) + if (p_at_pos >= 0 && p_at_pos < E->get().frames.size()) { E->get().frames.insert(p_at_pos, p_frame); - else + } else { E->get().frames.push_back(p_frame); + } emit_changed(); } @@ -123,15 +126,14 @@ int SpriteFrames::get_frame_count(const StringName &p_anim) const { } void SpriteFrames::remove_frame(const StringName &p_anim, int p_idx) { - Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist."); E->get().frames.remove(p_idx); emit_changed(); } -void SpriteFrames::clear(const StringName &p_anim) { +void SpriteFrames::clear(const StringName &p_anim) { Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist."); @@ -140,48 +142,38 @@ void SpriteFrames::clear(const StringName &p_anim) { } void SpriteFrames::clear_all() { - animations.clear(); add_animation("default"); } void SpriteFrames::add_animation(const StringName &p_anim) { - ERR_FAIL_COND_MSG(animations.has(p_anim), "SpriteFrames already has animation '" + p_anim + "'."); animations[p_anim] = Anim(); - animations[p_anim].normal_name = String(p_anim) + NORMAL_SUFFIX; - animations[p_anim].specular_name = String(p_anim) + SPECULAR_SUFFIX; } bool SpriteFrames::has_animation(const StringName &p_anim) const { - return animations.has(p_anim); } -void SpriteFrames::remove_animation(const StringName &p_anim) { +void SpriteFrames::remove_animation(const StringName &p_anim) { animations.erase(p_anim); } void SpriteFrames::rename_animation(const StringName &p_prev, const StringName &p_next) { - ERR_FAIL_COND_MSG(!animations.has(p_prev), "SpriteFrames doesn't have animation '" + String(p_prev) + "'."); ERR_FAIL_COND_MSG(animations.has(p_next), "Animation '" + String(p_next) + "' already exists."); Anim anim = animations[p_prev]; animations.erase(p_prev); animations[p_next] = anim; - animations[p_next].normal_name = String(p_next) + NORMAL_SUFFIX; - animations[p_next].specular_name = String(p_next) + SPECULAR_SUFFIX; } Vector<String> SpriteFrames::_get_animation_list() const { - Vector<String> ret; List<StringName> al; get_animation_list(&al); for (List<StringName>::Element *E = al.front(); E; E = E->next()) { - ret.push_back(E->get()); } @@ -189,14 +181,12 @@ Vector<String> SpriteFrames::_get_animation_list() const { } void SpriteFrames::get_animation_list(List<StringName> *r_animations) const { - for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) { r_animations->push_back(E->key()); } } Vector<String> SpriteFrames::get_animation_names() const { - Vector<String> names; for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) { names.push_back(E->key()); @@ -206,14 +196,13 @@ Vector<String> SpriteFrames::get_animation_names() const { } void SpriteFrames::set_animation_speed(const StringName &p_anim, float p_fps) { - ERR_FAIL_COND_MSG(p_fps < 0, "Animation speed cannot be negative (" + itos(p_fps) + ")."); Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist."); E->get().speed = p_fps; } -float SpriteFrames::get_animation_speed(const StringName &p_anim) const { +float SpriteFrames::get_animation_speed(const StringName &p_anim) const { const Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_V_MSG(!E, 0, "Animation '" + String(p_anim) + "' doesn't exist."); return E->get().speed; @@ -224,6 +213,7 @@ void SpriteFrames::set_animation_loop(const StringName &p_anim, bool p_loop) { ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist."); E->get().loop = p_loop; } + bool SpriteFrames::get_animation_loop(const StringName &p_anim) const { const Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_V_MSG(!E, false, "Animation '" + String(p_anim) + "' doesn't exist."); @@ -231,22 +221,21 @@ bool SpriteFrames::get_animation_loop(const StringName &p_anim) const { } void SpriteFrames::_set_frames(const Array &p_frames) { - clear_all(); Map<StringName, Anim>::Element *E = animations.find(SceneStringNames::get_singleton()->_default); ERR_FAIL_COND(!E); E->get().frames.resize(p_frames.size()); - for (int i = 0; i < E->get().frames.size(); i++) + for (int i = 0; i < E->get().frames.size(); i++) { E->get().frames.write[i] = p_frames[i]; + } } -Array SpriteFrames::_get_frames() const { +Array SpriteFrames::_get_frames() const { return Array(); } Array SpriteFrames::_get_animations() const { - Array anims; for (Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) { Dictionary d; @@ -263,11 +252,10 @@ Array SpriteFrames::_get_animations() const { return anims; } -void SpriteFrames::_set_animations(const Array &p_animations) { +void SpriteFrames::_set_animations(const Array &p_animations) { animations.clear(); for (int i = 0; i < p_animations.size(); i++) { - Dictionary d = p_animations[i]; ERR_CONTINUE(!d.has("name")); @@ -280,7 +268,6 @@ void SpriteFrames::_set_animations(const Array &p_animations) { anim.loop = d["loop"]; Array frames = d["frames"]; for (int j = 0; j < frames.size(); j++) { - RES res = frames[j]; anim.frames.push_back(res); } @@ -290,7 +277,6 @@ void SpriteFrames::_set_animations(const Array &p_animations) { } void SpriteFrames::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_animation", "anim"), &SpriteFrames::add_animation); ClassDB::bind_method(D_METHOD("has_animation", "anim"), &SpriteFrames::has_animation); ClassDB::bind_method(D_METHOD("remove_animation", "anim"), &SpriteFrames::remove_animation); @@ -324,16 +310,14 @@ void SpriteFrames::_bind_methods() { } SpriteFrames::SpriteFrames() { - add_animation(SceneStringNames::get_singleton()->_default); } void AnimatedSprite2D::_validate_property(PropertyInfo &property) const { - - if (!frames.is_valid()) + if (!frames.is_valid()) { return; + } if (property.name == "animation") { - property.hint = PROPERTY_HINT_ENUM; List<StringName> names; frames->get_animation_list(&names); @@ -371,43 +355,45 @@ void AnimatedSprite2D::_validate_property(PropertyInfo &property) const { } void AnimatedSprite2D::_notification(int p_what) { - switch (p_what) { case NOTIFICATION_INTERNAL_PROCESS: { - - if (frames.is_null()) + if (frames.is_null()) { return; - if (!frames->has_animation(animation)) + } + if (!frames->has_animation(animation)) { return; - if (frame < 0) + } + if (frame < 0) { return; + } float speed = frames->get_animation_speed(animation) * speed_scale; - if (speed == 0) + if (speed == 0) { return; //do nothing + } float remaining = get_process_delta_time(); while (remaining) { - if (timeout <= 0) { - timeout = _get_frame_duration(); int fc = frames->get_frame_count(animation); if ((!backwards && frame >= fc - 1) || (backwards && frame <= 0)) { if (frames->get_animation_loop(animation)) { - if (backwards) + if (backwards) { frame = fc - 1; - else + } else { frame = 0; + } emit_signal(SceneStringNames::get_singleton()->animation_finished); } else { - if (backwards) + if (backwards) { frame = 0; - else + } else { frame = fc - 1; + } if (!is_over) { is_over = true; @@ -415,10 +401,11 @@ void AnimatedSprite2D::_notification(int p_what) { } } } else { - if (backwards) + if (backwards) { frame--; - else + } else { frame++; + } } update(); @@ -433,52 +420,56 @@ void AnimatedSprite2D::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - - if (frames.is_null()) + if (frames.is_null()) { return; - if (frame < 0) + } + if (frame < 0) { return; - if (!frames->has_animation(animation)) + } + if (!frames->has_animation(animation)) { return; + } Ref<Texture2D> texture = frames->get_frame(animation, frame); - if (texture.is_null()) + if (texture.is_null()) { return; - - Ref<Texture2D> normal = frames->get_normal_frame(animation, frame); - Ref<Texture2D> specular = frames->get_specular_frame(animation, frame); + } RID ci = get_canvas_item(); Size2i s; s = texture->get_size(); Point2 ofs = offset; - if (centered) + if (centered) { ofs -= s / 2; + } - if (Engine::get_singleton()->get_use_pixel_snap()) { + if (get_viewport() && get_viewport()->is_snap_2d_transforms_to_pixel_enabled()) { ofs = ofs.floor(); } Rect2 dst_rect(ofs, s); - if (hflip) + if (hflip) { dst_rect.size.x = -dst_rect.size.x; - if (vflip) + } + if (vflip) { dst_rect.size.y = -dst_rect.size.y; + } - texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal, specular, Color(specular_color.r, specular_color.g, specular_color.b, shininess)); + texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false); } break; } } void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { - - if (frames.is_valid()) + if (frames.is_valid()) { frames->disconnect("changed", callable_mp(this, &AnimatedSprite2D::_res_changed)); + } frames = p_frames; - if (frames.is_valid()) + if (frames.is_valid()) { frames->connect("changed", callable_mp(this, &AnimatedSprite2D::_res_changed)); + } if (!frames.is_valid()) { frame = 0; @@ -493,27 +484,28 @@ void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { } Ref<SpriteFrames> AnimatedSprite2D::get_sprite_frames() const { - return frames; } void AnimatedSprite2D::set_frame(int p_frame) { - if (!frames.is_valid()) { return; } if (frames->has_animation(animation)) { int limit = frames->get_frame_count(animation); - if (p_frame >= limit) + if (p_frame >= limit) { p_frame = limit - 1; + } } - if (p_frame < 0) + if (p_frame < 0) { p_frame = 0; + } - if (frame == p_frame) + if (frame == p_frame) { return; + } frame = p_frame; _reset_timeout(); @@ -521,13 +513,12 @@ void AnimatedSprite2D::set_frame(int p_frame) { _change_notify("frame"); emit_signal(SceneStringNames::get_singleton()->frame_changed); } -int AnimatedSprite2D::get_frame() const { +int AnimatedSprite2D::get_frame() const { return frame; } void AnimatedSprite2D::set_speed_scale(float p_speed_scale) { - float elapsed = _get_frame_duration() - timeout; speed_scale = MAX(p_speed_scale, 0.0f); @@ -538,56 +529,49 @@ void AnimatedSprite2D::set_speed_scale(float p_speed_scale) { } float AnimatedSprite2D::get_speed_scale() const { - return speed_scale; } void AnimatedSprite2D::set_centered(bool p_center) { - centered = p_center; update(); item_rect_changed(); } bool AnimatedSprite2D::is_centered() const { - return centered; } void AnimatedSprite2D::set_offset(const Point2 &p_offset) { - offset = p_offset; update(); item_rect_changed(); _change_notify("offset"); } -Point2 AnimatedSprite2D::get_offset() const { +Point2 AnimatedSprite2D::get_offset() const { return offset; } void AnimatedSprite2D::set_flip_h(bool p_flip) { - hflip = p_flip; update(); } -bool AnimatedSprite2D::is_flipped_h() const { +bool AnimatedSprite2D::is_flipped_h() const { return hflip; } void AnimatedSprite2D::set_flip_v(bool p_flip) { - vflip = p_flip; update(); } -bool AnimatedSprite2D::is_flipped_v() const { +bool AnimatedSprite2D::is_flipped_v() const { return vflip; } void AnimatedSprite2D::_res_changed() { - set_frame(frame); _change_notify("frame"); _change_notify("animation"); @@ -595,39 +579,36 @@ void AnimatedSprite2D::_res_changed() { } void AnimatedSprite2D::_set_playing(bool p_playing) { - - if (playing == p_playing) + if (playing == p_playing) { return; + } playing = p_playing; _reset_timeout(); set_process_internal(playing); } bool AnimatedSprite2D::_is_playing() const { - return playing; } void AnimatedSprite2D::play(const StringName &p_animation, const bool p_backwards) { - backwards = p_backwards; if (p_animation) { set_animation(p_animation); - if (backwards && get_frame() == 0) + if (backwards && get_frame() == 0) { set_frame(frames->get_frame_count(p_animation) - 1); + } } _set_playing(true); } void AnimatedSprite2D::stop() { - _set_playing(false); } bool AnimatedSprite2D::is_playing() const { - return playing; } @@ -642,21 +623,21 @@ float AnimatedSprite2D::_get_frame_duration() { } void AnimatedSprite2D::_reset_timeout() { - - if (!playing) + if (!playing) { return; + } timeout = _get_frame_duration(); is_over = false; } 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)); - if (animation == p_animation) + if (animation == p_animation) { return; + } animation = p_animation; _reset_timeout(); @@ -664,40 +645,25 @@ void AnimatedSprite2D::set_animation(const StringName &p_animation) { _change_notify(); update(); } -StringName AnimatedSprite2D::get_animation() const { +StringName AnimatedSprite2D::get_animation() const { return animation; } String AnimatedSprite2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (frames.is_null()) { - return TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite to display frames."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite to display frames."); } - return String(); -} - -void AnimatedSprite2D::set_specular_color(const Color &p_color) { - specular_color = p_color; - update(); -} - -Color AnimatedSprite2D::get_specular_color() const { - return specular_color; -} - -void AnimatedSprite2D::set_shininess(float p_shininess) { - shininess = CLAMP(p_shininess, 0.0, 1.0); - update(); -} - -float AnimatedSprite2D::get_shininess() const { - return shininess; + return warning; } void AnimatedSprite2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_sprite_frames", "sprite_frames"), &AnimatedSprite2D::set_sprite_frames); ClassDB::bind_method(D_METHOD("get_sprite_frames"), &AnimatedSprite2D::get_sprite_frames); @@ -729,12 +695,6 @@ void AnimatedSprite2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_speed_scale", "speed_scale"), &AnimatedSprite2D::set_speed_scale); ClassDB::bind_method(D_METHOD("get_speed_scale"), &AnimatedSprite2D::get_speed_scale); - ClassDB::bind_method(D_METHOD("set_specular_color", "color"), &AnimatedSprite2D::set_specular_color); - ClassDB::bind_method(D_METHOD("get_specular_color"), &AnimatedSprite2D::get_specular_color); - - ClassDB::bind_method(D_METHOD("set_shininess", "shininess"), &AnimatedSprite2D::set_shininess); - ClassDB::bind_method(D_METHOD("get_shininess"), &AnimatedSprite2D::get_shininess); - ADD_SIGNAL(MethodInfo("frame_changed")); ADD_SIGNAL(MethodInfo("animation_finished")); @@ -744,9 +704,6 @@ void AnimatedSprite2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing"); - ADD_GROUP("Lighting", ""); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_shininess", "get_shininess"); ADD_GROUP("Offset", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); @@ -755,7 +712,6 @@ void AnimatedSprite2D::_bind_methods() { } AnimatedSprite2D::AnimatedSprite2D() { - centered = true; hflip = false; vflip = false; @@ -767,6 +723,4 @@ AnimatedSprite2D::AnimatedSprite2D() { animation = "default"; timeout = 0; is_over = false; - specular_color = Color(1, 1, 1, 1); - shininess = 1.0; } diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h index 726ecefd32..fddbf39be2 100644 --- a/scene/2d/animated_sprite_2d.h +++ b/scene/2d/animated_sprite_2d.h @@ -35,11 +35,9 @@ #include "scene/resources/texture.h" class SpriteFrames : public Resource { - GDCLASS(SpriteFrames, Resource); struct Anim { - float speed; bool loop; Vector<Ref<Texture2D>> frames; @@ -48,14 +46,8 @@ class SpriteFrames : public Resource { loop = true; speed = 5; } - - StringName normal_name; - StringName specular_name; }; - Color specular_color; - float shininess; - Map<StringName, Anim> animations; Array _get_frames() const; @@ -87,50 +79,23 @@ public: void add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos = -1); int get_frame_count(const StringName &p_anim) const; _FORCE_INLINE_ Ref<Texture2D> get_frame(const StringName &p_anim, int p_idx) const { - const Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist."); ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>()); - if (p_idx >= E->get().frames.size()) + if (p_idx >= E->get().frames.size()) { return Ref<Texture2D>(); + } return E->get().frames[p_idx]; } - _FORCE_INLINE_ Ref<Texture2D> get_normal_frame(const StringName &p_anim, int p_idx) const { - - const Map<StringName, Anim>::Element *E = animations.find(p_anim); - ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist."); - ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>()); - - const Map<StringName, Anim>::Element *EN = animations.find(E->get().normal_name); - - if (!EN || p_idx >= EN->get().frames.size()) - return Ref<Texture2D>(); - - return EN->get().frames[p_idx]; - } - - _FORCE_INLINE_ Ref<Texture2D> get_specular_frame(const StringName &p_anim, int p_idx) const { - - const Map<StringName, Anim>::Element *E = animations.find(p_anim); - ERR_FAIL_COND_V(!E, Ref<Texture2D>()); - ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>()); - - const Map<StringName, Anim>::Element *EN = animations.find(E->get().specular_name); - - if (!EN || p_idx >= EN->get().frames.size()) - return Ref<Texture2D>(); - - return EN->get().frames[p_idx]; - } - void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture2D> &p_frame) { Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist."); ERR_FAIL_COND(p_idx < 0); - if (p_idx >= E->get().frames.size()) + if (p_idx >= E->get().frames.size()) { return; + } E->get().frames.write[p_idx] = p_frame; } void remove_frame(const StringName &p_anim, int p_idx); @@ -141,7 +106,6 @@ public: }; class AnimatedSprite2D : public Node2D { - GDCLASS(AnimatedSprite2D, Node2D); Ref<SpriteFrames> frames; @@ -168,27 +132,24 @@ class AnimatedSprite2D : public Node2D { bool _is_playing() const; Rect2 _get_rect() const; - Color specular_color; - float shininess; - protected: static void _bind_methods(); void _notification(int p_what); - virtual void _validate_property(PropertyInfo &property) const; + virtual void _validate_property(PropertyInfo &property) const override; public: #ifdef TOOLS_ENABLED - virtual Dictionary _edit_get_state() const; - virtual void _edit_set_state(const Dictionary &p_state); - - virtual void _edit_set_pivot(const Point2 &p_pivot); - virtual Point2 _edit_get_pivot() const; - virtual bool _edit_use_pivot() const; - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; + virtual Dictionary _edit_get_state() const override; + virtual void _edit_set_state(const Dictionary &p_state) override; + + virtual void _edit_set_pivot(const Point2 &p_pivot) override; + virtual Point2 _edit_get_pivot() const override; + virtual bool _edit_use_pivot() const override; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; #endif - virtual Rect2 get_anchorable_rect() const; + virtual Rect2 get_anchorable_rect() const override; void set_sprite_frames(const Ref<SpriteFrames> &p_frames); Ref<SpriteFrames> get_sprite_frames() const; @@ -218,13 +179,7 @@ public: void set_flip_v(bool p_flip); bool is_flipped_v() const; - void set_specular_color(const Color &p_color); - Color get_specular_color() const; - - void set_shininess(float p_shininess); - float get_shininess() const; - - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; AnimatedSprite2D(); }; diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 8ba334bc67..d51ee3f9a8 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -35,27 +35,24 @@ #include "servers/physics_server_2d.h" void Area2D::set_space_override_mode(SpaceOverride p_mode) { - space_override = p_mode; PhysicsServer2D::get_singleton()->area_set_space_override_mode(get_rid(), PhysicsServer2D::AreaSpaceOverrideMode(p_mode)); } -Area2D::SpaceOverride Area2D::get_space_override_mode() const { +Area2D::SpaceOverride Area2D::get_space_override_mode() const { return space_override; } void Area2D::set_gravity_is_point(bool p_enabled) { - gravity_is_point = p_enabled; PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT, p_enabled); } -bool Area2D::is_gravity_a_point() const { +bool Area2D::is_gravity_a_point() const { return gravity_is_point; } void Area2D::set_gravity_distance_scale(real_t p_scale) { - gravity_distance_scale = p_scale; PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale); } @@ -65,58 +62,51 @@ real_t Area2D::get_gravity_distance_scale() const { } void Area2D::set_gravity_vector(const Vector2 &p_vec) { - gravity_vec = p_vec; PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, p_vec); } -Vector2 Area2D::get_gravity_vector() const { +Vector2 Area2D::get_gravity_vector() const { return gravity_vec; } void Area2D::set_gravity(real_t p_gravity) { - gravity = p_gravity; PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY, p_gravity); } -real_t Area2D::get_gravity() const { +real_t Area2D::get_gravity() const { return gravity; } void Area2D::set_linear_damp(real_t p_linear_damp) { - linear_damp = p_linear_damp; PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_LINEAR_DAMP, p_linear_damp); } -real_t Area2D::get_linear_damp() const { +real_t Area2D::get_linear_damp() const { return linear_damp; } void Area2D::set_angular_damp(real_t p_angular_damp) { - angular_damp = p_angular_damp; PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, p_angular_damp); } real_t Area2D::get_angular_damp() const { - return angular_damp; } void Area2D::set_priority(real_t p_priority) { - priority = p_priority; PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_PRIORITY, p_priority); } -real_t Area2D::get_priority() const { +real_t Area2D::get_priority() const { return priority; } void Area2D::_body_enter_tree(ObjectID p_id) { - Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -128,13 +118,11 @@ void Area2D::_body_enter_tree(ObjectID p_id) { E->get().in_tree = true; emit_signal(SceneStringNames::get_singleton()->body_entered, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); } } void Area2D::_body_exit_tree(ObjectID p_id) { - Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -144,13 +132,11 @@ void Area2D::_body_exit_tree(ObjectID p_id) { E->get().in_tree = false; emit_signal(SceneStringNames::get_singleton()->body_exited, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); } } void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape) { - bool body_in = p_status == PhysicsServer2D::AREA_BODY_ADDED; ObjectID objid = p_instance; @@ -167,7 +153,6 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i if (body_in) { if (!E) { - E = body_map.insert(objid, BodyState()); E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); @@ -180,46 +165,41 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i } } E->get().rc++; - if (node) + if (node) { E->get().shapes.insert(ShapePair(p_body_shape, p_area_shape)); + } if (!node || E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_area_shape); } } else { - E->get().rc--; - if (node) + if (node) { E->get().shapes.erase(ShapePair(p_body_shape, p_area_shape)); + } - bool eraseit = false; - + bool in_tree = E->get().in_tree; if (E->get().rc == 0) { - + body_map.erase(E); if (node) { node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree)); - if (E->get().in_tree) + if (in_tree) { emit_signal(SceneStringNames::get_singleton()->body_exited, obj); + } } - - eraseit = true; } - if (!node || E->get().in_tree) { + if (!node || in_tree) { emit_signal(SceneStringNames::get_singleton()->body_shape_exited, objid, obj, p_body_shape, p_area_shape); } - - if (eraseit) - body_map.erase(E); } locked = false; } void Area2D::_area_enter_tree(ObjectID p_id) { - Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -231,13 +211,11 @@ void Area2D::_area_enter_tree(ObjectID p_id) { E->get().in_tree = true; emit_signal(SceneStringNames::get_singleton()->area_entered, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); } } void Area2D::_area_exit_tree(ObjectID p_id) { - Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -247,13 +225,11 @@ void Area2D::_area_exit_tree(ObjectID p_id) { E->get().in_tree = false; emit_signal(SceneStringNames::get_singleton()->area_exited, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); } } void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape) { - bool area_in = p_status == PhysicsServer2D::AREA_BODY_ADDED; ObjectID objid = p_instance; @@ -269,7 +245,6 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i if (area_in) { if (!E) { - E = area_map.insert(objid, AreaState()); E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); @@ -282,46 +257,41 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i } } E->get().rc++; - if (node) + if (node) { E->get().shapes.insert(AreaShapePair(p_area_shape, p_self_shape)); + } if (!node || E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->area_shape_entered, objid, node, p_area_shape, p_self_shape); } } else { - E->get().rc--; - if (node) + if (node) { E->get().shapes.erase(AreaShapePair(p_area_shape, p_self_shape)); + } - bool eraseit = false; - + bool in_tree = E->get().in_tree; if (E->get().rc == 0) { - + area_map.erase(E); if (node) { node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree)); - if (E->get().in_tree) + if (in_tree) { emit_signal(SceneStringNames::get_singleton()->area_exited, obj); + } } - - eraseit = true; } - if (!node || E->get().in_tree) { + if (!node || in_tree) { emit_signal(SceneStringNames::get_singleton()->area_shape_exited, objid, obj, p_area_shape, p_self_shape); } - - if (eraseit) - area_map.erase(E); } locked = false; } void Area2D::_clear_monitoring() { - ERR_FAIL_COND_MSG(locked, "This function can't be used during the in/out signal."); { @@ -330,21 +300,21 @@ void Area2D::_clear_monitoring() { //disconnect all monitored stuff for (Map<ObjectID, BodyState>::Element *E = bmcopy.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); Node *node = Object::cast_to<Node>(obj); - if (!node) //node may have been deleted in previous frame or at other legitimate point + if (!node) { //node may have been deleted in previous frame or at other legitimate point continue; + } node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree)); - if (!E->get().in_tree) + if (!E->get().in_tree) { continue; + } for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->key(), node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); } @@ -353,27 +323,26 @@ void Area2D::_clear_monitoring() { } { - Map<ObjectID, AreaState> bmcopy = area_map; area_map.clear(); //disconnect all monitored stuff for (Map<ObjectID, AreaState>::Element *E = bmcopy.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); Node *node = Object::cast_to<Node>(obj); - if (!node) //node may have been deleted in previous frame or at other legitimate point + if (!node) { //node may have been deleted in previous frame or at other legitimate point continue; + } node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree)); - if (!E->get().in_tree) + if (!E->get().in_tree) { continue; + } for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->key(), node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); } @@ -383,26 +352,22 @@ void Area2D::_clear_monitoring() { } void Area2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_EXIT_TREE: { - _clear_monitoring(); } break; } } void Area2D::set_monitoring(bool p_enable) { - - if (p_enable == monitoring) + if (p_enable == monitoring) { return; + } ERR_FAIL_COND_MSG(locked, "Function blocked during in/out signal. Use set_deferred(\"monitoring\", true/false)."); monitoring = p_enable; if (monitoring) { - PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout); PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout); @@ -414,16 +379,15 @@ void Area2D::set_monitoring(bool p_enable) { } bool Area2D::is_monitoring() const { - return monitoring; } void Area2D::set_monitorable(bool p_enable) { - ERR_FAIL_COND_MSG(locked || (is_inside_tree() && PhysicsServer2D::get_singleton()->is_flushing_queries()), "Function blocked during in/out signal. Use set_deferred(\"monitorable\", true/false)."); - if (p_enable == monitorable) + if (p_enable == monitorable) { return; + } monitorable = p_enable; @@ -431,12 +395,10 @@ void Area2D::set_monitorable(bool p_enable) { } bool Area2D::is_monitorable() const { - return monitorable; } TypedArray<Node2D> Area2D::get_overlapping_bodies() const { - ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); TypedArray<Node2D> ret; ret.resize(body_map.size()); @@ -454,7 +416,6 @@ TypedArray<Node2D> Area2D::get_overlapping_bodies() const { } TypedArray<Area2D> Area2D::get_overlapping_areas() const { - ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); TypedArray<Area2D> ret; ret.resize(area_map.size()); @@ -472,92 +433,82 @@ TypedArray<Area2D> Area2D::get_overlapping_areas() const { } bool Area2D::overlaps_area(Node *p_area) const { - ERR_FAIL_NULL_V(p_area, false); const Map<ObjectID, AreaState>::Element *E = area_map.find(p_area->get_instance_id()); - if (!E) + if (!E) { return false; + } return E->get().in_tree; } bool Area2D::overlaps_body(Node *p_body) const { - ERR_FAIL_NULL_V(p_body, false); const Map<ObjectID, BodyState>::Element *E = body_map.find(p_body->get_instance_id()); - if (!E) + if (!E) { return false; + } return E->get().in_tree; } void Area2D::set_collision_mask(uint32_t p_mask) { - collision_mask = p_mask; PhysicsServer2D::get_singleton()->area_set_collision_mask(get_rid(), p_mask); } uint32_t Area2D::get_collision_mask() const { - return collision_mask; } void Area2D::set_collision_layer(uint32_t p_layer) { - collision_layer = p_layer; PhysicsServer2D::get_singleton()->area_set_collision_layer(get_rid(), p_layer); } uint32_t Area2D::get_collision_layer() const { - return collision_layer; } void Area2D::set_collision_mask_bit(int p_bit, bool p_value) { - uint32_t mask = get_collision_mask(); - if (p_value) + if (p_value) { mask |= 1 << p_bit; - else + } else { mask &= ~(1 << p_bit); + } set_collision_mask(mask); } bool Area2D::get_collision_mask_bit(int p_bit) const { - return get_collision_mask() & (1 << p_bit); } void Area2D::set_collision_layer_bit(int p_bit, bool p_value) { - uint32_t layer = get_collision_layer(); - if (p_value) + if (p_value) { layer |= 1 << p_bit; - else + } else { layer &= ~(1 << p_bit); + } set_collision_layer(layer); } bool Area2D::get_collision_layer_bit(int p_bit) const { - return get_collision_layer() & (1 << p_bit); } void Area2D::set_audio_bus_override(bool p_override) { - audio_bus_override = p_override; } bool Area2D::is_overriding_audio_bus() const { - return audio_bus_override; } void Area2D::set_audio_bus_name(const StringName &p_audio_bus) { - audio_bus = p_audio_bus; } StringName Area2D::get_audio_bus_name() const { - for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { if (AudioServer::get_singleton()->get_bus_name(i) == audio_bus) { return audio_bus; @@ -567,13 +518,12 @@ StringName Area2D::get_audio_bus_name() const { } void Area2D::_validate_property(PropertyInfo &property) const { - if (property.name == "audio_bus_name") { - String options; for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { - if (i > 0) + if (i > 0) { options += ","; + } String name = AudioServer::get_singleton()->get_bus_name(i); options += name; } @@ -677,7 +627,6 @@ void Area2D::_bind_methods() { Area2D::Area2D() : CollisionObject2D(PhysicsServer2D::get_singleton()->area_create(), true) { - space_override = SPACE_OVERRIDE_DISABLED; set_gravity(98); set_gravity_vector(Vector2(0, 1)); diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 0e2c0ac672..01426db999 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -31,11 +31,10 @@ #ifndef AREA_2D_H #define AREA_2D_H -#include "core/vset.h" +#include "core/templates/vset.h" #include "scene/2d/collision_object_2d.h" class Area2D : public CollisionObject2D { - GDCLASS(Area2D, CollisionObject2D); public: @@ -68,14 +67,14 @@ private: void _body_exit_tree(ObjectID p_id); struct ShapePair { - int body_shape; int area_shape; bool operator<(const ShapePair &p_sp) const { - if (body_shape == p_sp.body_shape) + if (body_shape == p_sp.body_shape) { return area_shape < p_sp.area_shape; - else + } else { return body_shape < p_sp.body_shape; + } } ShapePair() {} @@ -86,7 +85,6 @@ private: }; struct BodyState { - int rc; bool in_tree; VSet<ShapePair> shapes; @@ -100,14 +98,14 @@ private: void _area_exit_tree(ObjectID p_id); struct AreaShapePair { - int area_shape; int self_shape; bool operator<(const AreaShapePair &p_sp) const { - if (area_shape == p_sp.area_shape) + if (area_shape == p_sp.area_shape) { return self_shape < p_sp.self_shape; - else + } else { return area_shape < p_sp.area_shape; + } } AreaShapePair() {} @@ -118,7 +116,6 @@ private: }; struct AreaState { - int rc; bool in_tree; VSet<AreaShapePair> shapes; @@ -133,7 +130,7 @@ private: protected: void _notification(int p_what); static void _bind_methods(); - void _validate_property(PropertyInfo &property) const; + void _validate_property(PropertyInfo &property) const override; public: void set_space_override_mode(SpaceOverride p_mode); diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 55d111439a..9bd716aeaa 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -30,12 +30,11 @@ #include "audio_stream_player_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/2d/area_2d.h" #include "scene/main/window.h" void AudioStreamPlayer2D::_mix_audio() { - if (!stream_playback.is_valid() || !active || (stream_paused && !stream_paused_fade_out)) { return; @@ -59,7 +58,6 @@ void AudioStreamPlayer2D::_mix_audio() { //write all outputs for (int i = 0; i < output_count; i++) { - Output current = outputs[i]; //see if current output exists, to keep volume ramp @@ -92,13 +90,13 @@ void AudioStreamPlayer2D::_mix_audio() { int cc = AudioServer::get_singleton()->get_channel_count(); if (cc == 1) { - if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, 0)) + if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, 0)) { continue; //may have been removed + } AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 0); for (int j = 0; j < buffer_size; j++) { - target[j] += buffer[j] * vol; vol += vol_inc; } @@ -116,11 +114,11 @@ void AudioStreamPlayer2D::_mix_audio() { targets[k] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k); } - if (!valid) + if (!valid) { continue; + } for (int j = 0; j < buffer_size; j++) { - AudioFrame frame = buffer[j] * vol; for (int k = 0; k < cc; k++) { targets[k][j] += frame; @@ -145,9 +143,7 @@ void AudioStreamPlayer2D::_mix_audio() { } void AudioStreamPlayer2D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - AudioServer::get_singleton()->add_callback(_mix_audios, this); if (autoplay && !Engine::get_singleton()->is_editor_hint()) { play(); @@ -155,7 +151,6 @@ void AudioStreamPlayer2D::_notification(int p_what) { } if (p_what == NOTIFICATION_EXIT_TREE) { - AudioServer::get_singleton()->remove_callback(_mix_audios, this); } @@ -171,7 +166,6 @@ void AudioStreamPlayer2D::_notification(int p_what) { } if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { - //update anything related to position first, if possible of course if (!output_ready) { @@ -194,13 +188,14 @@ void AudioStreamPlayer2D::_notification(int p_what) { int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask, false, true); for (int i = 0; i < areas; i++) { - Area2D *area2d = Object::cast_to<Area2D>(sr[i].collider); - if (!area2d) + if (!area2d) { continue; + } - if (!area2d->is_overriding_audio_bus()) + if (!area2d->is_overriding_audio_bus()) { continue; + } StringName bus_name = area2d->get_audio_bus_name(); bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name); @@ -209,10 +204,8 @@ void AudioStreamPlayer2D::_notification(int p_what) { world_2d->get_viewport_list(&viewports); for (List<Viewport *>::Element *E = viewports.front(); E; E = E->next()) { - Viewport *vp = E->get(); if (vp->is_audio_listener_2d()) { - //compute matrix to convert to screen Transform2D to_screen = vp->get_global_canvas_transform() * vp->get_canvas_transform(); Vector2 screen_size = vp->get_visible_rect().size; @@ -222,8 +215,9 @@ void AudioStreamPlayer2D::_notification(int p_what) { float dist = global_pos.distance_to(screen_in_global); //distance to screen center - if (dist > max_distance) + if (dist > max_distance) { continue; //can't hear this sound in this viewport + } float multiplier = Math::pow(1.0f - dist / max_distance, attenuation); multiplier *= Math::db2linear(volume_db); //also apply player volume! @@ -240,8 +234,9 @@ void AudioStreamPlayer2D::_notification(int p_what) { outputs[new_output_count].bus_index = bus_index; outputs[new_output_count].viewport = vp; //keep pointer only for reference new_output_count++; - if (new_output_count == MAX_OUTPUTS) + if (new_output_count == MAX_OUTPUTS) { break; + } } } @@ -269,7 +264,6 @@ void AudioStreamPlayer2D::_notification(int p_what) { } void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) { - AudioServer::get_singleton()->lock(); mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size()); @@ -294,16 +288,14 @@ void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) { } Ref<AudioStream> AudioStreamPlayer2D::get_stream() const { - return stream; } void AudioStreamPlayer2D::set_volume_db(float p_volume) { - volume_db = p_volume; } -float AudioStreamPlayer2D::get_volume_db() const { +float AudioStreamPlayer2D::get_volume_db() const { return volume_db; } @@ -311,12 +303,12 @@ void AudioStreamPlayer2D::set_pitch_scale(float p_pitch_scale) { ERR_FAIL_COND(p_pitch_scale <= 0.0); pitch_scale = p_pitch_scale; } + float AudioStreamPlayer2D::get_pitch_scale() const { return pitch_scale; } void AudioStreamPlayer2D::play(float p_from_pos) { - if (!is_playing()) { // Reset the prev_output_count if the stream is stopped prev_output_count = 0; @@ -331,14 +323,12 @@ void AudioStreamPlayer2D::play(float p_from_pos) { } void AudioStreamPlayer2D::seek(float p_seconds) { - if (stream_playback.is_valid()) { setseek = p_seconds; } } void AudioStreamPlayer2D::stop() { - if (stream_playback.is_valid()) { active = false; set_physics_process_internal(false); @@ -347,7 +337,6 @@ void AudioStreamPlayer2D::stop() { } bool AudioStreamPlayer2D::is_playing() const { - if (stream_playback.is_valid()) { return active; // && stream_playback->is_playing(); } @@ -356,7 +345,6 @@ bool AudioStreamPlayer2D::is_playing() const { } float AudioStreamPlayer2D::get_playback_position() { - if (stream_playback.is_valid()) { return stream_playback->get_playback_position(); } @@ -365,14 +353,13 @@ float AudioStreamPlayer2D::get_playback_position() { } void AudioStreamPlayer2D::set_bus(const StringName &p_bus) { - //if audio is active, must lock this AudioServer::get_singleton()->lock(); bus = p_bus; AudioServer::get_singleton()->unlock(); } -StringName AudioStreamPlayer2D::get_bus() const { +StringName AudioStreamPlayer2D::get_bus() const { for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { if (AudioServer::get_singleton()->get_bus_name(i) == bus) { return bus; @@ -382,34 +369,32 @@ StringName AudioStreamPlayer2D::get_bus() const { } void AudioStreamPlayer2D::set_autoplay(bool p_enable) { - autoplay = p_enable; } -bool AudioStreamPlayer2D::is_autoplay_enabled() { +bool AudioStreamPlayer2D::is_autoplay_enabled() { return autoplay; } void AudioStreamPlayer2D::_set_playing(bool p_enable) { - - if (p_enable) + if (p_enable) { play(); - else + } else { stop(); + } } -bool AudioStreamPlayer2D::_is_active() const { +bool AudioStreamPlayer2D::_is_active() const { return active; } void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const { - if (property.name == "bus") { - String options; for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { - if (i > 0) + if (i > 0) { options += ","; + } String name = AudioServer::get_singleton()->get_bus_name(i); options += name; } @@ -419,42 +404,35 @@ void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const { } void AudioStreamPlayer2D::_bus_layout_changed() { - _change_notify(); } void AudioStreamPlayer2D::set_max_distance(float p_pixels) { - ERR_FAIL_COND(p_pixels <= 0.0); max_distance = p_pixels; } float AudioStreamPlayer2D::get_max_distance() const { - return max_distance; } void AudioStreamPlayer2D::set_attenuation(float p_curve) { - attenuation = p_curve; } -float AudioStreamPlayer2D::get_attenuation() const { +float AudioStreamPlayer2D::get_attenuation() const { return attenuation; } void AudioStreamPlayer2D::set_area_mask(uint32_t p_mask) { - area_mask = p_mask; } uint32_t AudioStreamPlayer2D::get_area_mask() const { - return area_mask; } void AudioStreamPlayer2D::set_stream_paused(bool p_pause) { - if (p_pause != stream_paused) { stream_paused = p_pause; stream_paused_fade_in = !p_pause; @@ -463,7 +441,6 @@ void AudioStreamPlayer2D::set_stream_paused(bool p_pause) { } bool AudioStreamPlayer2D::get_stream_paused() const { - return stream_paused; } @@ -472,7 +449,6 @@ Ref<AudioStreamPlayback> AudioStreamPlayer2D::get_stream_playback() { } void AudioStreamPlayer2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer2D::set_stream); ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer2D::get_stream); @@ -527,7 +503,6 @@ void AudioStreamPlayer2D::_bind_methods() { } AudioStreamPlayer2D::AudioStreamPlayer2D() { - volume_db = 0; pitch_scale = 1.0; autoplay = false; diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h index 86e931b3c6..4e236a367e 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -36,7 +36,6 @@ #include "servers/audio_server.h" class AudioStreamPlayer2D : public Node2D { - GDCLASS(AudioStreamPlayer2D, Node2D); private: @@ -47,7 +46,6 @@ private: }; struct Output { - AudioFrame vol; int bus_index; Viewport *viewport; //pointer only used for reference to previous mix @@ -91,7 +89,7 @@ private: float attenuation; protected: - void _validate_property(PropertyInfo &property) const; + void _validate_property(PropertyInfo &property) const override; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp index 4c952b7ca6..a36e0a86e1 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -31,19 +31,14 @@ #include "back_buffer_copy.h" void BackBufferCopy::_update_copy_mode() { - switch (copy_mode) { - case COPY_MODE_DISABLED: { - RS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), false, Rect2()); } break; case COPY_MODE_RECT: { - RS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), true, rect); } break; case COPY_MODE_VIEWPORT: { - RS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), true, Rect2()); } break; @@ -52,7 +47,6 @@ void BackBufferCopy::_update_copy_mode() { #ifdef TOOLS_ENABLED Rect2 BackBufferCopy::_edit_get_rect() const { - return rect; } @@ -62,12 +56,10 @@ bool BackBufferCopy::_edit_use_rect() const { #endif Rect2 BackBufferCopy::get_anchorable_rect() const { - return rect; } void BackBufferCopy::set_rect(const Rect2 &p_rect) { - rect = p_rect; _update_copy_mode(); } @@ -77,17 +69,15 @@ Rect2 BackBufferCopy::get_rect() const { } void BackBufferCopy::set_copy_mode(CopyMode p_mode) { - copy_mode = p_mode; _update_copy_mode(); } -BackBufferCopy::CopyMode BackBufferCopy::get_copy_mode() const { +BackBufferCopy::CopyMode BackBufferCopy::get_copy_mode() const { return copy_mode; } void BackBufferCopy::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_rect", "rect"), &BackBufferCopy::set_rect); ClassDB::bind_method(D_METHOD("get_rect"), &BackBufferCopy::get_rect); @@ -103,10 +93,10 @@ void BackBufferCopy::_bind_methods() { } BackBufferCopy::BackBufferCopy() { - rect = Rect2(-100, -100, 200, 200); copy_mode = COPY_MODE_RECT; _update_copy_mode(); } + BackBufferCopy::~BackBufferCopy() { } diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h index 4b26bf1bdc..b58034de19 100644 --- a/scene/2d/back_buffer_copy.h +++ b/scene/2d/back_buffer_copy.h @@ -54,13 +54,13 @@ protected: public: #ifdef TOOLS_ENABLED - Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; + Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; #endif void set_rect(const Rect2 &p_rect); Rect2 get_rect() const; - Rect2 get_anchorable_rect() const; + Rect2 get_anchorable_rect() const override; void set_copy_mode(CopyMode p_mode); CopyMode get_copy_mode() const; diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index d8af14a3fb..e22b24c16f 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -30,33 +30,33 @@ #include "camera_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/math/math_funcs.h" #include "scene/scene_string_names.h" #include "servers/rendering_server.h" void Camera2D::_update_scroll() { - - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } if (Engine::get_singleton()->is_editor_hint()) { update(); //will just be drawn return; } - if (!viewport) + if (!viewport) { return; + } if (current) { - ERR_FAIL_COND(custom_viewport && !ObjectDB::get_instance(custom_viewport_id)); Transform2D xform = get_camera_transform(); viewport->set_canvas_transform(xform); - Size2 screen_size = viewport->get_visible_rect().size; + Size2 screen_size = _get_camera_screen_size(); Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5) : Point2()); get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_camera_moved", xform, screen_offset); @@ -64,7 +64,6 @@ void Camera2D::_update_scroll() { } void Camera2D::_update_process_mode() { - if (Engine::get_singleton()->is_editor_hint()) { set_process_internal(false); set_physics_process_internal(false); @@ -78,7 +77,6 @@ void Camera2D::_update_process_mode() { } void Camera2D::set_zoom(const Vector2 &p_zoom) { - zoom = p_zoom; Point2 old_smoothed_camera_pos = smoothed_camera_pos; _update_scroll(); @@ -86,31 +84,27 @@ void Camera2D::set_zoom(const Vector2 &p_zoom) { }; Vector2 Camera2D::get_zoom() const { - return zoom; }; Transform2D Camera2D::get_camera_transform() { - - if (!get_tree()) + if (!get_tree()) { return Transform2D(); + } ERR_FAIL_COND_V(custom_viewport && !ObjectDB::get_instance(custom_viewport_id), Transform2D()); - Size2 screen_size = viewport->get_visible_rect().size; + Size2 screen_size = _get_camera_screen_size(); Point2 new_camera_pos = get_global_transform().get_origin(); Point2 ret_camera_pos; if (!first) { - if (anchor_mode == ANCHOR_MODE_DRAG_CENTER) { - if (h_drag_enabled && !Engine::get_singleton()->is_editor_hint() && !h_offset_changed) { camera_pos.x = MIN(camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * zoom.x * drag_margin[MARGIN_LEFT])); camera_pos.x = MAX(camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * zoom.x * drag_margin[MARGIN_RIGHT])); } else { - if (h_ofs < 0) { camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT] * h_ofs; } else { @@ -121,12 +115,10 @@ Transform2D Camera2D::get_camera_transform() { } if (v_drag_enabled && !Engine::get_singleton()->is_editor_hint() && !v_offset_changed) { - camera_pos.y = MIN(camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * zoom.y * drag_margin[MARGIN_TOP])); camera_pos.y = MAX(camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * zoom.y * drag_margin[MARGIN_BOTTOM])); } else { - if (v_ofs < 0) { camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs; } else { @@ -137,7 +129,6 @@ Transform2D Camera2D::get_camera_transform() { } } else if (anchor_mode == ANCHOR_MODE_FIXED_TOP_LEFT) { - camera_pos = new_camera_pos; } @@ -145,27 +136,29 @@ Transform2D Camera2D::get_camera_transform() { Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom); if (limit_smoothing_enabled) { - if (screen_rect.position.x < limit[MARGIN_LEFT]) + if (screen_rect.position.x < limit[MARGIN_LEFT]) { camera_pos.x -= screen_rect.position.x - limit[MARGIN_LEFT]; + } - if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT]) + if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT]) { camera_pos.x -= screen_rect.position.x + screen_rect.size.x - limit[MARGIN_RIGHT]; + } - if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) + if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) { camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[MARGIN_BOTTOM]; + } - if (screen_rect.position.y < limit[MARGIN_TOP]) + if (screen_rect.position.y < limit[MARGIN_TOP]) { camera_pos.y -= screen_rect.position.y - limit[MARGIN_TOP]; + } } if (smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) { - float c = smoothing * (process_mode == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time()); smoothed_camera_pos = ((camera_pos - smoothed_camera_pos) * c) + smoothed_camera_pos; ret_camera_pos = smoothed_camera_pos; //camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing; } else { - ret_camera_pos = smoothed_camera_pos = camera_pos; } @@ -182,20 +175,25 @@ Transform2D Camera2D::get_camera_transform() { } Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom); - if (screen_rect.position.x < limit[MARGIN_LEFT]) + if (screen_rect.position.x < limit[MARGIN_LEFT]) { screen_rect.position.x = limit[MARGIN_LEFT]; + } - if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT]) + if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT]) { screen_rect.position.x = limit[MARGIN_RIGHT] - screen_rect.size.x; + } - if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) + if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) { screen_rect.position.y = limit[MARGIN_BOTTOM] - screen_rect.size.y; + } - if (screen_rect.position.y < limit[MARGIN_TOP]) + if (screen_rect.position.y < limit[MARGIN_TOP]) { screen_rect.position.y = limit[MARGIN_TOP]; + } - if (offset != Vector2()) + if (offset != Vector2()) { screen_rect.position += offset; + } camera_screen_center = screen_rect.position + screen_rect.size * 0.5; @@ -218,23 +216,19 @@ Transform2D Camera2D::get_camera_transform() { } void Camera2D::_notification(int p_what) { - switch (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()) + if (!is_processing_internal() && !is_physics_processing_internal()) { _update_scroll(); + } } break; case NOTIFICATION_ENTER_TREE: { - if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) { viewport = custom_viewport; } else { @@ -256,7 +250,6 @@ void Camera2D::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - if (is_current()) { if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { viewport->set_canvas_transform(Transform2D()); @@ -268,9 +261,9 @@ void Camera2D::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - - if (!is_inside_tree() || !Engine::get_singleton()->is_editor_hint()) + if (!is_inside_tree() || !Engine::get_singleton()->is_editor_hint()) { break; + } if (screen_drawing_enabled) { Color area_axis_color(0.5, 0.42, 0.87, 0.63); @@ -281,7 +274,7 @@ void Camera2D::_notification(int p_what) { } Transform2D inv_camera_transform = get_camera_transform().affine_inverse(); - Size2 screen_size = get_viewport_rect().size; + Size2 screen_size = _get_camera_screen_size(); Vector2 screen_endpoints[4] = { inv_camera_transform.xform(Vector2(0, 0)), @@ -328,7 +321,7 @@ void Camera2D::_notification(int p_what) { } Transform2D inv_camera_transform = get_camera_transform().affine_inverse(); - Size2 screen_size = get_viewport_rect().size; + Size2 screen_size = _get_camera_screen_size(); Vector2 margin_endpoints[4] = { inv_camera_transform.xform(Vector2((screen_size.width / 2) - ((screen_size.width / 2) * drag_margin[MARGIN_LEFT]), (screen_size.height / 2) - ((screen_size.height / 2) * drag_margin[MARGIN_TOP]))), @@ -349,56 +342,51 @@ void Camera2D::_notification(int p_what) { } void Camera2D::set_offset(const Vector2 &p_offset) { - offset = p_offset; + Point2 old_smoothed_camera_pos = smoothed_camera_pos; _update_scroll(); + smoothed_camera_pos = old_smoothed_camera_pos; } Vector2 Camera2D::get_offset() const { - return offset; } void Camera2D::set_anchor_mode(AnchorMode p_anchor_mode) { - anchor_mode = p_anchor_mode; _update_scroll(); } Camera2D::AnchorMode Camera2D::get_anchor_mode() const { - return anchor_mode; } void Camera2D::set_rotating(bool p_rotating) { - rotating = p_rotating; + Point2 old_smoothed_camera_pos = smoothed_camera_pos; _update_scroll(); + smoothed_camera_pos = old_smoothed_camera_pos; } bool Camera2D::is_rotating() const { - return rotating; } void Camera2D::set_process_mode(Camera2DProcessMode p_mode) { - - if (process_mode == p_mode) + if (process_mode == p_mode) { return; + } process_mode = p_mode; _update_process_mode(); } Camera2D::Camera2DProcessMode Camera2D::get_process_mode() const { - return process_mode; } void Camera2D::_make_current(Object *p_which) { - if (p_which == this) { - current = true; } else { current = false; @@ -406,21 +394,19 @@ void Camera2D::_make_current(Object *p_which) { } void Camera2D::_set_current(bool p_current) { - - if (p_current) + if (p_current) { make_current(); + } current = p_current; update(); } bool Camera2D::is_current() const { - return current; } void Camera2D::make_current() { - if (!is_inside_tree()) { current = true; } else { @@ -430,7 +416,6 @@ void Camera2D::make_current() { } void Camera2D::clear_current() { - current = false; if (is_inside_tree()) { get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_make_current", (Object *)nullptr); @@ -438,63 +423,53 @@ void Camera2D::clear_current() { } void Camera2D::set_limit(Margin p_margin, int p_limit) { - ERR_FAIL_INDEX((int)p_margin, 4); limit[p_margin] = p_limit; update(); } int Camera2D::get_limit(Margin p_margin) const { - ERR_FAIL_INDEX_V((int)p_margin, 4, 0); return limit[p_margin]; } void Camera2D::set_limit_smoothing_enabled(bool enable) { - limit_smoothing_enabled = enable; _update_scroll(); } bool Camera2D::is_limit_smoothing_enabled() const { - return limit_smoothing_enabled; } void Camera2D::set_drag_margin(Margin p_margin, float p_drag_margin) { - ERR_FAIL_INDEX((int)p_margin, 4); drag_margin[p_margin] = p_drag_margin; update(); } float Camera2D::get_drag_margin(Margin p_margin) const { - ERR_FAIL_INDEX_V((int)p_margin, 4, 0); return drag_margin[p_margin]; } Vector2 Camera2D::get_camera_position() const { - return camera_pos; } void Camera2D::force_update_scroll() { - _update_scroll(); } void Camera2D::reset_smoothing() { - smoothed_camera_pos = camera_pos; _update_scroll(); } void Camera2D::align() { - ERR_FAIL_COND(custom_viewport && !ObjectDB::get_instance(custom_viewport_id)); - Size2 screen_size = viewport->get_visible_rect().size; + Size2 screen_size = _get_camera_screen_size(); Point2 current_camera_pos = get_global_transform().get_origin(); if (anchor_mode == ANCHOR_MODE_DRAG_CENTER) { @@ -509,7 +484,6 @@ void Camera2D::align() { camera_pos.y = current_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs; } } else if (anchor_mode == ANCHOR_MODE_FIXED_TOP_LEFT) { - camera_pos = current_camera_pos; } @@ -517,64 +491,67 @@ void Camera2D::align() { } void Camera2D::set_follow_smoothing(float p_speed) { - smoothing = p_speed; - if (smoothing > 0 && !(is_inside_tree() && Engine::get_singleton()->is_editor_hint())) + if (smoothing > 0 && !(is_inside_tree() && Engine::get_singleton()->is_editor_hint())) { set_process_internal(true); - else + } else { set_process_internal(false); + } } float Camera2D::get_follow_smoothing() const { - return smoothing; } Point2 Camera2D::get_camera_screen_center() const { - return camera_screen_center; } -void Camera2D::set_h_drag_enabled(bool p_enabled) { +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 get_viewport_rect().size; +} +void Camera2D::set_h_drag_enabled(bool p_enabled) { h_drag_enabled = p_enabled; } bool Camera2D::is_h_drag_enabled() const { - return h_drag_enabled; } void Camera2D::set_v_drag_enabled(bool p_enabled) { - v_drag_enabled = p_enabled; } bool Camera2D::is_v_drag_enabled() const { - return v_drag_enabled; } void Camera2D::set_v_offset(float p_offset) { - v_ofs = p_offset; v_offset_changed = true; + Point2 old_smoothed_camera_pos = smoothed_camera_pos; _update_scroll(); + smoothed_camera_pos = old_smoothed_camera_pos; } float Camera2D::get_v_offset() const { - return v_ofs; } void Camera2D::set_h_offset(float p_offset) { - h_ofs = p_offset; h_offset_changed = true; + Point2 old_smoothed_camera_pos = smoothed_camera_pos; _update_scroll(); + smoothed_camera_pos = old_smoothed_camera_pos; } -float Camera2D::get_h_offset() const { +float Camera2D::get_h_offset() const { return h_ofs; } @@ -587,12 +564,10 @@ void Camera2D::_set_old_smoothing(float p_enable) { } void Camera2D::set_enable_follow_smoothing(bool p_enabled) { - smoothing_enabled = p_enabled; } bool Camera2D::is_follow_smoothing_enabled() const { - return smoothing_enabled; } @@ -612,11 +587,11 @@ void Camera2D::set_custom_viewport(Node *p_viewport) { } if (is_inside_tree()) { - - if (custom_viewport) + if (custom_viewport) { viewport = custom_viewport; - else + } else { viewport = get_viewport(); + } RID vp = viewport->get_viewport_rid(); group_name = "__cameras_" + itos(vp.get_id()); @@ -627,7 +602,6 @@ void Camera2D::set_custom_viewport(Node *p_viewport) { } Node *Camera2D::get_custom_viewport() const { - return custom_viewport; } @@ -659,7 +633,6 @@ bool Camera2D::is_margin_drawing_enabled() const { } void Camera2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_offset", "offset"), &Camera2D::set_offset); ClassDB::bind_method(D_METHOD("get_offset"), &Camera2D::get_offset); @@ -777,7 +750,6 @@ void Camera2D::_bind_methods() { } Camera2D::Camera2D() { - anchor_mode = ANCHOR_MODE_DRAG_CENTER; rotating = false; current = false; diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 7a106ef79a..867a5562b2 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -35,7 +35,6 @@ #include "scene/main/window.h" class Camera2D : public Node2D { - GDCLASS(Camera2D, Node2D); public: @@ -95,6 +94,8 @@ protected: Camera2DProcessMode process_mode; + Size2 _get_camera_screen_size() const; + protected: virtual Transform2D get_camera_transform(); void _notification(int p_what); diff --git a/scene/2d/canvas_group.cpp b/scene/2d/canvas_group.cpp new file mode 100644 index 0000000000..39cae8e0c6 --- /dev/null +++ b/scene/2d/canvas_group.cpp @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* canvas_group.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "canvas_group.h" + +void CanvasGroup::set_fit_margin(float p_fit_margin) { + ERR_FAIL_COND(p_fit_margin < 0.0); + + fit_margin = p_fit_margin; + RS::get_singleton()->canvas_item_set_canvas_group_mode(get_canvas_item(), RS::CANVAS_GROUP_MODE_TRANSPARENT, clear_margin, true, fit_margin, use_mipmaps); + + update(); +} + +float CanvasGroup::get_fit_margin() const { + return fit_margin; +} + +void CanvasGroup::set_clear_margin(float p_clear_margin) { + ERR_FAIL_COND(p_clear_margin < 0.0); + + clear_margin = p_clear_margin; + RS::get_singleton()->canvas_item_set_canvas_group_mode(get_canvas_item(), RS::CANVAS_GROUP_MODE_TRANSPARENT, clear_margin, true, clear_margin, use_mipmaps); + + update(); +} + +float CanvasGroup::get_clear_margin() const { + return clear_margin; +} + +void CanvasGroup::set_use_mipmaps(bool p_use_mipmaps) { + use_mipmaps = p_use_mipmaps; + RS::get_singleton()->canvas_item_set_canvas_group_mode(get_canvas_item(), RS::CANVAS_GROUP_MODE_TRANSPARENT, clear_margin, true, fit_margin, use_mipmaps); +} +bool CanvasGroup::is_using_mipmaps() const { + return use_mipmaps; +} + +void CanvasGroup::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_fit_margin", "fit_margin"), &CanvasGroup::set_fit_margin); + ClassDB::bind_method(D_METHOD("get_fit_margin"), &CanvasGroup::get_fit_margin); + + ClassDB::bind_method(D_METHOD("set_clear_margin", "clear_margin"), &CanvasGroup::set_clear_margin); + ClassDB::bind_method(D_METHOD("get_clear_margin"), &CanvasGroup::get_clear_margin); + + ClassDB::bind_method(D_METHOD("set_use_mipmaps", "use_mipmaps"), &CanvasGroup::set_use_mipmaps); + ClassDB::bind_method(D_METHOD("is_using_mipmaps"), &CanvasGroup::is_using_mipmaps); + + ADD_GROUP("Tweaks", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fit_margin", PROPERTY_HINT_RANGE, "0,1024,1.0,or_greater"), "set_fit_margin", "get_fit_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "clear_margin", PROPERTY_HINT_RANGE, "0,1024,1.0,or_greater"), "set_clear_margin", "get_clear_margin"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_mipmaps"), "set_use_mipmaps", "is_using_mipmaps"); +} + +CanvasGroup::CanvasGroup() { + set_fit_margin(10.0); //sets things +} +CanvasGroup::~CanvasGroup() { +} diff --git a/scene/2d/canvas_group.h b/scene/2d/canvas_group.h new file mode 100644 index 0000000000..19630befc7 --- /dev/null +++ b/scene/2d/canvas_group.h @@ -0,0 +1,59 @@ +/*************************************************************************/ +/* canvas_group.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef CANVASGROUP_H +#define CANVASGROUP_H + +#include "scene/2d/node_2d.h" + +class CanvasGroup : public Node2D { + GDCLASS(CanvasGroup, Node2D) + float fit_margin = 10.0; + float clear_margin = 10.0; + bool use_mipmaps = false; + +protected: + static void _bind_methods(); + +public: + void set_fit_margin(float p_fit_margin); + float get_fit_margin() const; + + void set_clear_margin(float p_clear_margin); + float get_clear_margin() const; + + void set_use_mipmaps(bool p_use_mipmaps); + bool is_using_mipmaps() const; + + CanvasGroup(); + ~CanvasGroup(); +}; + +#endif // CANVASGROUP_H diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp index 05f8804e2a..8fb16534e8 100644 --- a/scene/2d/canvas_modulate.cpp +++ b/scene/2d/canvas_modulate.cpp @@ -31,22 +31,18 @@ #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())); } } 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())); @@ -60,7 +56,6 @@ void CanvasModulate::_notification(int p_what) { } void CanvasModulate::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_color", "color"), &CanvasModulate::set_color); ClassDB::bind_method(D_METHOD("get_color"), &CanvasModulate::get_color); @@ -68,30 +63,34 @@ void CanvasModulate::_bind_methods() { } void CanvasModulate::set_color(const Color &p_color) { - color = p_color; if (is_visible_in_tree()) { RS::get_singleton()->canvas_set_modulate(get_canvas(), color); } } -Color CanvasModulate::get_color() const { +Color CanvasModulate::get_color() const { return color; } String CanvasModulate::get_configuration_warning() const { - - if (!is_visible_in_tree() || !is_inside_tree()) + if (!is_visible_in_tree() || !is_inside_tree()) { return String(); + } + + String warning = Node2D::get_configuration_warning(); List<Node *> nodes; get_tree()->get_nodes_in_group("_canvas_modulate_" + itos(get_canvas().get_id()), &nodes); if (nodes.size() > 1) { - return TTR("Only one visible CanvasModulate is allowed per scene (or set of instanced scenes). The first created one will work, while the rest will be ignored."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("Only one visible CanvasModulate is allowed per scene (or set of instanced scenes). The first created one will work, while the rest will be ignored."); } - return String(); + return warning; } CanvasModulate::CanvasModulate() { diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h index ada6e27760..eac3cf9e54 100644 --- a/scene/2d/canvas_modulate.h +++ b/scene/2d/canvas_modulate.h @@ -34,7 +34,6 @@ #include "scene/2d/node_2d.h" class CanvasModulate : public Node2D { - GDCLASS(CanvasModulate, Node2D); Color color; @@ -47,7 +46,7 @@ public: void set_color(const Color &p_color); Color get_color() const; - String get_configuration_warning() const; + String get_configuration_warning() const override; CanvasModulate(); ~CanvasModulate(); diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index d82f4a2f2b..fe16d4089a 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -34,23 +34,22 @@ #include "servers/physics_server_2d.h" void CollisionObject2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - Transform2D global_transform = get_global_transform(); - if (area) + if (area) { PhysicsServer2D::get_singleton()->area_set_transform(rid, global_transform); - else + } else { PhysicsServer2D::get_singleton()->body_set_state(rid, PhysicsServer2D::BODY_STATE_TRANSFORM, global_transform); + } RID space = get_world_2d()->get_space(); if (area) { PhysicsServer2D::get_singleton()->area_set_space(rid, space); - } else + } else { PhysicsServer2D::get_singleton()->body_set_space(rid, space); + } _update_pickable(); @@ -58,52 +57,50 @@ void CollisionObject2D::_notification(int p_what) { } break; case NOTIFICATION_ENTER_CANVAS: { - - if (area) + if (area) { PhysicsServer2D::get_singleton()->area_attach_canvas_instance_id(rid, get_canvas_layer_instance_id()); - else + } else { PhysicsServer2D::get_singleton()->body_attach_canvas_instance_id(rid, get_canvas_layer_instance_id()); + } } break; case NOTIFICATION_VISIBILITY_CHANGED: { - _update_pickable(); } break; case NOTIFICATION_TRANSFORM_CHANGED: { - if (only_update_transform_changes) { return; } Transform2D global_transform = get_global_transform(); - if (area) + if (area) { PhysicsServer2D::get_singleton()->area_set_transform(rid, global_transform); - else + } else { PhysicsServer2D::get_singleton()->body_set_state(rid, PhysicsServer2D::BODY_STATE_TRANSFORM, global_transform); + } } break; case NOTIFICATION_EXIT_TREE: { - if (area) { PhysicsServer2D::get_singleton()->area_set_space(rid, RID()); - } else + } else { PhysicsServer2D::get_singleton()->body_set_space(rid, RID()); + } } break; case NOTIFICATION_EXIT_CANVAS: { - - if (area) + if (area) { PhysicsServer2D::get_singleton()->area_attach_canvas_instance_id(rid, ObjectID()); - else + } else { PhysicsServer2D::get_singleton()->body_attach_canvas_instance_id(rid, ObjectID()); + } } break; } } uint32_t CollisionObject2D::create_shape_owner(Object *p_owner) { - ShapeData sd; uint32_t id; @@ -121,7 +118,6 @@ uint32_t CollisionObject2D::create_shape_owner(Object *p_owner) { } void CollisionObject2D::remove_shape_owner(uint32_t owner) { - ERR_FAIL_COND(!shapes.has(owner)); shape_owner_clear_shapes(owner); @@ -144,16 +140,15 @@ void CollisionObject2D::shape_owner_set_disabled(uint32_t p_owner, bool p_disabl } bool CollisionObject2D::is_shape_owner_disabled(uint32_t p_owner) const { - ERR_FAIL_COND_V(!shapes.has(p_owner), false); return shapes[p_owner].disabled; } void CollisionObject2D::shape_owner_set_one_way_collision(uint32_t p_owner, bool p_enable) { - - if (area) + if (area) { return; //not for areas + } ERR_FAIL_COND(!shapes.has(p_owner)); @@ -165,16 +160,15 @@ void CollisionObject2D::shape_owner_set_one_way_collision(uint32_t p_owner, bool } bool CollisionObject2D::is_shape_owner_one_way_collision_enabled(uint32_t p_owner) const { - ERR_FAIL_COND_V(!shapes.has(p_owner), false); return shapes[p_owner].one_way_collision; } void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, float p_margin) { - - if (area) + if (area) { return; //not for areas + } ERR_FAIL_COND(!shapes.has(p_owner)); @@ -186,21 +180,18 @@ void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owne } float CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const { - ERR_FAIL_COND_V(!shapes.has(p_owner), 0); return shapes[p_owner].one_way_collision_margin; } void CollisionObject2D::get_shape_owners(List<uint32_t> *r_owners) { - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { r_owners->push_back(E->key()); } } Array CollisionObject2D::_get_shape_owners() { - Array ret; for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { ret.push_back(E->key()); @@ -210,7 +201,6 @@ Array CollisionObject2D::_get_shape_owners() { } void CollisionObject2D::shape_owner_set_transform(uint32_t p_owner, const Transform2D &p_transform) { - ERR_FAIL_COND(!shapes.has(p_owner)); ShapeData &sd = shapes[p_owner]; @@ -224,22 +214,20 @@ void CollisionObject2D::shape_owner_set_transform(uint32_t p_owner, const Transf } } } -Transform2D CollisionObject2D::shape_owner_get_transform(uint32_t p_owner) const { +Transform2D CollisionObject2D::shape_owner_get_transform(uint32_t p_owner) const { ERR_FAIL_COND_V(!shapes.has(p_owner), Transform2D()); return shapes[p_owner].xform; } 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; } void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape) { - ERR_FAIL_COND(!shapes.has(p_owner)); ERR_FAIL_COND(p_shape.is_null()); @@ -256,21 +244,21 @@ void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2 total_subshapes++; } -int CollisionObject2D::shape_owner_get_shape_count(uint32_t p_owner) const { +int CollisionObject2D::shape_owner_get_shape_count(uint32_t p_owner) const { ERR_FAIL_COND_V(!shapes.has(p_owner), 0); return shapes[p_owner].shapes.size(); } -Ref<Shape2D> CollisionObject2D::shape_owner_get_shape(uint32_t p_owner, int p_shape) const { +Ref<Shape2D> CollisionObject2D::shape_owner_get_shape(uint32_t p_owner, int p_shape) const { ERR_FAIL_COND_V(!shapes.has(p_owner), Ref<Shape2D>()); ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), Ref<Shape2D>()); return shapes[p_owner].shapes[p_shape].shape; } -int CollisionObject2D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const { +int CollisionObject2D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const { ERR_FAIL_COND_V(!shapes.has(p_owner), -1); ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), -1); @@ -278,7 +266,6 @@ int CollisionObject2D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape } void CollisionObject2D::shape_owner_remove_shape(uint32_t p_owner, int p_shape) { - ERR_FAIL_COND(!shapes.has(p_owner)); ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size()); @@ -303,7 +290,6 @@ void CollisionObject2D::shape_owner_remove_shape(uint32_t p_owner, int p_shape) } void CollisionObject2D::shape_owner_clear_shapes(uint32_t p_owner) { - ERR_FAIL_COND(!shapes.has(p_owner)); while (shape_owner_get_shape_count(p_owner) > 0) { @@ -312,7 +298,6 @@ void CollisionObject2D::shape_owner_clear_shapes(uint32_t p_owner) { } uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const { - ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0); for (const Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { @@ -328,21 +313,19 @@ uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const { } void CollisionObject2D::set_pickable(bool p_enabled) { - - if (pickable == p_enabled) + if (pickable == p_enabled) { return; + } pickable = p_enabled; _update_pickable(); } bool CollisionObject2D::is_pickable() const { - return pickable; } void CollisionObject2D::_input_event(Node *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape) { - if (get_script_instance()) { get_script_instance()->call(SceneStringNames::get_singleton()->_input_event, p_viewport, p_input_event, p_shape); } @@ -350,7 +333,6 @@ void CollisionObject2D::_input_event(Node *p_viewport, const Ref<InputEvent> &p_ } void CollisionObject2D::_mouse_enter() { - if (get_script_instance()) { get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_enter); } @@ -358,7 +340,6 @@ void CollisionObject2D::_mouse_enter() { } void CollisionObject2D::_mouse_exit() { - if (get_script_instance()) { get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_exit); } @@ -370,18 +351,19 @@ void CollisionObject2D::set_only_update_transform_changes(bool p_enable) { } void CollisionObject2D::_update_pickable() { - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } bool is_pickable = pickable && is_visible_in_tree(); - if (area) + if (area) { PhysicsServer2D::get_singleton()->area_set_pickable(rid, is_pickable); - else + } else { PhysicsServer2D::get_singleton()->body_set_pickable(rid, is_pickable); + } } String CollisionObject2D::get_configuration_warning() const { - String warning = Node2D::get_configuration_warning(); if (shapes.empty()) { @@ -395,7 +377,6 @@ String CollisionObject2D::get_configuration_warning() const { } void CollisionObject2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_rid"), &CollisionObject2D::get_rid); ClassDB::bind_method(D_METHOD("set_pickable", "enabled"), &CollisionObject2D::set_pickable); @@ -432,7 +413,6 @@ void CollisionObject2D::_bind_methods() { } CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) { - rid = p_rid; area = p_area; pickable = true; @@ -441,7 +421,6 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) { only_update_transform_changes = false; if (p_area) { - PhysicsServer2D::get_singleton()->area_attach_object_instance_id(rid, get_instance_id()); } else { PhysicsServer2D::get_singleton()->body_attach_object_instance_id(rid, get_instance_id()); @@ -449,13 +428,11 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) { } CollisionObject2D::CollisionObject2D() { - //owner= set_notify_transform(true); } CollisionObject2D::~CollisionObject2D() { - PhysicsServer2D::get_singleton()->free(rid); } diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index e931f20f40..8eff1b3aec 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -35,7 +35,6 @@ #include "scene/resources/shape_2d.h" class CollisionObject2D : public Node2D { - GDCLASS(CollisionObject2D, Node2D); bool area; @@ -43,7 +42,6 @@ class CollisionObject2D : public Node2D { bool pickable; struct ShapeData { - Object *owner; Transform2D xform; struct Shape { @@ -115,7 +113,7 @@ public: void set_pickable(bool p_enabled); bool is_pickable() const; - String get_configuration_warning() const; + String get_configuration_warning() const override; _FORCE_INLINE_ RID get_rid() const { return rid; } diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 1e48b2d67f..64d82d715c 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -31,23 +31,23 @@ #include "collision_polygon_2d.h" #include "collision_object_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" +#include "core/math/geometry_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" #include "thirdparty/misc/triangulator.h" void CollisionPolygon2D::_build_polygon() { - parent->shape_owner_clear_shapes(owner_id); - if (polygon.size() == 0) + if (polygon.size() == 0) { return; + } bool solids = build_mode == BUILD_SOLIDS; if (solids) { - //here comes the sun, lalalala //decompose concave into multiple convex polygons and add them Vector<Vector<Vector2>> decomp = _decompose_in_convex(); @@ -58,7 +58,6 @@ void CollisionPolygon2D::_build_polygon() { } } else { - Ref<ConcavePolygonShape2D> concave = memnew(ConcavePolygonShape2D); Vector<Vector2> segments; @@ -77,25 +76,23 @@ void CollisionPolygon2D::_build_polygon() { } Vector<Vector<Vector2>> CollisionPolygon2D::_decompose_in_convex() { - Vector<Vector<Vector2>> decomp = Geometry::decompose_polygon_in_convex(polygon); + Vector<Vector<Vector2>> decomp = Geometry2D::decompose_polygon_in_convex(polygon); return decomp; } void CollisionPolygon2D::_update_in_shape_owner(bool p_xform_only) { - parent->shape_owner_set_transform(owner_id, get_transform()); - if (p_xform_only) + if (p_xform_only) { return; + } parent->shape_owner_set_disabled(owner_id, disabled); parent->shape_owner_set_one_way_collision(owner_id, one_way_collision); parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin); } void CollisionPolygon2D::_notification(int p_what) { - switch (p_what) { case NOTIFICATION_PARENTED: { - parent = Object::cast_to<CollisionObject2D>(get_parent()); if (parent) { owner_id = parent->create_shape_owner(this); @@ -111,14 +108,12 @@ void CollisionPolygon2D::_notification(int p_what) { } break; case NOTIFICATION_ENTER_TREE: { - if (parent) { _update_in_shape_owner(); } } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - if (parent) { _update_in_shape_owner(true); } @@ -133,13 +128,11 @@ void CollisionPolygon2D::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) { break; } for (int i = 0; i < polygon.size(); i++) { - Vector2 p = polygon[i]; Vector2 n = polygon[(i + 1) % polygon.size()]; // draw line with width <= 1, so it does not scale with zoom and break pixel exact editing @@ -152,7 +145,6 @@ void CollisionPolygon2D::_notification(int p_what) { Color c(0.4, 0.9, 0.1); for (int i = 0; i < decomp.size(); i++) { - c.set_hsv(Math::fmod(c.get_h() + 0.738, 1), c.get_s(), c.get_v(), 0.5); draw_colored_polygon(decomp[i], c); } @@ -171,8 +163,9 @@ void CollisionPolygon2D::_notification(int p_what) { 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++) + for (int i = 0; i < 3; i++) { cols.push_back(dcol); + } draw_primitive(pts, cols, Vector<Vector2>()); //small arrow } @@ -181,18 +174,17 @@ void CollisionPolygon2D::_notification(int p_what) { } void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) { - polygon = p_polygon; { for (int i = 0; i < polygon.size(); i++) { - if (i == 0) + if (i == 0) { aabb = Rect2(polygon[i], Size2()); - else + } else { aabb.expand_to(polygon[i]); + } } if (aabb == Rect2()) { - aabb = Rect2(-10, -10, 20, 20); } else { aabb.position -= aabb.size * 0.3; @@ -208,12 +200,10 @@ void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) { } Vector<Point2> CollisionPolygon2D::get_polygon() const { - return polygon; } void CollisionPolygon2D::set_build_mode(BuildMode p_mode) { - ERR_FAIL_INDEX((int)p_mode, 2); build_mode = p_mode; if (parent) { @@ -222,13 +212,11 @@ void CollisionPolygon2D::set_build_mode(BuildMode p_mode) { } CollisionPolygon2D::BuildMode CollisionPolygon2D::get_build_mode() const { - return build_mode; } #ifdef TOOLS_ENABLED Rect2 CollisionPolygon2D::_edit_get_rect() const { - return aabb; } @@ -237,22 +225,28 @@ bool CollisionPolygon2D::_edit_use_rect() const { } bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - - return Geometry::is_point_in_polygon(p_point, Variant(polygon)); + return Geometry2D::is_point_in_polygon(p_point, Variant(polygon)); } #endif String CollisionPolygon2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (!Object::cast_to<CollisionObject2D>(get_parent())) { - return TTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."); } if (polygon.empty()) { - return TTR("An empty CollisionPolygon2D has no effect on collision."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("An empty CollisionPolygon2D has no effect on collision."); } - return String(); + return warning; } void CollisionPolygon2D::set_disabled(bool p_disabled) { @@ -276,7 +270,6 @@ void CollisionPolygon2D::set_one_way_collision(bool p_enable) { } bool CollisionPolygon2D::is_one_way_collision_enabled() const { - return one_way_collision; } @@ -290,8 +283,8 @@ void CollisionPolygon2D::set_one_way_collision_margin(float p_margin) { float CollisionPolygon2D::get_one_way_collision_margin() const { return one_way_collision_margin; } -void CollisionPolygon2D::_bind_methods() { +void CollisionPolygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &CollisionPolygon2D::set_polygon); ClassDB::bind_method(D_METHOD("get_polygon"), &CollisionPolygon2D::get_polygon); @@ -315,7 +308,6 @@ void CollisionPolygon2D::_bind_methods() { } CollisionPolygon2D::CollisionPolygon2D() { - aabb = Rect2(-10, -10, 20, 20); build_mode = BUILD_SOLIDS; set_notify_local_transform(true); diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index 92a2758813..0f6b654149 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -37,7 +37,6 @@ class CollisionObject2D; class CollisionPolygon2D : public Node2D { - GDCLASS(CollisionPolygon2D, Node2D); public: @@ -68,9 +67,9 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; #endif void set_build_mode(BuildMode p_mode); @@ -79,7 +78,7 @@ public: void set_polygon(const Vector<Point2> &p_polygon); Vector<Point2> get_polygon() const; - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; void set_disabled(bool p_disabled); bool is_disabled() const; diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index b1dbc57c94..a5cd624235 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -31,7 +31,7 @@ #include "collision_shape_2d.h" #include "collision_object_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/resources/capsule_shape_2d.h" #include "scene/resources/circle_shape_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" @@ -41,26 +41,22 @@ #include "scene/resources/segment_shape_2d.h" void CollisionShape2D::_shape_changed() { - update(); } void CollisionShape2D::_update_in_shape_owner(bool p_xform_only) { - parent->shape_owner_set_transform(owner_id, get_transform()); - if (p_xform_only) + if (p_xform_only) { return; + } parent->shape_owner_set_disabled(owner_id, disabled); parent->shape_owner_set_one_way_collision(owner_id, one_way_collision); parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin); } void CollisionShape2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_PARENTED: { - parent = Object::cast_to<CollisionObject2D>(get_parent()); if (parent) { owner_id = parent->create_shape_owner(this); @@ -78,14 +74,12 @@ void CollisionShape2D::_notification(int p_what) { } break; case NOTIFICATION_ENTER_TREE: { - if (parent) { _update_in_shape_owner(); } } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - if (parent) { _update_in_shape_owner(true); } @@ -100,7 +94,6 @@ void CollisionShape2D::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) { break; } @@ -137,8 +130,9 @@ void CollisionShape2D::_notification(int p_what) { 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++) + for (int i = 0; i < 3; i++) { cols.push_back(draw_col); + } draw_primitive(pts, cols, Vector<Vector2>()); } @@ -147,9 +141,9 @@ void CollisionShape2D::_notification(int p_what) { } void CollisionShape2D::set_shape(const Ref<Shape2D> &p_shape) { - - if (shape.is_valid()) + if (shape.is_valid()) { shape->disconnect("changed", callable_mp(this, &CollisionShape2D::_shape_changed)); + } shape = p_shape; update(); if (parent) { @@ -159,35 +153,37 @@ void CollisionShape2D::set_shape(const Ref<Shape2D> &p_shape) { } } - if (shape.is_valid()) + if (shape.is_valid()) { shape->connect("changed", callable_mp(this, &CollisionShape2D::_shape_changed)); + } update_configuration_warning(); } Ref<Shape2D> CollisionShape2D::get_shape() const { - return shape; } bool CollisionShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - - if (!shape.is_valid()) + if (!shape.is_valid()) { return false; + } return shape->_edit_is_selected_on_click(p_point, p_tolerance); } String CollisionShape2D::get_configuration_warning() const { - if (!Object::cast_to<CollisionObject2D>(get_parent())) { return TTR("CollisionShape2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."); } - if (!shape.is_valid()) { return TTR("A shape must be provided for CollisionShape2D to function. Please create a shape resource for it!"); } - + Ref<ConvexPolygonShape2D> convex = shape; + Ref<ConcavePolygonShape2D> concave = shape; + if (convex.is_valid() || concave.is_valid()) { + return TTR("Polygon-based shapes are not meant be used nor edited directly through the CollisionShape2D node. Please use the CollisionPolygon2D node instead."); + } return String(); } @@ -212,7 +208,6 @@ void CollisionShape2D::set_one_way_collision(bool p_enable) { } bool CollisionShape2D::is_one_way_collision_enabled() const { - return one_way_collision; } @@ -228,7 +223,6 @@ float CollisionShape2D::get_one_way_collision_margin() const { } void CollisionShape2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_shape", "shape"), &CollisionShape2D::set_shape); ClassDB::bind_method(D_METHOD("get_shape"), &CollisionShape2D::get_shape); ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &CollisionShape2D::set_disabled); @@ -245,7 +239,6 @@ void CollisionShape2D::_bind_methods() { } CollisionShape2D::CollisionShape2D() { - rect = Rect2(-Point2(10, 10), Point2(20, 20)); set_notify_local_transform(true); owner_id = 0; diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h index 80bea0a979..ced90d46f0 100644 --- a/scene/2d/collision_shape_2d.h +++ b/scene/2d/collision_shape_2d.h @@ -37,7 +37,6 @@ class CollisionObject2D; class CollisionShape2D : public Node2D { - GDCLASS(CollisionShape2D, Node2D); Ref<Shape2D> shape; Rect2 rect; @@ -55,7 +54,11 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; +#else virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; +#endif // TOOLS_ENABLED void set_shape(const Ref<Shape2D> &p_shape); Ref<Shape2D> get_shape() const; @@ -69,7 +72,7 @@ public: void set_one_way_collision_margin(float p_margin); float get_one_way_collision_margin() const; - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; CollisionShape2D(); }; diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 0a6b091a51..ef2a9a4911 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -37,17 +37,17 @@ #include "servers/rendering_server.h" void CPUParticles2D::set_emitting(bool p_emitting) { - - if (emitting == p_emitting) + if (emitting == p_emitting) { return; + } emitting = p_emitting; - if (emitting) + if (emitting) { set_process_internal(true); + } } void CPUParticles2D::set_amount(int p_amount) { - ERR_FAIL_COND_MSG(p_amount < 1, "Amount of particles must be greater than 0."); particles.resize(p_amount); @@ -64,100 +64,90 @@ void CPUParticles2D::set_amount(int p_amount) { particle_order.resize(p_amount); } -void CPUParticles2D::set_lifetime(float p_lifetime) { +void CPUParticles2D::set_lifetime(float p_lifetime) { ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0."); lifetime = p_lifetime; } void CPUParticles2D::set_one_shot(bool p_one_shot) { - one_shot = p_one_shot; } void CPUParticles2D::set_pre_process_time(float p_time) { - pre_process_time = p_time; } -void CPUParticles2D::set_explosiveness_ratio(float p_ratio) { +void CPUParticles2D::set_explosiveness_ratio(float p_ratio) { explosiveness_ratio = p_ratio; } -void CPUParticles2D::set_randomness_ratio(float p_ratio) { +void CPUParticles2D::set_randomness_ratio(float p_ratio) { randomness_ratio = p_ratio; } -void CPUParticles2D::set_lifetime_randomness(float p_random) { +void CPUParticles2D::set_lifetime_randomness(float p_random) { lifetime_randomness = p_random; } -void CPUParticles2D::set_use_local_coordinates(bool p_enable) { +void CPUParticles2D::set_use_local_coordinates(bool p_enable) { local_coords = p_enable; set_notify_transform(!p_enable); } void CPUParticles2D::set_speed_scale(float p_scale) { - speed_scale = p_scale; } bool CPUParticles2D::is_emitting() const { - return emitting; } -int CPUParticles2D::get_amount() const { +int CPUParticles2D::get_amount() const { return particles.size(); } -float CPUParticles2D::get_lifetime() const { +float CPUParticles2D::get_lifetime() const { return lifetime; } -bool CPUParticles2D::get_one_shot() const { +bool CPUParticles2D::get_one_shot() const { return one_shot; } float CPUParticles2D::get_pre_process_time() const { - return pre_process_time; } -float CPUParticles2D::get_explosiveness_ratio() const { +float CPUParticles2D::get_explosiveness_ratio() const { return explosiveness_ratio; } -float CPUParticles2D::get_randomness_ratio() const { +float CPUParticles2D::get_randomness_ratio() const { return randomness_ratio; } -float CPUParticles2D::get_lifetime_randomness() const { +float CPUParticles2D::get_lifetime_randomness() const { return lifetime_randomness; } bool CPUParticles2D::get_use_local_coordinates() const { - return local_coords; } float CPUParticles2D::get_speed_scale() const { - return speed_scale; } void CPUParticles2D::set_draw_order(DrawOrder p_order) { - draw_order = p_order; } CPUParticles2D::DrawOrder CPUParticles2D::get_draw_order() const { - return draw_order; } void CPUParticles2D::_update_mesh_texture() { - Size2 tex_size; if (texture.is_valid()) { tex_size = texture->get_size(); @@ -209,23 +199,25 @@ void CPUParticles2D::_update_mesh_texture() { } void CPUParticles2D::set_texture(const Ref<Texture2D> &p_texture) { - if (p_texture == texture) + if (p_texture == texture) { return; + } - if (texture.is_valid()) + if (texture.is_valid()) { texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CPUParticles2D::_texture_changed)); + } texture = p_texture; - if (texture.is_valid()) + if (texture.is_valid()) { texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CPUParticles2D::_texture_changed)); + } update(); _update_mesh_texture(); } void CPUParticles2D::_texture_changed() { - if (texture.is_valid()) { update(); _update_mesh_texture(); @@ -233,21 +225,9 @@ void CPUParticles2D::_texture_changed() { } Ref<Texture2D> CPUParticles2D::get_texture() const { - return texture; } -void CPUParticles2D::set_normalmap(const Ref<Texture2D> &p_normalmap) { - - normalmap = p_normalmap; - update(); -} - -Ref<Texture2D> CPUParticles2D::get_normalmap() const { - - return normalmap; -} - void CPUParticles2D::set_fixed_fps(int p_count) { fixed_fps = p_count; } @@ -265,16 +245,16 @@ bool CPUParticles2D::get_fractional_delta() const { } String CPUParticles2D::get_configuration_warning() const { - - String warnings; + String warnings = Node2D::get_configuration_warning(); CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr()); if (get_material().is_null() || (mat && !mat->get_particles_animation())) { if (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 || get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid()) { - if (warnings != String()) + if (warnings != String()) { warnings += "\n"; + } warnings += "- " + TTR("CPUParticles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."); } } @@ -283,7 +263,6 @@ String CPUParticles2D::get_configuration_warning() const { } void CPUParticles2D::restart() { - time = 0; inactive_time = 0; frame_remainder = 0; @@ -303,62 +282,55 @@ void CPUParticles2D::restart() { } void CPUParticles2D::set_direction(Vector2 p_direction) { - direction = p_direction; } Vector2 CPUParticles2D::get_direction() const { - return direction; } void CPUParticles2D::set_spread(float p_spread) { - spread = p_spread; } float CPUParticles2D::get_spread() const { - return spread; } void CPUParticles2D::set_param(Parameter p_param, float p_value) { - ERR_FAIL_INDEX(p_param, PARAM_MAX); parameters[p_param] = p_value; } -float CPUParticles2D::get_param(Parameter p_param) const { +float CPUParticles2D::get_param(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return parameters[p_param]; } void CPUParticles2D::set_param_randomness(Parameter p_param, float p_value) { - ERR_FAIL_INDEX(p_param, PARAM_MAX); randomness[p_param] = p_value; } -float CPUParticles2D::get_param_randomness(Parameter p_param) const { +float CPUParticles2D::get_param_randomness(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return randomness[p_param]; } static void _adjust_curve_range(const Ref<Curve> &p_curve, float p_min, float p_max) { - Ref<Curve> curve = p_curve; - if (!curve.is_valid()) + if (!curve.is_valid()) { return; + } curve->ensure_default_setup(p_min, p_max); } void CPUParticles2D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curve) { - ERR_FAIL_INDEX(p_param, PARAM_MAX); curve_parameters[p_param] = p_curve; @@ -389,7 +361,6 @@ void CPUParticles2D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv _adjust_curve_range(p_curve, -360, 360); } break; case PARAM_SCALE: { - } break; case PARAM_HUE_VARIATION: { _adjust_curve_range(p_curve, -1, 1); @@ -403,30 +374,26 @@ void CPUParticles2D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv } } } -Ref<Curve> CPUParticles2D::get_param_curve(Parameter p_param) const { +Ref<Curve> CPUParticles2D::get_param_curve(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Curve>()); return curve_parameters[p_param]; } void CPUParticles2D::set_color(const Color &p_color) { - color = p_color; } Color CPUParticles2D::get_color() const { - return color; } void CPUParticles2D::set_color_ramp(const Ref<Gradient> &p_ramp) { - color_ramp = p_ramp; } Ref<Gradient> CPUParticles2D::get_color_ramp() const { - return color_ramp; } @@ -447,67 +414,58 @@ void CPUParticles2D::set_emission_shape(EmissionShape p_shape) { } void CPUParticles2D::set_emission_sphere_radius(float p_radius) { - emission_sphere_radius = p_radius; } void CPUParticles2D::set_emission_rect_extents(Vector2 p_extents) { - emission_rect_extents = p_extents; } void CPUParticles2D::set_emission_points(const Vector<Vector2> &p_points) { - emission_points = p_points; } void CPUParticles2D::set_emission_normals(const Vector<Vector2> &p_normals) { - emission_normals = p_normals; } void CPUParticles2D::set_emission_colors(const Vector<Color> &p_colors) { - emission_colors = p_colors; } float CPUParticles2D::get_emission_sphere_radius() const { - return emission_sphere_radius; } -Vector2 CPUParticles2D::get_emission_rect_extents() const { +Vector2 CPUParticles2D::get_emission_rect_extents() const { return emission_rect_extents; } -Vector<Vector2> CPUParticles2D::get_emission_points() const { +Vector<Vector2> CPUParticles2D::get_emission_points() const { return emission_points; } -Vector<Vector2> CPUParticles2D::get_emission_normals() const { +Vector<Vector2> CPUParticles2D::get_emission_normals() const { return emission_normals; } Vector<Color> CPUParticles2D::get_emission_colors() const { - return emission_colors; } CPUParticles2D::EmissionShape CPUParticles2D::get_emission_shape() const { return emission_shape; } -void CPUParticles2D::set_gravity(const Vector2 &p_gravity) { +void CPUParticles2D::set_gravity(const Vector2 &p_gravity) { gravity = p_gravity; } Vector2 CPUParticles2D::get_gravity() const { - return gravity; } void CPUParticles2D::_validate_property(PropertyInfo &property) const { - if (property.name == "color" && color_ramp.is_valid()) { property.usage = 0; } @@ -538,7 +496,6 @@ void CPUParticles2D::_validate_property(PropertyInfo &property) const { } static uint32_t idhash(uint32_t x) { - x = ((x >> uint32_t(16)) ^ x) * uint32_t(0x45d9f3b); x = ((x >> uint32_t(16)) ^ x) * uint32_t(0x45d9f3b); x = (x >> uint32_t(16)) ^ x; @@ -548,18 +505,19 @@ static uint32_t idhash(uint32_t x) { static float rand_from_seed(uint32_t &seed) { int k; int s = int(seed); - if (s == 0) + if (s == 0) { s = 305420679; + } k = s / 127773; s = 16807 * (s - k * 127773) - 2836 * k; - if (s < 0) + if (s < 0) { s += 2147483647; + } seed = uint32_t(s); return float(seed % uint32_t(65536)) / 65535.0; } void CPUParticles2D::_update_internal() { - if (particles.size() == 0 || !is_visible_in_tree()) { _set_redraw(false); return; @@ -585,12 +543,12 @@ void CPUParticles2D::_update_internal() { _set_redraw(true); if (time == 0 && pre_process_time > 0.0) { - float frame_time; - if (fixed_fps > 0) + if (fixed_fps > 0) { frame_time = 1.0 / fixed_fps; - else + } else { frame_time = 1.0 / 30.0; + } float todo = pre_process_time; @@ -627,7 +585,6 @@ void CPUParticles2D::_update_internal() { } void CPUParticles2D::_particles_process(float p_delta) { - p_delta *= speed_scale; int pcount = particles.size(); @@ -657,11 +614,11 @@ void CPUParticles2D::_particles_process(float p_delta) { float system_phase = time / lifetime; for (int i = 0; i < pcount; i++) { - Particle &p = parray[i]; - if (!emitting && !p.active) + if (!emitting && !p.active) { continue; + } float local_delta = p_delta; @@ -715,7 +672,6 @@ void CPUParticles2D::_particles_process(float p_delta) { } if (restart) { - if (!emitting) { p.active = false; continue; @@ -774,17 +730,21 @@ void CPUParticles2D::_particles_process(float p_delta) { } break; case EMISSION_SHAPE_POINTS: case EMISSION_SHAPE_DIRECTED_POINTS: { - int pc = emission_points.size(); - if (pc == 0) + if (pc == 0) { break; + } int random_idx = Math::rand() % pc; p.transform[2] = emission_points.get(random_idx); if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS && emission_normals.size() == pc) { - p.velocity = emission_normals.get(random_idx); + Vector2 normal = emission_normals.get(random_idx); + Transform2D m2; + m2.set_axis(0, normal); + m2.set_axis(1, normal.tangent()); + p.velocity = m2.basis_xform(p.velocity); } if (emission_colors.size() == pc) { @@ -806,7 +766,6 @@ void CPUParticles2D::_particles_process(float p_delta) { } else if (p.time > p.lifetime) { p.active = false; } else { - uint32_t alt_seed = p.seed; p.time += local_delta; @@ -890,7 +849,6 @@ void CPUParticles2D::_particles_process(float p_delta) { } if (parameters[PARAM_DAMPING] + tex_damping > 0.0) { - float v = p.velocity.length(); float damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]); v -= damp * local_delta; @@ -949,7 +907,6 @@ void CPUParticles2D::_particles_process(float p_delta) { if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { if (p.velocity.length() > 0.0) { - p.transform.elements[1] = p.velocity.normalized(); p.transform.elements[0] = p.transform.elements[1].tangent(); } @@ -961,7 +918,9 @@ void CPUParticles2D::_particles_process(float p_delta) { //scale by scale float base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], 1.0f, p.scale_rand * randomness[PARAM_SCALE]); - if (base_scale < 0.000001) base_scale = 0.000001; + if (base_scale < 0.000001) { + base_scale = 0.000001; + } p.transform.elements[0] *= base_scale; p.transform.elements[1] *= base_scale; @@ -997,7 +956,6 @@ void CPUParticles2D::_update_particle_data_buffer() { } for (int i = 0; i < pc; i++) { - int idx = order ? order[i] : i; Transform2D t = r[idx].transform; @@ -1007,7 +965,6 @@ void CPUParticles2D::_update_particle_data_buffer() { } if (r[idx].active) { - ptr[0] = t.elements[0][0]; ptr[1] = t.elements[1][0]; ptr[2] = 0; @@ -1038,8 +995,9 @@ void CPUParticles2D::_update_particle_data_buffer() { } void CPUParticles2D::_set_redraw(bool p_redraw) { - if (redraw == p_redraw) + if (redraw == p_redraw) { return; + } redraw = p_redraw; { @@ -1064,14 +1022,12 @@ void CPUParticles2D::_set_redraw(bool p_redraw) { } void CPUParticles2D::_update_render_thread() { - MutexLock lock(update_mutex); RS::get_singleton()->multimesh_set_buffer(multimesh, particle_data); } void CPUParticles2D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { set_process_internal(emitting); } @@ -1082,23 +1038,20 @@ void CPUParticles2D::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { // first update before rendering to avoid one frame delay after emitting starts - if (emitting && (time == 0)) + if (emitting && (time == 0)) { _update_internal(); + } - if (!redraw) + if (!redraw) { return; // don't add to render list + } RID texrid; if (texture.is_valid()) { texrid = texture->get_rid(); } - RID normrid; - if (normalmap.is_valid()) { - normrid = normalmap->get_rid(); - } - - RS::get_singleton()->canvas_item_add_multimesh(get_canvas_item(), multimesh, texrid, normrid); + RS::get_singleton()->canvas_item_add_multimesh(get_canvas_item(), multimesh, texrid); } if (p_what == NOTIFICATION_INTERNAL_PROCESS) { @@ -1106,11 +1059,9 @@ void CPUParticles2D::_notification(int p_what) { } if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { - inv_emission_transform = get_global_transform().affine_inverse(); if (!local_coords) { - int pc = particles.size(); float *w = particle_data.ptrw(); @@ -1118,11 +1069,9 @@ void CPUParticles2D::_notification(int p_what) { float *ptr = w; for (int i = 0; i < pc; i++) { - Transform2D t = inv_emission_transform * r[i].transform; if (r[i].active) { - ptr[0] = t.elements[0][0]; ptr[1] = t.elements[1][0]; ptr[2] = 0; @@ -1143,7 +1092,6 @@ void CPUParticles2D::_notification(int p_what) { } void CPUParticles2D::convert_from_particles(Node *p_particles) { - GPUParticles2D *particles = Object::cast_to<GPUParticles2D>(p_particles); ERR_FAIL_COND_MSG(!particles, "Only GPUParticles2D nodes can be converted to CPUParticles2D."); @@ -1167,8 +1115,9 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { } Ref<ParticlesMaterial> material = particles->get_process_material(); - if (material.is_null()) + if (material.is_null()) { return; + } Vector3 dir = material->get_direction(); set_direction(Vector2(dir.x, dir.y)); @@ -1196,7 +1145,8 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \ { \ Ref<CurveTexture> ctex = material->get_param_texture(ParticlesMaterial::m_param); \ - if (ctex.is_valid()) set_param_curve(m_param, ctex->get_curve()); \ + if (ctex.is_valid()) \ + set_param_curve(m_param, ctex->get_curve()); \ } \ set_param_randomness(m_param, material->get_param_randomness(ParticlesMaterial::m_param)); @@ -1217,7 +1167,6 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { } void CPUParticles2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &CPUParticles2D::set_emitting); ClassDB::bind_method(D_METHOD("set_amount", "amount"), &CPUParticles2D::set_amount); ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &CPUParticles2D::set_lifetime); @@ -1251,9 +1200,6 @@ void CPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture"), &CPUParticles2D::set_texture); ClassDB::bind_method(D_METHOD("get_texture"), &CPUParticles2D::get_texture); - ClassDB::bind_method(D_METHOD("set_normalmap", "normalmap"), &CPUParticles2D::set_normalmap); - ClassDB::bind_method(D_METHOD("get_normalmap"), &CPUParticles2D::get_normalmap); - ClassDB::bind_method(D_METHOD("restart"), &CPUParticles2D::restart); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); @@ -1273,7 +1219,6 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates"); ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime"), "set_draw_order", "get_draw_order"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normalmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normalmap", "get_normalmap"); BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME); @@ -1328,7 +1273,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"), "set_emission_shape", "get_emission_shape"); + 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::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"); @@ -1420,7 +1365,6 @@ void CPUParticles2D::_bind_methods() { } CPUParticles2D::CPUParticles2D() { - time = 0; inactive_time = 0; frame_remainder = 0; diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 18d0caceed..0f2a3e4920 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -31,7 +31,7 @@ #ifndef CPU_PARTICLES_2D_H #define CPU_PARTICLES_2D_H -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/2d/node_2d.h" #include "scene/resources/texture.h" @@ -46,7 +46,6 @@ public: }; enum Parameter { - PARAM_INITIAL_LINEAR_VELOCITY, PARAM_ANGULAR_VELOCITY, PARAM_ORBIT_VELOCITY, @@ -124,7 +123,6 @@ private: const Particle *particles; Vector2 axis; bool operator()(int p_a, int p_b) const { - return axis.dot(particles[p_a].transform[2]) < axis.dot(particles[p_b].transform[2]); } }; @@ -148,7 +146,6 @@ private: DrawOrder draw_order; Ref<Texture2D> texture; - Ref<Texture2D> normalmap; //////// @@ -191,7 +188,7 @@ private: protected: static void _bind_methods(); void _notification(int p_what); - virtual void _validate_property(PropertyInfo &property) const; + virtual void _validate_property(PropertyInfo &property) const override; public: void set_emitting(bool p_emitting); @@ -233,9 +230,6 @@ public: void set_texture(const Ref<Texture2D> &p_texture); Ref<Texture2D> get_texture() const; - void set_normalmap(const Ref<Texture2D> &p_normalmap); - Ref<Texture2D> get_normalmap() const; - /////////////////// void set_direction(Vector2 p_direction); @@ -281,7 +275,7 @@ public: void set_gravity(const Vector2 &p_gravity); Vector2 get_gravity() const; - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; void restart(); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index de3f8fa09e..a4a930455b 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -35,11 +35,10 @@ #include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED -#include "core/engine.h" +#include "core/config/engine.h" #endif void GPUParticles2D::set_emitting(bool p_emitting) { - RS::get_singleton()->particles_set_emitting(particles, p_emitting); if (p_emitting && one_shot) { @@ -50,50 +49,49 @@ void GPUParticles2D::set_emitting(bool p_emitting) { } void GPUParticles2D::set_amount(int p_amount) { - ERR_FAIL_COND_MSG(p_amount < 1, "Amount of particles cannot be smaller than 1."); amount = p_amount; RS::get_singleton()->particles_set_amount(particles, amount); } -void GPUParticles2D::set_lifetime(float p_lifetime) { +void GPUParticles2D::set_lifetime(float p_lifetime) { ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0."); lifetime = p_lifetime; RS::get_singleton()->particles_set_lifetime(particles, lifetime); } void GPUParticles2D::set_one_shot(bool p_enable) { - one_shot = p_enable; RS::get_singleton()->particles_set_one_shot(particles, one_shot); if (is_emitting()) { - set_process_internal(true); - if (!one_shot) + if (!one_shot) { RenderingServer::get_singleton()->particles_restart(particles); + } } - if (!one_shot) + if (!one_shot) { set_process_internal(false); + } } -void GPUParticles2D::set_pre_process_time(float p_time) { +void GPUParticles2D::set_pre_process_time(float p_time) { pre_process_time = p_time; RS::get_singleton()->particles_set_pre_process_time(particles, pre_process_time); } -void GPUParticles2D::set_explosiveness_ratio(float p_ratio) { +void GPUParticles2D::set_explosiveness_ratio(float p_ratio) { explosiveness_ratio = p_ratio; RS::get_singleton()->particles_set_explosiveness_ratio(particles, explosiveness_ratio); } -void GPUParticles2D::set_randomness_ratio(float p_ratio) { +void GPUParticles2D::set_randomness_ratio(float p_ratio) { randomness_ratio = p_ratio; RS::get_singleton()->particles_set_randomness_ratio(particles, randomness_ratio); } -void GPUParticles2D::set_visibility_rect(const Rect2 &p_visibility_rect) { +void GPUParticles2D::set_visibility_rect(const Rect2 &p_visibility_rect) { visibility_rect = p_visibility_rect; AABB aabb; aabb.position.x = p_visibility_rect.position.x; @@ -106,8 +104,8 @@ void GPUParticles2D::set_visibility_rect(const Rect2 &p_visibility_rect) { _change_notify("visibility_rect"); update(); } -void GPUParticles2D::set_use_local_coordinates(bool p_enable) { +void GPUParticles2D::set_use_local_coordinates(bool p_enable) { local_coords = p_enable; RS::get_singleton()->particles_set_use_local_coordinates(particles, local_coords); set_notify_transform(!p_enable); @@ -117,7 +115,6 @@ void GPUParticles2D::set_use_local_coordinates(bool p_enable) { } void GPUParticles2D::_update_particle_emission_transform() { - Transform2D xf2d = get_global_transform(); Transform xf; xf.basis.set_axis(0, Vector3(xf2d.get_axis(0).x, xf2d.get_axis(0).y, 0)); @@ -128,7 +125,6 @@ void GPUParticles2D::_update_particle_emission_transform() { } void GPUParticles2D::set_process_material(const Ref<Material> &p_material) { - process_material = p_material; Ref<ParticlesMaterial> pm = p_material; if (pm.is_valid() && !pm->get_flag(ParticlesMaterial::FLAG_DISABLE_Z) && pm->get_gravity() == Vector3(0, -9.8, 0)) { @@ -137,74 +133,69 @@ void GPUParticles2D::set_process_material(const Ref<Material> &p_material) { pm->set_gravity(Vector3(0, 98, 0)); } RID material_rid; - if (process_material.is_valid()) + if (process_material.is_valid()) { material_rid = process_material->get_rid(); + } RS::get_singleton()->particles_set_process_material(particles, material_rid); update_configuration_warning(); } void GPUParticles2D::set_speed_scale(float p_scale) { - speed_scale = p_scale; RS::get_singleton()->particles_set_speed_scale(particles, p_scale); } bool GPUParticles2D::is_emitting() const { - return RS::get_singleton()->particles_get_emitting(particles); } -int GPUParticles2D::get_amount() const { +int GPUParticles2D::get_amount() const { return amount; } -float GPUParticles2D::get_lifetime() const { +float GPUParticles2D::get_lifetime() const { return lifetime; } bool GPUParticles2D::get_one_shot() const { - return one_shot; } -float GPUParticles2D::get_pre_process_time() const { +float GPUParticles2D::get_pre_process_time() const { return pre_process_time; } -float GPUParticles2D::get_explosiveness_ratio() const { +float GPUParticles2D::get_explosiveness_ratio() const { return explosiveness_ratio; } -float GPUParticles2D::get_randomness_ratio() const { +float GPUParticles2D::get_randomness_ratio() const { return randomness_ratio; } -Rect2 GPUParticles2D::get_visibility_rect() const { +Rect2 GPUParticles2D::get_visibility_rect() const { return visibility_rect; } -bool GPUParticles2D::get_use_local_coordinates() const { +bool GPUParticles2D::get_use_local_coordinates() const { return local_coords; } -Ref<Material> GPUParticles2D::get_process_material() const { +Ref<Material> GPUParticles2D::get_process_material() const { return process_material; } float GPUParticles2D::get_speed_scale() const { - return speed_scale; } void GPUParticles2D::set_draw_order(DrawOrder p_order) { - draw_order = p_order; RS::get_singleton()->particles_set_draw_order(particles, RS::ParticlesDrawOrder(p_order)); } GPUParticles2D::DrawOrder GPUParticles2D::get_draw_order() const { - return draw_order; } @@ -227,19 +218,18 @@ bool GPUParticles2D::get_fractional_delta() const { } String GPUParticles2D::get_configuration_warning() const { - if (RenderingServer::get_singleton()->is_low_end()) { return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles2D\" option for this purpose."); } - String warnings; + String warnings = Node2D::get_configuration_warning(); if (process_material.is_null()) { - if (warnings != String()) + if (warnings != String()) { warnings += "\n"; + } warnings += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted."); } else { - CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr()); if (get_material().is_null() || (mat && !mat->get_particles_animation())) { @@ -247,8 +237,9 @@ String GPUParticles2D::get_configuration_warning() const { if (process && (process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) { - if (warnings != String()) + if (warnings != String()) { warnings += "\n"; + } warnings += "- " + TTR("Particles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."); } } @@ -258,7 +249,6 @@ String GPUParticles2D::get_configuration_warning() const { } Rect2 GPUParticles2D::capture_rect() const { - AABB aabb = RS::get_singleton()->particles_get_current_aabb(particles); Rect2 r; r.position.x = aabb.position.x; @@ -277,16 +267,6 @@ Ref<Texture2D> GPUParticles2D::get_texture() const { return texture; } -void GPUParticles2D::set_normal_map(const Ref<Texture2D> &p_normal_map) { - - normal_map = p_normal_map; - update(); -} - -Ref<Texture2D> GPUParticles2D::get_normal_map() const { - return normal_map; -} - void GPUParticles2D::_validate_property(PropertyInfo &property) const { } @@ -296,21 +276,16 @@ void GPUParticles2D::restart() { } void GPUParticles2D::_notification(int p_what) { - if (p_what == NOTIFICATION_DRAW) { - RID texture_rid; - if (texture.is_valid()) + if (texture.is_valid()) { texture_rid = texture->get_rid(); - RID normal_rid; - if (normal_map.is_valid()) - normal_rid = normal_map->get_rid(); + } - RS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid, normal_rid); + RS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid); #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() && (this == get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->is_a_parent_of(this))) { - draw_rect(visibility_rect, Color(0, 0.7, 0.9, 0.4), false); } #endif @@ -320,7 +295,6 @@ void GPUParticles2D::_notification(int p_what) { if (can_process()) { RS::get_singleton()->particles_set_speed_scale(particles, speed_scale); } else { - RS::get_singleton()->particles_set_speed_scale(particles, 0); } } @@ -330,7 +304,6 @@ void GPUParticles2D::_notification(int p_what) { } if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - if (one_shot && !is_emitting()) { _change_notify(); set_process_internal(false); @@ -339,7 +312,6 @@ void GPUParticles2D::_notification(int p_what) { } void GPUParticles2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &GPUParticles2D::set_emitting); ClassDB::bind_method(D_METHOD("set_amount", "amount"), &GPUParticles2D::set_amount); ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &GPUParticles2D::set_lifetime); @@ -374,9 +346,6 @@ void GPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticles2D::set_texture); ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticles2D::get_texture); - ClassDB::bind_method(D_METHOD("set_normal_map", "texture"), &GPUParticles2D::set_normal_map); - ClassDB::bind_method(D_METHOD("get_normal_map"), &GPUParticles2D::get_normal_map); - ClassDB::bind_method(D_METHOD("capture_rect"), &GPUParticles2D::capture_rect); ClassDB::bind_method(D_METHOD("restart"), &GPUParticles2D::restart); @@ -400,14 +369,12 @@ void GPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticlesMaterial"), "set_process_material", "get_process_material"); ADD_GROUP("Textures", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map"); BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME); } GPUParticles2D::GPUParticles2D() { - particles = RS::get_singleton()->particles_create(); one_shot = false; // Needed so that set_emitting doesn't access uninitialized values @@ -427,6 +394,5 @@ GPUParticles2D::GPUParticles2D() { } GPUParticles2D::~GPUParticles2D() { - RS::get_singleton()->free(particles); } diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index 47951d76dc..0d1b82d93e 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -31,7 +31,7 @@ #ifndef PARTICLES_2D_H #define PARTICLES_2D_H -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/2d/node_2d.h" #include "scene/resources/texture.h" @@ -65,13 +65,12 @@ private: DrawOrder draw_order; Ref<Texture2D> texture; - Ref<Texture2D> normal_map; void _update_particle_emission_transform(); protected: static void _bind_methods(); - virtual void _validate_property(PropertyInfo &property) const; + virtual void _validate_property(PropertyInfo &property) const override; void _notification(int p_what); public: @@ -111,10 +110,7 @@ public: void set_texture(const Ref<Texture2D> &p_texture); Ref<Texture2D> get_texture() const; - void set_normal_map(const Ref<Texture2D> &p_normal_map); - Ref<Texture2D> get_normal_map() const; - - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; void restart(); Rect2 capture_rect() const; diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 4d49f4762f..0e4b1836da 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -30,15 +30,15 @@ #include "joints_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "physics_body_2d.h" #include "servers/physics_server_2d.h" void Joint2D::_update_joint(bool p_only_free) { - if (joint.is_valid()) { - if (ba.is_valid() && bb.is_valid() && exclude_from_collision) + if (ba.is_valid() && bb.is_valid() && exclude_from_collision) { PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false); + } PhysicsServer2D::get_singleton()->free(joint); joint = RID(); @@ -46,25 +46,29 @@ void Joint2D::_update_joint(bool p_only_free) { bb = RID(); } - if (p_only_free || !is_inside_tree()) + if (p_only_free || !is_inside_tree()) { return; + } Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)nullptr; Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)nullptr; - if (!node_a || !node_b) + if (!node_a || !node_b) { return; + } PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a); PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b); - if (!body_a || !body_b) + if (!body_a || !body_b) { return; + } joint = _configure_joint(body_a, body_b); - if (!joint.is_valid()) + if (!joint.is_valid()) { return; + } PhysicsServer2D::get_singleton()->get_singleton()->joint_set_param(joint, PhysicsServer2D::JOINT_PARAM_BIAS, bias); @@ -75,35 +79,32 @@ void Joint2D::_update_joint(bool p_only_free) { } void Joint2D::set_node_a(const NodePath &p_node_a) { - - if (a == p_node_a) + if (a == p_node_a) { return; + } a = p_node_a; _update_joint(); } NodePath Joint2D::get_node_a() const { - return a; } void Joint2D::set_node_b(const NodePath &p_node_b) { - - if (b == p_node_b) + if (b == p_node_b) { return; + } b = p_node_b; _update_joint(); } -NodePath Joint2D::get_node_b() const { +NodePath Joint2D::get_node_b() const { return b; } void Joint2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_READY: { _update_joint(); } break; @@ -116,21 +117,20 @@ void Joint2D::_notification(int p_what) { } void Joint2D::set_bias(real_t p_bias) { - bias = p_bias; - if (joint.is_valid()) + if (joint.is_valid()) { PhysicsServer2D::get_singleton()->get_singleton()->joint_set_param(joint, PhysicsServer2D::JOINT_PARAM_BIAS, bias); + } } real_t Joint2D::get_bias() const { - return bias; } void Joint2D::set_exclude_nodes_from_collision(bool p_enable) { - - if (exclude_from_collision == p_enable) + if (exclude_from_collision == p_enable) { return; + } _update_joint(true); exclude_from_collision = p_enable; @@ -138,12 +138,10 @@ void Joint2D::set_exclude_nodes_from_collision(bool p_enable) { } bool Joint2D::get_exclude_nodes_from_collision() const { - return exclude_from_collision; } void Joint2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_node_a", "node"), &Joint2D::set_node_a); ClassDB::bind_method(D_METHOD("get_node_a"), &Joint2D::get_node_a); @@ -163,7 +161,6 @@ void Joint2D::_bind_methods() { } Joint2D::Joint2D() { - bias = 0; exclude_from_collision = true; } @@ -173,12 +170,11 @@ Joint2D::Joint2D() { /////////////////////////////////////////////////////////////////////////////// void PinJoint2D::_notification(int p_what) { - switch (p_what) { case NOTIFICATION_DRAW: { - - if (!is_inside_tree()) + if (!is_inside_tree()) { break; + } if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) { break; @@ -191,27 +187,24 @@ void PinJoint2D::_notification(int p_what) { } RID PinJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) { - RID pj = PhysicsServer2D::get_singleton()->pin_joint_create(get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID()); PhysicsServer2D::get_singleton()->pin_joint_set_param(pj, PhysicsServer2D::PIN_JOINT_SOFTNESS, softness); return pj; } void PinJoint2D::set_softness(real_t p_softness) { - softness = p_softness; update(); - if (get_joint().is_valid()) + if (get_joint().is_valid()) { PhysicsServer2D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer2D::PIN_JOINT_SOFTNESS, p_softness); + } } real_t PinJoint2D::get_softness() const { - return softness; } void PinJoint2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_softness", "softness"), &PinJoint2D::set_softness); ClassDB::bind_method(D_METHOD("get_softness"), &PinJoint2D::get_softness); @@ -219,7 +212,6 @@ void PinJoint2D::_bind_methods() { } PinJoint2D::PinJoint2D() { - softness = 0; } @@ -228,11 +220,11 @@ PinJoint2D::PinJoint2D() { /////////////////////////////////////////////////////////////////////////////// void GrooveJoint2D::_notification(int p_what) { - switch (p_what) { case NOTIFICATION_DRAW: { - if (!is_inside_tree()) + if (!is_inside_tree()) { break; + } if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) { break; @@ -247,7 +239,6 @@ void GrooveJoint2D::_notification(int p_what) { } RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) { - Transform2D gt = get_global_transform(); Vector2 groove_A1 = gt.get_origin(); Vector2 groove_A2 = gt.xform(Vector2(0, length)); @@ -257,29 +248,24 @@ RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b } void GrooveJoint2D::set_length(real_t p_length) { - length = p_length; update(); } real_t GrooveJoint2D::get_length() const { - return length; } void GrooveJoint2D::set_initial_offset(real_t p_initial_offset) { - initial_offset = p_initial_offset; update(); } real_t GrooveJoint2D::get_initial_offset() const { - return initial_offset; } void GrooveJoint2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_length", "length"), &GrooveJoint2D::set_length); ClassDB::bind_method(D_METHOD("get_length"), &GrooveJoint2D::get_length); ClassDB::bind_method(D_METHOD("set_initial_offset", "offset"), &GrooveJoint2D::set_initial_offset); @@ -290,7 +276,6 @@ void GrooveJoint2D::_bind_methods() { } GrooveJoint2D::GrooveJoint2D() { - length = 50; initial_offset = 25; } @@ -300,12 +285,11 @@ GrooveJoint2D::GrooveJoint2D() { /////////////////////////////////////////////////////////////////////////////// void DampedSpringJoint2D::_notification(int p_what) { - switch (p_what) { case NOTIFICATION_DRAW: { - - if (!is_inside_tree()) + if (!is_inside_tree()) { break; + } if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) { break; @@ -319,72 +303,66 @@ void DampedSpringJoint2D::_notification(int p_what) { } RID DampedSpringJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) { - Transform2D gt = get_global_transform(); Vector2 anchor_A = gt.get_origin(); Vector2 anchor_B = gt.xform(Vector2(0, length)); RID dsj = PhysicsServer2D::get_singleton()->damped_spring_joint_create(anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid()); - if (rest_length) - PhysicsServer2D::get_singleton()->damped_string_joint_set_param(dsj, PhysicsServer2D::DAMPED_STRING_REST_LENGTH, rest_length); - PhysicsServer2D::get_singleton()->damped_string_joint_set_param(dsj, PhysicsServer2D::DAMPED_STRING_STIFFNESS, stiffness); - PhysicsServer2D::get_singleton()->damped_string_joint_set_param(dsj, PhysicsServer2D::DAMPED_STRING_DAMPING, damping); + if (rest_length) { + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, rest_length); + } + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_STIFFNESS, stiffness); + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_DAMPING, damping); return dsj; } void DampedSpringJoint2D::set_length(real_t p_length) { - length = p_length; update(); } real_t DampedSpringJoint2D::get_length() const { - return length; } void DampedSpringJoint2D::set_rest_length(real_t p_rest_length) { - rest_length = p_rest_length; update(); - if (get_joint().is_valid()) - PhysicsServer2D::get_singleton()->damped_string_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_STRING_REST_LENGTH, p_rest_length ? p_rest_length : length); + if (get_joint().is_valid()) { + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, p_rest_length ? p_rest_length : length); + } } real_t DampedSpringJoint2D::get_rest_length() const { - return rest_length; } void DampedSpringJoint2D::set_stiffness(real_t p_stiffness) { - stiffness = p_stiffness; update(); - if (get_joint().is_valid()) - PhysicsServer2D::get_singleton()->damped_string_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_STRING_STIFFNESS, p_stiffness); + if (get_joint().is_valid()) { + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_STIFFNESS, p_stiffness); + } } real_t DampedSpringJoint2D::get_stiffness() const { - return stiffness; } void DampedSpringJoint2D::set_damping(real_t p_damping) { - damping = p_damping; update(); - if (get_joint().is_valid()) - PhysicsServer2D::get_singleton()->damped_string_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_STRING_DAMPING, p_damping); + if (get_joint().is_valid()) { + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_DAMPING, p_damping); + } } real_t DampedSpringJoint2D::get_damping() const { - return damping; } void DampedSpringJoint2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_length", "length"), &DampedSpringJoint2D::set_length); ClassDB::bind_method(D_METHOD("get_length"), &DampedSpringJoint2D::get_length); ClassDB::bind_method(D_METHOD("set_rest_length", "rest_length"), &DampedSpringJoint2D::set_rest_length); @@ -401,7 +379,6 @@ void DampedSpringJoint2D::_bind_methods() { } DampedSpringJoint2D::DampedSpringJoint2D() { - length = 50; rest_length = 0; stiffness = 20; diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h index f1750e56b6..60534cae65 100644 --- a/scene/2d/joints_2d.h +++ b/scene/2d/joints_2d.h @@ -36,7 +36,6 @@ class PhysicsBody2D; class Joint2D : public Node2D { - GDCLASS(Joint2D, Node2D); RID joint; @@ -74,14 +73,13 @@ public: }; class PinJoint2D : public Joint2D { - GDCLASS(PinJoint2D, Joint2D); real_t softness; protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b); + virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; static void _bind_methods(); public: @@ -92,7 +90,6 @@ public: }; class GrooveJoint2D : public Joint2D { - GDCLASS(GrooveJoint2D, Joint2D); real_t length; @@ -100,7 +97,7 @@ class GrooveJoint2D : public Joint2D { protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b); + virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; static void _bind_methods(); public: @@ -114,7 +111,6 @@ public: }; class DampedSpringJoint2D : public Joint2D { - GDCLASS(DampedSpringJoint2D, Joint2D); real_t stiffness; @@ -124,7 +120,7 @@ class DampedSpringJoint2D : public Joint2D { protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b); + virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; static void _bind_methods(); public: diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index b3d54b81f8..2b373a669b 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -30,59 +30,13 @@ #include "light_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "servers/rendering_server.h" -#ifdef TOOLS_ENABLED -Dictionary Light2D::_edit_get_state() const { - Dictionary state = Node2D::_edit_get_state(); - state["offset"] = get_texture_offset(); - return state; -} - -void Light2D::_edit_set_state(const Dictionary &p_state) { - Node2D::_edit_set_state(p_state); - set_texture_offset(p_state["offset"]); -} - -void Light2D::_edit_set_pivot(const Point2 &p_pivot) { - set_position(get_transform().xform(p_pivot)); - set_texture_offset(get_texture_offset() - p_pivot); -} - -Point2 Light2D::_edit_get_pivot() const { - return Vector2(); -} - -bool Light2D::_edit_use_pivot() const { - return true; -} - -Rect2 Light2D::_edit_get_rect() const { - if (texture.is_null()) - return Rect2(); - - Size2 s = texture->get_size() * _scale; - return Rect2(texture_offset - s / 2.0, s); -} - -bool Light2D::_edit_use_rect() const { - return !texture.is_null(); -} -#endif - -Rect2 Light2D::get_anchorable_rect() const { - if (texture.is_null()) - return Rect2(); - - Size2 s = texture->get_size() * _scale; - return Rect2(texture_offset - s / 2.0, s); -} - void Light2D::_update_light_visibility() { - - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } bool editor_ok = true; @@ -104,198 +58,113 @@ void Light2D::_update_light_visibility() { } void Light2D::set_enabled(bool p_enabled) { - enabled = p_enabled; _update_light_visibility(); } bool Light2D::is_enabled() const { - return enabled; } void Light2D::set_editor_only(bool p_editor_only) { - editor_only = p_editor_only; _update_light_visibility(); } bool Light2D::is_editor_only() const { - return editor_only; } -void Light2D::set_texture(const Ref<Texture2D> &p_texture) { - - texture = p_texture; - if (texture.is_valid()) - RS::get_singleton()->canvas_light_set_texture(canvas_light, texture->get_rid()); - else - RS::get_singleton()->canvas_light_set_texture(canvas_light, RID()); - - update_configuration_warning(); -} - -Ref<Texture2D> Light2D::get_texture() const { - - return texture; -} - -void Light2D::set_texture_offset(const Vector2 &p_offset) { - - texture_offset = p_offset; - RS::get_singleton()->canvas_light_set_texture_offset(canvas_light, texture_offset); - item_rect_changed(); - _change_notify("offset"); -} - -Vector2 Light2D::get_texture_offset() const { - - return texture_offset; -} - void Light2D::set_color(const Color &p_color) { - color = p_color; RS::get_singleton()->canvas_light_set_color(canvas_light, color); } -Color Light2D::get_color() const { +Color Light2D::get_color() const { return color; } void Light2D::set_height(float p_height) { - height = p_height; RS::get_singleton()->canvas_light_set_height(canvas_light, height); } float Light2D::get_height() const { - return height; } void Light2D::set_energy(float p_energy) { - energy = p_energy; RS::get_singleton()->canvas_light_set_energy(canvas_light, energy); } float Light2D::get_energy() const { - return energy; } -void Light2D::set_texture_scale(float p_scale) { - - _scale = p_scale; - // Avoid having 0 scale values, can lead to errors in physics and rendering. - if (_scale == 0) { - _scale = CMP_EPSILON; - } - RS::get_singleton()->canvas_light_set_scale(canvas_light, _scale); - item_rect_changed(); -} - -float Light2D::get_texture_scale() const { - - return _scale; -} - void Light2D::set_z_range_min(int p_min_z) { - z_min = p_min_z; RS::get_singleton()->canvas_light_set_z_range(canvas_light, z_min, z_max); } -int Light2D::get_z_range_min() const { +int Light2D::get_z_range_min() const { return z_min; } void Light2D::set_z_range_max(int p_max_z) { - z_max = p_max_z; RS::get_singleton()->canvas_light_set_z_range(canvas_light, z_min, z_max); } -int Light2D::get_z_range_max() const { +int Light2D::get_z_range_max() const { return z_max; } void Light2D::set_layer_range_min(int p_min_layer) { - layer_min = p_min_layer; RS::get_singleton()->canvas_light_set_layer_range(canvas_light, layer_min, layer_max); } -int Light2D::get_layer_range_min() const { +int Light2D::get_layer_range_min() const { return layer_min; } void Light2D::set_layer_range_max(int p_max_layer) { - layer_max = p_max_layer; RS::get_singleton()->canvas_light_set_layer_range(canvas_light, layer_min, layer_max); } -int Light2D::get_layer_range_max() const { +int Light2D::get_layer_range_max() const { return layer_max; } void Light2D::set_item_cull_mask(int p_mask) { - item_mask = p_mask; RS::get_singleton()->canvas_light_set_item_cull_mask(canvas_light, item_mask); } int Light2D::get_item_cull_mask() const { - return item_mask; } void Light2D::set_item_shadow_cull_mask(int p_mask) { - item_shadow_mask = p_mask; RS::get_singleton()->canvas_light_set_item_shadow_cull_mask(canvas_light, item_shadow_mask); } int Light2D::get_item_shadow_cull_mask() const { - return item_shadow_mask; } -void Light2D::set_mode(Mode p_mode) { - - mode = p_mode; - RS::get_singleton()->canvas_light_set_mode(canvas_light, RS::CanvasLightMode(p_mode)); -} - -Light2D::Mode Light2D::get_mode() const { - - return mode; -} - void Light2D::set_shadow_enabled(bool p_enabled) { - shadow = p_enabled; RS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light, shadow); } -bool Light2D::is_shadow_enabled() const { +bool Light2D::is_shadow_enabled() const { return shadow; } -void Light2D::set_shadow_buffer_size(int p_size) { - - shadow_buffer_size = p_size; - RS::get_singleton()->canvas_light_set_shadow_buffer_size(canvas_light, shadow_buffer_size); -} - -int Light2D::get_shadow_buffer_size() const { - - return shadow_buffer_size; -} - void Light2D::set_shadow_filter(ShadowFilter p_filter) { ERR_FAIL_INDEX(p_filter, SHADOW_FILTER_MAX); shadow_filter = p_filter; @@ -303,7 +172,6 @@ void Light2D::set_shadow_filter(ShadowFilter p_filter) { } Light2D::ShadowFilter Light2D::get_shadow_filter() const { - return shadow_filter; } @@ -316,76 +184,56 @@ Color Light2D::get_shadow_color() const { return shadow_color; } -void Light2D::_notification(int p_what) { +void Light2D::set_blend_mode(BlendMode p_mode) { + blend_mode = p_mode; + RS::get_singleton()->canvas_light_set_blend_mode(_get_light(), RS::CanvasLightBlendMode(p_mode)); +} - if (p_what == NOTIFICATION_ENTER_TREE) { +Light2D::BlendMode Light2D::get_blend_mode() const { + return blend_mode; +} +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(); } } -String Light2D::get_configuration_warning() const { - - if (!texture.is_valid()) { - return TTR("A texture with the shape of the light must be supplied to the \"Texture\" property."); - } - - return String(); -} - void Light2D::set_shadow_smooth(float p_amount) { - shadow_smooth = p_amount; RS::get_singleton()->canvas_light_set_shadow_smooth(canvas_light, shadow_smooth); } float Light2D::get_shadow_smooth() const { - return shadow_smooth; } void Light2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Light2D::set_enabled); ClassDB::bind_method(D_METHOD("is_enabled"), &Light2D::is_enabled); ClassDB::bind_method(D_METHOD("set_editor_only", "editor_only"), &Light2D::set_editor_only); ClassDB::bind_method(D_METHOD("is_editor_only"), &Light2D::is_editor_only); - ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Light2D::set_texture); - ClassDB::bind_method(D_METHOD("get_texture"), &Light2D::get_texture); - - ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &Light2D::set_texture_offset); - ClassDB::bind_method(D_METHOD("get_texture_offset"), &Light2D::get_texture_offset); - ClassDB::bind_method(D_METHOD("set_color", "color"), &Light2D::set_color); ClassDB::bind_method(D_METHOD("get_color"), &Light2D::get_color); - ClassDB::bind_method(D_METHOD("set_height", "height"), &Light2D::set_height); - ClassDB::bind_method(D_METHOD("get_height"), &Light2D::get_height); - ClassDB::bind_method(D_METHOD("set_energy", "energy"), &Light2D::set_energy); ClassDB::bind_method(D_METHOD("get_energy"), &Light2D::get_energy); - ClassDB::bind_method(D_METHOD("set_texture_scale", "texture_scale"), &Light2D::set_texture_scale); - ClassDB::bind_method(D_METHOD("get_texture_scale"), &Light2D::get_texture_scale); - ClassDB::bind_method(D_METHOD("set_z_range_min", "z"), &Light2D::set_z_range_min); ClassDB::bind_method(D_METHOD("get_z_range_min"), &Light2D::get_z_range_min); @@ -404,15 +252,9 @@ void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_shadow_cull_mask", "item_shadow_cull_mask"), &Light2D::set_item_shadow_cull_mask); ClassDB::bind_method(D_METHOD("get_item_shadow_cull_mask"), &Light2D::get_item_shadow_cull_mask); - ClassDB::bind_method(D_METHOD("set_mode", "mode"), &Light2D::set_mode); - ClassDB::bind_method(D_METHOD("get_mode"), &Light2D::get_mode); - ClassDB::bind_method(D_METHOD("set_shadow_enabled", "enabled"), &Light2D::set_shadow_enabled); ClassDB::bind_method(D_METHOD("is_shadow_enabled"), &Light2D::is_shadow_enabled); - ClassDB::bind_method(D_METHOD("set_shadow_buffer_size", "size"), &Light2D::set_shadow_buffer_size); - ClassDB::bind_method(D_METHOD("get_shadow_buffer_size"), &Light2D::get_shadow_buffer_size); - ClassDB::bind_method(D_METHOD("set_shadow_smooth", "smooth"), &Light2D::set_shadow_smooth); ClassDB::bind_method(D_METHOD("get_shadow_smooth"), &Light2D::get_shadow_smooth); @@ -422,16 +264,18 @@ void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_color", "shadow_color"), &Light2D::set_shadow_color); ClassDB::bind_method(D_METHOD("get_shadow_color"), &Light2D::get_shadow_color); + ClassDB::bind_method(D_METHOD("set_blend_mode", "mode"), &Light2D::set_blend_mode); + ClassDB::bind_method(D_METHOD("get_blend_mode"), &Light2D::get_blend_mode); + + ClassDB::bind_method(D_METHOD("set_height", "height"), &Light2D::set_height); + ClassDB::bind_method(D_METHOD("get_height"), &Light2D::get_height); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Add,Sub,Mix,Mask"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Add,Sub,Mix"), "set_blend_mode", "get_blend_mode"); ADD_GROUP("Range", "range_"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "range_height", PROPERTY_HINT_RANGE, "-2048,2048,0.1,or_lesser,or_greater"), "set_height", "get_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_min", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_min", "get_z_range_min"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_max", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_max", "get_z_range_max"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_layer_min", PROPERTY_HINT_RANGE, "-512,512,1"), "set_layer_range_min", "get_layer_range_min"); @@ -441,47 +285,188 @@ void Light2D::_bind_methods() { ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow_enabled", "is_shadow_enabled"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_buffer_size", PROPERTY_HINT_RANGE, "32,16384,1"), "set_shadow_buffer_size", "get_shadow_buffer_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13"), "set_shadow_filter", "get_shadow_filter"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask"); - BIND_ENUM_CONSTANT(MODE_ADD); - BIND_ENUM_CONSTANT(MODE_SUB); - BIND_ENUM_CONSTANT(MODE_MIX); - BIND_ENUM_CONSTANT(MODE_MASK); - BIND_ENUM_CONSTANT(SHADOW_FILTER_NONE); BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF5); BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF13); + + BIND_ENUM_CONSTANT(BLEND_MODE_ADD); + BIND_ENUM_CONSTANT(BLEND_MODE_SUB); + BIND_ENUM_CONSTANT(BLEND_MODE_MIX); } Light2D::Light2D() { - canvas_light = RenderingServer::get_singleton()->canvas_light_create(); enabled = true; editor_only = false; shadow = false; color = Color(1, 1, 1); height = 0; - _scale = 1.0; z_min = -1024; z_max = 1024; layer_min = 0; layer_max = 0; item_mask = 1; item_shadow_mask = 1; - mode = MODE_ADD; - shadow_buffer_size = 2048; energy = 1.0; shadow_color = Color(0, 0, 0, 0); shadow_filter = SHADOW_FILTER_NONE; shadow_smooth = 0; - + blend_mode = BLEND_MODE_ADD; set_notify_transform(true); } Light2D::~Light2D() { - RenderingServer::get_singleton()->free(canvas_light); } + +////////////////////////////// + +#ifdef TOOLS_ENABLED + +Dictionary PointLight2D::_edit_get_state() const { + Dictionary state = Node2D::_edit_get_state(); + state["offset"] = get_texture_offset(); + return state; +} + +void PointLight2D::_edit_set_state(const Dictionary &p_state) { + Node2D::_edit_set_state(p_state); + set_texture_offset(p_state["offset"]); +} + +void PointLight2D::_edit_set_pivot(const Point2 &p_pivot) { + set_position(get_transform().xform(p_pivot)); + set_texture_offset(get_texture_offset() - p_pivot); +} + +Point2 PointLight2D::_edit_get_pivot() const { + return Vector2(); +} + +bool PointLight2D::_edit_use_pivot() const { + return true; +} + +Rect2 PointLight2D::_edit_get_rect() const { + if (texture.is_null()) { + return Rect2(); + } + + Size2 s = texture->get_size() * _scale; + return Rect2(texture_offset - s / 2.0, s); +} + +bool PointLight2D::_edit_use_rect() const { + return !texture.is_null(); +} +#endif + +Rect2 PointLight2D::get_anchorable_rect() const { + if (texture.is_null()) { + return Rect2(); + } + + Size2 s = texture->get_size() * _scale; + return Rect2(texture_offset - s / 2.0, s); +} + +void PointLight2D::set_texture(const Ref<Texture2D> &p_texture) { + texture = p_texture; + if (texture.is_valid()) { + RS::get_singleton()->canvas_light_set_texture(_get_light(), texture->get_rid()); + } else { + RS::get_singleton()->canvas_light_set_texture(_get_light(), RID()); + } + + update_configuration_warning(); +} + +Ref<Texture2D> PointLight2D::get_texture() const { + return texture; +} + +void PointLight2D::set_texture_offset(const Vector2 &p_offset) { + texture_offset = p_offset; + RS::get_singleton()->canvas_light_set_texture_offset(_get_light(), texture_offset); + item_rect_changed(); + _change_notify("offset"); +} + +Vector2 PointLight2D::get_texture_offset() const { + return texture_offset; +} + +String PointLight2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); + + if (!texture.is_valid()) { + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("A texture with the shape of the light must be supplied to the \"Texture\" property."); + } + + return warning; +} + +void PointLight2D::set_texture_scale(float p_scale) { + _scale = p_scale; + // Avoid having 0 scale values, can lead to errors in physics and rendering. + if (_scale == 0) { + _scale = CMP_EPSILON; + } + RS::get_singleton()->canvas_light_set_texture_scale(_get_light(), _scale); + item_rect_changed(); +} + +float PointLight2D::get_texture_scale() const { + return _scale; +} + +void PointLight2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_texture", "texture"), &PointLight2D::set_texture); + ClassDB::bind_method(D_METHOD("get_texture"), &PointLight2D::get_texture); + + ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &PointLight2D::set_texture_offset); + ClassDB::bind_method(D_METHOD("get_texture_offset"), &PointLight2D::get_texture_offset); + + ClassDB::bind_method(D_METHOD("set_texture_scale", "texture_scale"), &PointLight2D::set_texture_scale); + ClassDB::bind_method(D_METHOD("get_texture_scale"), &PointLight2D::get_texture_scale); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1024,1,or_greater"), "set_height", "get_height"); +} + +PointLight2D::PointLight2D() { + RS::get_singleton()->canvas_light_set_mode(_get_light(), RS::CANVAS_LIGHT_MODE_POINT); +} + +////////// + +void DirectionalLight2D::set_max_distance(float p_distance) { + max_distance = p_distance; + RS::get_singleton()->canvas_light_set_directional_distance(_get_light(), max_distance); +} + +float DirectionalLight2D::get_max_distance() const { + return max_distance; +} + +void DirectionalLight2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_max_distance", "pixels"), &DirectionalLight2D::set_max_distance); + ClassDB::bind_method(D_METHOD("get_max_distance"), &DirectionalLight2D::get_max_distance); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,16384.0,1.0,or_greater"), "set_max_distance", "get_max_distance"); +} + +DirectionalLight2D::DirectionalLight2D() { + RS::get_singleton()->canvas_light_set_mode(_get_light(), RS::CANVAS_LIGHT_MODE_DIRECTIONAL); + set_max_distance(max_distance); // Update RenderingServer. +} diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 7134029441..7dfeddc8e5 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -34,17 +34,9 @@ #include "scene/2d/node_2d.h" class Light2D : public Node2D { - GDCLASS(Light2D, Node2D); public: - enum Mode { - MODE_ADD, - MODE_SUB, - MODE_MIX, - MODE_MASK, - }; - enum ShadowFilter { SHADOW_FILTER_NONE, SHADOW_FILTER_PCF5, @@ -52,6 +44,12 @@ public: SHADOW_FILTER_MAX }; + enum BlendMode { + BLEND_MODE_ADD, + BLEND_MODE_SUB, + BLEND_MODE_MIX, + }; + private: RID canvas_light; bool enabled; @@ -60,7 +58,6 @@ private: Color color; Color shadow_color; float height; - float _scale; float energy; int z_min; int z_max; @@ -68,45 +65,26 @@ private: int layer_max; int item_mask; int item_shadow_mask; - int shadow_buffer_size; float shadow_smooth; - Mode mode; Ref<Texture2D> texture; Vector2 texture_offset; ShadowFilter shadow_filter; + BlendMode blend_mode; void _update_light_visibility(); protected: + _FORCE_INLINE_ RID _get_light() const { return canvas_light; } void _notification(int p_what); static void _bind_methods(); public: -#ifdef TOOLS_ENABLED - virtual Dictionary _edit_get_state() const; - virtual void _edit_set_state(const Dictionary &p_state); - - virtual void _edit_set_pivot(const Point2 &p_pivot); - virtual Point2 _edit_get_pivot() const; - virtual bool _edit_use_pivot() const; - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; -#endif - - virtual Rect2 get_anchorable_rect() const; - void set_enabled(bool p_enabled); bool is_enabled() const; void set_editor_only(bool p_editor_only); bool is_editor_only() const; - void set_texture(const Ref<Texture2D> &p_texture); - Ref<Texture2D> get_texture() const; - - void set_texture_offset(const Vector2 &p_offset); - Vector2 get_texture_offset() const; - void set_color(const Color &p_color); Color get_color() const; @@ -116,9 +94,6 @@ public: void set_energy(float p_energy); float get_energy() const; - void set_texture_scale(float p_scale); - float get_texture_scale() const; - void set_z_range_min(int p_min_z); int get_z_range_min() const; @@ -137,15 +112,9 @@ public: void set_item_shadow_cull_mask(int p_mask); int get_item_shadow_cull_mask() const; - void set_mode(Mode p_mode); - Mode get_mode() const; - void set_shadow_enabled(bool p_enabled); bool is_shadow_enabled() const; - void set_shadow_buffer_size(int p_size); - int get_shadow_buffer_size() const; - void set_shadow_filter(ShadowFilter p_filter); ShadowFilter get_shadow_filter() const; @@ -155,13 +124,68 @@ public: void set_shadow_smooth(float p_amount); float get_shadow_smooth() const; - String get_configuration_warning() const; + void set_blend_mode(BlendMode p_mode); + BlendMode get_blend_mode() const; Light2D(); ~Light2D(); }; -VARIANT_ENUM_CAST(Light2D::Mode); VARIANT_ENUM_CAST(Light2D::ShadowFilter); +VARIANT_ENUM_CAST(Light2D::BlendMode); + +class PointLight2D : public Light2D { + GDCLASS(PointLight2D, Light2D); + +private: + float _scale = 1.0; + Ref<Texture2D> texture; + Vector2 texture_offset; + +protected: + static void _bind_methods(); + +public: +#ifdef TOOLS_ENABLED + virtual Dictionary _edit_get_state() const override; + virtual void _edit_set_state(const Dictionary &p_state) override; + + virtual void _edit_set_pivot(const Point2 &p_pivot) override; + virtual Point2 _edit_get_pivot() const override; + virtual bool _edit_use_pivot() const override; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; +#endif + + virtual Rect2 get_anchorable_rect() const override; + + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; + + void set_texture_offset(const Vector2 &p_offset); + Vector2 get_texture_offset() const; + + void set_texture_scale(float p_scale); + float get_texture_scale() const; + + String get_configuration_warning() const override; + + PointLight2D(); +}; + +class DirectionalLight2D : public Light2D { + GDCLASS(DirectionalLight2D, Light2D); + + float max_distance = 10000.0; + +protected: + static void _bind_methods(); + +public: + void set_max_distance(float p_distance); + float get_max_distance() const; + + DirectionalLight2D(); +}; #endif // LIGHT_2D_H diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index bd1a820aec..0531762ed8 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -29,24 +29,25 @@ /*************************************************************************/ #include "light_occluder_2d.h" +#include "core/math/geometry_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #define LINE_GRAB_WIDTH 8 #ifdef TOOLS_ENABLED Rect2 OccluderPolygon2D::_edit_get_rect() const { - if (rect_cache_dirty) { if (closed) { const Vector2 *r = polygon.ptr(); item_rect = Rect2(); for (int i = 0; i < polygon.size(); i++) { Vector2 pos = r[i]; - if (i == 0) + if (i == 0) { item_rect.position = pos; - else + } else { item_rect.expand_to(pos); + } } rect_cache_dirty = false; } else { @@ -67,16 +68,16 @@ Rect2 OccluderPolygon2D::_edit_get_rect() const { } bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - if (closed) { - return Geometry::is_point_in_polygon(p_point, Variant(polygon)); + return Geometry2D::is_point_in_polygon(p_point, Variant(polygon)); } else { const real_t d = LINE_GRAB_WIDTH / 2 + p_tolerance; const Vector2 *points = polygon.ptr(); for (int i = 0; i < polygon.size() - 1; i++) { - Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, &points[i]); - if (p.distance_to(p_point) <= d) + Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, &points[i]); + if (p.distance_to(p_point) <= d) { return true; + } } return false; @@ -85,7 +86,6 @@ bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double #endif void OccluderPolygon2D::set_polygon(const Vector<Vector2> &p_polygon) { - polygon = p_polygon; rect_cache_dirty = true; RS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon, p_polygon, closed); @@ -93,43 +93,38 @@ void OccluderPolygon2D::set_polygon(const Vector<Vector2> &p_polygon) { } Vector<Vector2> OccluderPolygon2D::get_polygon() const { - return polygon; } void OccluderPolygon2D::set_closed(bool p_closed) { - - if (closed == p_closed) + if (closed == p_closed) { return; + } closed = p_closed; - if (polygon.size()) + if (polygon.size()) { RS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon, polygon, closed); + } emit_changed(); } bool OccluderPolygon2D::is_closed() const { - return closed; } void OccluderPolygon2D::set_cull_mode(CullMode p_mode) { - cull = p_mode; RS::get_singleton()->canvas_occluder_polygon_set_cull_mode(occ_polygon, RS::CanvasOccluderPolygonCullMode(p_mode)); } OccluderPolygon2D::CullMode OccluderPolygon2D::get_cull_mode() const { - return cull; } RID OccluderPolygon2D::get_rid() const { - return occ_polygon; } void OccluderPolygon2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_closed", "closed"), &OccluderPolygon2D::set_closed); ClassDB::bind_method(D_METHOD("is_closed"), &OccluderPolygon2D::is_closed); @@ -149,7 +144,6 @@ void OccluderPolygon2D::_bind_methods() { } OccluderPolygon2D::OccluderPolygon2D() { - occ_polygon = RS::get_singleton()->canvas_occluder_polygon_create(); closed = true; cull = CULL_DISABLED; @@ -157,40 +151,31 @@ OccluderPolygon2D::OccluderPolygon2D() { } OccluderPolygon2D::~OccluderPolygon2D() { - RS::get_singleton()->free(occ_polygon); } void LightOccluder2D::_poly_changed() { - #ifdef DEBUG_ENABLED update(); #endif } 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()) { @@ -199,11 +184,9 @@ void LightOccluder2D::_notification(int p_what) { 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); } } @@ -213,74 +196,76 @@ void LightOccluder2D::_notification(int p_what) { } if (p_what == NOTIFICATION_EXIT_CANVAS) { - RS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder, RID()); } } #ifdef TOOLS_ENABLED Rect2 LightOccluder2D::_edit_get_rect() const { - return occluder_polygon.is_valid() ? occluder_polygon->_edit_get_rect() : Rect2(); } bool LightOccluder2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - return occluder_polygon.is_valid() ? occluder_polygon->_edit_is_selected_on_click(p_point, p_tolerance) : false; } #endif void LightOccluder2D::set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polygon) { - #ifdef DEBUG_ENABLED - if (occluder_polygon.is_valid()) + if (occluder_polygon.is_valid()) { occluder_polygon->disconnect("changed", callable_mp(this, &LightOccluder2D::_poly_changed)); + } #endif occluder_polygon = p_polygon; - if (occluder_polygon.is_valid()) + if (occluder_polygon.is_valid()) { RS::get_singleton()->canvas_light_occluder_set_polygon(occluder, occluder_polygon->get_rid()); - else + } else { RS::get_singleton()->canvas_light_occluder_set_polygon(occluder, RID()); + } #ifdef DEBUG_ENABLED - if (occluder_polygon.is_valid()) + if (occluder_polygon.is_valid()) { occluder_polygon->connect("changed", callable_mp(this, &LightOccluder2D::_poly_changed)); + } update(); #endif } Ref<OccluderPolygon2D> LightOccluder2D::get_occluder_polygon() const { - return occluder_polygon; } void LightOccluder2D::set_occluder_light_mask(int p_mask) { - mask = p_mask; RS::get_singleton()->canvas_light_occluder_set_light_mask(occluder, mask); } int LightOccluder2D::get_occluder_light_mask() const { - return mask; } String LightOccluder2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (!occluder_polygon.is_valid()) { - return TTR("An occluder polygon must be set (or drawn) for this occluder to take effect."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("An occluder polygon must be set (or drawn) for this occluder to take effect."); } if (occluder_polygon.is_valid() && occluder_polygon->get_polygon().size() == 0) { - return TTR("The occluder polygon for this occluder is empty. Please draw a polygon."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("The occluder polygon for this occluder is empty. Please draw a polygon."); } - return String(); + return warning; } void LightOccluder2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_occluder_polygon", "polygon"), &LightOccluder2D::set_occluder_polygon); ClassDB::bind_method(D_METHOD("get_occluder_polygon"), &LightOccluder2D::get_occluder_polygon); @@ -292,13 +277,11 @@ void LightOccluder2D::_bind_methods() { } LightOccluder2D::LightOccluder2D() { - occluder = RS::get_singleton()->canvas_light_occluder_create(); mask = 1; set_notify_transform(true); } LightOccluder2D::~LightOccluder2D() { - RS::get_singleton()->free(occluder); } diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index 83702f2875..694097f985 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -34,7 +34,6 @@ #include "scene/2d/node_2d.h" class OccluderPolygon2D : public Resource { - GDCLASS(OccluderPolygon2D, Resource); public: @@ -71,7 +70,7 @@ public: void set_cull_mode(CullMode p_mode); CullMode get_cull_mode() const; - virtual RID get_rid() const; + virtual RID get_rid() const override; OccluderPolygon2D(); ~OccluderPolygon2D(); }; @@ -94,8 +93,8 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; #endif void set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polygon); @@ -104,7 +103,7 @@ public: void set_occluder_light_mask(int p_mask); int get_occluder_light_mask() const; - String get_configuration_warning() const; + String get_configuration_warning() const override; LightOccluder2D(); ~LightOccluder2D(); diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index c45eab70df..e990e9f53e 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -31,6 +31,7 @@ #include "line_2d.h" #include "core/core_string_names.h" +#include "core/math/geometry_2d.h" #include "line_builder.h" // Needed so we can bind functions @@ -43,7 +44,7 @@ Line2D::Line2D() { _begin_cap_mode = LINE_CAP_NONE; _end_cap_mode = LINE_CAP_NONE; _width = 10; - _default_color = Color(0.4, 0.5, 1); + _default_color = Color(1, 1, 1); _texture_mode = LINE_TEXTURE_NONE; _sharp_limit = 2.f; _round_precision = 8; @@ -52,9 +53,9 @@ Line2D::Line2D() { #ifdef TOOLS_ENABLED Rect2 Line2D::_edit_get_rect() const { - - if (_points.size() == 0) + if (_points.size() == 0) { return Rect2(0, 0, 0, 0); + } Vector2 d = Vector2(_width, _width); Rect2 aabb = Rect2(_points[0] - d, 2 * d); for (int i = 1; i < _points.size(); i++) { @@ -69,13 +70,13 @@ bool Line2D::_edit_use_rect() const { } bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - const real_t d = _width / 2 + p_tolerance; const Vector2 *points = _points.ptr(); for (int i = 0; i < _points.size() - 1; i++) { - Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, &points[i]); - if (p.distance_to(p_point) <= d) + Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, &points[i]); + if (p.distance_to(p_point) <= d) { return true; + } } return false; @@ -88,8 +89,9 @@ void Line2D::set_points(const Vector<Vector2> &p_points) { } void Line2D::set_width(float p_width) { - if (p_width < 0.0) + if (p_width < 0.0) { p_width = 0.0; + } _width = p_width; update(); } @@ -168,7 +170,6 @@ Color Line2D::get_default_color() const { } void Line2D::set_gradient(const Ref<Gradient> &p_gradient) { - // Cleanup previous connection if any if (_gradient.is_valid()) { _gradient->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_gradient_changed)); @@ -176,7 +177,7 @@ void Line2D::set_gradient(const Ref<Gradient> &p_gradient) { _gradient = p_gradient; - // Connect to the gradient so the line will update when the ColorRamp is changed + // Connect to the gradient so the line will update when the Gradient is changed if (_gradient.is_valid()) { _gradient->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_gradient_changed)); } @@ -242,8 +243,9 @@ void Line2D::_notification(int p_what) { } void Line2D::set_sharp_limit(float p_limit) { - if (p_limit < 0.f) + if (p_limit < 0.f) { p_limit = 0.f; + } _sharp_limit = p_limit; update(); } @@ -253,8 +255,9 @@ float Line2D::get_sharp_limit() const { } void Line2D::set_round_precision(int p_precision) { - if (p_precision < 1) + if (p_precision < 1) { p_precision = 1; + } _round_precision = p_precision; update(); } @@ -273,8 +276,9 @@ bool Line2D::get_antialiased() const { } void Line2D::_draw() { - if (_points.size() <= 1 || _width == 0.f) + if (_points.size() <= 1 || _width == 0.f) { return; + } // TODO Is this really needed? // Copy points for faster access @@ -350,7 +354,6 @@ void Line2D::_curve_changed() { // static void Line2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_points", "points"), &Line2D::set_points); ClassDB::bind_method(D_METHOD("get_points"), &Line2D::get_points); diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index 51706befdb..43739ee638 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -34,7 +34,6 @@ #include "node_2d.h" class Line2D : public Node2D { - GDCLASS(Line2D, Node2D); public: @@ -57,9 +56,9 @@ public: }; #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; #endif Line2D(); diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp index 6b06f2227a..f1522dbaeb 100644 --- a/scene/2d/line_builder.cpp +++ b/scene/2d/line_builder.cpp @@ -53,8 +53,9 @@ static SegmentIntersectionResult segment_intersection( float ub = (ab.x * (a.y - c.y) - ab.y * (a.x - c.x)) / div; *out_intersection = a + ua * ab; if (ua >= 0.f && ua <= 1.f && - ub >= 0.f && ub <= 1.f) + ub >= 0.f && ub <= 1.f) { return SEGMENT_INTERSECT; + } return SEGMENT_NO_INTERSECT; } @@ -117,7 +118,6 @@ void LineBuilder::clear_output() { } void LineBuilder::build() { - // Need at least 2 points to draw a line if (points.size() < 2) { clear_output(); @@ -158,28 +158,32 @@ void LineBuilder::build() { //Adjust totalDistance. // The line's outer length will be a little higher due to begin and end caps if (begin_cap_mode == Line2D::LINE_CAP_BOX || begin_cap_mode == Line2D::LINE_CAP_ROUND) { - if (retrieve_curve) + if (retrieve_curve) { total_distance += width * curve->interpolate_baked(0.f) * 0.5f; - else + } else { total_distance += width * 0.5f; + } } if (end_cap_mode == Line2D::LINE_CAP_BOX || end_cap_mode == Line2D::LINE_CAP_ROUND) { - if (retrieve_curve) + if (retrieve_curve) { total_distance += width * curve->interpolate_baked(1.f) * 0.5f; - else + } else { total_distance += width * 0.5f; + } } } - if (_interpolate_color) + if (_interpolate_color) { color0 = gradient->get_color(0); - else + } else { colors.push_back(default_color); + } float uvx0 = 0.f; float uvx1 = 0.f; - if (retrieve_curve) + if (retrieve_curve) { width_factor = curve->interpolate_baked(0.f); + } pos_up0 += u0 * hw * width_factor; pos_down0 -= u0 * hw * width_factor; @@ -220,7 +224,6 @@ void LineBuilder::build() { // For each additional segment for (int i = 1; i < len - 1; ++i) { - pos1 = points[i]; Vector2 pos2 = points[i + 1]; @@ -271,10 +274,10 @@ void LineBuilder::build() { pos1 + inner_normal1, pos2 + inner_normal1, &corner_pos_in); - if (intersection_result == SEGMENT_INTERSECT) + if (intersection_result == SEGMENT_INTERSECT) { // Inner parts of the segments intersect corner_pos_out = 2.f * pos1 - corner_pos_in; - else { + } else { // No intersection, segments are either parallel or too sharp corner_pos_in = pos1 + inner_normal0; corner_pos_out = pos1 - inner_normal0; @@ -359,7 +362,6 @@ void LineBuilder::build() { // Add joint geometry if (current_joint_mode != Line2D::LINE_JOINT_SHARP) { - /* ________________ cbegin * / \ * / \ @@ -386,10 +388,11 @@ void LineBuilder::build() { strip_add_arc(pos1, vbegin.angle_to(vend), orientation); } - if (intersection_result != SEGMENT_INTERSECT) + if (intersection_result != SEGMENT_INTERSECT) { // In this case the joint is too corrputed to be re-used, // start again the strip with fallback points strip_begin(pos_up0, pos_down0, color1, uvx1); + } } } // Last (or only) segment @@ -541,7 +544,6 @@ void LineBuilder::strip_add_tri(Vector2 up, Orientation orientation) { } void LineBuilder::strip_add_arc(Vector2 center, float angle_delta, Orientation orientation) { - // Take the two last vertices and extrude an arc made of triangles // that all share one of the initial vertices @@ -551,8 +553,9 @@ void LineBuilder::strip_add_arc(Vector2 center, float angle_delta, Orientation o float angle_step = Math_PI / static_cast<float>(round_precision); float steps = Math::abs(angle_delta) / angle_step; - if (angle_delta < 0.f) + if (angle_delta < 0.f) { angle_step = -angle_step; + } float t = Vector2(1, 0).angle_to(vbegin); float end_angle = t + angle_delta; @@ -570,7 +573,6 @@ void LineBuilder::strip_add_arc(Vector2 center, float angle_delta, Orientation o } void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Color color, Rect2 uv_rect) { - // Make a standalone arc that doesn't use existing vertices, // with undistorted UVs from within a square section @@ -578,8 +580,9 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col float angle_step = Math_PI / static_cast<float>(round_precision); float steps = Math::abs(angle_delta) / angle_step; - if (angle_delta < 0.f) + if (angle_delta < 0.f) { angle_step = -angle_step; + } float t = Vector2(1, 0).angle_to(vbegin); float end_angle = t + angle_delta; @@ -590,10 +593,12 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col // Center vertice int vi = vertices.size(); vertices.push_back(center); - if (_interpolate_color) + if (_interpolate_color) { colors.push_back(color); - if (texture_mode != Line2D::LINE_TEXTURE_NONE) + } + if (texture_mode != Line2D::LINE_TEXTURE_NONE) { uvs.push_back(interpolate(uv_rect, Vector2(0.5f, 0.5f))); + } // Arc vertices for (int ti = 0; ti < steps; ++ti, t += angle_step) { @@ -601,8 +606,9 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col rpos = center + sc * radius; vertices.push_back(rpos); - if (_interpolate_color) + if (_interpolate_color) { colors.push_back(color); + } if (texture_mode != Line2D::LINE_TEXTURE_NONE) { Vector2 tsc = Vector2(Math::cos(tt), Math::sin(tt)); uvs.push_back(interpolate(uv_rect, 0.5f * (tsc + Vector2(1.f, 1.f)))); @@ -614,8 +620,9 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col Vector2 sc = Vector2(Math::cos(end_angle), Math::sin(end_angle)); rpos = center + sc * radius; vertices.push_back(rpos); - if (_interpolate_color) + if (_interpolate_color) { colors.push_back(color); + } if (texture_mode != Line2D::LINE_TEXTURE_NONE) { tt = tt_begin + angle_delta; Vector2 tsc = Vector2(Math::cos(tt), Math::sin(tt)); diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index 9e3dbbd6c1..0e033d9be1 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -31,7 +31,7 @@ #ifndef LINE_BUILDER_H #define LINE_BUILDER_H -#include "core/color.h" +#include "core/math/color.h" #include "core/math/vector2.h" #include "line_2d.h" #include "scene/resources/gradient.h" diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 5e258be700..037e423ce9 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -31,16 +31,14 @@ #include "mesh_instance_2d.h" void MeshInstance2D::_notification(int p_what) { - if (p_what == NOTIFICATION_DRAW) { if (mesh.is_valid()) { - draw_mesh(mesh, texture, normal_map); + draw_mesh(mesh, texture); } } } void MeshInstance2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MeshInstance2D::set_mesh); ClassDB::bind_method(D_METHOD("get_mesh"), &MeshInstance2D::get_mesh); @@ -58,20 +56,18 @@ void MeshInstance2D::_bind_methods() { } void MeshInstance2D::set_mesh(const Ref<Mesh> &p_mesh) { - mesh = p_mesh; update(); } Ref<Mesh> MeshInstance2D::get_mesh() const { - return mesh; } void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { - - if (p_texture == texture) + if (p_texture == texture) { return; + } texture = p_texture; update(); emit_signal("texture_changed"); @@ -79,24 +75,20 @@ void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { } void MeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) { - normal_map = p_texture; update(); } Ref<Texture2D> MeshInstance2D::get_normal_map() const { - return normal_map; } Ref<Texture2D> MeshInstance2D::get_texture() const { - return texture; } #ifdef TOOLS_ENABLED Rect2 MeshInstance2D::_edit_get_rect() const { - if (mesh.is_valid()) { AABB aabb = mesh->get_aabb(); return Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h index 3356f44e91..f10ab17a7c 100644 --- a/scene/2d/mesh_instance_2d.h +++ b/scene/2d/mesh_instance_2d.h @@ -47,7 +47,7 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; + virtual Rect2 _edit_get_rect() const override; #endif void set_mesh(const Ref<Mesh> &p_mesh); diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 6620027020..c258e30eab 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -31,16 +31,14 @@ #include "multimesh_instance_2d.h" void MultiMeshInstance2D::_notification(int p_what) { - if (p_what == NOTIFICATION_DRAW) { if (multimesh.is_valid()) { - draw_multimesh(multimesh, texture, normal_map); + draw_multimesh(multimesh, texture); } } } void MultiMeshInstance2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_multimesh", "multimesh"), &MultiMeshInstance2D::set_multimesh); ClassDB::bind_method(D_METHOD("get_multimesh"), &MultiMeshInstance2D::get_multimesh); @@ -58,20 +56,18 @@ void MultiMeshInstance2D::_bind_methods() { } void MultiMeshInstance2D::set_multimesh(const Ref<MultiMesh> &p_multimesh) { - multimesh = p_multimesh; update(); } Ref<MultiMesh> MultiMeshInstance2D::get_multimesh() const { - return multimesh; } void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { - - if (p_texture == texture) + if (p_texture == texture) { return; + } texture = p_texture; update(); emit_signal("texture_changed"); @@ -79,24 +75,20 @@ void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { } Ref<Texture2D> MultiMeshInstance2D::get_texture() const { - return texture; } void MultiMeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) { - normal_map = p_texture; update(); } Ref<Texture2D> MultiMeshInstance2D::get_normal_map() const { - return normal_map; } #ifdef TOOLS_ENABLED Rect2 MultiMeshInstance2D::_edit_get_rect() const { - if (multimesh.is_valid()) { AABB aabb = multimesh->get_aabb(); return Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h index a843606ebf..aadedac42a 100644 --- a/scene/2d/multimesh_instance_2d.h +++ b/scene/2d/multimesh_instance_2d.h @@ -48,7 +48,7 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; + virtual Rect2 _edit_get_rect() const override; #endif void set_multimesh(const Ref<MultiMesh> &p_multimesh); diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp index ae9fc0f32c..039c6f2e53 100644 --- a/scene/2d/navigation_2d.cpp +++ b/scene/2d/navigation_2d.cpp @@ -54,7 +54,6 @@ void Navigation2D::_notification(int p_what) { NavigationServer2D::get_singleton()->map_set_active(map, true); } break; case NOTIFICATION_EXIT_TREE: { - NavigationServer2D::get_singleton()->map_set_active(map, false); } break; } @@ -83,7 +82,6 @@ RID Navigation2D::get_closest_point_owner(const Vector2 &p_point) const { } Navigation2D::Navigation2D() { - map = NavigationServer2D::get_singleton()->map_create(); set_cell_size(10); // Ten pixels set_edge_connection_margin(100); diff --git a/scene/2d/navigation_2d.h b/scene/2d/navigation_2d.h index 1da13fc78a..6046bddb32 100644 --- a/scene/2d/navigation_2d.h +++ b/scene/2d/navigation_2d.h @@ -35,7 +35,6 @@ #include "scene/2d/node_2d.h" class Navigation2D : public Node2D { - GDCLASS(Navigation2D, Node2D); RID map; diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 32da46e8a8..1c7063d0d3 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -30,12 +30,12 @@ #include "navigation_agent_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" +#include "core/math/geometry_2d.h" #include "scene/2d/navigation_2d.h" #include "servers/navigation_server_2d.h" void NavigationAgent2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent2D::set_target_desired_distance); ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent2D::get_target_desired_distance); @@ -91,7 +91,6 @@ void NavigationAgent2D::_bind_methods() { void NavigationAgent2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { - agent_parent = Object::cast_to<Node2D>(get_parent()); NavigationServer2D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done"); @@ -102,10 +101,11 @@ void NavigationAgent2D::_notification(int p_what) { Node *p = get_parent(); while (p != nullptr) { nav = Object::cast_to<Navigation2D>(p); - if (nav != nullptr) + if (nav != nullptr) { p = nullptr; - else + } else { p = p->get_parent(); + } } set_navigation(nav); @@ -120,7 +120,6 @@ void NavigationAgent2D::_notification(int p_what) { } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (agent_parent) { - NavigationServer2D::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().get_origin()); if (!target_reached) { if (distance_to_target() < target_desired_distance) { @@ -133,15 +132,7 @@ void NavigationAgent2D::_notification(int p_what) { } } -NavigationAgent2D::NavigationAgent2D() : - agent_parent(nullptr), - navigation(nullptr), - agent(RID()), - target_desired_distance(1.0), - path_max_distance(3.0), - velocity_submitted(false), - target_reached(false), - navigation_finished(true) { +NavigationAgent2D::NavigationAgent2D() { agent = NavigationServer2D::get_singleton()->agent_create(); set_neighbor_dist(500.0); set_max_neighbors(10); @@ -156,8 +147,9 @@ NavigationAgent2D::~NavigationAgent2D() { } void NavigationAgent2D::set_navigation(Navigation2D *p_nav) { - if (navigation == p_nav) + if (navigation == p_nav) { return; // Pointless + } navigation = p_nav; NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid()); @@ -279,18 +271,28 @@ void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) { } String NavigationAgent2D::get_configuration_warning() const { + String warning = Node::get_configuration_warning(); + if (!Object::cast_to<Node2D>(get_parent())) { - return TTR("The NavigationAgent2D can be used only under a Node2D node"); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("The NavigationAgent2D can be used only under a Node2D node"); } - return String(); + return warning; } void NavigationAgent2D::update_navigation() { - - if (agent_parent == nullptr) return; - if (navigation == nullptr) return; - if (update_frame_id == Engine::get_singleton()->get_physics_frames()) return; + if (agent_parent == nullptr) { + return; + } + if (navigation == nullptr) { + return; + } + if (update_frame_id == Engine::get_singleton()->get_physics_frames()) { + return; + } update_frame_id = Engine::get_singleton()->get_physics_frames(); @@ -308,7 +310,7 @@ void NavigationAgent2D::update_navigation() { Vector2 segment[2]; segment[0] = navigation_path[nav_path_index - 1]; segment[1] = navigation_path[nav_path_index]; - Vector2 p = Geometry::get_closest_point_to_segment_2d(o, segment); + Vector2 p = Geometry2D::get_closest_point_to_segment(o, segment); if (o.distance_to(p) >= path_max_distance) { // To faraway, reload path reload_path = true; @@ -323,8 +325,9 @@ void NavigationAgent2D::update_navigation() { emit_signal("path_changed"); } - if (navigation_path.size() == 0) + if (navigation_path.size() == 0) { return; + } // Check if we can advance the navigation path if (navigation_finished == false) { diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 26eccfc949..1f2377837b 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -31,7 +31,7 @@ #ifndef NAVIGATION_AGENT_2D_H #define NAVIGATION_AGENT_2D_H -#include "core/vector.h" +#include "core/templates/vector.h" #include "scene/main/node.h" class Node2D; @@ -40,29 +40,29 @@ class Navigation2D; class NavigationAgent2D : public Node { GDCLASS(NavigationAgent2D, Node); - Node2D *agent_parent; - Navigation2D *navigation; + Node2D *agent_parent = nullptr; + Navigation2D *navigation = nullptr; RID agent; - real_t target_desired_distance; + real_t target_desired_distance = 1.0; real_t radius; real_t neighbor_dist; int max_neighbors; real_t time_horizon; real_t max_speed; - real_t path_max_distance; + real_t path_max_distance = 3.0; Vector2 target_location; Vector<Vector2> navigation_path; int nav_path_index; - bool velocity_submitted; + bool velocity_submitted = false; Vector2 prev_safe_velocity; /// The submitted target velocity Vector2 target_velocity; - bool target_reached; - bool navigation_finished; + bool target_reached = false; + bool navigation_finished = true; // No initialized on purpose uint32_t update_frame_id; @@ -141,7 +141,7 @@ public: void set_velocity(Vector2 p_velocity); void _avoidance_done(Vector3 p_new_velocity); - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; private: void update_navigation(); diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index 50d02ca507..252d7cbb96 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -36,7 +36,6 @@ #include "servers/navigation_server_2d.h" void NavigationObstacle2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle2D::set_navigation_node); ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle2D::get_navigation_node); } @@ -44,7 +43,6 @@ void NavigationObstacle2D::_bind_methods() { void NavigationObstacle2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { - update_agent_shape(); // Search the navigation node and set it @@ -53,10 +51,11 @@ void NavigationObstacle2D::_notification(int p_what) { Node *p = get_parent(); while (p != nullptr) { nav = Object::cast_to<Navigation2D>(p); - if (nav != nullptr) + if (nav != nullptr) { p = nullptr; - else + } else { p = p->get_parent(); + } } set_navigation(nav); @@ -78,9 +77,7 @@ void NavigationObstacle2D::_notification(int p_what) { } } -NavigationObstacle2D::NavigationObstacle2D() : - navigation(nullptr), - agent(RID()) { +NavigationObstacle2D::NavigationObstacle2D() { agent = NavigationServer2D::get_singleton()->agent_create(); } @@ -90,8 +87,9 @@ NavigationObstacle2D::~NavigationObstacle2D() { } void NavigationObstacle2D::set_navigation(Navigation2D *p_nav) { - if (navigation == p_nav) + if (navigation == p_nav) { return; // Pointless + } navigation = p_nav; NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid()); @@ -108,11 +106,16 @@ Node *NavigationObstacle2D::get_navigation_node() const { } String NavigationObstacle2D::get_configuration_warning() const { + String warning = Node::get_configuration_warning(); + if (!Object::cast_to<Node2D>(get_parent())) { - return TTR("The NavigationObstacle2D only serves to provide collision avoidance to a Node2D object."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("The NavigationObstacle2D only serves to provide collision avoidance to a Node2D object."); } - return String(); + return warning; } void NavigationObstacle2D::update_agent_shape() { @@ -142,8 +145,9 @@ void NavigationObstacle2D::update_agent_shape() { radius *= MAX(s.x, s.y); } - if (radius == 0.0) + if (radius == 0.0) { radius = 1.0; // Never a 0 radius + } // Initialize the Agent as an object NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0); diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h index 3935fe1bc5..d65f44bc0e 100644 --- a/scene/2d/navigation_obstacle_2d.h +++ b/scene/2d/navigation_obstacle_2d.h @@ -38,7 +38,7 @@ class Navigation2D; class NavigationObstacle2D : public Node { GDCLASS(NavigationObstacle2D, Node); - Navigation2D *navigation; + Navigation2D *navigation = nullptr; RID agent; @@ -62,7 +62,7 @@ public: return agent; } - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; private: void update_agent_shape(); diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index 19484442b1..98817ec03e 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -30,8 +30,9 @@ #include "navigation_region_2d.h" +#include "core/config/engine.h" #include "core/core_string_names.h" -#include "core/engine.h" +#include "core/math/geometry_2d.h" #include "core/os/mutex.h" #include "navigation_2d.h" #include "servers/navigation_server_2d.h" @@ -40,7 +41,6 @@ #ifdef TOOLS_ENABLED Rect2 NavigationPolygon::_edit_get_rect() const { - if (rect_cache_dirty) { item_rect = Rect2(); bool first = true; @@ -48,8 +48,9 @@ Rect2 NavigationPolygon::_edit_get_rect() const { for (int i = 0; i < outlines.size(); i++) { const Vector<Vector2> &outline = outlines[i]; const int outline_size = outline.size(); - if (outline_size < 3) + if (outline_size < 3) { continue; + } const Vector2 *p = outline.ptr(); for (int j = 0; j < outline_size; j++) { if (first) { @@ -67,21 +68,21 @@ Rect2 NavigationPolygon::_edit_get_rect() const { } bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - for (int i = 0; i < outlines.size(); i++) { const Vector<Vector2> &outline = outlines[i]; const int outline_size = outline.size(); - if (outline_size < 3) + if (outline_size < 3) { continue; - if (Geometry::is_point_in_polygon(p_point, Variant(outline))) + } + if (Geometry2D::is_point_in_polygon(p_point, Variant(outline))) { return true; + } } return false; } #endif void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) { - { MutexLock lock(navmesh_generation); navmesh.unref(); @@ -91,12 +92,10 @@ void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) { } Vector<Vector2> NavigationPolygon::get_vertices() const { - return vertices; } void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array) { - { MutexLock lock(navmesh_generation); navmesh.unref(); @@ -108,7 +107,6 @@ void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array } Array NavigationPolygon::_get_polygons() const { - Array ret; ret.resize(polygons.size()); for (int i = 0; i < ret.size(); i++) { @@ -118,8 +116,7 @@ Array NavigationPolygon::_get_polygons() const { return ret; } -void NavigationPolygon::_set_outlines(const TypedArray<Vector<int32_t>> &p_array) { - +void NavigationPolygon::_set_outlines(const TypedArray<Vector<Vector2>> &p_array) { outlines.resize(p_array.size()); for (int i = 0; i < p_array.size(); i++) { outlines.write[i] = p_array[i]; @@ -128,7 +125,6 @@ void NavigationPolygon::_set_outlines(const TypedArray<Vector<int32_t>> &p_array } Array NavigationPolygon::_get_outlines() const { - Array ret; ret.resize(outlines.size()); for (int i = 0; i < ret.size(); i++) { @@ -139,7 +135,6 @@ Array NavigationPolygon::_get_outlines() const { } void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) { - Polygon polygon; polygon.indices = p_polygon; polygons.push_back(polygon); @@ -150,22 +145,20 @@ void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) { } void NavigationPolygon::add_outline_at_index(const Vector<Vector2> &p_outline, int p_index) { - outlines.insert(p_index, p_outline); rect_cache_dirty = true; } int NavigationPolygon::get_polygon_count() const { - return polygons.size(); } -Vector<int> NavigationPolygon::get_polygon(int p_idx) { +Vector<int> NavigationPolygon::get_polygon(int p_idx) { ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>()); return polygons[p_idx].indices; } -void NavigationPolygon::clear_polygons() { +void NavigationPolygon::clear_polygons() { polygons.clear(); { MutexLock lock(navmesh_generation); @@ -200,13 +193,11 @@ Ref<NavigationMesh> NavigationPolygon::get_mesh() { } void NavigationPolygon::add_outline(const Vector<Vector2> &p_outline) { - outlines.push_back(p_outline); rect_cache_dirty = true; } int NavigationPolygon::get_outline_count() const { - return outlines.size(); } @@ -217,7 +208,6 @@ void NavigationPolygon::set_outline(int p_idx, const Vector<Vector2> &p_outline) } void NavigationPolygon::remove_outline(int p_idx) { - ERR_FAIL_INDEX(p_idx, outlines.size()); outlines.remove(p_idx); rect_cache_dirty = true; @@ -229,12 +219,11 @@ Vector<Vector2> NavigationPolygon::get_outline(int p_idx) const { } void NavigationPolygon::clear_outlines() { - outlines.clear(); rect_cache_dirty = true; } -void NavigationPolygon::make_polygons_from_outlines() { +void NavigationPolygon::make_polygons_from_outlines() { { MutexLock lock(navmesh_generation); navmesh.unref(); @@ -244,11 +233,11 @@ void NavigationPolygon::make_polygons_from_outlines() { Vector2 outside_point(-1e10, -1e10); for (int i = 0; i < outlines.size(); i++) { - Vector<Vector2> ol = outlines[i]; int olsize = ol.size(); - if (olsize < 3) + if (olsize < 3) { continue; + } const Vector2 *r = ol.ptr(); for (int j = 0; j < olsize; j++) { outside_point.x = MAX(r[j].x, outside_point.x); @@ -259,29 +248,29 @@ void NavigationPolygon::make_polygons_from_outlines() { outside_point += Vector2(0.7239784, 0.819238); //avoid precision issues for (int i = 0; i < outlines.size(); i++) { - Vector<Vector2> ol = outlines[i]; int olsize = ol.size(); - if (olsize < 3) + if (olsize < 3) { continue; + } const Vector2 *r = ol.ptr(); int interscount = 0; //test if this is an outer outline for (int k = 0; k < outlines.size(); k++) { - - if (i == k) + if (i == k) { continue; //no self intersect + } Vector<Vector2> ol2 = outlines[k]; int olsize2 = ol2.size(); - if (olsize2 < 3) + if (olsize2 < 3) { continue; + } const Vector2 *r2 = ol2.ptr(); for (int l = 0; l < olsize2; l++) { - - if (Geometry::segment_intersects_segment_2d(r[0], outside_point, r2[l], r2[(l + 1) % olsize2], nullptr)) { + if (Geometry2D::segment_intersects_segment(r[0], outside_point, r2[l], r2[(l + 1) % olsize2], nullptr)) { interscount++; } } @@ -295,9 +284,9 @@ void NavigationPolygon::make_polygons_from_outlines() { tp[j] = r[j]; } - if (outer) + if (outer) { tp.SetOrientation(TRIANGULATOR_CCW); - else { + } else { tp.SetOrientation(TRIANGULATOR_CW); tp.SetHole(true); } @@ -316,13 +305,11 @@ void NavigationPolygon::make_polygons_from_outlines() { Map<Vector2, int> points; for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) { - TriangulatorPoly &tp = I->get(); struct Polygon p; for (int64_t i = 0; i < tp.GetNumPoints(); i++) { - Map<Vector2, int>::Element *E = points.find(tp[i]); if (!E) { E = points.insert(tp[i], vertices.size()); @@ -338,7 +325,6 @@ void NavigationPolygon::make_polygons_from_outlines() { } void NavigationPolygon::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationPolygon::set_vertices); ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationPolygon::get_vertices); @@ -367,68 +353,52 @@ void NavigationPolygon::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_outlines", "_get_outlines"); } -NavigationPolygon::NavigationPolygon() : - rect_cache_dirty(true) { -} - -NavigationPolygon::~NavigationPolygon() { -} - void NavigationRegion2D::set_enabled(bool p_enabled) { - - if (enabled == p_enabled) + if (enabled == p_enabled) { return; + } enabled = p_enabled; - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } if (!enabled) { - NavigationServer2D::get_singleton()->region_set_map(region, RID()); } else { - if (navigation) { - NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid()); } } - if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) + if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) { update(); + } } bool NavigationRegion2D::is_enabled() const { - return enabled; } ///////////////////////////// #ifdef TOOLS_ENABLED Rect2 NavigationRegion2D::_edit_get_rect() const { - return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2(); } bool NavigationRegion2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - return navpoly.is_valid() ? navpoly->_edit_is_selected_on_click(p_point, p_tolerance) : false; } #endif void NavigationRegion2D::_notification(int p_what) { - switch (p_what) { case NOTIFICATION_ENTER_TREE: { - Node2D *c = this; while (c) { - navigation = Object::cast_to<Navigation2D>(c); if (navigation) { - if (enabled) { - NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid()); } break; @@ -439,26 +409,22 @@ void NavigationRegion2D::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform()); } break; case NOTIFICATION_EXIT_TREE: { - if (navigation) { - NavigationServer2D::get_singleton()->region_set_map(region, RID()); } navigation = nullptr; } 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(); int vsize = verts.size(); - if (vsize < 3) + if (vsize < 3) { return; + } Color color; if (enabled) { @@ -484,10 +450,8 @@ void NavigationRegion2D::_notification(int p_what) { Vector<int> polygon = navpoly->get_polygon(i); for (int j = 2; j < polygon.size(); j++) { - int kofs[3] = { 0, j - 1, j }; for (int k = 0; k < 3; k++) { - int idx = polygon[kofs[k]]; ERR_FAIL_INDEX(idx, vsize); indices.push_back(idx); @@ -501,7 +465,6 @@ void NavigationRegion2D::_notification(int p_what) { } void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) { - if (p_navpoly == navpoly) { return; } @@ -523,39 +486,43 @@ void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_ } Ref<NavigationPolygon> NavigationRegion2D::get_navigation_polygon() const { - return navpoly; } void NavigationRegion2D::_navpoly_changed() { - - if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) + if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) { update(); + } } String NavigationRegion2D::get_configuration_warning() const { - - if (!is_visible_in_tree() || !is_inside_tree()) + if (!is_visible_in_tree() || !is_inside_tree()) { return String(); + } + + String warning = Node2D::get_configuration_warning(); if (!navpoly.is_valid()) { - return TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon."); } const Node2D *c = this; while (c) { - if (Object::cast_to<Navigation2D>(c)) { - return String(); + return warning; } c = Object::cast_to<Node2D>(c->get_parent()); } - - return TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data."); + if (!warning.empty()) { + warning += "\n\n"; + } + return warning + TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data."); } void NavigationRegion2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navpoly"), &NavigationRegion2D::set_navigation_polygon); ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationRegion2D::get_navigation_polygon); @@ -569,12 +536,8 @@ void NavigationRegion2D::_bind_methods() { } NavigationRegion2D::NavigationRegion2D() { - - enabled = true; set_notify_transform(true); region = NavigationServer2D::get_singleton()->region_create(); - - navigation = nullptr; } NavigationRegion2D::~NavigationRegion2D() { diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index cbfe4299fb..ba92d27a95 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -35,7 +35,6 @@ #include "scene/resources/navigation_mesh.h" class NavigationPolygon : public Resource { - GDCLASS(NavigationPolygon, Resource); Vector<Vector2> vertices; @@ -46,7 +45,7 @@ class NavigationPolygon : public Resource { Vector<Vector<Vector2>> outlines; mutable Rect2 item_rect; - mutable bool rect_cache_dirty; + mutable bool rect_cache_dirty = true; Mutex navmesh_generation; // Navigation mesh @@ -58,7 +57,7 @@ protected: void _set_polygons(const TypedArray<Vector<int32_t>> &p_array); Array _get_polygons() const; - void _set_outlines(const TypedArray<Vector<int32_t>> &p_array); + void _set_outlines(const TypedArray<Vector<Vector2>> &p_array); Array _get_outlines() const; public: @@ -88,19 +87,18 @@ public: Ref<NavigationMesh> get_mesh(); - NavigationPolygon(); - ~NavigationPolygon(); + NavigationPolygon() {} + ~NavigationPolygon() {} }; class Navigation2D; class NavigationRegion2D : public Node2D { - GDCLASS(NavigationRegion2D, Node2D); - bool enabled; + bool enabled = true; RID region; - Navigation2D *navigation; + Navigation2D *navigation = nullptr; Ref<NavigationPolygon> navpoly; void _navpoly_changed(); @@ -111,8 +109,8 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; #endif void set_enabled(bool p_enabled); @@ -121,7 +119,7 @@ public: void set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly); Ref<NavigationPolygon> get_navigation_polygon() const; - String get_configuration_warning() const; + String get_configuration_warning() const override; NavigationRegion2D(); ~NavigationRegion2D(); diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index ac8a77b6cb..42c2585487 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -30,32 +30,34 @@ #include "node_2d.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "scene/gui/control.h" #include "scene/main/window.h" #include "servers/rendering_server.h" #ifdef TOOLS_ENABLED Dictionary Node2D::_edit_get_state() const { - Dictionary state; state["position"] = get_position(); state["rotation"] = get_rotation(); state["scale"] = get_scale(); + state["skew"] = get_skew(); return state; } void Node2D::_edit_set_state(const Dictionary &p_state) { - pos = p_state["position"]; angle = p_state["rotation"]; _scale = p_state["scale"]; + skew = p_state["skew"]; _update_transform(); _change_notify("rotation"); _change_notify("rotation_degrees"); _change_notify("scale"); + _change_notify("skew"); + _change_notify("skew_degrees"); _change_notify("position"); } @@ -96,22 +98,26 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { Rect2 r = _edit_get_rect(); Vector2 zero_offset; - if (r.size.x != 0) + if (r.size.x != 0) { zero_offset.x = -r.position.x / r.size.x; - if (r.size.y != 0) + } + if (r.size.y != 0) { zero_offset.y = -r.position.y / r.size.y; + } Size2 new_scale(1, 1); - if (r.size.x != 0) + if (r.size.x != 0) { new_scale.x = p_edit_rect.size.x / r.size.x; - if (r.size.y != 0) + } + if (r.size.y != 0) { new_scale.y = p_edit_rect.size.y / r.size.y; + } Point2 new_pos = p_edit_rect.position + p_edit_rect.size * zero_offset; Transform2D postxf; - postxf.set_rotation_and_scale(angle, _scale); + postxf.set_rotation_scale_and_skew(angle, _scale, skew); new_pos = postxf.xform(new_pos); pos += new_pos; @@ -124,140 +130,161 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { #endif void Node2D::_update_xform_values() { - pos = _mat.elements[2]; angle = _mat.get_rotation(); _scale = _mat.get_scale(); + skew = _mat.get_skew(); _xform_dirty = false; } void Node2D::_update_transform() { - - _mat.set_rotation_and_scale(angle, _scale); + _mat.set_rotation_scale_and_skew(angle, _scale, skew); _mat.elements[2] = pos; RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat); - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } _notify_transform(); } void Node2D::set_position(const Point2 &p_pos) { - - if (_xform_dirty) + if (_xform_dirty) { ((Node2D *)this)->_update_xform_values(); + } pos = p_pos; _update_transform(); _change_notify("position"); } void Node2D::set_rotation(float p_radians) { - - if (_xform_dirty) + if (_xform_dirty) { ((Node2D *)this)->_update_xform_values(); + } angle = p_radians; _update_transform(); _change_notify("rotation"); _change_notify("rotation_degrees"); } -void Node2D::set_rotation_degrees(float p_degrees) { +void Node2D::set_skew(float p_radians) { + if (_xform_dirty) { + ((Node2D *)this)->_update_xform_values(); + } + skew = p_radians; + _update_transform(); + _change_notify("skew"); + _change_notify("skew_degrees"); +} +void Node2D::set_rotation_degrees(float p_degrees) { set_rotation(Math::deg2rad(p_degrees)); } -void Node2D::set_scale(const Size2 &p_scale) { +void Node2D::set_skew_degrees(float p_degrees) { + set_skew(Math::deg2rad(p_degrees)); +} - if (_xform_dirty) +void Node2D::set_scale(const Size2 &p_scale) { + if (_xform_dirty) { ((Node2D *)this)->_update_xform_values(); + } _scale = p_scale; // Avoid having 0 scale values, can lead to errors in physics and rendering. - if (_scale.x == 0) + if (_scale.x == 0) { _scale.x = CMP_EPSILON; - if (_scale.y == 0) + } + if (_scale.y == 0) { _scale.y = CMP_EPSILON; + } _update_transform(); _change_notify("scale"); } Point2 Node2D::get_position() const { - - if (_xform_dirty) + if (_xform_dirty) { ((Node2D *)this)->_update_xform_values(); + } return pos; } float Node2D::get_rotation() const { - if (_xform_dirty) + if (_xform_dirty) { ((Node2D *)this)->_update_xform_values(); + } return angle; } -float Node2D::get_rotation_degrees() const { +float Node2D::get_skew() const { + if (_xform_dirty) { + ((Node2D *)this)->_update_xform_values(); + } + return skew; +} + +float Node2D::get_rotation_degrees() const { return Math::rad2deg(get_rotation()); } +float Node2D::get_skew_degrees() const { + return Math::rad2deg(get_skew()); +} + Size2 Node2D::get_scale() const { - if (_xform_dirty) + if (_xform_dirty) { ((Node2D *)this)->_update_xform_values(); + } return _scale; } Transform2D Node2D::get_transform() const { - return _mat; } void Node2D::rotate(float p_radians) { - set_rotation(get_rotation() + p_radians); } void Node2D::translate(const Vector2 &p_amount) { - set_position(get_position() + p_amount); } void Node2D::global_translate(const Vector2 &p_amount) { - set_global_position(get_global_position() + p_amount); } void Node2D::apply_scale(const Size2 &p_amount) { - set_scale(get_scale() * p_amount); } void Node2D::move_x(float p_delta, bool p_scaled) { - Transform2D t = get_transform(); Vector2 m = t[0]; - if (!p_scaled) + if (!p_scaled) { m.normalize(); + } set_position(t[2] + m * p_delta); } void Node2D::move_y(float p_delta, bool p_scaled) { - Transform2D t = get_transform(); Vector2 m = t[1]; - if (!p_scaled) + if (!p_scaled) { m.normalize(); + } set_position(t[2] + m * p_delta); } Point2 Node2D::get_global_position() const { - return get_global_transform().get_origin(); } void Node2D::set_global_position(const Point2 &p_pos) { - Transform2D inv; CanvasItem *pi = get_parent_item(); if (pi) { @@ -269,12 +296,10 @@ void Node2D::set_global_position(const Point2 &p_pos) { } float Node2D::get_global_rotation() const { - return get_global_transform().get_rotation(); } void Node2D::set_global_rotation(float p_radians) { - CanvasItem *pi = get_parent_item(); if (pi) { const float parent_global_rot = pi->get_global_transform().get_rotation(); @@ -285,22 +310,18 @@ void Node2D::set_global_rotation(float p_radians) { } float Node2D::get_global_rotation_degrees() const { - return Math::rad2deg(get_global_rotation()); } void Node2D::set_global_rotation_degrees(float p_degrees) { - set_global_rotation(Math::deg2rad(p_degrees)); } Size2 Node2D::get_global_scale() const { - return get_global_transform().get_scale(); } void Node2D::set_global_scale(const Size2 &p_scale) { - CanvasItem *pi = get_parent_item(); if (pi) { const Size2 parent_global_scale = pi->get_global_transform().get_scale(); @@ -311,29 +332,28 @@ void Node2D::set_global_scale(const Size2 &p_scale) { } void Node2D::set_transform(const Transform2D &p_transform) { - _mat = p_transform; _xform_dirty = true; RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat); - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } _notify_transform(); } void Node2D::set_global_transform(const Transform2D &p_transform) { - CanvasItem *pi = get_parent_item(); - if (pi) + if (pi) { set_transform(pi->get_global_transform().affine_inverse() * p_transform); - else + } else { set_transform(p_transform); + } } void Node2D::set_z_index(int p_z) { - ERR_FAIL_COND(p_z < RS::CANVAS_ITEM_Z_MIN); ERR_FAIL_COND(p_z > RS::CANVAS_ITEM_Z_MAX); z_index = p_z; @@ -342,67 +362,65 @@ void Node2D::set_z_index(int p_z) { } void Node2D::set_z_as_relative(bool p_enabled) { - - if (z_relative == p_enabled) + if (z_relative == p_enabled) { return; + } z_relative = p_enabled; RS::get_singleton()->canvas_item_set_z_as_relative_to_parent(get_canvas_item(), p_enabled); } bool Node2D::is_z_relative() const { - return z_relative; } int Node2D::get_z_index() const { - return z_index; } Transform2D Node2D::get_relative_transform_to_parent(const Node *p_parent) const { - - if (p_parent == this) + if (p_parent == this) { return Transform2D(); + } Node2D *parent_2d = Object::cast_to<Node2D>(get_parent()); ERR_FAIL_COND_V(!parent_2d, Transform2D()); - if (p_parent == parent_2d) + if (p_parent == parent_2d) { return get_transform(); - else + } else { return parent_2d->get_relative_transform_to_parent(p_parent) * get_transform(); + } } void Node2D::look_at(const Vector2 &p_pos) { - rotate(get_angle_to(p_pos)); } float Node2D::get_angle_to(const Vector2 &p_pos) const { - return (to_local(p_pos) * get_scale()).angle(); } Point2 Node2D::to_local(Point2 p_global) const { - return get_global_transform().affine_inverse().xform(p_global); } Point2 Node2D::to_global(Point2 p_local) const { - return get_global_transform().xform(p_local); } void Node2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_position", "position"), &Node2D::set_position); ClassDB::bind_method(D_METHOD("set_rotation", "radians"), &Node2D::set_rotation); ClassDB::bind_method(D_METHOD("set_rotation_degrees", "degrees"), &Node2D::set_rotation_degrees); + ClassDB::bind_method(D_METHOD("set_skew", "radians"), &Node2D::set_skew); + ClassDB::bind_method(D_METHOD("set_skew_degrees", "degrees"), &Node2D::set_skew_degrees); ClassDB::bind_method(D_METHOD("set_scale", "scale"), &Node2D::set_scale); ClassDB::bind_method(D_METHOD("get_position"), &Node2D::get_position); ClassDB::bind_method(D_METHOD("get_rotation"), &Node2D::get_rotation); ClassDB::bind_method(D_METHOD("get_rotation_degrees"), &Node2D::get_rotation_degrees); + ClassDB::bind_method(D_METHOD("get_skew"), &Node2D::get_skew); + ClassDB::bind_method(D_METHOD("get_skew_degrees"), &Node2D::get_skew_degrees); ClassDB::bind_method(D_METHOD("get_scale"), &Node2D::get_scale); ClassDB::bind_method(D_METHOD("rotate", "radians"), &Node2D::rotate); @@ -443,6 +461,8 @@ void Node2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_skew", "get_skew"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew_degrees", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1", PROPERTY_USAGE_EDITOR), "set_skew_degrees", "get_skew_degrees"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", 0), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position", PROPERTY_HINT_NONE, "", 0), "set_global_position", "get_global_position"); @@ -457,9 +477,9 @@ void Node2D::_bind_methods() { } Node2D::Node2D() { - angle = 0; _scale = Vector2(1, 1); + skew = 0; _xform_dirty = false; z_index = 0; z_relative = true; diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index abed05ed0c..e20f746447 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -34,12 +34,12 @@ #include "scene/main/canvas_item.h" class Node2D : public CanvasItem { - GDCLASS(Node2D, CanvasItem); Point2 pos; float angle; Size2 _scale; + float skew; int z_index; bool z_relative; @@ -56,25 +56,27 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Dictionary _edit_get_state() const; - virtual void _edit_set_state(const Dictionary &p_state); + virtual Dictionary _edit_get_state() const override; + virtual void _edit_set_state(const Dictionary &p_state) override; - virtual void _edit_set_position(const Point2 &p_position); - virtual Point2 _edit_get_position() const; + virtual void _edit_set_position(const Point2 &p_position) override; + virtual Point2 _edit_get_position() const override; - virtual void _edit_set_scale(const Size2 &p_scale); - virtual Size2 _edit_get_scale() const; + virtual void _edit_set_scale(const Size2 &p_scale) override; + virtual Size2 _edit_get_scale() const override; - virtual void _edit_set_rotation(float p_rotation); - virtual float _edit_get_rotation() const; - virtual bool _edit_use_rotation() const; + virtual void _edit_set_rotation(float p_rotation) override; + virtual float _edit_get_rotation() const override; + virtual bool _edit_use_rotation() const override; - virtual void _edit_set_rect(const Rect2 &p_edit_rect); + virtual void _edit_set_rect(const Rect2 &p_edit_rect) override; #endif void set_position(const Point2 &p_pos); void set_rotation(float p_radians); void set_rotation_degrees(float p_degrees); + void set_skew(float p_radians); + void set_skew_degrees(float p_radians); void set_scale(const Size2 &p_scale); void rotate(float p_radians); @@ -86,7 +88,9 @@ public: Point2 get_position() const; float get_rotation() const; + float get_skew() const; float get_rotation_degrees() const; + float get_skew_degrees() const; Size2 get_scale() const; Point2 get_global_position() const; @@ -115,7 +119,7 @@ public: Transform2D get_relative_transform_to_parent(const Node *p_parent) const; - Transform2D get_transform() const; + Transform2D get_transform() const override; Node2D(); }; diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp index 0d5f74a265..8c9432f2fa 100644 --- a/scene/2d/parallax_background.cpp +++ b/scene/2d/parallax_background.cpp @@ -32,24 +32,19 @@ #include "parallax_layer.h" void ParallaxBackground::_notification(int p_what) { - switch (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; } } void ParallaxBackground::_camera_moved(const Transform2D &p_transform, const Point2 &p_screen_offset) { - screen_offset = p_screen_offset; set_scroll_scale(p_transform.get_scale().dot(Vector2(0.5, 0.5))); @@ -57,26 +52,23 @@ void ParallaxBackground::_camera_moved(const Transform2D &p_transform, const Poi } void ParallaxBackground::set_scroll_scale(float p_scale) { - scale = p_scale; } float ParallaxBackground::get_scroll_scale() const { - return scale; } void ParallaxBackground::set_scroll_offset(const Point2 &p_ofs) { - offset = p_ofs; _update_scroll(); } void ParallaxBackground::_update_scroll() { - - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } Vector2 ofs = base_offset + offset * base_scale; @@ -84,103 +76,91 @@ void ParallaxBackground::_update_scroll() { ofs = -ofs; if (limit_begin.x < limit_end.x) { - - if (ofs.x < limit_begin.x) + if (ofs.x < limit_begin.x) { ofs.x = limit_begin.x; - else if (ofs.x + vps.x > limit_end.x) + } else if (ofs.x + vps.x > limit_end.x) { ofs.x = limit_end.x - vps.x; + } } if (limit_begin.y < limit_end.y) { - - if (ofs.y < limit_begin.y) + if (ofs.y < limit_begin.y) { ofs.y = limit_begin.y; - else if (ofs.y + vps.y > limit_end.y) + } else if (ofs.y + vps.y > limit_end.y) { ofs.y = limit_end.y - vps.y; + } } ofs = -ofs; final_offset = ofs; for (int i = 0; i < get_child_count(); i++) { - ParallaxLayer *l = Object::cast_to<ParallaxLayer>(get_child(i)); - if (!l) + if (!l) { continue; + } - if (ignore_camera_zoom) - l->set_base_offset_and_scale(ofs, 1.0, screen_offset); - else + if (ignore_camera_zoom) { + l->set_base_offset_and_scale((ofs + screen_offset * (scale - 1)) / scale, 1.0, screen_offset); + } else { l->set_base_offset_and_scale(ofs, scale, screen_offset); + } } } Point2 ParallaxBackground::get_scroll_offset() const { - return offset; } void ParallaxBackground::set_scroll_base_offset(const Point2 &p_ofs) { - base_offset = p_ofs; _update_scroll(); } Point2 ParallaxBackground::get_scroll_base_offset() const { - return base_offset; } void ParallaxBackground::set_scroll_base_scale(const Point2 &p_ofs) { - base_scale = p_ofs; _update_scroll(); } Point2 ParallaxBackground::get_scroll_base_scale() const { - return base_scale; } void ParallaxBackground::set_limit_begin(const Point2 &p_ofs) { - limit_begin = p_ofs; _update_scroll(); } Point2 ParallaxBackground::get_limit_begin() const { - return limit_begin; } void ParallaxBackground::set_limit_end(const Point2 &p_ofs) { - limit_end = p_ofs; _update_scroll(); } Point2 ParallaxBackground::get_limit_end() const { - return limit_end; } void ParallaxBackground::set_ignore_camera_zoom(bool ignore) { - ignore_camera_zoom = ignore; } bool ParallaxBackground::is_ignore_camera_zoom() { - return ignore_camera_zoom; } Vector2 ParallaxBackground::get_final_offset() const { - return final_offset; } void ParallaxBackground::_bind_methods() { - ClassDB::bind_method(D_METHOD("_camera_moved"), &ParallaxBackground::_camera_moved); ClassDB::bind_method(D_METHOD("set_scroll_offset", "ofs"), &ParallaxBackground::set_scroll_offset); ClassDB::bind_method(D_METHOD("get_scroll_offset"), &ParallaxBackground::get_scroll_offset); @@ -205,7 +185,6 @@ void ParallaxBackground::_bind_methods() { } ParallaxBackground::ParallaxBackground() { - scale = 1.0; set_layer(-100); //behind all by default diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h index 25ccd910d1..1667880ddb 100644 --- a/scene/2d/parallax_background.h +++ b/scene/2d/parallax_background.h @@ -36,7 +36,6 @@ #include "scene/main/canvas_layer.h" class ParallaxBackground : public CanvasLayer { - GDCLASS(ParallaxBackground, CanvasLayer); Point2 offset; diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 181f0f158c..01aa5838b4 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -30,11 +30,10 @@ #include "parallax_layer.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "parallax_background.h" void ParallaxLayer::set_motion_scale(const Size2 &p_scale) { - motion_scale = p_scale; ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent()); @@ -46,12 +45,10 @@ void ParallaxLayer::set_motion_scale(const Size2 &p_scale) { } Size2 ParallaxLayer::get_motion_scale() const { - return motion_scale; } void ParallaxLayer::set_motion_offset(const Size2 &p_offset) { - motion_offset = p_offset; ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent()); @@ -63,18 +60,16 @@ void ParallaxLayer::set_motion_offset(const Size2 &p_offset) { } Size2 ParallaxLayer::get_motion_offset() const { - return motion_offset; } void ParallaxLayer::_update_mirroring() { - - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent()); if (pb) { - RID c = pb->get_canvas(); RID ci = get_canvas_item(); Point2 mirrorScale = mirroring * get_scale(); @@ -83,33 +78,29 @@ void ParallaxLayer::_update_mirroring() { } void ParallaxLayer::set_mirroring(const Size2 &p_mirroring) { - mirroring = p_mirroring; - if (mirroring.x < 0) + if (mirroring.x < 0) { mirroring.x = 0; - if (mirroring.y < 0) + } + if (mirroring.y < 0) { mirroring.y = 0; + } _update_mirroring(); } Size2 ParallaxLayer::get_mirroring() const { - return mirroring; } void ParallaxLayer::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - orig_offset = get_position(); orig_scale = get_scale(); _update_mirroring(); } break; case NOTIFICATION_EXIT_TREE: { - set_position(orig_offset); set_scale(orig_scale); } break; @@ -119,10 +110,12 @@ void ParallaxLayer::_notification(int p_what) { void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_scale, const Point2 &p_screen_offset) { screen_offset = p_screen_offset; - if (!is_inside_tree()) + if (!is_inside_tree()) { return; - if (Engine::get_singleton()->is_editor_hint()) + } + if (Engine::get_singleton()->is_editor_hint()) { return; + } Point2 new_ofs = (screen_offset + (p_offset - screen_offset) * motion_scale) + motion_offset * p_scale + orig_offset * p_scale; @@ -143,16 +136,19 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_sc } String ParallaxLayer::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (!Object::cast_to<ParallaxBackground>(get_parent())) { - return TTR("ParallaxLayer node only works when set as child of a ParallaxBackground node."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("ParallaxLayer node only works when set as child of a ParallaxBackground node."); } - return String(); + return warning; } void ParallaxLayer::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_motion_scale", "scale"), &ParallaxLayer::set_motion_scale); ClassDB::bind_method(D_METHOD("get_motion_scale"), &ParallaxLayer::get_motion_scale); ClassDB::bind_method(D_METHOD("set_motion_offset", "offset"), &ParallaxLayer::set_motion_offset); diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h index ba59184649..788df19a75 100644 --- a/scene/2d/parallax_layer.h +++ b/scene/2d/parallax_layer.h @@ -34,7 +34,6 @@ #include "scene/2d/node_2d.h" class ParallaxLayer : public Node2D { - GDCLASS(ParallaxLayer, Node2D); Point2 orig_offset; @@ -62,7 +61,7 @@ public: void set_base_offset_and_scale(const Point2 &p_offset, float p_scale, const Point2 &p_screen_offset); - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; ParallaxLayer(); }; diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index ed8481db4a..d305f2805e 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -30,7 +30,8 @@ #include "path_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" +#include "core/math/geometry_2d.h" #include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED @@ -39,16 +40,14 @@ #ifdef TOOLS_ENABLED Rect2 Path2D::_edit_get_rect() const { - - if (!curve.is_valid() || curve->get_point_count() == 0) + if (!curve.is_valid() || curve->get_point_count() == 0) { return Rect2(0, 0, 0, 0); + } Rect2 aabb = Rect2(curve->get_point_position(0), Vector2(0, 0)); for (int i = 0; i < curve->get_point_count(); i++) { - for (int j = 0; j <= 8; j++) { - real_t frac = j / 8.0; Vector2 p = curve->interpolate(i, frac); aabb.expand_to(p); @@ -63,7 +62,6 @@ bool Path2D::_edit_use_rect() const { } bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - if (curve.is_null()) { return false; } @@ -76,9 +74,10 @@ bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc real_t frac = j / 8.0; s[1] = curve->interpolate(i, frac); - Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, s); - if (p.distance_to(p_point) <= p_tolerance) + Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, s); + if (p.distance_to(p_point) <= p_tolerance) { return true; + } s[0] = s[1]; } @@ -89,7 +88,6 @@ 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!! @@ -102,14 +100,12 @@ void Path2D::_notification(int p_what) { #else const float line_width = 2; #endif - const Color color = Color(1.0, 1.0, 1.0, 1.0); + const Color color = Color(0.5, 0.6, 1.0, 0.7); for (int i = 0; i < curve->get_point_count(); i++) { - Vector2 prev_p = curve->get_point_position(i); for (int j = 1; j <= 8; j++) { - real_t frac = j / 8.0; Vector2 p = curve->interpolate(i, frac); draw_line(prev_p, p, color, line_width); @@ -132,7 +128,6 @@ void Path2D::_curve_changed() { } void Path2D::set_curve(const Ref<Curve2D> &p_curve) { - if (curve.is_valid()) { curve->disconnect("changed", callable_mp(this, &Path2D::_curve_changed)); } @@ -147,34 +142,27 @@ void Path2D::set_curve(const Ref<Curve2D> &p_curve) { } Ref<Curve2D> Path2D::get_curve() const { - return curve; } void Path2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path2D::set_curve); ClassDB::bind_method(D_METHOD("get_curve"), &Path2D::get_curve); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve2D"), "set_curve", "get_curve"); -} - -Path2D::Path2D() { - - set_curve(Ref<Curve2D>(memnew(Curve2D))); //create one by default - set_self_modulate(Color(0.5, 0.6, 1.0, 0.7)); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_curve", "get_curve"); } ///////////////////////////////////////////////////////////////////////////////// void PathFollow2D::_update_transform() { - - if (!path) + if (!path) { return; + } Ref<Curve2D> c = path->get_curve(); - if (!c.is_valid()) + if (!c.is_valid()) { return; + } float path_length = c->get_baked_length(); if (path_length == 0) { @@ -220,7 +208,6 @@ void PathFollow2D::_update_transform() { set_rotation(tangent_to_curve.angle()); } else { - pos.x += h_offset; pos.y += v_offset; } @@ -229,11 +216,8 @@ void PathFollow2D::_update_transform() { } void PathFollow2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - path = Object::cast_to<Path2D>(get_parent()); if (path) { _update_transform(); @@ -241,48 +225,48 @@ void PathFollow2D::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - path = nullptr; } break; } } void PathFollow2D::set_cubic_interpolation(bool p_enable) { - cubic = p_enable; } bool PathFollow2D::get_cubic_interpolation() const { - return cubic; } void PathFollow2D::_validate_property(PropertyInfo &property) const { - if (property.name == "offset") { - float max = 10000; - if (path && path->get_curve().is_valid()) + if (path && path->get_curve().is_valid()) { max = path->get_curve()->get_baked_length(); + } property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater"; } } String PathFollow2D::get_configuration_warning() const { - - if (!is_visible_in_tree() || !is_inside_tree()) + if (!is_visible_in_tree() || !is_inside_tree()) { return String(); + } + + String warning = Node2D::get_configuration_warning(); if (!Object::cast_to<Path2D>(get_parent())) { - return TTR("PathFollow2D only works when set as a child of a Path2D node."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("PathFollow2D only works when set as a child of a Path2D node."); } - return String(); + return warning; } void PathFollow2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_offset", "offset"), &PathFollow2D::set_offset); ClassDB::bind_method(D_METHOD("get_offset"), &PathFollow2D::get_offset); @@ -318,7 +302,6 @@ void PathFollow2D::_bind_methods() { } void PathFollow2D::set_offset(float p_offset) { - offset = p_offset; if (path) { if (path->get_curve().is_valid()) { @@ -341,81 +324,71 @@ void PathFollow2D::set_offset(float p_offset) { } void PathFollow2D::set_h_offset(float p_h_offset) { - h_offset = p_h_offset; - if (path) + if (path) { _update_transform(); + } } float PathFollow2D::get_h_offset() const { - return h_offset; } void PathFollow2D::set_v_offset(float p_v_offset) { - v_offset = p_v_offset; - if (path) + if (path) { _update_transform(); + } } float PathFollow2D::get_v_offset() const { - return v_offset; } float PathFollow2D::get_offset() const { - return offset; } void PathFollow2D::set_unit_offset(float p_unit_offset) { - - if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) + if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { set_offset(p_unit_offset * path->get_curve()->get_baked_length()); + } } float PathFollow2D::get_unit_offset() const { - - if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) + if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { return get_offset() / path->get_curve()->get_baked_length(); - else + } else { return 0; + } } void PathFollow2D::set_lookahead(float p_lookahead) { - lookahead = p_lookahead; } float PathFollow2D::get_lookahead() const { - return lookahead; } void PathFollow2D::set_rotate(bool p_rotate) { - rotate = p_rotate; _update_transform(); } bool PathFollow2D::is_rotating() const { - return rotate; } void PathFollow2D::set_loop(bool p_loop) { - loop = p_loop; } bool PathFollow2D::has_loop() const { - return loop; } PathFollow2D::PathFollow2D() { - offset = 0; h_offset = 0; v_offset = 0; diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 35cf8211f4..7fea75cd7c 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -35,7 +35,6 @@ #include "scene/resources/curve.h" class Path2D : public Node2D { - GDCLASS(Path2D, Node2D); Ref<Curve2D> curve; @@ -48,19 +47,18 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; #endif void set_curve(const Ref<Curve2D> &p_curve); Ref<Curve2D> get_curve() const; - Path2D(); + Path2D() {} }; class PathFollow2D : public Node2D { - GDCLASS(PathFollow2D, Node2D); public: @@ -77,7 +75,7 @@ private: void _update_transform(); protected: - virtual void _validate_property(PropertyInfo &property) const; + virtual void _validate_property(PropertyInfo &property) const override; void _notification(int p_what); static void _bind_methods(); @@ -107,7 +105,7 @@ public: void set_cubic_interpolation(bool p_enable); bool get_cubic_interpolation() const; - String get_configuration_warning() const; + String get_configuration_warning() const override; PathFollow2D(); }; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index de15f0efc2..300799ff9d 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -30,31 +30,18 @@ #include "physics_body_2d.h" +#include "core/config/engine.h" #include "core/core_string_names.h" -#include "core/engine.h" -#include "core/list.h" #include "core/math/math_funcs.h" -#include "core/method_bind_ext.gen.inc" -#include "core/object.h" -#include "core/rid.h" +#include "core/object/class_db.h" +#include "core/templates/list.h" +#include "core/templates/rid.h" #include "scene/scene_string_names.h" void PhysicsBody2D::_notification(int p_what) { } -void PhysicsBody2D::_set_layers(uint32_t p_mask) { - - set_collision_layer(p_mask); - set_collision_mask(p_mask); -} - -uint32_t PhysicsBody2D::_get_layers() const { - - return get_collision_layer(); -} - void PhysicsBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &PhysicsBody2D::set_collision_layer); ClassDB::bind_method(D_METHOD("get_collision_layer"), &PhysicsBody2D::get_collision_layer); ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &PhysicsBody2D::set_collision_mask); @@ -66,13 +53,9 @@ void PhysicsBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &PhysicsBody2D::set_collision_layer_bit); ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &PhysicsBody2D::get_collision_layer_bit); - ClassDB::bind_method(D_METHOD("_set_layers", "mask"), &PhysicsBody2D::_set_layers); - ClassDB::bind_method(D_METHOD("_get_layers"), &PhysicsBody2D::_get_layers); - 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); ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody2D::remove_collision_exception_with); - ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_2D_PHYSICS, "", 0), "_set_layers", "_get_layers"); //for backwards compat ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); @@ -80,59 +63,53 @@ void PhysicsBody2D::_bind_methods() { } void PhysicsBody2D::set_collision_layer(uint32_t p_layer) { - collision_layer = p_layer; PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), p_layer); } uint32_t PhysicsBody2D::get_collision_layer() const { - return collision_layer; } void PhysicsBody2D::set_collision_mask(uint32_t p_mask) { - collision_mask = p_mask; PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), p_mask); } uint32_t PhysicsBody2D::get_collision_mask() const { - return collision_mask; } void PhysicsBody2D::set_collision_mask_bit(int p_bit, bool p_value) { - uint32_t mask = get_collision_mask(); - if (p_value) + if (p_value) { mask |= 1 << p_bit; - else + } else { mask &= ~(1 << p_bit); + } set_collision_mask(mask); } -bool PhysicsBody2D::get_collision_mask_bit(int p_bit) const { +bool PhysicsBody2D::get_collision_mask_bit(int p_bit) const { return get_collision_mask() & (1 << p_bit); } void PhysicsBody2D::set_collision_layer_bit(int p_bit, bool p_value) { - uint32_t collision_layer = get_collision_layer(); - if (p_value) + if (p_value) { collision_layer |= 1 << p_bit; - else + } else { collision_layer &= ~(1 << p_bit); + } set_collision_layer(collision_layer); } bool PhysicsBody2D::get_collision_layer_bit(int p_bit) const { - return get_collision_layer() & (1 << p_bit); } PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) : CollisionObject2D(PhysicsServer2D::get_singleton()->body_create(), false) { - PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), p_mode); collision_layer = 1; collision_mask = 1; @@ -154,7 +131,6 @@ TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() { } void PhysicsBody2D::add_collision_exception_with(Node *p_node) { - ERR_FAIL_NULL(p_node); PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(p_node); ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody2D type."); @@ -162,7 +138,6 @@ void PhysicsBody2D::add_collision_exception_with(Node *p_node) { } void PhysicsBody2D::remove_collision_exception_with(Node *p_node) { - ERR_FAIL_NULL(p_node); PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(p_node); ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody2D type."); @@ -170,23 +145,20 @@ void PhysicsBody2D::remove_collision_exception_with(Node *p_node) { } void StaticBody2D::set_constant_linear_velocity(const Vector2 &p_vel) { - constant_linear_velocity = p_vel; PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); } void StaticBody2D::set_constant_angular_velocity(real_t p_vel) { - constant_angular_velocity = p_vel; PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); } Vector2 StaticBody2D::get_constant_linear_velocity() const { - return constant_linear_velocity; } -real_t StaticBody2D::get_constant_angular_velocity() const { +real_t StaticBody2D::get_constant_angular_velocity() const { return constant_angular_velocity; } @@ -210,7 +182,6 @@ Ref<PhysicsMaterial> StaticBody2D::get_physics_material_override() const { } void StaticBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody2D::set_constant_linear_velocity); ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "vel"), &StaticBody2D::set_constant_angular_velocity); ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody2D::get_constant_linear_velocity); @@ -226,7 +197,6 @@ void StaticBody2D::_bind_methods() { StaticBody2D::StaticBody2D() : PhysicsBody2D(PhysicsServer2D::BODY_MODE_STATIC) { - constant_angular_velocity = 0; } @@ -244,7 +214,6 @@ void StaticBody2D::_reload_physics_characteristics() { } void RigidBody2D::_body_enter_tree(ObjectID p_id) { - Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -260,7 +229,6 @@ void RigidBody2D::_body_enter_tree(ObjectID p_id) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); } @@ -268,7 +236,6 @@ void RigidBody2D::_body_enter_tree(ObjectID p_id) { } void RigidBody2D::_body_exit_tree(ObjectID p_id) { - Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -283,7 +250,6 @@ void RigidBody2D::_body_exit_tree(ObjectID p_id) { emit_signal(SceneStringNames::get_singleton()->body_exited, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); } @@ -291,7 +257,6 @@ void RigidBody2D::_body_exit_tree(ObjectID p_id) { } void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape) { - bool body_in = p_status == 1; ObjectID objid = p_instance; @@ -305,7 +270,6 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap if (body_in) { if (!E) { - E = contact_monitor->body_map.insert(objid, BodyState()); //E->get().rc=0; E->get().in_scene = node && node->is_inside_tree(); @@ -320,29 +284,30 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap //E->get().rc++; } - if (node) + if (node) { E->get().shapes.insert(ShapePair(p_body_shape, p_local_shape)); + } if (E->get().in_scene) { emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_local_shape); } } else { - //E->get().rc--; - if (node) + if (node) { E->get().shapes.erase(ShapePair(p_body_shape, p_local_shape)); + } bool in_scene = E->get().in_scene; if (E->get().shapes.empty()) { - if (node) { node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree)); - if (in_scene) + if (in_scene) { emit_signal(SceneStringNames::get_singleton()->body_exited, node); + } } contact_monitor->body_map.erase(E); @@ -354,22 +319,20 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap } struct _RigidBody2DInOut { - ObjectID id; int shape; int local_shape; }; bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { - PhysicsServer2D::MotionResult *r = nullptr; - if (p_result.is_valid()) + if (p_result.is_valid()) { r = p_result->get_result_ptr(); + } return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), get_global_transform(), p_motion, p_infinite_inertia, p_margin, r); } void RigidBody2D::_direct_state_changed(Object *p_state) { - #ifdef DEBUG_ENABLED state = Object::cast_to<PhysicsDirectBodyState2D>(p_state); #else @@ -377,28 +340,27 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { #endif set_block_transform_notify(true); // don't want notify (would feedback loop) - if (mode != MODE_KINEMATIC) + if (mode != MODE_KINEMATIC) { set_global_transform(state->get_transform()); + } linear_velocity = state->get_linear_velocity(); angular_velocity = state->get_angular_velocity(); if (sleeping != state->is_sleeping()) { sleeping = state->is_sleeping(); emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); } - if (get_script_instance()) + if (get_script_instance()) { get_script_instance()->call("_integrate_forces", state); + } set_block_transform_notify(false); // want it back if (contact_monitor) { - contact_monitor->locked = true; //untag all int rc = 0; for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - E->get().shapes[i].tagged = false; rc++; } @@ -412,7 +374,6 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { //put the ones to add for (int i = 0; i < state->get_contact_count(); i++) { - ObjectID obj = state->get_contact_collider_id(i); int local_shape = state->get_contact_local_shape(i); int shape = state->get_contact_collider_shape(i); @@ -431,7 +392,6 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { ShapePair sp(shape, local_shape); int idx = E->get().shapes.find(sp); if (idx == -1) { - toadd[toadd_count].local_shape = local_shape; toadd[toadd_count].id = obj; toadd[toadd_count].shape = shape; @@ -445,11 +405,8 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { //put the ones to remove for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - if (!E->get().shapes[i].tagged) { - toremove[toremove_count].body_id = E->key(); toremove[toremove_count].pair = E->get().shapes[i]; toremove_count++; @@ -460,14 +417,12 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { //process remotions for (int i = 0; i < toremove_count; i++) { - _body_inout(0, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape); } //process aditions for (int i = 0; i < toadd_count; i++) { - _body_inout(1, toadd[i].id, toadd[i].shape, toadd[i].local_shape); } @@ -478,21 +433,16 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { } void RigidBody2D::set_mode(Mode p_mode) { - mode = p_mode; switch (p_mode) { - case MODE_RIGID: { - PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_RIGID); } break; case MODE_STATIC: { - PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_STATIC); } break; case MODE_KINEMATIC: { - PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_KINEMATIC); } break; @@ -504,41 +454,35 @@ void RigidBody2D::set_mode(Mode p_mode) { } RigidBody2D::Mode RigidBody2D::get_mode() const { - return mode; } void RigidBody2D::set_mass(real_t p_mass) { - ERR_FAIL_COND(p_mass <= 0); mass = p_mass; _change_notify("mass"); _change_notify("weight"); PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_MASS, mass); } -real_t RigidBody2D::get_mass() const { +real_t RigidBody2D::get_mass() const { return mass; } void RigidBody2D::set_inertia(real_t p_inertia) { - ERR_FAIL_COND(p_inertia < 0); PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_INERTIA, p_inertia); } real_t RigidBody2D::get_inertia() const { - return PhysicsServer2D::get_singleton()->body_get_param(get_rid(), PhysicsServer2D::BODY_PARAM_INERTIA); } void RigidBody2D::set_weight(real_t p_weight) { - set_mass(p_weight / (real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10)); } real_t RigidBody2D::get_weight() const { - return mass * (real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10); } @@ -562,39 +506,35 @@ Ref<PhysicsMaterial> RigidBody2D::get_physics_material_override() const { } void RigidBody2D::set_gravity_scale(real_t p_gravity_scale) { - gravity_scale = p_gravity_scale; PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_GRAVITY_SCALE, gravity_scale); } -real_t RigidBody2D::get_gravity_scale() const { +real_t RigidBody2D::get_gravity_scale() const { return gravity_scale; } void RigidBody2D::set_linear_damp(real_t p_linear_damp) { - ERR_FAIL_COND(p_linear_damp < -1); linear_damp = p_linear_damp; PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_LINEAR_DAMP, linear_damp); } -real_t RigidBody2D::get_linear_damp() const { +real_t RigidBody2D::get_linear_damp() const { return linear_damp; } void RigidBody2D::set_angular_damp(real_t p_angular_damp) { - ERR_FAIL_COND(p_angular_damp < -1); angular_damp = p_angular_damp; PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP, angular_damp); } -real_t RigidBody2D::get_angular_damp() const { +real_t RigidBody2D::get_angular_damp() const { return angular_damp; } void RigidBody2D::set_axis_velocity(const Vector2 &p_axis) { - Vector2 v = state ? state->get_linear_velocity() : linear_velocity; Vector2 axis = p_axis.normalized(); v -= axis * axis.dot(v); @@ -608,77 +548,68 @@ void RigidBody2D::set_axis_velocity(const Vector2 &p_axis) { } void RigidBody2D::set_linear_velocity(const Vector2 &p_velocity) { - linear_velocity = p_velocity; - if (state) + if (state) { state->set_linear_velocity(linear_velocity); - else { - + } else { PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, linear_velocity); } } Vector2 RigidBody2D::get_linear_velocity() const { - return linear_velocity; } void RigidBody2D::set_angular_velocity(real_t p_velocity) { - angular_velocity = p_velocity; - if (state) + if (state) { state->set_angular_velocity(angular_velocity); - else + } else { PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, angular_velocity); + } } -real_t RigidBody2D::get_angular_velocity() const { +real_t RigidBody2D::get_angular_velocity() const { return angular_velocity; } void RigidBody2D::set_use_custom_integrator(bool p_enable) { - - if (custom_integrator == p_enable) + if (custom_integrator == p_enable) { return; + } custom_integrator = p_enable; PhysicsServer2D::get_singleton()->body_set_omit_force_integration(get_rid(), p_enable); } -bool RigidBody2D::is_using_custom_integrator() { +bool RigidBody2D::is_using_custom_integrator() { return custom_integrator; } void RigidBody2D::set_sleeping(bool p_sleeping) { - sleeping = p_sleeping; PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_SLEEPING, sleeping); } void RigidBody2D::set_can_sleep(bool p_active) { - can_sleep = p_active; PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_CAN_SLEEP, p_active); } bool RigidBody2D::is_able_to_sleep() const { - return can_sleep; } bool RigidBody2D::is_sleeping() const { - return sleeping; } void RigidBody2D::set_max_contacts_reported(int p_amount) { - max_contacts_reported = p_amount; PhysicsServer2D::get_singleton()->body_set_max_contacts_reported(get_rid(), p_amount); } int RigidBody2D::get_max_contacts_reported() const { - return max_contacts_reported; } @@ -686,9 +617,8 @@ void RigidBody2D::apply_central_impulse(const Vector2 &p_impulse) { PhysicsServer2D::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse); } -void RigidBody2D::apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse) { - - PhysicsServer2D::get_singleton()->body_apply_impulse(get_rid(), p_offset, p_impulse); +void RigidBody2D::apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position) { + PhysicsServer2D::get_singleton()->body_apply_impulse(get_rid(), p_impulse, p_position); } void RigidBody2D::apply_torque_impulse(float p_torque) { @@ -696,22 +626,18 @@ void RigidBody2D::apply_torque_impulse(float p_torque) { } void RigidBody2D::set_applied_force(const Vector2 &p_force) { - PhysicsServer2D::get_singleton()->body_set_applied_force(get_rid(), p_force); }; Vector2 RigidBody2D::get_applied_force() const { - return PhysicsServer2D::get_singleton()->body_get_applied_force(get_rid()); }; void RigidBody2D::set_applied_torque(const float p_torque) { - PhysicsServer2D::get_singleton()->body_set_applied_torque(get_rid(), p_torque); }; float RigidBody2D::get_applied_torque() const { - return PhysicsServer2D::get_singleton()->body_get_applied_torque(get_rid()); }; @@ -719,9 +645,8 @@ void RigidBody2D::add_central_force(const Vector2 &p_force) { PhysicsServer2D::get_singleton()->body_add_central_force(get_rid(), p_force); } -void RigidBody2D::add_force(const Vector2 &p_offset, const Vector2 &p_force) { - - PhysicsServer2D::get_singleton()->body_add_force(get_rid(), p_offset, p_force); +void RigidBody2D::add_force(const Vector2 &p_force, const Vector2 &p_position) { + PhysicsServer2D::get_singleton()->body_add_force(get_rid(), p_force, p_position); } void RigidBody2D::add_torque(const float p_torque) { @@ -729,18 +654,15 @@ void RigidBody2D::add_torque(const float p_torque) { } void RigidBody2D::set_continuous_collision_detection_mode(CCDMode p_mode) { - ccd_mode = p_mode; PhysicsServer2D::get_singleton()->body_set_continuous_collision_detection_mode(get_rid(), PhysicsServer2D::CCDMode(p_mode)); } RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() const { - return ccd_mode; } TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const { - ERR_FAIL_COND_V(!contact_monitor, Array()); TypedArray<Node2D> ret; @@ -759,16 +681,14 @@ TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const { } void RigidBody2D::set_contact_monitor(bool p_enabled) { - - if (p_enabled == is_contact_monitor_enabled()) + if (p_enabled == is_contact_monitor_enabled()) { return; + } if (!p_enabled) { - ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead."); for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - //clean up mess Object *obj = ObjectDB::get_instance(E->key()); Node *node = Object::cast_to<Node>(obj); @@ -782,19 +702,16 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) { memdelete(contact_monitor); contact_monitor = nullptr; } else { - contact_monitor = memnew(ContactMonitor); contact_monitor->locked = false; } } bool RigidBody2D::is_contact_monitor_enabled() const { - return contact_monitor != nullptr; } void RigidBody2D::_notification(int p_what) { - #ifdef TOOLS_ENABLED if (p_what == NOTIFICATION_ENTER_TREE) { if (Engine::get_singleton()->is_editor_hint()) { @@ -812,13 +729,12 @@ void RigidBody2D::_notification(int p_what) { } String RigidBody2D::get_configuration_warning() const { - Transform2D t = get_transform(); String warning = CollisionObject2D::get_configuration_warning(); if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.elements[0].length() - 1.0) > 0.05 || ABS(t.elements[1].length() - 1.0) > 0.05)) { - if (warning != String()) { + if (!warning.empty()) { warning += "\n\n"; } warning += TTR("Size changes to RigidBody2D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead."); @@ -828,7 +744,6 @@ String RigidBody2D::get_configuration_warning() const { } void RigidBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_mode", "mode"), &RigidBody2D::set_mode); ClassDB::bind_method(D_METHOD("get_mode"), &RigidBody2D::get_mode); @@ -872,8 +787,8 @@ void RigidBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_continuous_collision_detection_mode"), &RigidBody2D::get_continuous_collision_detection_mode); ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidBody2D::set_axis_velocity); - ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidBody2D::apply_central_impulse); - ClassDB::bind_method(D_METHOD("apply_impulse", "offset", "impulse"), &RigidBody2D::apply_impulse); + ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidBody2D::apply_central_impulse, Vector2()); + ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &RigidBody2D::apply_impulse, Vector2()); ClassDB::bind_method(D_METHOD("apply_torque_impulse", "torque"), &RigidBody2D::apply_torque_impulse); ClassDB::bind_method(D_METHOD("set_applied_force", "force"), &RigidBody2D::set_applied_force); @@ -883,7 +798,7 @@ void RigidBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_applied_torque"), &RigidBody2D::get_applied_torque); ClassDB::bind_method(D_METHOD("add_central_force", "force"), &RigidBody2D::add_central_force); - ClassDB::bind_method(D_METHOD("add_force", "offset", "force"), &RigidBody2D::add_force); + ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &RigidBody2D::add_force, Vector2()); ClassDB::bind_method(D_METHOD("add_torque", "torque"), &RigidBody2D::add_torque); ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidBody2D::set_sleeping); @@ -940,7 +855,6 @@ void RigidBody2D::_bind_methods() { RigidBody2D::RigidBody2D() : PhysicsBody2D(PhysicsServer2D::BODY_MODE_RIGID) { - mode = MODE_RIGID; mass = 1; @@ -964,9 +878,9 @@ RigidBody2D::RigidBody2D() : } RigidBody2D::~RigidBody2D() { - - if (contact_monitor) + if (contact_monitor) { memdelete(contact_monitor); + } } void RigidBody2D::_reload_physics_characteristics() { @@ -982,7 +896,6 @@ void RigidBody2D::_reload_physics_characteristics() { ////////////////////////// Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) { - Collision col; if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) { @@ -1000,7 +913,6 @@ Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p } bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) { - PhysicsServer2D::SeparationResult sep_res[8]; //max 8 rays Transform2D gt = get_global_transform(); @@ -1037,7 +949,6 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision } bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { - if (sync_to_physics) { ERR_PRINT("Functions move_and_slide and move_and_collide do not work together with 'sync to physics' option. Please read the documentation."); } @@ -1070,9 +981,9 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_ #define FLOOR_ANGLE_THRESHOLD 0.01 Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { - Vector2 body_velocity = p_linear_velocity; Vector2 body_velocity_normal = body_velocity.normalized(); + Vector2 up_direction = p_up_direction.normalized(); Vector2 current_floor_velocity = floor_velocity; if (on_floor && on_floor_body.is_valid()) { @@ -1095,7 +1006,6 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const floor_velocity = Vector2(); while (p_max_slides) { - Collision collision; bool found_collision = false; @@ -1120,11 +1030,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const colliders.push_back(collision); motion = collision.remainder; - if (p_up_direction == Vector2()) { + if (up_direction == Vector2()) { //all is a wall on_wall = true; } else { - if (Math::acos(collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor + if (Math::acos(collision.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor on_floor = true; floor_normal = collision.normal; @@ -1132,14 +1042,14 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const floor_velocity = collision.collider_vel; if (p_stop_on_slope) { - if ((body_velocity_normal + p_up_direction).length() < 0.01 && collision.travel.length() < 1) { + if ((body_velocity_normal + up_direction).length() < 0.01 && collision.travel.length() < 1) { Transform2D gt = get_global_transform(); - gt.elements[2] -= collision.travel.slide(p_up_direction); + gt.elements[2] -= collision.travel.slide(up_direction); set_global_transform(gt); return Vector2(); } } - } else if (Math::acos(collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling + } else if (Math::acos(collision.normal.dot(-up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling on_ceiling = true; } else { on_wall = true; @@ -1151,8 +1061,9 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const } } - if (!found_collision || motion == Vector2()) + if (!found_collision || motion == Vector2()) { break; + } --p_max_slides; } @@ -1161,10 +1072,10 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const } Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { - + Vector2 up_direction = p_up_direction.normalized(); bool was_on_floor = on_floor; - Vector2 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); + Vector2 ret = move_and_slide(p_linear_velocity, up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); if (!was_on_floor || p_snap == Vector2()) { return ret; } @@ -1174,8 +1085,8 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { bool apply = true; - if (p_up_direction != Vector2()) { - if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) { + if (up_direction != Vector2()) { + if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { on_floor = true; floor_normal = col.normal; on_floor_body = col.collider_rid; @@ -1183,7 +1094,7 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci if (p_stop_on_slope) { // move and collide may stray the object a bit because of pre un-stucking, // so only ensure that motion happens on floor direction in this case. - col.travel = p_up_direction * p_up_direction.dot(col.travel); + col.travel = up_direction * up_direction.dot(col.travel); } } else { @@ -1201,47 +1112,40 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci } bool KinematicBody2D::is_on_floor() const { - return on_floor; } -bool KinematicBody2D::is_on_wall() const { +bool KinematicBody2D::is_on_wall() const { return on_wall; } -bool KinematicBody2D::is_on_ceiling() const { +bool KinematicBody2D::is_on_ceiling() const { return on_ceiling; } Vector2 KinematicBody2D::get_floor_normal() const { - return floor_normal; } Vector2 KinematicBody2D::get_floor_velocity() const { - return floor_velocity; } bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia) { - ERR_FAIL_COND_V(!is_inside_tree(), false); return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, margin); } void KinematicBody2D::set_safe_margin(float p_margin) { - margin = p_margin; } float KinematicBody2D::get_safe_margin() const { - return margin; } int KinematicBody2D::get_slide_count() const { - return colliders.size(); } @@ -1251,7 +1155,6 @@ KinematicBody2D::Collision KinematicBody2D::get_slide_collision(int p_bounce) co } Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) { - ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision2D>()); if (p_bounce >= slide_colliders.size()) { slide_colliders.resize(p_bounce + 1); @@ -1267,14 +1170,14 @@ Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) { } void KinematicBody2D::set_sync_to_physics(bool p_enable) { - if (sync_to_physics == p_enable) { return; } sync_to_physics = p_enable; - if (Engine::get_singleton()->is_editor_hint()) + if (Engine::get_singleton()->is_editor_hint()) { return; + } if (p_enable) { PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); @@ -1292,9 +1195,9 @@ bool KinematicBody2D::is_sync_to_physics_enabled() const { } void KinematicBody2D::_direct_state_changed(Object *p_state) { - - if (!sync_to_physics) + if (!sync_to_physics) { return; + } PhysicsDirectBodyState2D *state = Object::cast_to<PhysicsDirectBodyState2D>(p_state); @@ -1327,8 +1230,8 @@ void KinematicBody2D::_notification(int p_what) { set_notify_local_transform(true); } } -void KinematicBody2D::_bind_methods() { +void KinematicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); @@ -1358,7 +1261,6 @@ void KinematicBody2D::_bind_methods() { KinematicBody2D::KinematicBody2D() : PhysicsBody2D(PhysicsServer2D::BODY_MODE_KINEMATIC) { - margin = 0.08; on_floor = false; @@ -1366,6 +1268,7 @@ KinematicBody2D::KinematicBody2D() : on_wall = false; sync_to_physics = false; } + KinematicBody2D::~KinematicBody2D() { if (motion_cache.is_valid()) { motion_cache->owner = nullptr; @@ -1381,38 +1284,42 @@ KinematicBody2D::~KinematicBody2D() { //////////////////////// Vector2 KinematicCollision2D::get_position() const { - return collision.collision; } + Vector2 KinematicCollision2D::get_normal() const { return collision.normal; } + Vector2 KinematicCollision2D::get_travel() const { return collision.travel; } + Vector2 KinematicCollision2D::get_remainder() const { return collision.remainder; } + Object *KinematicCollision2D::get_local_shape() const { - if (!owner) return nullptr; + if (!owner) { + return nullptr; + } uint32_t ownerid = owner->shape_find_owner(collision.local_shape); return owner->shape_owner_get_owner(ownerid); } Object *KinematicCollision2D::get_collider() const { - if (collision.collider.is_valid()) { return ObjectDB::get_instance(collision.collider); } return nullptr; } -ObjectID KinematicCollision2D::get_collider_id() const { +ObjectID KinematicCollision2D::get_collider_id() const { return collision.collider; } -Object *KinematicCollision2D::get_collider_shape() const { +Object *KinematicCollision2D::get_collider_shape() const { Object *collider = get_collider(); if (collider) { CollisionObject2D *obj2d = Object::cast_to<CollisionObject2D>(collider); @@ -1424,21 +1331,20 @@ Object *KinematicCollision2D::get_collider_shape() const { return nullptr; } -int KinematicCollision2D::get_collider_shape_index() const { +int KinematicCollision2D::get_collider_shape_index() const { return collision.collider_shape; } -Vector2 KinematicCollision2D::get_collider_velocity() const { +Vector2 KinematicCollision2D::get_collider_velocity() const { return collision.collider_vel; } -Variant KinematicCollision2D::get_collider_metadata() const { +Variant KinematicCollision2D::get_collider_metadata() const { return Variant(); } void KinematicCollision2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision2D::get_position); ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision2D::get_normal); ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision2D::get_travel); @@ -1465,7 +1371,6 @@ void KinematicCollision2D::_bind_methods() { } KinematicCollision2D::KinematicCollision2D() { - collision.collider_shape = 0; collision.local_shape = 0; owner = nullptr; diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 75f4f778bf..1db2d23bb8 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -31,7 +31,7 @@ #ifndef PHYSICS_BODY_2D_H #define PHYSICS_BODY_2D_H -#include "core/vset.h" +#include "core/templates/vset.h" #include "scene/2d/collision_object_2d.h" #include "scene/resources/physics_material.h" #include "servers/physics_server_2d.h" @@ -39,15 +39,11 @@ class KinematicCollision2D; class PhysicsBody2D : public CollisionObject2D { - GDCLASS(PhysicsBody2D, CollisionObject2D); uint32_t collision_layer; uint32_t collision_mask; - void _set_layers(uint32_t p_mask); - uint32_t _get_layers() const; - protected: void _notification(int p_what); PhysicsBody2D(PhysicsServer2D::BodyMode p_mode); @@ -75,7 +71,6 @@ public: }; class StaticBody2D : public PhysicsBody2D { - GDCLASS(StaticBody2D, PhysicsBody2D); Vector2 constant_linear_velocity; @@ -104,7 +99,6 @@ private: }; class RigidBody2D : public PhysicsBody2D { - GDCLASS(RigidBody2D, PhysicsBody2D); public: @@ -143,13 +137,13 @@ private: CCDMode ccd_mode; struct ShapePair { - int body_shape; int local_shape; bool tagged; bool operator<(const ShapePair &p_sp) const { - if (body_shape == p_sp.body_shape) + if (body_shape == p_sp.body_shape) { return local_shape < p_sp.local_shape; + } return body_shape < p_sp.body_shape; } @@ -161,19 +155,16 @@ private: } }; struct RigidBody2D_RemoveAction { - ObjectID body_id; ShapePair pair; }; struct BodyState { - //int rc; bool in_scene; VSet<ShapePair> shapes; }; struct ContactMonitor { - bool locked; Map<ObjectID, BodyState> body_map; }; @@ -243,7 +234,7 @@ public: CCDMode get_continuous_collision_detection_mode() const; void apply_central_impulse(const Vector2 &p_impulse); - void apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse); + void apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2()); void apply_torque_impulse(float p_torque); void set_applied_force(const Vector2 &p_force); @@ -253,12 +244,12 @@ public: float get_applied_torque() const; void add_central_force(const Vector2 &p_force); - void add_force(const Vector2 &p_offset, const Vector2 &p_force); + void add_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()); void add_torque(float p_torque); TypedArray<Node2D> get_colliding_bodies() const; //function for script - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; RigidBody2D(); ~RigidBody2D(); @@ -271,7 +262,6 @@ VARIANT_ENUM_CAST(RigidBody2D::Mode); VARIANT_ENUM_CAST(RigidBody2D::CCDMode); class KinematicBody2D : public PhysicsBody2D { - GDCLASS(KinematicBody2D, PhysicsBody2D); public: @@ -344,7 +334,6 @@ public: }; class KinematicCollision2D : public Reference { - GDCLASS(KinematicCollision2D, Reference); KinematicBody2D *owner; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 84c1828b47..26340bb861 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -30,7 +30,7 @@ #include "polygon_2d.h" -#include "core/math/geometry.h" +#include "core/math/geometry_2d.h" #include "skeleton_2d.h" #ifdef TOOLS_ENABLED @@ -65,10 +65,11 @@ Rect2 Polygon2D::_edit_get_rect() const { item_rect = Rect2(); for (int i = 0; i < l; i++) { Vector2 pos = r[i] + offset; - if (i == 0) + if (i == 0) { item_rect.position = pos; - else + } else { item_rect.expand_to(pos); + } } rect_cache_dirty = false; } @@ -81,12 +82,11 @@ bool Polygon2D::_edit_use_rect() const { } bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - Vector<Vector2> polygon2d = Variant(polygon); if (internal_vertices > 0) { polygon2d.resize(polygon2d.size() - internal_vertices); } - return Geometry::is_point_in_polygon(p_point - get_offset(), polygon2d); + return Geometry2D::is_point_in_polygon(p_point - get_offset(), polygon2d); } #endif @@ -95,13 +95,11 @@ void Polygon2D::_skeleton_bone_setup_changed() { } void Polygon2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_DRAW: { - - if (polygon.size() < 3) + if (polygon.size() < 3) { return; + } Skeleton2D *skeleton_node = nullptr; if (has_node(skeleton)) { @@ -147,7 +145,6 @@ void Polygon2D::_notification(int p_what) { points.resize(len); { - const Vector2 *polyr = polygon.ptr(); for (int i = 0; i < len; i++) { points.write[i] = polyr[i] + offset; @@ -155,17 +152,17 @@ void Polygon2D::_notification(int p_what) { } if (invert) { - Rect2 bounds; int highest_idx = -1; float highest_y = -1e20; float sum = 0; for (int i = 0; i < len; i++) { - if (i == 0) + if (i == 0) { bounds.position = points[i]; - else + } else { bounds.expand_to(points[i]); + } if (points[i].y > highest_y) { highest_idx = i; highest_y = points[i].y; @@ -195,12 +192,10 @@ void Polygon2D::_notification(int p_what) { points.resize(points.size() + 7); for (int i = points.size() - 1; i >= highest_idx + 7; i--) { - points.write[i] = points[i - 7]; } for (int i = 0; i < 7; i++) { - points.write[highest_idx + i + 1] = ep[i]; } @@ -208,7 +203,6 @@ void Polygon2D::_notification(int p_what) { } if (texture.is_valid()) { - Transform2D texmat(tex_rot, tex_ofs); texmat.scale(tex_scale); Size2 tex_size = texture->get_size(); @@ -216,7 +210,6 @@ void Polygon2D::_notification(int p_what) { uvs.resize(len); if (points.size() == uv.size()) { - const Vector2 *uvr = uv.ptr(); for (int i = 0; i < len; i++) { @@ -259,8 +252,9 @@ void Polygon2D::_notification(int p_what) { int bone_index = bone->get_index_in_skeleton(); const float *r = bone_weights[i].weights.ptr(); for (int j = 0; j < vc; j++) { - if (r[j] == 0.0) + if (r[j] == 0.0) { continue; //weight is unpainted, skip + } //find an index with a weight for (int k = 0; k < 4; k++) { if (weightsw[j * 4 + k] < r[j]) { @@ -283,8 +277,9 @@ void Polygon2D::_notification(int p_what) { for (int j = 0; j < 4; j++) { tw += weightsw[i * 4 + j]; } - if (tw == 0) + if (tw == 0) { continue; //unpainted, do nothing + } //normalize for (int j = 0; j < 4; j++) { @@ -305,9 +300,9 @@ void Polygon2D::_notification(int p_what) { } if (invert || polygons.size() == 0) { - Vector<int> indices = Geometry::triangulate_polygon(points); + Vector<int> indices = Geometry2D::triangulate_polygon(points); if (indices.size()) { - RS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, normal_map.is_valid() ? normal_map->get_rid() : RID(), specular_map.is_valid() ? specular_map->get_rid() : RID(), Color(specular_color.r, specular_color.g, specular_color.b, shininess)); + RS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1); } } else { //draw individual polygons @@ -315,8 +310,9 @@ void Polygon2D::_notification(int p_what) { for (int i = 0; i < polygons.size(); i++) { Vector<int> src_indices = polygons[i]; int ic = src_indices.size(); - if (ic < 3) + if (ic < 3) { continue; + } const int *r = src_indices.ptr(); Vector<Vector2> tmp_points; @@ -327,7 +323,7 @@ void Polygon2D::_notification(int p_what) { ERR_CONTINUE(idx < 0 || idx >= points.size()); tmp_points.write[j] = points[r[j]]; } - Vector<int> indices = Geometry::triangulate_polygon(tmp_points); + Vector<int> indices = Geometry2D::triangulate_polygon(tmp_points); int ic2 = indices.size(); const int *r2 = indices.ptr(); @@ -356,12 +352,10 @@ void Polygon2D::set_polygon(const Vector<Vector2> &p_polygon) { } Vector<Vector2> Polygon2D::get_polygon() const { - return polygon; } void Polygon2D::set_internal_vertex_count(int p_count) { - internal_vertices = p_count; } @@ -370,49 +364,42 @@ int Polygon2D::get_internal_vertex_count() const { } void Polygon2D::set_uv(const Vector<Vector2> &p_uv) { - uv = p_uv; update(); } Vector<Vector2> Polygon2D::get_uv() const { - return uv; } void Polygon2D::set_polygons(const Array &p_polygons) { - polygons = p_polygons; update(); } Array Polygon2D::get_polygons() const { - return polygons; } void Polygon2D::set_color(const Color &p_color) { - color = p_color; update(); } -Color Polygon2D::get_color() const { +Color Polygon2D::get_color() const { return color; } void Polygon2D::set_vertex_colors(const Vector<Color> &p_colors) { - vertex_colors = p_colors; update(); } -Vector<Color> Polygon2D::get_vertex_colors() const { +Vector<Color> Polygon2D::get_vertex_colors() const { return vertex_colors; } void Polygon2D::set_texture(const Ref<Texture2D> &p_texture) { - texture = p_texture; /*if (texture.is_valid()) { @@ -425,118 +412,74 @@ void Polygon2D::set_texture(const Ref<Texture2D> &p_texture) { }*/ update(); } -Ref<Texture2D> Polygon2D::get_texture() const { +Ref<Texture2D> Polygon2D::get_texture() const { return texture; } -void Polygon2D::set_normal_map(const Ref<Texture2D> &p_normal_map) { - normal_map = p_normal_map; - update(); -} - -Ref<Texture2D> Polygon2D::get_normal_map() const { - return normal_map; -} - -void Polygon2D::set_specular_map(const Ref<Texture2D> &p_specular_map) { - specular_map = p_specular_map; - update(); -} - -Ref<Texture2D> Polygon2D::get_specular_map() const { - return specular_map; -} - -void Polygon2D::set_specular_color(const Color &p_specular_color) { - specular_color = p_specular_color; - update(); -} - -Color Polygon2D::get_specular_color() const { - return specular_color; -} - -void Polygon2D::set_shininess(float p_shininess) { - shininess = CLAMP(p_shininess, 0.0, 1.0); - update(); -} - -float Polygon2D::get_shininess() const { - return shininess; -} - void Polygon2D::set_texture_offset(const Vector2 &p_offset) { - tex_ofs = p_offset; update(); } -Vector2 Polygon2D::get_texture_offset() const { +Vector2 Polygon2D::get_texture_offset() const { return tex_ofs; } void Polygon2D::set_texture_rotation(float p_rot) { - tex_rot = p_rot; update(); } -float Polygon2D::get_texture_rotation() const { +float Polygon2D::get_texture_rotation() const { return tex_rot; } void Polygon2D::set_texture_rotation_degrees(float p_rot) { - set_texture_rotation(Math::deg2rad(p_rot)); } -float Polygon2D::get_texture_rotation_degrees() const { +float Polygon2D::get_texture_rotation_degrees() const { return Math::rad2deg(get_texture_rotation()); } void Polygon2D::set_texture_scale(const Size2 &p_scale) { - tex_scale = p_scale; update(); } -Size2 Polygon2D::get_texture_scale() const { +Size2 Polygon2D::get_texture_scale() const { return tex_scale; } void Polygon2D::set_invert(bool p_invert) { - invert = p_invert; update(); } -bool Polygon2D::get_invert() const { +bool Polygon2D::get_invert() const { return invert; } void Polygon2D::set_antialiased(bool p_antialiased) { - antialiased = p_antialiased; update(); } -bool Polygon2D::get_antialiased() const { +bool Polygon2D::get_antialiased() const { return antialiased; } void Polygon2D::set_invert_border(float p_invert_border) { - invert_border = p_invert_border; update(); } -float Polygon2D::get_invert_border() const { +float Polygon2D::get_invert_border() const { return invert_border; } void Polygon2D::set_offset(const Vector2 &p_offset) { - offset = p_offset; rect_cache_dirty = true; update(); @@ -544,31 +487,31 @@ void Polygon2D::set_offset(const Vector2 &p_offset) { } Vector2 Polygon2D::get_offset() const { - return offset; } void Polygon2D::add_bone(const NodePath &p_path, const Vector<float> &p_weights) { - Bone bone; bone.path = p_path; bone.weights = p_weights; bone_weights.push_back(bone); } + int Polygon2D::get_bone_count() const { return bone_weights.size(); } + NodePath Polygon2D::get_bone_path(int p_index) const { ERR_FAIL_INDEX_V(p_index, bone_weights.size(), NodePath()); return bone_weights[p_index].path; } -Vector<float> Polygon2D::get_bone_weights(int p_index) const { +Vector<float> Polygon2D::get_bone_weights(int p_index) const { ERR_FAIL_INDEX_V(p_index, bone_weights.size(), Vector<float>()); return bone_weights[p_index].weights; } -void Polygon2D::erase_bone(int p_idx) { +void Polygon2D::erase_bone(int p_idx) { ERR_FAIL_INDEX(p_idx, bone_weights.size()); bone_weights.remove(p_idx); } @@ -582,6 +525,7 @@ void Polygon2D::set_bone_weights(int p_index, const Vector<float> &p_weights) { bone_weights.write[p_index].weights = p_weights; update(); } + void Polygon2D::set_bone_path(int p_index, const NodePath &p_path) { ERR_FAIL_INDEX(p_index, bone_weights.size()); bone_weights.write[p_index].path = p_path; @@ -596,8 +540,8 @@ Array Polygon2D::_get_bones() const { } return bones; } -void Polygon2D::_set_bones(const Array &p_bones) { +void Polygon2D::_set_bones(const Array &p_bones) { ERR_FAIL_COND(p_bones.size() & 1); clear_bones(); for (int i = 0; i < p_bones.size(); i += 2) { @@ -606,8 +550,9 @@ void Polygon2D::_set_bones(const Array &p_bones) { } void Polygon2D::set_skeleton(const NodePath &p_skeleton) { - if (skeleton == p_skeleton) + if (skeleton == p_skeleton) { return; + } skeleton = p_skeleton; update(); } @@ -617,7 +562,6 @@ NodePath Polygon2D::get_skeleton() const { } void Polygon2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &Polygon2D::set_polygon); ClassDB::bind_method(D_METHOD("get_polygon"), &Polygon2D::get_polygon); @@ -636,18 +580,6 @@ void Polygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Polygon2D::set_texture); ClassDB::bind_method(D_METHOD("get_texture"), &Polygon2D::get_texture); - ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map"), &Polygon2D::set_normal_map); - ClassDB::bind_method(D_METHOD("get_normal_map"), &Polygon2D::get_normal_map); - - ClassDB::bind_method(D_METHOD("set_specular_map", "specular_map"), &Polygon2D::set_specular_map); - ClassDB::bind_method(D_METHOD("get_specular_map"), &Polygon2D::get_specular_map); - - ClassDB::bind_method(D_METHOD("set_specular_color", "specular_color"), &Polygon2D::set_specular_color); - ClassDB::bind_method(D_METHOD("get_specular_color"), &Polygon2D::get_specular_color); - - ClassDB::bind_method(D_METHOD("set_shininess", "shininess"), &Polygon2D::set_shininess); - ClassDB::bind_method(D_METHOD("get_shininess"), &Polygon2D::get_shininess); - ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &Polygon2D::set_texture_offset); ClassDB::bind_method(D_METHOD("get_texture_offset"), &Polygon2D::get_texture_offset); @@ -700,11 +632,6 @@ void Polygon2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_scale"), "set_texture_scale", "get_texture_scale"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_texture_rotation_degrees", "get_texture_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation"); - ADD_GROUP("Lighting", ""); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "specular_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_specular_map", "get_specular_map"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_shininess", "get_shininess"); ADD_GROUP("Skeleton", ""); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton2D"), "set_skeleton", "get_skeleton"); @@ -722,8 +649,7 @@ void Polygon2D::_bind_methods() { } Polygon2D::Polygon2D() { - - invert = 0; + invert = false; invert_border = 100; antialiased = false; tex_rot = 0; @@ -732,7 +658,4 @@ Polygon2D::Polygon2D() { color = Color(1, 1, 1); rect_cache_dirty = true; internal_vertices = 0; - - specular_color = Color(1, 1, 1, 1); - shininess = 1.0; } diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index 777c1f82f3..e2a8db414a 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -34,7 +34,6 @@ #include "scene/2d/node_2d.h" class Polygon2D : public Node2D { - GDCLASS(Polygon2D, Node2D); Vector<Vector2> polygon; @@ -52,10 +51,6 @@ class Polygon2D : public Node2D { Color color; Ref<Texture2D> texture; - Ref<Texture2D> normal_map; - Ref<Texture2D> specular_map; - Color specular_color; - float shininess; Size2 tex_scale; Vector2 tex_ofs; @@ -83,16 +78,16 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Dictionary _edit_get_state() const; - virtual void _edit_set_state(const Dictionary &p_state); + virtual Dictionary _edit_get_state() const override; + virtual void _edit_set_state(const Dictionary &p_state) override; - virtual void _edit_set_pivot(const Point2 &p_pivot); - virtual Point2 _edit_get_pivot() const; - virtual bool _edit_use_pivot() const; - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; + virtual void _edit_set_pivot(const Point2 &p_pivot) override; + virtual Point2 _edit_get_pivot() const override; + virtual bool _edit_use_pivot() const override; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; #endif void set_polygon(const Vector<Vector2> &p_polygon); @@ -116,18 +111,6 @@ public: void set_texture(const Ref<Texture2D> &p_texture); Ref<Texture2D> get_texture() const; - void set_normal_map(const Ref<Texture2D> &p_normal_map); - Ref<Texture2D> get_normal_map() const; - - void set_specular_map(const Ref<Texture2D> &p_specular_map); - Ref<Texture2D> get_specular_map() const; - - void set_specular_color(const Color &p_specular_color); - Color get_specular_color() const; - - void set_shininess(float p_shininess); - float get_shininess() const; - void set_texture_offset(const Vector2 &p_offset); Vector2 get_texture_offset() const; diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index 9e95a55d9f..8e4165cf50 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -30,13 +30,12 @@ #include "position_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/resources/texture.h" const float DEFAULT_GIZMO_EXTENTS = 10.0; void Position2D::_draw_cross() { - float extents = get_gizmo_extents(); // Colors taken from `axis_x_color` and `axis_y_color` (defined in `editor/editor_themes.cpp`) draw_line(Point2(-extents, 0), Point2(+extents, 0), Color(0.96, 0.20, 0.32)); @@ -45,7 +44,6 @@ void Position2D::_draw_cross() { #ifdef TOOLS_ENABLED Rect2 Position2D::_edit_get_rect() const { - float extents = get_gizmo_extents(); return Rect2(Point2(-extents, -extents), Size2(extents * 2, extents * 2)); } @@ -56,18 +54,17 @@ bool Position2D::_edit_use_rect() const { #endif void Position2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - update(); } break; case NOTIFICATION_DRAW: { - if (!is_inside_tree()) + if (!is_inside_tree()) { break; - if (Engine::get_singleton()->is_editor_hint()) + } + if (Engine::get_singleton()->is_editor_hint()) { _draw_cross(); + } } break; } @@ -92,7 +89,6 @@ float Position2D::get_gizmo_extents() const { } void Position2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("_set_gizmo_extents", "extents"), &Position2D::set_gizmo_extents); ClassDB::bind_method(D_METHOD("_get_gizmo_extents"), &Position2D::get_gizmo_extents); diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h index 3ea636171d..01b380bca8 100644 --- a/scene/2d/position_2d.h +++ b/scene/2d/position_2d.h @@ -34,7 +34,6 @@ #include "scene/2d/node_2d.h" class Position2D : public Node2D { - GDCLASS(Position2D, Node2D); void _draw_cross(); @@ -45,8 +44,8 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; #endif void set_gizmo_extents(float p_extents); diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 9d6c7304ce..e53f89c46d 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -31,142 +31,137 @@ #include "ray_cast_2d.h" #include "collision_object_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "physics_body_2d.h" #include "servers/physics_server_2d.h" -void RayCast2D::set_cast_to(const Vector2 &p_point) { - - cast_to = p_point; - if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) +void RayCast2D::set_target_position(const Vector2 &p_point) { + target_position = p_point; + if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) { update(); + } } -Vector2 RayCast2D::get_cast_to() const { - - return cast_to; +Vector2 RayCast2D::get_target_position() const { + return target_position; } void RayCast2D::set_collision_mask(uint32_t p_mask) { - collision_mask = p_mask; } uint32_t RayCast2D::get_collision_mask() const { - return collision_mask; } void RayCast2D::set_collision_mask_bit(int p_bit, bool p_value) { - uint32_t mask = get_collision_mask(); - if (p_value) + if (p_value) { mask |= 1 << p_bit; - else + } else { mask &= ~(1 << p_bit); + } set_collision_mask(mask); } bool RayCast2D::get_collision_mask_bit(int p_bit) const { - return get_collision_mask() & (1 << p_bit); } bool RayCast2D::is_colliding() const { - return collided; } -Object *RayCast2D::get_collider() const { - if (against.is_null()) +Object *RayCast2D::get_collider() const { + if (against.is_null()) { return nullptr; + } return ObjectDB::get_instance(against); } int RayCast2D::get_collider_shape() const { - return against_shape; } -Vector2 RayCast2D::get_collision_point() const { +Vector2 RayCast2D::get_collision_point() const { return collision_point; } -Vector2 RayCast2D::get_collision_normal() const { +Vector2 RayCast2D::get_collision_normal() const { return collision_normal; } void RayCast2D::set_enabled(bool p_enabled) { - enabled = p_enabled; update(); - if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) + if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) { set_physics_process_internal(p_enabled); - if (!p_enabled) + } + if (!p_enabled) { collided = false; + } } bool RayCast2D::is_enabled() const { - return enabled; } void RayCast2D::set_exclude_parent_body(bool p_exclude_parent_body) { - - if (exclude_parent_body == p_exclude_parent_body) + if (exclude_parent_body == p_exclude_parent_body) { return; + } exclude_parent_body = p_exclude_parent_body; - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } if (Object::cast_to<CollisionObject2D>(get_parent())) { - if (exclude_parent_body) + if (exclude_parent_body) { exclude.insert(Object::cast_to<CollisionObject2D>(get_parent())->get_rid()); - else + } else { exclude.erase(Object::cast_to<CollisionObject2D>(get_parent())->get_rid()); + } } } bool RayCast2D::get_exclude_parent_body() const { - return exclude_parent_body; } void RayCast2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - - if (enabled && !Engine::get_singleton()->is_editor_hint()) + if (enabled && !Engine::get_singleton()->is_editor_hint()) { set_physics_process_internal(true); - else + } else { set_physics_process_internal(false); + } if (Object::cast_to<CollisionObject2D>(get_parent())) { - if (exclude_parent_body) + if (exclude_parent_body) { exclude.insert(Object::cast_to<CollisionObject2D>(get_parent())->get_rid()); - else + } else { exclude.erase(Object::cast_to<CollisionObject2D>(get_parent())->get_rid()); + } } } break; case NOTIFICATION_EXIT_TREE: { - - if (enabled) + if (enabled) { set_physics_process_internal(false); + } } break; case NOTIFICATION_DRAW: { - - if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) + if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) { break; + } Transform2D xf; - xf.rotate(cast_to.angle()); - xf.translate(Vector2(cast_to.length(), 0)); + xf.rotate(target_position.angle()); + xf.translate(Vector2(target_position.length(), 0)); // Draw an arrow indicating where the RayCast is pointing to Color draw_col = get_tree()->get_debug_collisions_color(); @@ -176,24 +171,25 @@ void RayCast2D::_notification(int p_what) { draw_col.g = g; draw_col.b = g; } - draw_line(Vector2(), cast_to, draw_col, 2); + 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++) + for (int i = 0; i < 3; i++) { cols.push_back(draw_col); + } draw_primitive(pts, cols, Vector<Vector2>()); } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - - if (!enabled) + if (!enabled) { break; + } _update_raycast_state(); @@ -210,14 +206,14 @@ void RayCast2D::_update_raycast_state() { Transform2D gt = get_global_transform(); - Vector2 to = cast_to; - if (to == Vector2()) + Vector2 to = target_position; + if (to == Vector2()) { to = Vector2(0, 0.01); + } PhysicsDirectSpaceState2D::RayResult rr; if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask, collide_with_bodies, collide_with_areas)) { - collided = true; against = rr.collider_id; collision_point = rr.position; @@ -235,65 +231,57 @@ void RayCast2D::force_raycast_update() { } 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) + if (!co) { return; + } add_exception_rid(co->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) + if (!co) { return; + } remove_exception_rid(co->get_rid()); } void RayCast2D::clear_exceptions() { - exclude.clear(); } void RayCast2D::set_collide_with_areas(bool p_clip) { - collide_with_areas = p_clip; } bool RayCast2D::is_collide_with_areas_enabled() const { - return collide_with_areas; } void RayCast2D::set_collide_with_bodies(bool p_clip) { - collide_with_bodies = p_clip; } bool RayCast2D::is_collide_with_bodies_enabled() const { - return collide_with_bodies; } void RayCast2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast2D::set_enabled); ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast2D::is_enabled); - ClassDB::bind_method(D_METHOD("set_cast_to", "local_point"), &RayCast2D::set_cast_to); - ClassDB::bind_method(D_METHOD("get_cast_to"), &RayCast2D::get_cast_to); + ClassDB::bind_method(D_METHOD("set_target_position", "local_point"), &RayCast2D::set_target_position); + ClassDB::bind_method(D_METHOD("get_target_position"), &RayCast2D::get_target_position); ClassDB::bind_method(D_METHOD("is_colliding"), &RayCast2D::is_colliding); ClassDB::bind_method(D_METHOD("force_raycast_update"), &RayCast2D::force_raycast_update); @@ -328,7 +316,7 @@ void RayCast2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "cast_to"), "set_cast_to", "get_cast_to"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position"), "set_target_position", "get_target_position"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); ADD_GROUP("Collide With", "collide_with"); @@ -337,13 +325,11 @@ void RayCast2D::_bind_methods() { } RayCast2D::RayCast2D() { - - enabled = false; - + enabled = true; collided = false; against_shape = 0; collision_mask = 1; - cast_to = Vector2(0, 50); + target_position = Vector2(0, 50); exclude_parent_body = true; collide_with_bodies = true; collide_with_areas = false; diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index 20f05e7525..14932f782b 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -34,7 +34,6 @@ #include "scene/2d/node_2d.h" class RayCast2D : public Node2D { - GDCLASS(RayCast2D, Node2D); bool enabled; @@ -47,7 +46,7 @@ class RayCast2D : public Node2D { uint32_t collision_mask; bool exclude_parent_body; - Vector2 cast_to; + Vector2 target_position; bool collide_with_areas; bool collide_with_bodies; @@ -67,8 +66,8 @@ public: void set_enabled(bool p_enabled); bool is_enabled() const; - void set_cast_to(const Vector2 &p_point); - Vector2 get_cast_to() const; + void set_target_position(const Vector2 &p_point); + Vector2 get_target_position() const; void set_collision_mask(uint32_t p_mask); uint32_t get_collision_mask() const; diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index ec50f5f922..7655416ce2 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -32,7 +32,6 @@ #include "scene/scene_string_names.h" void RemoteTransform2D::_update_cache() { - cache = ObjectID(); if (has_node(remote_node)) { Node *node = get_node(remote_node); @@ -45,23 +44,25 @@ void RemoteTransform2D::_update_cache() { } void RemoteTransform2D::_update_remote() { - - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } - if (cache.is_null()) + if (cache.is_null()) { return; + } Node2D *n = Object::cast_to<Node2D>(ObjectDB::get_instance(cache)); - if (!n) + if (!n) { return; + } - if (!n->is_inside_tree()) + if (!n->is_inside_tree()) { return; + } //todo make faster if (use_global_coordinates) { - if (update_remote_position && update_remote_rotation && update_remote_scale) { n->set_global_transform(get_global_transform()); } else { @@ -69,21 +70,23 @@ void RemoteTransform2D::_update_remote() { Transform2D our_trans = get_global_transform(); Vector2 n_scale = n->get_scale(); - if (!update_remote_position) + if (!update_remote_position) { our_trans.set_origin(n_trans.get_origin()); - if (!update_remote_rotation) + } + if (!update_remote_rotation) { our_trans.set_rotation(n_trans.get_rotation()); + } n->set_global_transform(our_trans); - if (update_remote_scale) + if (update_remote_scale) { n->set_scale(get_global_scale()); - else + } else { n->set_scale(n_scale); + } } } else { - if (update_remote_position && update_remote_rotation && update_remote_scale) { n->set_transform(get_transform()); } else { @@ -91,36 +94,36 @@ void RemoteTransform2D::_update_remote() { Transform2D our_trans = get_transform(); Vector2 n_scale = n->get_scale(); - if (!update_remote_position) + if (!update_remote_position) { our_trans.set_origin(n_trans.get_origin()); - if (!update_remote_rotation) + } + if (!update_remote_rotation) { our_trans.set_rotation(n_trans.get_rotation()); + } n->set_transform(our_trans); - if (update_remote_scale) + if (update_remote_scale) { n->set_scale(get_scale()); - else + } else { n->set_scale(n_scale); + } } } } void RemoteTransform2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - _update_cache(); } break; case NOTIFICATION_TRANSFORM_CHANGED: { - if (!is_inside_tree()) + if (!is_inside_tree()) { break; + } if (cache.is_valid()) { - _update_remote(); } @@ -129,7 +132,6 @@ void RemoteTransform2D::_notification(int p_what) { } void RemoteTransform2D::set_remote_node(const NodePath &p_remote_node) { - remote_node = p_remote_node; if (is_inside_tree()) { _update_cache(); @@ -140,7 +142,6 @@ void RemoteTransform2D::set_remote_node(const NodePath &p_remote_node) { } NodePath RemoteTransform2D::get_remote_node() const { - return remote_node; } @@ -185,16 +186,19 @@ void RemoteTransform2D::force_update_cache() { } String RemoteTransform2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (!has_node(remote_node) || !Object::cast_to<Node2D>(get_node(remote_node))) { - return TTR("Path property must point to a valid Node2D node to work."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("Path property must point to a valid Node2D node to work."); } - return String(); + return warning; } void RemoteTransform2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_remote_node", "path"), &RemoteTransform2D::set_remote_node); ClassDB::bind_method(D_METHOD("get_remote_node"), &RemoteTransform2D::get_remote_node); ClassDB::bind_method(D_METHOD("force_update_cache"), &RemoteTransform2D::force_update_cache); @@ -219,7 +223,6 @@ void RemoteTransform2D::_bind_methods() { } RemoteTransform2D::RemoteTransform2D() { - use_global_coordinates = true; update_remote_position = true; update_remote_rotation = true; diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h index f5b949d10b..8b6f8d9678 100644 --- a/scene/2d/remote_transform_2d.h +++ b/scene/2d/remote_transform_2d.h @@ -34,7 +34,6 @@ #include "scene/2d/node_2d.h" class RemoteTransform2D : public Node2D { - GDCLASS(RemoteTransform2D, Node2D); NodePath remote_node; @@ -71,7 +70,7 @@ public: void force_update_cache(); - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; RemoteTransform2D(); }; diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 86c9ff6076..ea1d9f5930 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -31,17 +31,18 @@ #include "skeleton_2d.h" 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) + if (skeleton) { break; - if (!Object::cast_to<Bone2D>(parent)) + } + if (!Object::cast_to<Bone2D>(parent)) { break; //skeletons must be chained to Bone2Ds. + } parent = parent->get_parent(); } @@ -78,8 +79,8 @@ void Bone2D::_notification(int p_what) { parent_bone = nullptr; } } -void Bone2D::_bind_methods() { +void Bone2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_rest", "rest"), &Bone2D::set_rest); ClassDB::bind_method(D_METHOD("get_rest"), &Bone2D::get_rest); ClassDB::bind_method(D_METHOD("apply_rest"), &Bone2D::apply_rest); @@ -95,8 +96,9 @@ void Bone2D::_bind_methods() { void Bone2D::set_rest(const Transform2D &p_rest) { rest = p_rest; - if (skeleton) + if (skeleton) { skeleton->_make_bone_setup_dirty(); + } update_configuration_warning(); } @@ -106,7 +108,6 @@ Transform2D Bone2D::get_rest() const { } Transform2D Bone2D::get_skeleton_rest() const { - if (parent_bone) { return parent_bone->get_skeleton_rest() * rest; } else { @@ -119,7 +120,6 @@ void Bone2D::apply_rest() { } void Bone2D::set_default_length(float p_length) { - default_length = p_length; } @@ -132,11 +132,11 @@ int Bone2D::get_index_in_skeleton() const { skeleton->_update_bone_setup(); return skeleton_index; } -String Bone2D::get_configuration_warning() const { +String Bone2D::get_configuration_warning() const { String warning = Node2D::get_configuration_warning(); if (!skeleton) { - if (warning != String()) { + if (!warning.empty()) { warning += "\n\n"; } if (parent_bone) { @@ -147,7 +147,7 @@ String Bone2D::get_configuration_warning() const { } if (rest == Transform2D(0, 0, 0, 0, 0, 0)) { - if (warning != String()) { + if (!warning.empty()) { warning += "\n\n"; } warning += TTR("This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."); @@ -171,9 +171,9 @@ Bone2D::Bone2D() { ////////////////////////////////////// void Skeleton2D::_make_bone_setup_dirty() { - - if (bone_setup_dirty) + if (bone_setup_dirty) { return; + } bone_setup_dirty = true; if (is_inside_tree()) { call_deferred("_update_bone_setup"); @@ -181,9 +181,9 @@ void Skeleton2D::_make_bone_setup_dirty() { } void Skeleton2D::_update_bone_setup() { - - if (!bone_setup_dirty) + if (!bone_setup_dirty) { return; + } bone_setup_dirty = false; RS::get_singleton()->skeleton_allocate(skeleton, bones.size(), true); @@ -207,9 +207,9 @@ void Skeleton2D::_update_bone_setup() { } void Skeleton2D::_make_transform_dirty() { - - if (transform_dirty) + if (transform_dirty) { return; + } transform_dirty = true; if (is_inside_tree()) { call_deferred("_update_transform"); @@ -217,18 +217,17 @@ void Skeleton2D::_make_transform_dirty() { } void Skeleton2D::_update_transform() { - if (bone_setup_dirty) { _update_bone_setup(); return; //above will update transform anyway } - if (!transform_dirty) + if (!transform_dirty) { return; + } transform_dirty = false; for (int i = 0; i < bones.size(); i++) { - ERR_CONTINUE(bones[i].parent_index >= i); if (bones[i].parent_index >= 0) { bones.write[i].accum_transform = bones[bones[i].parent_index].accum_transform * bones[i].bone->get_transform(); @@ -238,14 +237,12 @@ void Skeleton2D::_update_transform() { } for (int i = 0; i < bones.size(); i++) { - Transform2D final_xform = bones[i].accum_transform * bones[i].rest_inverse; RS::get_singleton()->skeleton_bone_set_transform_2d(skeleton, i, final_xform); } } int Skeleton2D::get_bone_count() const { - ERR_FAIL_COND_V(!is_inside_tree(), 0); if (bone_setup_dirty) { @@ -256,7 +253,6 @@ int Skeleton2D::get_bone_count() const { } Bone2D *Skeleton2D::get_bone(int p_idx) { - ERR_FAIL_COND_V(!is_inside_tree(), nullptr); ERR_FAIL_INDEX_V(p_idx, bones.size(), nullptr); @@ -264,13 +260,13 @@ Bone2D *Skeleton2D::get_bone(int p_idx) { } void Skeleton2D::_notification(int p_what) { - if (p_what == NOTIFICATION_READY) { - - if (bone_setup_dirty) + if (bone_setup_dirty) { _update_bone_setup(); - if (transform_dirty) + } + if (transform_dirty) { _update_transform(); + } request_ready(); } @@ -283,8 +279,8 @@ void Skeleton2D::_notification(int p_what) { RID Skeleton2D::get_skeleton() const { return skeleton; } -void Skeleton2D::_bind_methods() { +void Skeleton2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_bone_setup"), &Skeleton2D::_update_bone_setup); ClassDB::bind_method(D_METHOD("_update_transform"), &Skeleton2D::_update_transform); @@ -305,6 +301,5 @@ Skeleton2D::Skeleton2D() { } Skeleton2D::~Skeleton2D() { - RS::get_singleton()->free(skeleton); } diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h index c6bee8d92b..7e9ffd98e6 100644 --- a/scene/2d/skeleton_2d.h +++ b/scene/2d/skeleton_2d.h @@ -60,7 +60,7 @@ public: void apply_rest(); Transform2D get_skeleton_rest() const; - String get_configuration_warning() const; + String get_configuration_warning() const override; void set_default_length(float p_length); float get_default_length() const; diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp index df8859bd9a..a065565a0f 100644 --- a/scene/2d/sprite_2d.cpp +++ b/scene/2d/sprite_2d.cpp @@ -61,7 +61,6 @@ bool Sprite2D::_edit_use_pivot() const { } bool Sprite2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - return is_pixel_opaque(p_point); } @@ -79,7 +78,6 @@ Rect2 Sprite2D::get_anchorable_rect() const { } void Sprite2D::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const { - Rect2 base_rect; if (region) { @@ -98,28 +96,30 @@ void Sprite2D::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_c r_src_rect.position = base_rect.position + frame_offset; Point2 dest_offset = offset; - if (centered) + if (centered) { dest_offset -= frame_size / 2; - if (Engine::get_singleton()->get_use_pixel_snap()) { + } + + if (get_viewport() && get_viewport()->is_snap_2d_transforms_to_pixel_enabled()) { dest_offset = dest_offset.floor(); } r_dst_rect = Rect2(dest_offset, frame_size); - if (hflip) + if (hflip) { r_dst_rect.size.x = -r_dst_rect.size.x; - if (vflip) + } + if (vflip) { r_dst_rect.size.y = -r_dst_rect.size.y; + } } void Sprite2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_DRAW: { - - if (texture.is_null()) + if (texture.is_null()) { return; + } RID ci = get_canvas_item(); @@ -131,24 +131,26 @@ void Sprite2D::_notification(int p_what) { Rect2 src_rect, dst_rect; bool filter_clip; _get_rects(src_rect, dst_rect, filter_clip); - texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, normal_map, specular, Color(specular_color.r, specular_color.g, specular_color.b, shininess), RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, filter_clip); + texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, filter_clip); } break; } } void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) { - - if (p_texture == texture) + if (p_texture == texture) { return; + } - if (texture.is_valid()) + if (texture.is_valid()) { texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite2D::_texture_changed)); + } texture = p_texture; - if (texture.is_valid()) + if (texture.is_valid()) { texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite2D::_texture_changed)); + } update(); emit_signal("texture_changed"); @@ -156,124 +158,77 @@ void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) { _change_notify("texture"); } -void Sprite2D::set_normal_map(const Ref<Texture2D> &p_texture) { - - normal_map = p_texture; - update(); -} - -Ref<Texture2D> Sprite2D::get_normal_map() const { - - return normal_map; -} - -void Sprite2D::set_specular_map(const Ref<Texture2D> &p_texture) { - - specular = p_texture; - update(); -} - -Ref<Texture2D> Sprite2D::get_specular_map() const { - - return specular; -} - -void Sprite2D::set_specular_color(const Color &p_color) { - specular_color = p_color; - update(); -} - -Color Sprite2D::get_specular_color() const { - return specular_color; -} - -void Sprite2D::set_shininess(float p_shininess) { - shininess = CLAMP(p_shininess, 0.0, 1.0); - update(); -} - -float Sprite2D::get_shininess() const { - return shininess; -} - Ref<Texture2D> Sprite2D::get_texture() const { - return texture; } void Sprite2D::set_centered(bool p_center) { - centered = p_center; update(); item_rect_changed(); } bool Sprite2D::is_centered() const { - return centered; } void Sprite2D::set_offset(const Point2 &p_offset) { - offset = p_offset; update(); item_rect_changed(); _change_notify("offset"); } -Point2 Sprite2D::get_offset() const { +Point2 Sprite2D::get_offset() const { return offset; } void Sprite2D::set_flip_h(bool p_flip) { - hflip = p_flip; update(); } -bool Sprite2D::is_flipped_h() const { +bool Sprite2D::is_flipped_h() const { return hflip; } void Sprite2D::set_flip_v(bool p_flip) { - vflip = p_flip; update(); } -bool Sprite2D::is_flipped_v() const { +bool Sprite2D::is_flipped_v() const { return vflip; } void Sprite2D::set_region(bool p_region) { - - if (p_region == region) + if (p_region == region) { return; + } region = p_region; update(); } bool Sprite2D::is_region() const { - return region; } void Sprite2D::set_region_rect(const Rect2 &p_region_rect) { - - if (region_rect == p_region_rect) + if (region_rect == p_region_rect) { return; + } region_rect = p_region_rect; - if (region) + if (region) { item_rect_changed(); + } _change_notify("region_rect"); } Rect2 Sprite2D::get_region_rect() const { - return region_rect; } @@ -287,11 +242,11 @@ bool Sprite2D::is_region_filter_clip_enabled() const { } void Sprite2D::set_frame(int p_frame) { - ERR_FAIL_INDEX(p_frame, vframes * hframes); - if (frame != p_frame) + if (frame != p_frame) { item_rect_changed(); + } frame = p_frame; @@ -301,7 +256,6 @@ void Sprite2D::set_frame(int p_frame) { } int Sprite2D::get_frame() const { - return frame; } @@ -317,52 +271,54 @@ Vector2 Sprite2D::get_frame_coords() const { } void Sprite2D::set_vframes(int p_amount) { - ERR_FAIL_COND_MSG(p_amount < 1, "Amount of vframes cannot be smaller than 1."); vframes = p_amount; update(); item_rect_changed(); _change_notify(); } -int Sprite2D::get_vframes() const { +int Sprite2D::get_vframes() const { return vframes; } void Sprite2D::set_hframes(int p_amount) { - ERR_FAIL_COND_MSG(p_amount < 1, "Amount of hframes cannot be smaller than 1."); hframes = p_amount; update(); item_rect_changed(); _change_notify(); } -int Sprite2D::get_hframes() const { +int Sprite2D::get_hframes() const { return hframes; } bool Sprite2D::is_pixel_opaque(const Point2 &p_point) const { - - if (texture.is_null()) + if (texture.is_null()) { return false; + } - if (texture->get_size().width == 0 || texture->get_size().height == 0) + if (texture->get_size().width == 0 || texture->get_size().height == 0) { return false; + } Rect2 src_rect, dst_rect; bool filter_clip; _get_rects(src_rect, dst_rect, filter_clip); dst_rect.size = dst_rect.size.abs(); - if (!dst_rect.has_point(p_point)) + if (!dst_rect.has_point(p_point)) { return false; + } Vector2 q = (p_point - dst_rect.position) / dst_rect.size; - if (hflip) + if (hflip) { q.x = 1.0f - q.x; - if (vflip) + } + if (vflip) { q.y = 1.0f - q.y; + } q = q * src_rect.size + src_rect.position; #ifndef _MSC_VER #warning this need to be obtained from CanvasItem new repeat mode (but it needs to guess it from hierarchy, need to add a function for that) @@ -393,9 +349,9 @@ bool Sprite2D::is_pixel_opaque(const Point2 &p_point) const { } Rect2 Sprite2D::get_rect() const { - - if (texture.is_null()) + if (texture.is_null()) { return Rect2(0, 0, 1, 1); + } Size2i s; @@ -408,17 +364,22 @@ Rect2 Sprite2D::get_rect() const { s = s / Point2(hframes, vframes); Point2 ofs = offset; - if (centered) + if (centered) { ofs -= Size2(s) / 2; + } + + if (get_viewport() && get_viewport()->is_snap_2d_transforms_to_pixel_enabled()) { + ofs = ofs.floor(); + } - if (s == Size2(0, 0)) + if (s == Size2(0, 0)) { s = Size2(1, 1); + } return Rect2(ofs, s); } void Sprite2D::_validate_property(PropertyInfo &property) const { - if (property.name == "frame") { property.hint = PROPERTY_HINT_RANGE; property.hint_string = "0," + itos(vframes * hframes - 1) + ",1"; @@ -431,7 +392,6 @@ void Sprite2D::_validate_property(PropertyInfo &property) const { } void Sprite2D::_texture_changed() { - // Changes to the texture need to trigger an update to make // the editor redraw the sprite with the updated texture. if (texture.is_valid()) { @@ -440,22 +400,9 @@ void Sprite2D::_texture_changed() { } void Sprite2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Sprite2D::set_texture); ClassDB::bind_method(D_METHOD("get_texture"), &Sprite2D::get_texture); - ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map"), &Sprite2D::set_normal_map); - ClassDB::bind_method(D_METHOD("get_normal_map"), &Sprite2D::get_normal_map); - - ClassDB::bind_method(D_METHOD("set_specular_map", "specular_map"), &Sprite2D::set_specular_map); - ClassDB::bind_method(D_METHOD("get_specular_map"), &Sprite2D::get_specular_map); - - ClassDB::bind_method(D_METHOD("set_specular_color", "specular_color"), &Sprite2D::set_specular_color); - ClassDB::bind_method(D_METHOD("get_specular_color"), &Sprite2D::get_specular_color); - - ClassDB::bind_method(D_METHOD("set_shininess", "shininess"), &Sprite2D::set_shininess); - ClassDB::bind_method(D_METHOD("get_shininess"), &Sprite2D::get_shininess); - ClassDB::bind_method(D_METHOD("set_centered", "centered"), &Sprite2D::set_centered); ClassDB::bind_method(D_METHOD("is_centered"), &Sprite2D::is_centered); @@ -497,19 +444,14 @@ void Sprite2D::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_GROUP("Lighting", ""); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "specular_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_specular_map", "get_specular_map"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_shininess", "get_shininess"); ADD_GROUP("Offset", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v"); ADD_GROUP("Animation", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords"); @@ -520,14 +462,11 @@ void Sprite2D::_bind_methods() { } Sprite2D::Sprite2D() { - centered = true; hflip = false; vflip = false; region = false; region_filter_clip = false; - shininess = 1.0; - specular_color = Color(1, 1, 1, 1); frame = 0; diff --git a/scene/2d/sprite_2d.h b/scene/2d/sprite_2d.h index 599a9e937e..2875d333bb 100644 --- a/scene/2d/sprite_2d.h +++ b/scene/2d/sprite_2d.h @@ -35,12 +35,9 @@ #include "scene/resources/texture.h" class Sprite2D : public Node2D { - GDCLASS(Sprite2D, Node2D); Ref<Texture2D> texture; - Ref<Texture2D> normal_map; - Ref<Texture2D> specular; Color specular_color; float shininess; @@ -67,20 +64,20 @@ protected: static void _bind_methods(); - virtual void _validate_property(PropertyInfo &property) const; + virtual void _validate_property(PropertyInfo &property) const override; public: #ifdef TOOLS_ENABLED - virtual Dictionary _edit_get_state() const; - virtual void _edit_set_state(const Dictionary &p_state); + virtual Dictionary _edit_get_state() const override; + virtual void _edit_set_state(const Dictionary &p_state) override; - virtual void _edit_set_pivot(const Point2 &p_pivot); - virtual Point2 _edit_get_pivot() const; - virtual bool _edit_use_pivot() const; - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; + virtual void _edit_set_pivot(const Point2 &p_pivot) override; + virtual Point2 _edit_get_pivot() const override; + virtual bool _edit_use_pivot() const override; + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; #endif bool is_pixel_opaque(const Point2 &p_point) const; @@ -88,18 +85,6 @@ public: void set_texture(const Ref<Texture2D> &p_texture); Ref<Texture2D> get_texture() const; - void set_normal_map(const Ref<Texture2D> &p_texture); - Ref<Texture2D> get_normal_map() const; - - void set_specular_map(const Ref<Texture2D> &p_texture); - Ref<Texture2D> get_specular_map() const; - - void set_specular_color(const Color &p_color); - Color get_specular_color() const; - - void set_shininess(float p_shininess); - float get_shininess() const; - void set_centered(bool p_center); bool is_centered() const; @@ -134,7 +119,7 @@ public: int get_hframes() const; Rect2 get_rect() const; - virtual Rect2 get_anchorable_rect() const; + virtual Rect2 get_anchorable_rect() const override; Sprite2D(); ~Sprite2D(); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 9628c01718..bff191a2bf 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -32,29 +32,24 @@ #include "collision_object_2d.h" #include "core/io/marshalls.h" -#include "core/method_bind_ext.gen.inc" #include "core/os/os.h" #include "scene/2d/area_2d.h" #include "servers/navigation_server_2d.h" #include "servers/physics_server_2d.h" int TileMap::_get_quadrant_size() const { - - if (y_sort_mode) + if (use_y_sort) { return 1; - else + } else { return quadrant_size; + } } void TileMap::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - Node2D *c = this; while (c) { - navigation = Object::cast_to<Navigation2D>(c); if (navigation) { break; @@ -79,14 +74,11 @@ void TileMap::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - _update_quadrant_space(RID()); for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID()); } q.navpoly_ids.clear(); @@ -109,13 +101,11 @@ void TileMap::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - //move stuff _update_quadrant_transform(); } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - if (use_parent) { _recreate_quadrants(); } @@ -125,10 +115,8 @@ void TileMap::_notification(int p_what) { } void TileMap::_update_quadrant_space(const RID &p_space) { - if (!use_parent) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); PhysicsServer2D::get_singleton()->body_set_space(q.body, p_space); } @@ -136,22 +124,23 @@ void TileMap::_update_quadrant_space(const RID &p_space) { } void TileMap::_update_quadrant_transform() { - - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } Transform2D global_transform = get_global_transform(); Transform2D local_transform; - if (collision_parent) + if (collision_parent) { local_transform = get_transform(); + } Transform2D nav_rel; - if (navigation) + if (navigation) { nav_rel = get_relative_transform_to_parent(navigation); + } for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); Transform2D xform; xform.set_origin(q.pos); @@ -163,7 +152,6 @@ void TileMap::_update_quadrant_transform() { if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - NavigationServer2D::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform); } } @@ -175,7 +163,6 @@ void TileMap::_update_quadrant_transform() { } void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { - if (tile_set.is_valid()) { tile_set->disconnect("changed", callable_mp(this, &TileMap::_recreate_quadrants)); tile_set->remove_change_receptor(this); @@ -196,12 +183,10 @@ void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { } Ref<TileSet> TileMap::get_tileset() const { - return tile_set; } void TileMap::set_cell_size(Size2 p_size) { - ERR_FAIL_COND(p_size.x < 1 || p_size.y < 1); _clear_quadrants(); @@ -211,12 +196,10 @@ void TileMap::set_cell_size(Size2 p_size) { } Size2 TileMap::get_cell_size() const { - return cell_size; } void TileMap::set_quadrant_size(int p_size) { - ERR_FAIL_COND_MSG(p_size < 1, "Quadrant size cannot be smaller than 1."); _clear_quadrants(); @@ -226,17 +209,14 @@ void TileMap::set_quadrant_size(int p_size) { } int TileMap::get_quadrant_size() const { - return quadrant_size; } void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc) { - Size2 s = p_sc; Vector2 offset = p_offset; if (compatibility_mode && !centered_textures) { - if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { offset.y += cell_size.y; } else if (tile_origin == TILE_ORIGIN_CENTER) { @@ -326,9 +306,9 @@ void TileMap::_add_shape(int &shape_idx, const Quadrant &p_q, const Ref<Shape2D> } void TileMap::update_dirty_quadrants() { - - if (!pending_update) + if (!pending_update) { return; + } if (!is_inside_tree() || !tile_set.is_valid()) { pending_update = false; return; @@ -338,8 +318,9 @@ void TileMap::update_dirty_quadrants() { PhysicsServer2D *ps = PhysicsServer2D::get_singleton(); Vector2 tofs = get_cell_draw_offset(); Transform2D nav_rel; - if (navigation) + if (navigation) { nav_rel = get_relative_transform_to_parent(navigation); + } Vector2 qofs; @@ -358,11 +339,9 @@ void TileMap::update_dirty_quadrants() { } while (dirty_quadrant_list.first()) { - Quadrant &q = *dirty_quadrant_list.first()->self(); for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { - vs->free(E->get()); } @@ -377,7 +356,6 @@ void TileMap::update_dirty_quadrants() { if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { - NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID()); } q.navpoly_ids.clear(); @@ -393,20 +371,21 @@ void TileMap::update_dirty_quadrants() { RID prev_debug_canvas_item; for (int i = 0; i < q.cells.size(); i++) { - Map<PosKey, Cell>::Element *E = tile_map.find(q.cells[i]); Cell &c = E->get(); //moment of truth - if (!tile_set->has_tile(c.id)) + if (!tile_set->has_tile(c.id)) { continue; + } Ref<Texture2D> tex = tile_set->tile_get_texture(c.id); Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id); Vector2 wofs = _map_to_world(E->key().x, E->key().y); Vector2 offset = wofs - q.pos + tofs; - if (!tex.is_valid()) + if (!tex.is_valid()) { continue; + } Ref<ShaderMaterial> mat = tile_set->tile_get_material(c.id); int z_index = tile_set->tile_get_z_index(c.id); @@ -420,10 +399,10 @@ void TileMap::update_dirty_quadrants() { RID debug_canvas_item; if (prev_canvas_item == RID() || prev_material != mat || prev_z_index != z_index) { - canvas_item = vs->canvas_item_create(); - if (mat.is_valid()) + if (mat.is_valid()) { vs->canvas_item_set_material(canvas_item, mat->get_rid()); + } vs->canvas_item_set_parent(canvas_item, get_canvas_item()); _update_item_material_state(canvas_item); Transform2D xform; @@ -432,10 +411,12 @@ void TileMap::update_dirty_quadrants() { vs->canvas_item_set_light_mask(canvas_item, get_light_mask()); vs->canvas_item_set_z_index(canvas_item, z_index); + vs->canvas_item_set_default_texture_filter(canvas_item, RS::CanvasItemTextureFilter(CanvasItem::get_texture_filter())); + vs->canvas_item_set_default_texture_repeat(canvas_item, RS::CanvasItemTextureRepeat(CanvasItem::get_texture_repeat())); + q.canvas_items.push_back(canvas_item); if (debug_shapes) { - debug_canvas_item = vs->canvas_item_create(); vs->canvas_item_set_parent(debug_canvas_item, canvas_item); vs->canvas_item_set_z_as_relative_to_parent(debug_canvas_item, false); @@ -463,10 +444,11 @@ void TileMap::update_dirty_quadrants() { } Size2 s; - if (r == Rect2()) + if (r == Rect2()) { s = tex->get_size(); - else + } else { s = r.size; + } Rect2 rect; rect.position = offset.floor(); @@ -476,11 +458,13 @@ void TileMap::update_dirty_quadrants() { if (compatibility_mode && !centered_textures) { if (rect.size.y > rect.size.x) { - if ((c.flip_h && (c.flip_v || c.transpose)) || (c.flip_v && !c.transpose)) + if ((c.flip_h && (c.flip_v || c.transpose)) || (c.flip_v && !c.transpose)) { tile_ofs.y += rect.size.y - rect.size.x; + } } else if (rect.size.y < rect.size.x) { - if ((c.flip_v && (c.flip_h || c.transpose)) || (c.flip_h && !c.transpose)) + if ((c.flip_v && (c.flip_h || c.transpose)) || (c.flip_h && !c.transpose)) { tile_ofs.x += rect.size.x - rect.size.y; + } } } @@ -509,48 +493,49 @@ void TileMap::update_dirty_quadrants() { rect.position += tile_ofs; } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { - rect.position += tile_ofs; if (c.transpose) { - if (c.flip_h) + if (c.flip_h) { rect.position.x -= cell_size.x; - else + } else { rect.position.x += cell_size.x; + } } else { - if (c.flip_v) + if (c.flip_v) { rect.position.y -= cell_size.y; - else + } else { rect.position.y += cell_size.y; + } } } else if (tile_origin == TILE_ORIGIN_CENTER) { - rect.position += tile_ofs; - if (c.flip_h) + if (c.flip_h) { rect.position.x -= cell_size.x / 2; - else + } else { rect.position.x += cell_size.x / 2; + } - if (c.flip_v) + if (c.flip_v) { rect.position.y -= cell_size.y / 2; - else + } else { rect.position.y += cell_size.y / 2; + } } } else { rect.position += tile_ofs; } - Ref<Texture2D> normal_map = tile_set->tile_get_normal_map(c.id); Color modulate = tile_set->tile_get_modulate(c.id); Color self_modulate = get_self_modulate(); modulate = Color(modulate.r * self_modulate.r, modulate.g * self_modulate.g, modulate.b * self_modulate.b, modulate.a * self_modulate.a); if (r == Rect2()) { - tex->draw_rect(canvas_item, rect, false, modulate, c.transpose, normal_map); + tex->draw_rect(canvas_item, rect, false, modulate, c.transpose); } else { - tex->draw_rect_region(canvas_item, rect, r, modulate, c.transpose, normal_map, Ref<Texture2D>(), Color(1, 1, 1, 1), RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, clip_uv); + tex->draw_rect_region(canvas_item, rect, r, modulate, c.transpose, clip_uv); } Vector<TileSet::ShapeData> shapes = tile_set->tile_get_shapes(c.id); @@ -651,10 +636,8 @@ void TileMap::update_dirty_quadrants() { Vector<int> polygon = navpoly->get_polygon(j); for (int k = 2; k < polygon.size(); k++) { - int kofs[3] = { 0, k - 1, k }; for (int l = 0; l < 3; l++) { - int idx = polygon[kofs[l]]; ERR_FAIL_INDEX(idx, vsize); indices.push_back(idx); @@ -704,13 +687,10 @@ void TileMap::update_dirty_quadrants() { pending_update = false; if (quadrant_order_dirty) { - int index = -(int64_t)0x80000000; //always must be drawn below children for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - RS::get_singleton()->canvas_item_set_draw_index(F->get(), index++); } } @@ -722,24 +702,24 @@ void TileMap::update_dirty_quadrants() { } void TileMap::_recompute_rect_cache() { - #ifdef DEBUG_ENABLED - if (!rect_cache_dirty) + if (!rect_cache_dirty) { return; + } Rect2 r_total; for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Rect2 r; r.position = _map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size()); r.expand_to(_map_to_world(E->key().x * _get_quadrant_size() + _get_quadrant_size(), E->key().y * _get_quadrant_size())); r.expand_to(_map_to_world(E->key().x * _get_quadrant_size() + _get_quadrant_size(), E->key().y * _get_quadrant_size() + _get_quadrant_size())); r.expand_to(_map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size() + _get_quadrant_size())); - if (E == quadrant_map.front()) + if (E == quadrant_map.front()) { r_total = r; - else + } else { r_total = r_total.merge(r); + } } rect_cache = r_total; @@ -751,16 +731,16 @@ void TileMap::_recompute_rect_cache() { } Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(const PosKey &p_qk) { - Transform2D xform; //xform.set_origin(Point2(p_qk.x,p_qk.y)*cell_size*quadrant_size); Quadrant q; q.pos = _map_to_world(p_qk.x * _get_quadrant_size(), p_qk.y * _get_quadrant_size()); q.pos += get_cell_draw_offset(); - if (tile_origin == TILE_ORIGIN_CENTER) + if (tile_origin == TILE_ORIGIN_CENTER) { q.pos += cell_size / 2; - else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) + } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { q.pos.y += cell_size.y; + } xform.set_origin(q.pos); //q.canvas_item = RenderingServer::get_singleton()->canvas_item_create(); @@ -794,7 +774,6 @@ Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(cons } void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) { - Quadrant &q = Q->get(); if (!use_parent) { PhysicsServer2D::get_singleton()->free(q.body); @@ -803,16 +782,15 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) { } for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { - RenderingServer::get_singleton()->free(E->get()); } q.canvas_items.clear(); - if (q.dirty_list.in_list()) + if (q.dirty_list.in_list()) { dirty_quadrant_list.remove(&q.dirty_list); + } if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { - NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID()); } q.navpoly_ids.clear(); @@ -828,16 +806,18 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) { } void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool update) { - Quadrant &q = Q->get(); - if (!q.dirty_list.in_list()) + if (!q.dirty_list.in_list()) { dirty_quadrant_list.add(&q.dirty_list); + } - if (pending_update) + if (pending_update) { return; + } pending_update = true; - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } if (update) { call_deferred("update_dirty_quadrants"); @@ -845,12 +825,10 @@ void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool updat } void TileMap::set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose) { - set_cell(p_pos.x, p_pos.y, p_tile, p_flip_x, p_flip_y, p_transpose); } void TileMap::_set_celld(const Vector2 &p_pos, const Dictionary &p_data) { - Variant v_pos_x = p_pos.x, v_pos_y = p_pos.y, v_tile = p_data["id"], v_flip_h = p_data["flip_h"], v_flip_v = p_data["flip_y"], v_transpose = p_data["transpose"], v_autotile_coord = p_data["auto_coord"]; const Variant *args[7] = { &v_pos_x, &v_pos_y, &v_tile, &v_flip_h, &v_flip_v, &v_transpose, &v_autotile_coord }; Callable::CallError ce; @@ -858,12 +836,12 @@ void TileMap::_set_celld(const Vector2 &p_pos, const Dictionary &p_data) { } void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose, Vector2 p_autotile_coord) { - PosKey pk(p_x, p_y); Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E && p_tile == INVALID_CELL) + if (!E && p_tile == INVALID_CELL) { return; //nothing to do + } PosKey qk = pk.to_quadrant(_get_quadrant_size()); if (p_tile == INVALID_CELL) { @@ -873,10 +851,11 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_ ERR_FAIL_COND(!Q); Quadrant &q = Q->get(); q.cells.erase(pk); - if (q.cells.size() == 0) + if (q.cells.size() == 0) { _erase_quadrant(Q); - else + } else { _make_quadrant_dirty(Q); + } used_size_cache_dirty = true; return; @@ -894,8 +873,9 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_ } else { ERR_FAIL_COND(!Q); // quadrant should exist... - if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose && E->get().autotile_coord_x == (uint16_t)p_autotile_coord.x && E->get().autotile_coord_y == (uint16_t)p_autotile_coord.y) + if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose && E->get().autotile_coord_x == (uint16_t)p_autotile_coord.x && E->get().autotile_coord_y == (uint16_t)p_autotile_coord.y) { return; //nothing changed + } } Cell &c = E->get(); @@ -912,12 +892,10 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_ } int TileMap::get_cellv(const Vector2 &p_pos) const { - return get_cell(p_pos.x, p_pos.y); } void TileMap::make_bitmask_area_dirty(const Vector2 &p_pos) { - for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) { for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) { PosKey p(x, y); @@ -929,7 +907,6 @@ void TileMap::make_bitmask_area_dirty(const Vector2 &p_pos) { } void TileMap::update_bitmask_area(const Vector2 &p_pos) { - for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) { for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) { update_cell_bitmask(x, y); @@ -938,15 +915,11 @@ void TileMap::update_bitmask_area(const Vector2 &p_pos) { } void TileMap::update_bitmask_region(const Vector2 &p_start, const Vector2 &p_end) { - if ((p_end.x < p_start.x || p_end.y < p_start.y) || (p_end.x == p_start.x && p_end.y == p_start.y)) { - int i; Array a = get_used_cells(); - for (i = 0; i < a.size(); i++) { - // update_bitmask_area() in order to update cells adjacent to the - // current cell, since ordering in array may not be reliable + for (int i = 0; i < a.size(); i++) { Vector2 vector = (Vector2)a[i]; - update_bitmask_area(Vector2(vector.x, vector.y)); + update_cell_bitmask(vector.x, vector.y); } return; } @@ -958,7 +931,6 @@ void TileMap::update_bitmask_region(const Vector2 &p_start, const Vector2 &p_end } void TileMap::update_cell_bitmask(int p_x, int p_y) { - ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot update cell bitmask if Tileset is not open."); PosKey p(p_x, p_y); Map<PosKey, Cell>::Element *E = tile_map.find(p); @@ -1030,11 +1002,9 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) { _make_quadrant_dirty(Q); } else if (tile_set->tile_get_tile_mode(id) == TileSet::SINGLE_TILE) { - E->get().autotile_coord_x = 0; E->get().autotile_coord_y = 0; } else if (tile_set->tile_get_tile_mode(id) == TileSet::ATLAS_TILE) { - if (tile_set->autotile_get_bitmask(id, Vector2(p_x, p_y)) == TileSet::BIND_CENTER) { Vector2 coord = tile_set->atlastile_get_subtile_by_priority(id, this, Vector2(p_x, p_y)); @@ -1046,7 +1016,6 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) { } void TileMap::update_dirty_bitmask() { - while (dirty_bitmask.size() > 0) { update_cell_bitmask(dirty_bitmask[0].x, dirty_bitmask[0].y); dirty_bitmask.pop_front(); @@ -1054,10 +1023,8 @@ void TileMap::update_dirty_bitmask() { } void TileMap::fix_invalid_tiles() { - ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot fix invalid tiles if Tileset is not open."); for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - if (!tile_set->has_tile(get_cell(E->key().x, E->key().y))) { set_cell(E->key().x, E->key().y, INVALID_CELL); } @@ -1065,58 +1032,61 @@ void TileMap::fix_invalid_tiles() { } int TileMap::get_cell(int p_x, int p_y) const { - PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return INVALID_CELL; + } return E->get().id; } -bool TileMap::is_cell_x_flipped(int p_x, int p_y) const { +bool TileMap::is_cell_x_flipped(int p_x, int p_y) const { PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return false; + } return E->get().flip_h; } -bool TileMap::is_cell_y_flipped(int p_x, int p_y) const { +bool TileMap::is_cell_y_flipped(int p_x, int p_y) const { PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return false; + } return E->get().flip_v; } -bool TileMap::is_cell_transposed(int p_x, int p_y) const { +bool TileMap::is_cell_transposed(int p_x, int p_y) const { PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return false; + } return E->get().transpose; } void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord) { - PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return; + } Cell c = E->get(); c.autotile_coord_x = p_coord.x; @@ -1126,30 +1096,29 @@ void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord) PosKey qk = pk.to_quadrant(_get_quadrant_size()); Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk); - if (!Q) + if (!Q) { return; + } _make_quadrant_dirty(Q); } Vector2 TileMap::get_cell_autotile_coord(int p_x, int p_y) const { - PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return Vector2(); + } return Vector2(E->get().autotile_coord_x, E->get().autotile_coord_y); } void TileMap::_recreate_quadrants() { - _clear_quadrants(); for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - PosKey qk = PosKey(E->key().x, E->key().y).to_quadrant(_get_quadrant_size()); Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk); @@ -1165,50 +1134,41 @@ void TileMap::_recreate_quadrants() { } void TileMap::_clear_quadrants() { - while (quadrant_map.size()) { _erase_quadrant(quadrant_map.front()); } } void TileMap::set_material(const Ref<Material> &p_material) { - CanvasItem::set_material(p_material); _update_all_items_material_state(); } void TileMap::set_use_parent_material(bool p_use_parent_material) { - CanvasItem::set_use_parent_material(p_use_parent_material); _update_all_items_material_state(); } void TileMap::_update_all_items_material_state() { - for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - _update_item_material_state(F->get()); } } } void TileMap::_update_item_material_state(const RID &p_canvas_item) { - RS::get_singleton()->canvas_item_set_use_parent_material(p_canvas_item, get_use_parent_material() || get_material().is_valid()); } void TileMap::clear() { - _clear_quadrants(); tile_map.clear(); used_size_cache_dirty = true; } void TileMap::_set_tile_data(const Vector<int> &p_data) { - ERR_FAIL_COND(format > FORMAT_2); int c = p_data.size(); @@ -1218,11 +1178,11 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) { clear(); for (int i = 0; i < c; i += offset) { - const uint8_t *ptr = (const uint8_t *)&r[i]; uint8_t local[12]; - for (int j = 0; j < ((format == FORMAT_2) ? 12 : 8); j++) + for (int j = 0; j < ((format == FORMAT_2) ? 12 : 8); j++) { local[j] = ptr[j]; + } #ifdef BIG_ENDIAN_ENABLED @@ -1256,7 +1216,6 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) { } Vector<int> TileMap::_get_tile_data() const { - Vector<int> data; data.resize(tile_map.size() * 3); int *w = data.ptrw(); @@ -1269,12 +1228,15 @@ Vector<int> TileMap::_get_tile_data() const { encode_uint16(E->key().x, &ptr[0]); encode_uint16(E->key().y, &ptr[2]); uint32_t val = E->get().id; - if (E->get().flip_h) + if (E->get().flip_h) { val |= (1 << 29); - if (E->get().flip_v) + } + if (E->get().flip_v) { val |= (1 << 30); - if (E->get().transpose) + } + if (E->get().transpose) { val |= (1 << 31); + } encode_uint32(val, &ptr[4]); encode_uint16(E->get().autotile_coord_x, &ptr[8]); encode_uint16(E->get().autotile_coord_y, &ptr[10]); @@ -1296,11 +1258,9 @@ Rect2 TileMap::_edit_get_rect() const { #endif void TileMap::set_collision_layer(uint32_t p_layer) { - collision_layer = p_layer; if (!use_parent) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); PhysicsServer2D::get_singleton()->body_set_collision_layer(q.body, collision_layer); } @@ -1308,11 +1268,9 @@ void TileMap::set_collision_layer(uint32_t p_layer) { } void TileMap::set_collision_mask(uint32_t p_mask) { - collision_mask = p_mask; if (!use_parent) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); PhysicsServer2D::get_singleton()->body_set_collision_mask(q.body, collision_mask); } @@ -1320,45 +1278,43 @@ void TileMap::set_collision_mask(uint32_t p_mask) { } void TileMap::set_collision_layer_bit(int p_bit, bool p_value) { - uint32_t layer = get_collision_layer(); - if (p_value) + if (p_value) { layer |= 1 << p_bit; - else + } else { layer &= ~(1 << p_bit); + } set_collision_layer(layer); } void TileMap::set_collision_mask_bit(int p_bit, bool p_value) { - uint32_t mask = get_collision_mask(); - if (p_value) + if (p_value) { mask |= 1 << p_bit; - else + } else { mask &= ~(1 << p_bit); + } set_collision_mask(mask); } bool TileMap::get_collision_use_kinematic() const { - return use_kinematic; } void TileMap::set_collision_use_kinematic(bool p_use_kinematic) { - _clear_quadrants(); use_kinematic = p_use_kinematic; _recreate_quadrants(); } bool TileMap::get_collision_use_parent() const { - return use_parent; } void TileMap::set_collision_use_parent(bool p_use_parent) { - - if (use_parent == p_use_parent) return; + if (use_parent == p_use_parent) { + return; + } _clear_quadrants(); @@ -1377,11 +1333,9 @@ void TileMap::set_collision_use_parent(bool p_use_parent) { } void TileMap::set_collision_friction(float p_friction) { - friction = p_friction; if (!use_parent) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); PhysicsServer2D::get_singleton()->body_set_param(q.body, PhysicsServer2D::BODY_PARAM_FRICTION, p_friction); } @@ -1389,48 +1343,40 @@ void TileMap::set_collision_friction(float p_friction) { } float TileMap::get_collision_friction() const { - return friction; } void TileMap::set_collision_bounce(float p_bounce) { - bounce = p_bounce; if (!use_parent) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); PhysicsServer2D::get_singleton()->body_set_param(q.body, PhysicsServer2D::BODY_PARAM_BOUNCE, p_bounce); } } } -float TileMap::get_collision_bounce() const { +float TileMap::get_collision_bounce() const { return bounce; } uint32_t TileMap::get_collision_layer() const { - return collision_layer; } uint32_t TileMap::get_collision_mask() const { - return collision_mask; } bool TileMap::get_collision_layer_bit(int p_bit) const { - return get_collision_layer() & (1 << p_bit); } bool TileMap::get_collision_mask_bit(int p_bit) const { - return get_collision_mask() & (1 << p_bit); } void TileMap::set_mode(Mode p_mode) { - _clear_quadrants(); mode = p_mode; _recreate_quadrants(); @@ -1442,7 +1388,6 @@ TileMap::Mode TileMap::get_mode() const { } void TileMap::set_half_offset(HalfOffset p_half_offset) { - _clear_quadrants(); half_offset = p_half_offset; _recreate_quadrants(); @@ -1450,7 +1395,6 @@ void TileMap::set_half_offset(HalfOffset p_half_offset) { } void TileMap::set_tile_origin(TileOrigin p_tile_origin) { - _clear_quadrants(); tile_origin = p_tile_origin; _recreate_quadrants(); @@ -1458,25 +1402,19 @@ void TileMap::set_tile_origin(TileOrigin p_tile_origin) { } TileMap::TileOrigin TileMap::get_tile_origin() const { - return tile_origin; } Vector2 TileMap::get_cell_draw_offset() const { - switch (mode) { - case MODE_SQUARE: { - return Vector2(); } break; case MODE_ISOMETRIC: { - return Vector2(-cell_size.x * 0.5, 0); } break; case MODE_CUSTOM: { - Vector2 min; min.x = MIN(custom_transform[0].x, min.x); min.y = MIN(custom_transform[0].y, min.y); @@ -1494,18 +1432,14 @@ TileMap::HalfOffset TileMap::get_half_offset() const { } Transform2D TileMap::get_cell_transform() const { - switch (mode) { - case MODE_SQUARE: { - Transform2D m; m[0] *= cell_size.x; m[1] *= cell_size.y; return m; } break; case MODE_ISOMETRIC: { - //isometric only makes sense when y is positive in both x and y vectors, otherwise //the drawing of tiles will overlap Transform2D m; @@ -1515,7 +1449,6 @@ Transform2D TileMap::get_cell_transform() const { } break; case MODE_CUSTOM: { - return custom_transform; } break; } @@ -1524,7 +1457,6 @@ Transform2D TileMap::get_cell_transform() const { } void TileMap::set_custom_transform(const Transform2D &p_xform) { - _clear_quadrants(); custom_transform = p_xform; _recreate_quadrants(); @@ -1532,20 +1464,16 @@ void TileMap::set_custom_transform(const Transform2D &p_xform) { } Transform2D TileMap::get_custom_transform() const { - return custom_transform; } Vector2 TileMap::_map_to_world(int p_x, int p_y, bool p_ignore_ofs) const { - Vector2 ret = get_cell_transform().xform(Vector2(p_x, p_y)); if (!p_ignore_ofs) { switch (half_offset) { - case HALF_OFFSET_X: case HALF_OFFSET_NEGATIVE_X: { if (ABS(p_y) & 1) { - ret += get_cell_transform()[0] * (half_offset == HALF_OFFSET_X ? 0.5 : -0.5); } } break; @@ -1564,7 +1492,6 @@ Vector2 TileMap::_map_to_world(int p_x, int p_y, bool p_ignore_ofs) const { } bool TileMap::_set(const StringName &p_name, const Variant &p_value) { - if (p_name == "format") { if (p_value.get_type() == Variant::INT) { format = (DataFormat)(p_value.operator int64_t()); // Set format used for loading @@ -1581,7 +1508,6 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { } bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { - if (p_name == "format") { r_ret = FORMAT_2; // When saving, always save highest format return true; @@ -1593,7 +1519,6 @@ bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { } void TileMap::_get_property_list(List<PropertyInfo> *p_list) const { - PropertyInfo p(Variant::INT, "format", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL); p_list->push_back(p); @@ -1608,16 +1533,13 @@ void TileMap::_validate_property(PropertyInfo &property) const { } Vector2 TileMap::map_to_world(const Vector2 &p_pos, bool p_ignore_ofs) const { - return _map_to_world(p_pos.x, p_pos.y, p_ignore_ofs); } Vector2 TileMap::world_to_map(const Vector2 &p_pos) const { - Vector2 ret = get_cell_transform().affine_inverse().xform(p_pos); switch (half_offset) { - case HALF_OFFSET_X: { if (int(floor(ret.y)) & 1) { ret.x -= 0.5; @@ -1651,22 +1573,19 @@ Vector2 TileMap::world_to_map(const Vector2 &p_pos) const { return ret.floor(); } -void TileMap::set_y_sort_mode(bool p_enable) { - +void TileMap::set_y_sort_enabled(bool p_enable) { _clear_quadrants(); - y_sort_mode = p_enable; - RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), y_sort_mode); + use_y_sort = p_enable; + RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), use_y_sort); _recreate_quadrants(); emit_signal("settings_changed"); } -bool TileMap::is_y_sort_mode_enabled() const { - - return y_sort_mode; +bool TileMap::is_y_sort_enabled() const { + return use_y_sort; } void TileMap::set_compatibility_mode(bool p_enable) { - _clear_quadrants(); compatibility_mode = p_enable; _recreate_quadrants(); @@ -1674,12 +1593,10 @@ void TileMap::set_compatibility_mode(bool p_enable) { } bool TileMap::is_compatibility_mode_enabled() const { - return compatibility_mode; } void TileMap::set_centered_textures(bool p_enable) { - _clear_quadrants(); centered_textures = p_enable; _recreate_quadrants(); @@ -1687,17 +1604,14 @@ void TileMap::set_centered_textures(bool p_enable) { } bool TileMap::is_centered_textures_enabled() const { - return centered_textures; } TypedArray<Vector2i> TileMap::get_used_cells() const { - TypedArray<Vector2i> a; a.resize(tile_map.size()); int i = 0; for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - Vector2i p(E->key().x, E->key().y); a[i++] = p; } @@ -1705,11 +1619,9 @@ TypedArray<Vector2i> TileMap::get_used_cells() const { return a; } -TypedArray<Vector2i> TileMap::get_used_cells_by_id(int p_id) const { - +TypedArray<Vector2i> TileMap::get_used_cells_by_index(int p_id) const { TypedArray<Vector2i> a; for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - if (E->value().id == p_id) { Vector2i p(E->key().x, E->key().y); a.push_back(p); @@ -1741,10 +1653,8 @@ Rect2 TileMap::get_used_rect() { // Not const because of cache } void TileMap::set_occluder_light_mask(int p_mask) { - occluder_light_mask = p_mask; for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - for (Map<PosKey, Quadrant::Occluder>::Element *F = E->get().occluder_instances.front(); F; F = F->next()) { RenderingServer::get_singleton()->canvas_light_occluder_set_light_mask(F->get().id, occluder_light_mask); } @@ -1752,15 +1662,12 @@ void TileMap::set_occluder_light_mask(int p_mask) { } int TileMap::get_occluder_light_mask() const { - return occluder_light_mask; } void TileMap::set_light_mask(int p_light_mask) { - CanvasItem::set_light_mask(p_light_mask); for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - for (List<RID>::Element *F = E->get().canvas_items.front(); F; F = F->next()) { RenderingServer::get_singleton()->canvas_item_set_light_mask(F->get(), get_light_mask()); } @@ -1768,9 +1675,9 @@ void TileMap::set_light_mask(int p_light_mask) { } void TileMap::set_clip_uv(bool p_enable) { - - if (clip_uv == p_enable) + if (clip_uv == p_enable) { return; + } _clear_quadrants(); clip_uv = p_enable; @@ -1778,12 +1685,32 @@ void TileMap::set_clip_uv(bool p_enable) { } bool TileMap::get_clip_uv() const { - return clip_uv; } -String TileMap::get_configuration_warning() const { +void TileMap::set_texture_filter(TextureFilter p_texture_filter) { + CanvasItem::set_texture_filter(p_texture_filter); + for (Map<PosKey, Quadrant>::Element *F = quadrant_map.front(); F; F = F->next()) { + Quadrant &q = F->get(); + for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { + RenderingServer::get_singleton()->canvas_item_set_default_texture_filter(E->get(), RS::CanvasItemTextureFilter(p_texture_filter)); + _make_quadrant_dirty(F); + } + } +} + +void TileMap::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) { + CanvasItem::set_texture_repeat(p_texture_repeat); + for (Map<PosKey, Quadrant>::Element *F = quadrant_map.front(); F; F = F->next()) { + Quadrant &q = F->get(); + for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { + RenderingServer::get_singleton()->canvas_item_set_default_texture_repeat(E->get(), RS::CanvasItemTextureRepeat(p_texture_repeat)); + _make_quadrant_dirty(F); + } + } +} +String TileMap::get_configuration_warning() const { String warning = Node2D::get_configuration_warning(); if (use_parent && !collision_parent) { @@ -1797,7 +1724,6 @@ String TileMap::get_configuration_warning() const { } void TileMap::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_tileset", "tileset"), &TileMap::set_tileset); ClassDB::bind_method(D_METHOD("get_tileset"), &TileMap::get_tileset); @@ -1825,8 +1751,8 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_clip_uv", "enable"), &TileMap::set_clip_uv); ClassDB::bind_method(D_METHOD("get_clip_uv"), &TileMap::get_clip_uv); - ClassDB::bind_method(D_METHOD("set_y_sort_mode", "enable"), &TileMap::set_y_sort_mode); - ClassDB::bind_method(D_METHOD("is_y_sort_mode_enabled"), &TileMap::is_y_sort_mode_enabled); + ClassDB::bind_method(D_METHOD("set_y_sort_enabled", "enable"), &TileMap::set_y_sort_enabled); + ClassDB::bind_method(D_METHOD("is_y_sort_enabled"), &TileMap::is_y_sort_enabled); ClassDB::bind_method(D_METHOD("set_compatibility_mode", "enable"), &TileMap::set_compatibility_mode); ClassDB::bind_method(D_METHOD("is_compatibility_mode_enabled"), &TileMap::is_compatibility_mode_enabled); @@ -1876,7 +1802,7 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear); ClassDB::bind_method(D_METHOD("get_used_cells"), &TileMap::get_used_cells); - ClassDB::bind_method(D_METHOD("get_used_cells_by_id", "id"), &TileMap::get_used_cells_by_id); + ClassDB::bind_method(D_METHOD("get_used_cells_by_index", "index"), &TileMap::get_used_cells_by_index); ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect); ClassDB::bind_method(D_METHOD("map_to_world", "map_position", "ignore_half_ofs"), &TileMap::map_to_world, DEFVAL(false)); @@ -1900,7 +1826,7 @@ void TileMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "cell_custom_transform"), "set_custom_transform", "get_custom_transform"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_half_offset", PROPERTY_HINT_ENUM, "Offset X,Offset Y,Disabled,Offset Negative X,Offset Negative Y"), "set_half_offset", "get_half_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_tile_origin", PROPERTY_HINT_ENUM, "Top Left,Center,Bottom Left"), "set_tile_origin", "get_tile_origin"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_y_sort"), "set_y_sort_mode", "is_y_sort_mode_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_y_sort"), "set_y_sort_enabled", "is_y_sort_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compatibility_mode"), "set_compatibility_mode", "is_compatibility_mode_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered_textures"), "set_centered_textures", "is_centered_textures_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_clip_uv"), "set_clip_uv", "get_clip_uv"); @@ -1944,7 +1870,6 @@ void TileMap::_changed_callback(Object *p_changed, const char *p_prop) { } TileMap::TileMap() { - rect_cache_dirty = true; used_size_cache_dirty = true; pending_update = false; @@ -1962,7 +1887,7 @@ TileMap::TileMap() { collision_parent = nullptr; use_kinematic = false; navigation = nullptr; - y_sort_mode = false; + use_y_sort = false; compatibility_mode = false; centered_textures = false; occluder_light_mask = 1; @@ -1976,9 +1901,9 @@ TileMap::TileMap() { } TileMap::~TileMap() { - - if (tile_set.is_valid()) + if (tile_set.is_valid()) { tile_set->remove_change_receptor(this); + } clear(); } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index cc1537f583..22b615a379 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -31,8 +31,8 @@ #ifndef TILE_MAP_H #define TILE_MAP_H -#include "core/self_list.h" -#include "core/vset.h" +#include "core/templates/self_list.h" +#include "core/templates/vset.h" #include "scene/2d/navigation_2d.h" #include "scene/2d/node_2d.h" #include "scene/resources/tile_set.h" @@ -40,7 +40,6 @@ class CollisionObject2D; class TileMap : public Node2D { - GDCLASS(TileMap, Node2D); public: @@ -82,7 +81,6 @@ private: Navigation2D *navigation; union PosKey { - struct { int16_t x; int16_t y; @@ -112,7 +110,6 @@ private: }; union Cell { - struct { int32_t id : 24; bool flip_h : 1; @@ -130,7 +127,6 @@ private: List<PosKey> dirty_bitmask; struct Quadrant { - Vector2 pos; List<RID> canvas_items; RID body; @@ -187,7 +183,7 @@ private: Rect2 used_size_cache; bool used_size_cache_dirty; bool quadrant_order_dirty; - bool y_sort_mode; + bool use_y_sort; bool compatibility_mode; bool centered_textures; bool clip_uv; @@ -236,8 +232,8 @@ protected: void _notification(int p_what); static void _bind_methods(); - virtual void _validate_property(PropertyInfo &property) const; - virtual void _changed_callback(Object *p_changed, const char *p_prop); + virtual void _validate_property(PropertyInfo &property) const override; + virtual void _changed_callback(Object *p_changed, const char *p_prop) override; public: enum { @@ -245,7 +241,7 @@ public: }; #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; + virtual Rect2 _edit_get_rect() const override; #endif void set_tileset(const Ref<TileSet> &p_tileset); @@ -319,8 +315,8 @@ public: Vector2 map_to_world(const Vector2 &p_pos, bool p_ignore_ofs = false) const; Vector2 world_to_map(const Vector2 &p_pos) const; - void set_y_sort_mode(bool p_enable); - bool is_y_sort_mode_enabled() const; + void set_y_sort_enabled(bool p_enable); + bool is_y_sort_enabled() const; void set_compatibility_mode(bool p_enable); bool is_compatibility_mode_enabled() const; @@ -329,22 +325,26 @@ public: bool is_centered_textures_enabled() const; TypedArray<Vector2i> get_used_cells() const; - TypedArray<Vector2i> get_used_cells_by_id(int p_id) const; + TypedArray<Vector2i> get_used_cells_by_index(int p_index) const; Rect2 get_used_rect(); // Not const because of cache void set_occluder_light_mask(int p_mask); int get_occluder_light_mask() const; - virtual void set_light_mask(int p_light_mask); + virtual void set_light_mask(int p_light_mask) override; - virtual void set_material(const Ref<Material> &p_material); + virtual void set_material(const Ref<Material> &p_material) override; - virtual void set_use_parent_material(bool p_use_parent_material); + virtual void set_use_parent_material(bool p_use_parent_material) override; void set_clip_uv(bool p_enable); bool get_clip_uv() const; - String get_configuration_warning() const; + String get_configuration_warning() const override; + + virtual void set_texture_filter(CanvasItem::TextureFilter p_texture_filter) override; + + virtual void set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) override; void fix_invalid_tiles(); void clear(); diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 2cb979a0e0..4597300db8 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -30,110 +30,102 @@ #include "touch_screen_button.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/input/input_map.h" #include "core/os/os.h" #include "scene/main/window.h" # void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) { - texture = p_texture; update(); } Ref<Texture2D> TouchScreenButton::get_texture() const { - return texture; } void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pressed) { - texture_pressed = p_texture_pressed; update(); } Ref<Texture2D> TouchScreenButton::get_texture_pressed() const { - return texture_pressed; } void TouchScreenButton::set_bitmask(const Ref<BitMap> &p_bitmask) { - bitmask = p_bitmask; } Ref<BitMap> TouchScreenButton::get_bitmask() const { - return bitmask; } void TouchScreenButton::set_shape(const Ref<Shape2D> &p_shape) { - - if (shape.is_valid()) + if (shape.is_valid()) { shape->disconnect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); + } shape = p_shape; - if (shape.is_valid()) + if (shape.is_valid()) { shape->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); + } update(); } Ref<Shape2D> TouchScreenButton::get_shape() const { - return shape; } void TouchScreenButton::set_shape_centered(bool p_shape_centered) { - shape_centered = p_shape_centered; update(); } bool TouchScreenButton::is_shape_visible() const { - return shape_visible; } void TouchScreenButton::set_shape_visible(bool p_shape_visible) { - shape_visible = p_shape_visible; update(); } bool TouchScreenButton::is_shape_centered() const { - return shape_centered; } void TouchScreenButton::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_DRAW: { - - if (!is_inside_tree()) + if (!is_inside_tree()) { return; - 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) + } + 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; + } if (finger_pressed != -1) { - - if (texture_pressed.is_valid()) + if (texture_pressed.is_valid()) { draw_texture(texture_pressed, Point2()); - else if (texture.is_valid()) + } else if (texture.is_valid()) { draw_texture(texture, Point2()); + } } else { - if (texture.is_valid()) + if (texture.is_valid()) { draw_texture(texture, Point2()); + } } - if (!shape_visible) + if (!shape_visible) { return; - if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) + } + if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) { return; + } if (shape.is_valid()) { Color draw_col = get_tree()->get_debug_collisions_color(); @@ -145,80 +137,79 @@ void TouchScreenButton::_notification(int p_what) { } 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) + 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; + } update(); - if (!Engine::get_singleton()->is_editor_hint()) + if (!Engine::get_singleton()->is_editor_hint()) { set_process_input(is_visible_in_tree()); + } } break; case NOTIFICATION_EXIT_TREE: { - if (is_pressed()) + if (is_pressed()) { _release(true); + } } break; case NOTIFICATION_VISIBILITY_CHANGED: { - if (Engine::get_singleton()->is_editor_hint()) + if (Engine::get_singleton()->is_editor_hint()) { break; + } if (is_visible_in_tree()) { set_process_input(true); } else { set_process_input(false); - if (is_pressed()) + if (is_pressed()) { _release(); + } } } break; case NOTIFICATION_PAUSED: { - if (is_pressed()) + if (is_pressed()) { _release(); + } } break; } } bool TouchScreenButton::is_pressed() const { - return finger_pressed != -1; } void TouchScreenButton::set_action(const String &p_action) { - action = p_action; } String TouchScreenButton::get_action() const { - return action; } void TouchScreenButton::_input(const Ref<InputEvent> &p_event) { - - if (!get_tree()) + if (!get_tree()) { return; + } - if (p_event->get_device() != 0) + if (p_event->get_device() != 0) { return; + } ERR_FAIL_COND(!is_visible_in_tree()); const InputEventScreenTouch *st = Object::cast_to<InputEventScreenTouch>(*p_event); if (passby_press) { - const InputEventScreenDrag *sd = Object::cast_to<InputEventScreenDrag>(*p_event); if (st && !st->is_pressed() && finger_pressed == st->get_index()) { - _release(); } if ((st && st->is_pressed()) || sd) { - int index = st ? st->get_index() : sd->get_index(); Point2 coord = st ? st->get_position() : sd->get_position(); if (finger_pressed == -1 || index == finger_pressed) { - if (_is_point_inside(coord)) { if (finger_pressed == -1) { _press(index); @@ -232,14 +223,12 @@ void TouchScreenButton::_input(const Ref<InputEvent> &p_event) { } } else { - if (st) { - if (st->is_pressed()) { - const bool can_press = finger_pressed == -1; - if (!can_press) + if (!can_press) { return; //already fingering + } if (_is_point_inside(st->get_position())) { _press(st->get_index()); @@ -260,37 +249,36 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { bool check_rect = true; if (shape.is_valid()) { - check_rect = false; - Transform2D xform = shape_centered ? Transform2D().translated(shape->get_rect().size * 0.5f) : Transform2D(); + + Vector2 size = texture.is_null() ? shape->get_rect().size : texture->get_size(); + Transform2D xform = shape_centered ? Transform2D().translated(size * 0.5f) : Transform2D(); touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); } if (bitmask.is_valid()) { - check_rect = false; if (!touched && Rect2(Point2(), bitmask->get_size()).has_point(coord)) { - - if (bitmask->get_bit(coord)) + if (bitmask->get_bit(coord)) { touched = true; + } } } if (!touched && check_rect) { - if (texture.is_valid()) + if (texture.is_valid()) { touched = Rect2(Size2(), texture->get_size()).has_point(coord); + } } return touched; } void TouchScreenButton::_press(int p_finger_pressed) { - finger_pressed = p_finger_pressed; if (action != StringName()) { - - InputFilter::get_singleton()->action_press(action); + Input::get_singleton()->action_press(action); Ref<InputEventAction> iea; iea.instance(); iea->set_action(action); @@ -303,14 +291,11 @@ void TouchScreenButton::_press(int p_finger_pressed) { } void TouchScreenButton::_release(bool p_exiting_tree) { - finger_pressed = -1; if (action != StringName()) { - - InputFilter::get_singleton()->action_release(action); + Input::get_singleton()->action_release(action); if (!p_exiting_tree) { - Ref<InputEventAction> iea; iea.instance(); iea->set_action(action); @@ -327,8 +312,9 @@ void TouchScreenButton::_release(bool p_exiting_tree) { #ifdef TOOLS_ENABLED Rect2 TouchScreenButton::_edit_get_rect() const { - if (texture.is_null()) + if (texture.is_null()) { return CanvasItem::_edit_get_rect(); + } return Rect2(Size2(), texture->get_size()); } @@ -339,8 +325,9 @@ bool TouchScreenButton::_edit_use_rect() const { #endif Rect2 TouchScreenButton::get_anchorable_rect() const { - if (texture.is_null()) + if (texture.is_null()) { return CanvasItem::get_anchorable_rect(); + } return Rect2(Size2(), texture->get_size()); } @@ -351,22 +338,18 @@ void TouchScreenButton::set_visibility_mode(VisibilityMode p_mode) { } TouchScreenButton::VisibilityMode TouchScreenButton::get_visibility_mode() const { - return visibility; } void TouchScreenButton::set_passby_press(bool p_enable) { - passby_press = p_enable; } bool TouchScreenButton::is_passby_press_enabled() const { - return passby_press; } 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); @@ -416,7 +399,6 @@ void TouchScreenButton::_bind_methods() { } TouchScreenButton::TouchScreenButton() { - finger_pressed = -1; passby_press = false; visibility = VISIBILITY_ALWAYS; diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h index 42e93f7048..287f886c2c 100644 --- a/scene/2d/touch_screen_button.h +++ b/scene/2d/touch_screen_button.h @@ -37,7 +37,6 @@ #include "scene/resources/texture.h" class TouchScreenButton : public Node2D { - GDCLASS(TouchScreenButton, Node2D); public: @@ -75,8 +74,8 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; #endif void set_texture(const Ref<Texture2D> &p_texture); @@ -108,7 +107,7 @@ public: bool is_pressed() const; - virtual Rect2 get_anchorable_rect() const; + virtual Rect2 get_anchorable_rect() const override; TouchScreenButton(); }; diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index c374dd5faa..e217f2a394 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -30,7 +30,7 @@ #include "visibility_notifier_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "gpu_particles_2d.h" #include "scene/2d/animated_sprite_2d.h" #include "scene/2d/physics_body_2d.h" @@ -49,12 +49,12 @@ bool VisibilityNotifier2D::_edit_use_rect() const { #endif void VisibilityNotifier2D::_enter_viewport(Viewport *p_viewport) { - ERR_FAIL_COND(viewports.has(p_viewport)); viewports.insert(p_viewport); - if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) + if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) { return; + } if (viewports.size() == 1) { emit_signal(SceneStringNames::get_singleton()->screen_entered); @@ -65,12 +65,12 @@ void VisibilityNotifier2D::_enter_viewport(Viewport *p_viewport) { } void VisibilityNotifier2D::_exit_viewport(Viewport *p_viewport) { - ERR_FAIL_COND(!viewports.has(p_viewport)); viewports.erase(p_viewport); - if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) + if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) { return; + } emit_signal(SceneStringNames::get_singleton()->viewport_exited, p_viewport); if (viewports.size() == 0) { @@ -81,7 +81,6 @@ void VisibilityNotifier2D::_exit_viewport(Viewport *p_viewport) { } void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) { - rect = p_rect; if (is_inside_tree()) { get_world_2d()->_update_notifier(this, get_global_transform().xform(rect)); @@ -95,44 +94,35 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) { } Rect2 VisibilityNotifier2D::get_rect() const { - return rect; } void VisibilityNotifier2D::_notification(int p_what) { - switch (p_what) { case NOTIFICATION_ENTER_TREE: { - //get_world_2d()-> get_world_2d()->_register_notifier(this, get_global_transform().xform(rect)); } break; case NOTIFICATION_TRANSFORM_CHANGED: { - //get_world_2d()-> get_world_2d()->_update_notifier(this, get_global_transform().xform(rect)); } 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: { - get_world_2d()->_remove_notifier(this); } break; } } bool VisibilityNotifier2D::is_on_screen() const { - return viewports.size() > 0; } void VisibilityNotifier2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_rect", "rect"), &VisibilityNotifier2D::set_rect); ClassDB::bind_method(D_METHOD("get_rect"), &VisibilityNotifier2D::get_rect); ClassDB::bind_method(D_METHOD("is_on_screen"), &VisibilityNotifier2D::is_on_screen); @@ -146,7 +136,6 @@ void VisibilityNotifier2D::_bind_methods() { } VisibilityNotifier2D::VisibilityNotifier2D() { - rect = Rect2(-10, -10, 20, 20); set_notify_transform(true); } @@ -154,44 +143,42 @@ VisibilityNotifier2D::VisibilityNotifier2D() { ////////////////////////////////////// void VisibilityEnabler2D::_screen_enter() { - for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) { - _change_node_state(E->key(), true); } - if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) + if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) { get_parent()->set_physics_process(true); - if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) + } + if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) { get_parent()->set_process(true); + } visible = true; } void VisibilityEnabler2D::_screen_exit() { - for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) { - _change_node_state(E->key(), false); } - if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) + if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) { get_parent()->set_physics_process(false); - if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) + } + if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) { get_parent()->set_process(false); + } visible = false; } void VisibilityEnabler2D::_find_nodes(Node *p_node) { - bool add = false; Variant meta; { RigidBody2D *rb2d = Object::cast_to<RigidBody2D>(p_node); if (rb2d && ((rb2d->get_mode() == RigidBody2D::MODE_CHARACTER || rb2d->get_mode() == RigidBody2D::MODE_RIGID))) { - add = true; meta = rb2d->get_mode(); } @@ -219,7 +206,6 @@ void VisibilityEnabler2D::_find_nodes(Node *p_node) { } if (add) { - p_node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler2D::_node_removed), varray(p_node), CONNECT_ONESHOT); nodes[p_node] = meta; _change_node_state(p_node, false); @@ -227,42 +213,52 @@ void VisibilityEnabler2D::_find_nodes(Node *p_node) { for (int i = 0; i < p_node->get_child_count(); i++) { Node *c = p_node->get_child(i); - if (c->get_filename() != String()) + if (c->get_filename() != String()) { continue; //skip, instance + } _find_nodes(c); } } void VisibilityEnabler2D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - - if (Engine::get_singleton()->is_editor_hint()) + if (Engine::get_singleton()->is_editor_hint()) { return; + } Node *from = this; //find where current scene starts - while (from->get_parent() && from->get_filename() == String()) + while (from->get_parent() && from->get_filename() == String()) { from = from->get_parent(); + } _find_nodes(from); - if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) - get_parent()->set_physics_process(false); - if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) - get_parent()->set_process(false); + // We need to defer the call of set_process and set_physics_process, + // otherwise they are overwritten inside NOTIFICATION_READY. + // We can't use call_deferred, because it happens after a physics frame. + // The ready signal works as it's emitted immediately after NOTIFICATION_READY. + + if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) { + get_parent()->connect(SceneStringNames::get_singleton()->ready, + callable_mp(get_parent(), &Node::set_physics_process), varray(false), CONNECT_ONESHOT); + } + if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) { + get_parent()->connect(SceneStringNames::get_singleton()->ready, + callable_mp(get_parent(), &Node::set_process), varray(false), CONNECT_ONESHOT); + } } if (p_what == NOTIFICATION_EXIT_TREE) { - - if (Engine::get_singleton()->is_editor_hint()) + if (Engine::get_singleton()->is_editor_hint()) { return; + } for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) { - - if (!visible) + if (!visible) { _change_node_state(E->key(), true); + } E->key()->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler2D::_node_removed)); } @@ -271,13 +267,11 @@ void VisibilityEnabler2D::_notification(int p_what) { } void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) { - ERR_FAIL_COND(!nodes.has(p_node)); if (enabler[ENABLER_FREEZE_BODIES]) { RigidBody2D *rb = Object::cast_to<RigidBody2D>(p_node); if (rb) { - rb->set_sleeping(!p_enabled); } } @@ -286,7 +280,6 @@ void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); if (ap) { - ap->set_active(p_enabled); } } @@ -295,11 +288,11 @@ void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) { AnimatedSprite2D *as = Object::cast_to<AnimatedSprite2D>(p_node); if (as) { - - if (p_enabled) + if (p_enabled) { as->play(); - else + } else { as->stop(); + } } } @@ -307,30 +300,33 @@ void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) { GPUParticles2D *ps = Object::cast_to<GPUParticles2D>(p_node); if (ps) { - ps->set_emitting(p_enabled); } } } void VisibilityEnabler2D::_node_removed(Node *p_node) { - - if (!visible) + if (!visible) { _change_node_state(p_node, true); + } nodes.erase(p_node); } String VisibilityEnabler2D::get_configuration_warning() const { + String warning = VisibilityNotifier2D::get_configuration_warning(); + #ifdef TOOLS_ENABLED if (is_inside_tree() && get_parent() && (get_parent()->get_filename() == String() && get_parent() != get_tree()->get_edited_scene_root())) { - return TTR("VisibilityEnabler2D works best when used with the edited scene root directly as parent."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("VisibilityEnabler2D works best when used with the edited scene root directly as parent."); } #endif - return String(); + return warning; } void VisibilityEnabler2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_enabler", "enabler", "enabled"), &VisibilityEnabler2D::set_enabler); ClassDB::bind_method(D_METHOD("is_enabler_enabled", "enabler"), &VisibilityEnabler2D::is_enabler_enabled); ClassDB::bind_method(D_METHOD("_node_removed"), &VisibilityEnabler2D::_node_removed); @@ -352,20 +348,19 @@ void VisibilityEnabler2D::_bind_methods() { } void VisibilityEnabler2D::set_enabler(Enabler p_enabler, bool p_enable) { - ERR_FAIL_INDEX(p_enabler, ENABLER_MAX); enabler[p_enabler] = p_enable; } -bool VisibilityEnabler2D::is_enabler_enabled(Enabler p_enabler) const { +bool VisibilityEnabler2D::is_enabler_enabled(Enabler p_enabler) const { ERR_FAIL_INDEX_V(p_enabler, ENABLER_MAX, false); return enabler[p_enabler]; } VisibilityEnabler2D::VisibilityEnabler2D() { - - for (int i = 0; i < ENABLER_MAX; i++) + for (int i = 0; i < ENABLER_MAX; i++) { enabler[i] = true; + } enabler[ENABLER_PARENT_PROCESS] = false; enabler[ENABLER_PARENT_PHYSICS_PROCESS] = false; diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index a3b79d29e9..671378bd4e 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -35,7 +35,6 @@ class Viewport; class VisibilityNotifier2D : public Node2D { - GDCLASS(VisibilityNotifier2D, Node2D); Set<Viewport *> viewports; @@ -56,8 +55,8 @@ protected: public: #ifdef TOOLS_ENABLED - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; #endif void set_rect(const Rect2 &p_rect); @@ -69,7 +68,6 @@ public: }; class VisibilityEnabler2D : public VisibilityNotifier2D { - GDCLASS(VisibilityEnabler2D, VisibilityNotifier2D); public: @@ -84,8 +82,8 @@ public: }; protected: - virtual void _screen_enter(); - virtual void _screen_exit(); + virtual void _screen_enter() override; + virtual void _screen_exit() override; bool visible; @@ -104,7 +102,7 @@ public: void set_enabler(Enabler p_enabler, bool p_enable); bool is_enabler_enabled(Enabler p_enabler) const; - String get_configuration_warning() const; + String get_configuration_warning() const override; VisibilityEnabler2D(); }; diff --git a/scene/2d/y_sort.cpp b/scene/2d/y_sort.cpp index 15d97eeaa0..7c2b41db70 100644 --- a/scene/2d/y_sort.cpp +++ b/scene/2d/y_sort.cpp @@ -31,18 +31,15 @@ #include "y_sort.h" void YSort::set_sort_enabled(bool p_enabled) { - sort_enabled = p_enabled; RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), sort_enabled); } bool YSort::is_sort_enabled() const { - return sort_enabled; } void YSort::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_sort_enabled", "enabled"), &YSort::set_sort_enabled); ClassDB::bind_method(D_METHOD("is_sort_enabled"), &YSort::is_sort_enabled); @@ -51,7 +48,6 @@ void YSort::_bind_methods() { } YSort::YSort() { - sort_enabled = true; RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), true); } |