diff options
Diffstat (limited to 'scene/2d')
76 files changed, 3430 insertions, 6004 deletions
diff --git a/scene/2d/SCsub b/scene/2d/SCsub index b01e2fd54d..fc61250247 100644 --- a/scene/2d/SCsub +++ b/scene/2d/SCsub @@ -1,5 +1,5 @@ #!/usr/bin/env python -Import('env') +Import("env") env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite_2d.cpp index 917ced5feb..3268544519 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* animated_sprite.cpp */ +/* animated_sprite_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,88 +28,94 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "animated_sprite.h" +#include "animated_sprite_2d.h" #include "core/os/os.h" #include "scene/scene_string_names.h" #define NORMAL_SUFFIX "_normal" +#define SPECULAR_SUFFIX "_specular" #ifdef TOOLS_ENABLED -Dictionary AnimatedSprite::_edit_get_state() const { +Dictionary AnimatedSprite2D::_edit_get_state() const { Dictionary state = Node2D::_edit_get_state(); state["offset"] = offset; return state; } -void AnimatedSprite::_edit_set_state(const Dictionary &p_state) { +void AnimatedSprite2D::_edit_set_state(const Dictionary &p_state) { Node2D::_edit_set_state(p_state); set_offset(p_state["offset"]); } -void AnimatedSprite::_edit_set_pivot(const Point2 &p_pivot) { +void AnimatedSprite2D::_edit_set_pivot(const Point2 &p_pivot) { set_offset(get_offset() - p_pivot); set_position(get_transform().xform(p_pivot)); } -Point2 AnimatedSprite::_edit_get_pivot() const { +Point2 AnimatedSprite2D::_edit_get_pivot() const { return Vector2(); } -bool AnimatedSprite::_edit_use_pivot() const { +bool AnimatedSprite2D::_edit_use_pivot() const { return true; } -Rect2 AnimatedSprite::_edit_get_rect() const { +Rect2 AnimatedSprite2D::_edit_get_rect() const { return _get_rect(); } -bool AnimatedSprite::_edit_use_rect() const { +bool AnimatedSprite2D::_edit_use_rect() const { if (!frames.is_valid() || !frames->has_animation(animation) || frame < 0 || frame >= frames->get_frame_count(animation)) { return false; } - Ref<Texture> t; - if (animation) + Ref<Texture2D> t; + if (animation) { t = frames->get_frame(animation, frame); + } return t.is_valid(); } #endif -Rect2 AnimatedSprite::get_anchorable_rect() const { +Rect2 AnimatedSprite2D::get_anchorable_rect() const { return _get_rect(); } -Rect2 AnimatedSprite::_get_rect() const { +Rect2 AnimatedSprite2D::_get_rect() const { if (!frames.is_valid() || !frames->has_animation(animation) || frame < 0 || frame >= frames->get_frame_count(animation)) { return Rect2(); } - Ref<Texture> t; - if (animation) + Ref<Texture2D> t; + 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<Texture> &p_frame, int p_at_pos) { - +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(); } @@ -122,15 +128,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."); @@ -139,30 +144,27 @@ 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."); @@ -170,15 +172,14 @@ void SpriteFrames::rename_animation(const StringName &p_prev, const StringName & 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()); } @@ -186,14 +187,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()); @@ -203,14 +202,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; @@ -221,6 +219,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."); @@ -228,22 +227,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; @@ -260,11 +258,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")); @@ -277,7 +274,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); } @@ -287,7 +283,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); @@ -321,16 +316,14 @@ void SpriteFrames::_bind_methods() { } SpriteFrames::SpriteFrames() { - add_animation(SceneStringNames::get_singleton()->_default); } -void AnimatedSprite::_validate_property(PropertyInfo &property) const { - - if (!frames.is_valid()) +void AnimatedSprite2D::_validate_property(PropertyInfo &property) const { + if (!frames.is_valid()) { return; + } if (property.name == "animation") { - property.hint = PROPERTY_HINT_ENUM; List<StringName> names; frames->get_animation_list(&names); @@ -367,44 +360,46 @@ void AnimatedSprite::_validate_property(PropertyInfo &property) const { } } -void AnimatedSprite::_notification(int p_what) { - +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; @@ -412,10 +407,11 @@ void AnimatedSprite::_notification(int p_what) { } } } else { - if (backwards) + if (backwards) { frame--; - else + } else { frame++; + } } update(); @@ -430,51 +426,59 @@ void AnimatedSprite::_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<Texture> texture = frames->get_frame(animation, frame); - if (texture.is_null()) + Ref<Texture2D> texture = frames->get_frame(animation, frame); + if (texture.is_null()) { return; + } - Ref<Texture> normal = frames->get_normal_frame(animation, frame); + 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()) { 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); + 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)); } break; } } -void AnimatedSprite::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { - - if (frames.is_valid()) - frames->disconnect("changed", this, "_res_changed"); +void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { + if (frames.is_valid()) { + frames->disconnect("changed", callable_mp(this, &AnimatedSprite2D::_res_changed)); + } frames = p_frames; - if (frames.is_valid()) - frames->connect("changed", this, "_res_changed"); + if (frames.is_valid()) { + frames->connect("changed", callable_mp(this, &AnimatedSprite2D::_res_changed)); + } if (!frames.is_valid()) { frame = 0; @@ -488,28 +492,29 @@ void AnimatedSprite::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { update_configuration_warning(); } -Ref<SpriteFrames> AnimatedSprite::get_sprite_frames() const { - +Ref<SpriteFrames> AnimatedSprite2D::get_sprite_frames() const { return frames; } -void AnimatedSprite::set_frame(int p_frame) { - +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(); @@ -517,13 +522,12 @@ void AnimatedSprite::set_frame(int p_frame) { _change_notify("frame"); emit_signal(SceneStringNames::get_singleton()->frame_changed); } -int AnimatedSprite::get_frame() const { +int AnimatedSprite2D::get_frame() const { return frame; } -void AnimatedSprite::set_speed_scale(float p_speed_scale) { - +void AnimatedSprite2D::set_speed_scale(float p_speed_scale) { float elapsed = _get_frame_duration() - timeout; speed_scale = MAX(p_speed_scale, 0.0f); @@ -533,101 +537,91 @@ void AnimatedSprite::set_speed_scale(float p_speed_scale) { timeout -= elapsed; } -float AnimatedSprite::get_speed_scale() const { - +float AnimatedSprite2D::get_speed_scale() const { return speed_scale; } -void AnimatedSprite::set_centered(bool p_center) { - +void AnimatedSprite2D::set_centered(bool p_center) { centered = p_center; update(); item_rect_changed(); } -bool AnimatedSprite::is_centered() const { - +bool AnimatedSprite2D::is_centered() const { return centered; } -void AnimatedSprite::set_offset(const Point2 &p_offset) { - +void AnimatedSprite2D::set_offset(const Point2 &p_offset) { offset = p_offset; update(); item_rect_changed(); _change_notify("offset"); } -Point2 AnimatedSprite::get_offset() const { +Point2 AnimatedSprite2D::get_offset() const { return offset; } -void AnimatedSprite::set_flip_h(bool p_flip) { - +void AnimatedSprite2D::set_flip_h(bool p_flip) { hflip = p_flip; update(); } -bool AnimatedSprite::is_flipped_h() const { +bool AnimatedSprite2D::is_flipped_h() const { return hflip; } -void AnimatedSprite::set_flip_v(bool p_flip) { - +void AnimatedSprite2D::set_flip_v(bool p_flip) { vflip = p_flip; update(); } -bool AnimatedSprite::is_flipped_v() const { +bool AnimatedSprite2D::is_flipped_v() const { return vflip; } -void AnimatedSprite::_res_changed() { - +void AnimatedSprite2D::_res_changed() { set_frame(frame); _change_notify("frame"); _change_notify("animation"); update(); } -void AnimatedSprite::_set_playing(bool p_playing) { - - if (playing == p_playing) +void AnimatedSprite2D::_set_playing(bool p_playing) { + if (playing == p_playing) { return; + } playing = p_playing; _reset_timeout(); set_process_internal(playing); } -bool AnimatedSprite::_is_playing() const { - +bool AnimatedSprite2D::_is_playing() const { return playing; } -void AnimatedSprite::play(const StringName &p_animation, const bool p_backwards) { - +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 AnimatedSprite::stop() { - +void AnimatedSprite2D::stop() { _set_playing(false); } -bool AnimatedSprite::is_playing() const { - +bool AnimatedSprite2D::is_playing() const { return playing; } -float AnimatedSprite::_get_frame_duration() { +float AnimatedSprite2D::_get_frame_duration() { if (frames.is_valid() && frames->has_animation(animation)) { float speed = frames->get_animation_speed(animation) * speed_scale; if (speed > 0) { @@ -637,22 +631,22 @@ float AnimatedSprite::_get_frame_duration() { return 0.0; } -void AnimatedSprite::_reset_timeout() { - - if (!playing) +void AnimatedSprite2D::_reset_timeout() { + if (!playing) { return; + } timeout = _get_frame_duration(); is_over = false; } -void AnimatedSprite::set_animation(const StringName &p_animation) { - - ERR_FAIL_COND_MSG(frames == NULL, vformat("There is no animation with name '%s'.", p_animation)); +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(); @@ -660,13 +654,12 @@ void AnimatedSprite::set_animation(const StringName &p_animation) { _change_notify(); update(); } -StringName AnimatedSprite::get_animation() const { +StringName AnimatedSprite2D::get_animation() const { return animation; } -String AnimatedSprite::get_configuration_warning() const { - +String AnimatedSprite2D::get_configuration_warning() const { 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."); } @@ -674,57 +667,82 @@ String AnimatedSprite::get_configuration_warning() const { return String(); } -void AnimatedSprite::_bind_methods() { +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; +} + +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); - ClassDB::bind_method(D_METHOD("set_sprite_frames", "sprite_frames"), &AnimatedSprite::set_sprite_frames); - ClassDB::bind_method(D_METHOD("get_sprite_frames"), &AnimatedSprite::get_sprite_frames); + ClassDB::bind_method(D_METHOD("set_animation", "animation"), &AnimatedSprite2D::set_animation); + ClassDB::bind_method(D_METHOD("get_animation"), &AnimatedSprite2D::get_animation); - ClassDB::bind_method(D_METHOD("set_animation", "animation"), &AnimatedSprite::set_animation); - ClassDB::bind_method(D_METHOD("get_animation"), &AnimatedSprite::get_animation); + ClassDB::bind_method(D_METHOD("_set_playing", "playing"), &AnimatedSprite2D::_set_playing); + ClassDB::bind_method(D_METHOD("_is_playing"), &AnimatedSprite2D::_is_playing); - ClassDB::bind_method(D_METHOD("_set_playing", "playing"), &AnimatedSprite::_set_playing); - ClassDB::bind_method(D_METHOD("_is_playing"), &AnimatedSprite::_is_playing); + ClassDB::bind_method(D_METHOD("play", "anim", "backwards"), &AnimatedSprite2D::play, DEFVAL(StringName()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("stop"), &AnimatedSprite2D::stop); + ClassDB::bind_method(D_METHOD("is_playing"), &AnimatedSprite2D::is_playing); - ClassDB::bind_method(D_METHOD("play", "anim", "backwards"), &AnimatedSprite::play, DEFVAL(StringName()), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("stop"), &AnimatedSprite::stop); - ClassDB::bind_method(D_METHOD("is_playing"), &AnimatedSprite::is_playing); + ClassDB::bind_method(D_METHOD("set_centered", "centered"), &AnimatedSprite2D::set_centered); + ClassDB::bind_method(D_METHOD("is_centered"), &AnimatedSprite2D::is_centered); - ClassDB::bind_method(D_METHOD("set_centered", "centered"), &AnimatedSprite::set_centered); - ClassDB::bind_method(D_METHOD("is_centered"), &AnimatedSprite::is_centered); + ClassDB::bind_method(D_METHOD("set_offset", "offset"), &AnimatedSprite2D::set_offset); + ClassDB::bind_method(D_METHOD("get_offset"), &AnimatedSprite2D::get_offset); - ClassDB::bind_method(D_METHOD("set_offset", "offset"), &AnimatedSprite::set_offset); - ClassDB::bind_method(D_METHOD("get_offset"), &AnimatedSprite::get_offset); + ClassDB::bind_method(D_METHOD("set_flip_h", "flip_h"), &AnimatedSprite2D::set_flip_h); + ClassDB::bind_method(D_METHOD("is_flipped_h"), &AnimatedSprite2D::is_flipped_h); - ClassDB::bind_method(D_METHOD("set_flip_h", "flip_h"), &AnimatedSprite::set_flip_h); - ClassDB::bind_method(D_METHOD("is_flipped_h"), &AnimatedSprite::is_flipped_h); + ClassDB::bind_method(D_METHOD("set_flip_v", "flip_v"), &AnimatedSprite2D::set_flip_v); + ClassDB::bind_method(D_METHOD("is_flipped_v"), &AnimatedSprite2D::is_flipped_v); - ClassDB::bind_method(D_METHOD("set_flip_v", "flip_v"), &AnimatedSprite::set_flip_v); - ClassDB::bind_method(D_METHOD("is_flipped_v"), &AnimatedSprite::is_flipped_v); + ClassDB::bind_method(D_METHOD("set_frame", "frame"), &AnimatedSprite2D::set_frame); + ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite2D::get_frame); - ClassDB::bind_method(D_METHOD("set_frame", "frame"), &AnimatedSprite::set_frame); - ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite::get_frame); + 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_speed_scale", "speed_scale"), &AnimatedSprite::set_speed_scale); - ClassDB::bind_method(D_METHOD("get_speed_scale"), &AnimatedSprite::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("_res_changed"), &AnimatedSprite::_res_changed); + 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")); + ADD_GROUP("Animation", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation"); ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale"), "set_speed_scale", "get_speed_scale"); + 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"); 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"); } -AnimatedSprite::AnimatedSprite() { - +AnimatedSprite2D::AnimatedSprite2D() { centered = true; hflip = false; vflip = false; @@ -736,4 +754,6 @@ AnimatedSprite::AnimatedSprite() { animation = "default"; timeout = 0; is_over = false; + specular_color = Color(1, 1, 1, 1); + shininess = 1.0; } diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite_2d.h index cd00a4e181..cefed56620 100644 --- a/scene/2d/animated_sprite.h +++ b/scene/2d/animated_sprite_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* animated_sprite.h */ +/* animated_sprite_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,19 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ANIMATED_SPRITE_H -#define ANIMATED_SPRITE_H +#ifndef ANIMATED_SPRITE_2D_H +#define ANIMATED_SPRITE_2D_H #include "scene/2d/node_2d.h" #include "scene/resources/texture.h" class SpriteFrames : public Resource { - GDCLASS(SpriteFrames, Resource); struct Anim { - float speed; bool loop; - Vector<Ref<Texture> > frames; + Vector<Ref<Texture2D>> frames; Anim() { loop = true; @@ -50,8 +48,12 @@ class SpriteFrames : public Resource { } StringName normal_name; + StringName specular_name; }; + Color specular_color; + float shininess; + Map<StringName, Anim> animations; Array _get_frames() const; @@ -80,39 +82,54 @@ public: void set_animation_loop(const StringName &p_anim, bool p_loop); bool get_animation_loop(const StringName &p_anim) const; - void add_frame(const StringName &p_anim, const Ref<Texture> &p_frame, int p_at_pos = -1); + 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<Texture> get_frame(const StringName &p_anim, int p_idx) 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<Texture>(), "Animation '" + String(p_anim) + "' doesn't exist."); - ERR_FAIL_COND_V(p_idx < 0, Ref<Texture>()); - if (p_idx >= E->get().frames.size()) - return Ref<Texture>(); + 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()) { + return Ref<Texture2D>(); + } return E->get().frames[p_idx]; } - _FORCE_INLINE_ Ref<Texture> get_normal_frame(const StringName &p_anim, int p_idx) const { - + _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<Texture>(), "Animation '" + String(p_anim) + "' doesn't exist."); - ERR_FAIL_COND_V(p_idx < 0, Ref<Texture>()); + 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<Texture>(); + 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<Texture> &p_frame) { + _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); @@ -122,9 +139,8 @@ public: SpriteFrames(); }; -class AnimatedSprite : public Node2D { - - GDCLASS(AnimatedSprite, Node2D); +class AnimatedSprite2D : public Node2D { + GDCLASS(AnimatedSprite2D, Node2D); Ref<SpriteFrames> frames; bool playing; @@ -150,24 +166,27 @@ class AnimatedSprite : 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; @@ -197,11 +216,14 @@ public: void set_flip_v(bool p_flip); bool is_flipped_v() const; - void set_modulate(const Color &p_color); - Color get_modulate() 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; - AnimatedSprite(); + virtual String get_configuration_warning() const override; + AnimatedSprite2D(); }; #endif // ANIMATED_SPRITE_H diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 8302ba5336..ebfcb9cad6 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -29,34 +29,32 @@ /*************************************************************************/ #include "area_2d.h" + #include "scene/scene_string_names.h" #include "servers/audio_server.h" -#include "servers/physics_2d_server.h" +#include "servers/physics_server_2d.h" void Area2D::set_space_override_mode(SpaceOverride p_mode) { - space_override = p_mode; - Physics2DServer::get_singleton()->area_set_space_override_mode(get_rid(), Physics2DServer::AreaSpaceOverrideMode(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; - Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_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; - Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale); + PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale); } real_t Area2D::get_gravity_distance_scale() const { @@ -64,58 +62,51 @@ real_t Area2D::get_gravity_distance_scale() const { } void Area2D::set_gravity_vector(const Vector2 &p_vec) { - gravity_vec = p_vec; - Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_GRAVITY_VECTOR, 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; - Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_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; - Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_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; - Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_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; - Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_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); @@ -127,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); @@ -143,14 +132,12 @@ 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, int p_instance, int p_body_shape, int p_area_shape) { - - bool body_in = p_status == Physics2DServer::AREA_BODY_ADDED; +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; Object *obj = ObjectDB::get_instance(objid); @@ -166,42 +153,42 @@ void Area2D::_body_inout(int p_status, const RID &p_body, int p_instance, int p_ if (body_in) { if (!E) { - E = body_map.insert(objid, BodyState()); E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree, make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree, make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree), make_binds(objid)); if (E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } } } 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; if (E->get().rc == 0) { - if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); - if (E->get().in_tree) + 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) { emit_signal(SceneStringNames::get_singleton()->body_exited, obj); + } } eraseit = true; @@ -210,15 +197,15 @@ void Area2D::_body_inout(int p_status, const RID &p_body, int p_instance, int p_ emit_signal(SceneStringNames::get_singleton()->body_shape_exited, objid, obj, p_body_shape, p_area_shape); } - if (eraseit) + 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); @@ -230,13 +217,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); @@ -246,14 +231,12 @@ 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, int p_instance, int p_area_shape, int p_self_shape) { - - bool area_in = p_status == Physics2DServer::AREA_BODY_ADDED; +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; Object *obj = ObjectDB::get_instance(objid); @@ -268,42 +251,42 @@ void Area2D::_area_inout(int p_status, const RID &p_area, int p_instance, int p_ if (area_in) { if (!E) { - E = area_map.insert(objid, AreaState()); E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_area_enter_tree, make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_area_exit_tree, make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree), make_binds(objid)); if (E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->area_entered, node); } } } 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; if (E->get().rc == 0) { - if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_area_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_area_exit_tree); - if (E->get().in_tree) + 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) { emit_signal(SceneStringNames::get_singleton()->area_exited, obj); + } } eraseit = true; @@ -312,15 +295,15 @@ void Area2D::_area_inout(int p_status, const RID &p_area, int p_instance, int p_ emit_signal(SceneStringNames::get_singleton()->area_shape_exited, objid, obj, p_area_shape, p_self_shape); } - if (eraseit) + 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."); { @@ -329,22 +312,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 legiminate point + if (!node) { //node may have been deleted in previous frame or at other legitimate point continue; - //ERR_CONTINUE(!node); + } - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); + 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,28 +335,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 legiminate point + if (!node) { //node may have been deleted in previous frame or at other legitimate point continue; - //ERR_CONTINUE(!node); + } - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_area_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_area_exit_tree); + 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); } @@ -384,62 +364,55 @@ 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) { - - Physics2DServer::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout); - Physics2DServer::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout); + 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); } else { - Physics2DServer::get_singleton()->area_set_monitor_callback(get_rid(), NULL, StringName()); - Physics2DServer::get_singleton()->area_set_area_monitor_callback(get_rid(), NULL, StringName()); + PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), nullptr, StringName()); + PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), nullptr, StringName()); _clear_monitoring(); } } 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)."); - ERR_FAIL_COND_MSG(locked || (is_inside_tree() && Physics2DServer::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; - Physics2DServer::get_singleton()->area_set_monitorable(get_rid(), monitorable); + PhysicsServer2D::get_singleton()->area_set_monitorable(get_rid(), monitorable); } bool Area2D::is_monitorable() const { - return monitorable; } -Array Area2D::get_overlapping_bodies() const { - +TypedArray<Node2D> Area2D::get_overlapping_bodies() const { ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); - Array ret; + TypedArray<Node2D> ret; ret.resize(body_map.size()); int idx = 0; for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) { @@ -454,10 +427,9 @@ Array Area2D::get_overlapping_bodies() const { return ret; } -Array Area2D::get_overlapping_areas() const { - +TypedArray<Area2D> Area2D::get_overlapping_areas() const { ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); - Array ret; + TypedArray<Area2D> ret; ret.resize(area_map.size()); int idx = 0; for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) { @@ -473,92 +445,82 @@ Array 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; - Physics2DServer::get_singleton()->area_set_collision_mask(get_rid(), 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; - Physics2DServer::get_singleton()->area_set_collision_layer(get_rid(), 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; @@ -568,13 +530,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; } @@ -584,13 +545,6 @@ void Area2D::_validate_property(PropertyInfo &property) const { } void Area2D::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_body_enter_tree", "id"), &Area2D::_body_enter_tree); - ClassDB::bind_method(D_METHOD("_body_exit_tree", "id"), &Area2D::_body_exit_tree); - - ClassDB::bind_method(D_METHOD("_area_enter_tree", "id"), &Area2D::_area_enter_tree); - ClassDB::bind_method(D_METHOD("_area_exit_tree", "id"), &Area2D::_area_exit_tree); - ClassDB::bind_method(D_METHOD("set_space_override_mode", "space_override_mode"), &Area2D::set_space_override_mode); ClassDB::bind_method(D_METHOD("get_space_override_mode"), &Area2D::get_space_override_mode); @@ -660,11 +614,11 @@ void Area2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine"), "set_space_override_mode", "get_space_override_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point"), "set_gravity_is_point", "is_gravity_a_point"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_vec"), "set_gravity_vector", "get_gravity_vector"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.001"), "set_gravity", "get_gravity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.001"), "set_gravity", "get_gravity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable"); @@ -674,7 +628,7 @@ void Area2D::_bind_methods() { ADD_GROUP("Audio Bus", "audio_bus_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus_name", "get_audio_bus_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus_name", "get_audio_bus_name"); BIND_ENUM_CONSTANT(SPACE_OVERRIDE_DISABLED); BIND_ENUM_CONSTANT(SPACE_OVERRIDE_COMBINE); @@ -684,8 +638,7 @@ void Area2D::_bind_methods() { } Area2D::Area2D() : - CollisionObject2D(Physics2DServer::get_singleton()->area_create(), true) { - + 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 6d9386c535..32226ef5a4 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -35,7 +35,6 @@ #include "scene/2d/collision_object_2d.h" class Area2D : public CollisionObject2D { - GDCLASS(Area2D, CollisionObject2D); public: @@ -62,20 +61,20 @@ private: bool monitorable; bool locked; - void _body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape); + void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape); void _body_enter_tree(ObjectID p_id); 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; @@ -94,20 +92,20 @@ private: Map<ObjectID, BodyState> body_map; - void _area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape); + void _area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape); void _area_enter_tree(ObjectID p_id); 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); @@ -178,8 +175,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; //function for script - Array get_overlapping_areas() const; //function for script + TypedArray<Node2D> get_overlapping_bodies() const; //function for script + TypedArray<Area2D> get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 4f0f681a01..5b89ac15b1 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -32,10 +32,9 @@ #include "core/engine.h" #include "scene/2d/area_2d.h" -#include "scene/main/viewport.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 @@ -87,18 +85,18 @@ void AudioStreamPlayer2D::_mix_audio() { AudioFrame target_volume = stream_paused_fade_out ? AudioFrame(0.f, 0.f) : current.vol; AudioFrame vol_prev = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol; AudioFrame vol_inc = (target_volume - vol_prev) / float(buffer_size); - AudioFrame vol = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : current.vol; + AudioFrame vol = vol_prev; 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) { @@ -187,20 +181,21 @@ void AudioStreamPlayer2D::_notification(int p_what) { //check if any area is diverting sound into a bus - Physics2DDirectSpaceState *space_state = Physics2DServer::get_singleton()->space_get_direct_state(world_2d->get_space()); + PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space()); - Physics2DDirectSpaceState::ShapeResult sr[MAX_INTERSECT_AREAS]; + PhysicsDirectSpaceState2D::ShapeResult sr[MAX_INTERSECT_AREAS]; 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); @@ -512,24 +488,21 @@ void AudioStreamPlayer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer2D::get_stream_playback); - ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer2D::_bus_layout_changed); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,32,0.01"), "set_pitch_scale", "get_pitch_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_EXP_RANGE, "1,4096,1,or_greater"), "set_max_distance", "get_max_distance"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_attenuation", "get_attenuation"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_EXP_RANGE, "1,4096,1,or_greater"), "set_max_distance", "get_max_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_attenuation", "get_attenuation"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask"); ADD_SIGNAL(MethodInfo("finished")); } AudioStreamPlayer2D::AudioStreamPlayer2D() { - volume_db = 0; pitch_scale = 1.0; autoplay = false; @@ -545,7 +518,7 @@ AudioStreamPlayer2D::AudioStreamPlayer2D() { stream_paused = false; stream_paused_fade_in = false; stream_paused_fade_out = false; - AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); + AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer2D::_bus_layout_changed)); } AudioStreamPlayer2D::~AudioStreamPlayer2D() { 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 faeb6b7169..a36e0a86e1 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -31,20 +31,15 @@ #include "back_buffer_copy.h" void BackBufferCopy::_update_copy_mode() { - switch (copy_mode) { - case COPY_MODE_DISABLED: { - - VS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), false, Rect2()); + RS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), false, Rect2()); } break; case COPY_MODE_RECT: { - - VS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), true, rect); + RS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), true, rect); } break; case COPY_MODE_VIEWPORT: { - - VS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), true, Rect2()); + 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 e9f8c5dff2..fd4d5981ff 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -33,30 +33,30 @@ #include "core/engine.h" #include "core/math/math_funcs.h" #include "scene/scene_string_names.h" -#include "servers/visual_server.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,23 +115,20 @@ 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_TOP] * v_ofs; - } else { camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs; + } else { + camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_TOP] * v_ofs; } v_offset_changed = false; } } 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()); @@ -264,13 +257,13 @@ void Camera2D::_notification(int p_what) { } remove_from_group(group_name); remove_from_group(canvas_group_name); - viewport = NULL; + viewport = nullptr; } 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,71 +416,60 @@ 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 *)(NULL)); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_make_current", (Object *)nullptr); } } 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; } @@ -608,15 +583,15 @@ void Camera2D::set_custom_viewport(Node *p_viewport) { if (custom_viewport) { custom_viewport_id = custom_viewport->get_instance_id(); } else { - custom_viewport_id = 0; + custom_viewport_id = ObjectID(); } 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); @@ -753,17 +726,17 @@ void Camera2D::_bind_methods() { ADD_GROUP("Smoothing", "smoothing_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smoothing_enabled"), "set_enable_follow_smoothing", "is_follow_smoothing_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "smoothing_speed"), "set_follow_smoothing", "get_follow_smoothing"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "smoothing_speed"), "set_follow_smoothing", "get_follow_smoothing"); ADD_GROUP("Offset", "offset_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_h", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_h_offset", "get_h_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_v", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_v_offset", "get_v_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "offset_h", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_h_offset", "get_h_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "offset_v", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_v_offset", "get_v_offset"); ADD_GROUP("Drag Margin", "drag_margin_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "drag_margin_left", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "drag_margin_top", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "drag_margin_right", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "drag_margin_bottom", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_left", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_top", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_right", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_bottom", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_BOTTOM); ADD_GROUP("Editor", "editor_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_draw_screen"), "set_screen_drawing_enabled", "is_screen_drawing_enabled"); @@ -777,7 +750,6 @@ void Camera2D::_bind_methods() { } Camera2D::Camera2D() { - anchor_mode = ANCHOR_MODE_DRAG_CENTER; rotating = false; current = false; @@ -794,8 +766,8 @@ Camera2D::Camera2D() { first = true; smoothing_enabled = false; limit_smoothing_enabled = false; - custom_viewport = NULL; - custom_viewport_id = 0; + custom_viewport = nullptr; + process_mode = CAMERA2D_PROCESS_IDLE; smoothing = 5.0; diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 04b5260444..867a5562b2 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -32,10 +32,9 @@ #define CAMERA_2D_H #include "scene/2d/node_2d.h" -#include "scene/main/viewport.h" +#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_item.cpp b/scene/2d/canvas_item.cpp deleted file mode 100644 index 5631aa3355..0000000000 --- a/scene/2d/canvas_item.cpp +++ /dev/null @@ -1,1348 +0,0 @@ -/*************************************************************************/ -/* canvas_item.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_item.h" -#include "core/message_queue.h" -#include "core/method_bind_ext.gen.inc" -#include "core/os/input.h" -#include "scene/main/canvas_layer.h" -#include "scene/main/viewport.h" -#include "scene/resources/font.h" -#include "scene/resources/style_box.h" -#include "scene/resources/texture.h" -#include "scene/scene_string_names.h" -#include "servers/visual/visual_server_raster.h" -#include "servers/visual_server.h" - -Mutex *CanvasItemMaterial::material_mutex = NULL; -SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = NULL; -Map<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData> CanvasItemMaterial::shader_map; -CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = NULL; - -void CanvasItemMaterial::init_shaders() { - -#ifndef NO_THREADS - material_mutex = Mutex::create(); -#endif - - dirty_materials = memnew(SelfList<CanvasItemMaterial>::List); - - shader_names = memnew(ShaderNames); - - shader_names->particles_anim_h_frames = "particles_anim_h_frames"; - shader_names->particles_anim_v_frames = "particles_anim_v_frames"; - shader_names->particles_anim_loop = "particles_anim_loop"; -} - -void CanvasItemMaterial::finish_shaders() { - - memdelete(dirty_materials); - memdelete(shader_names); - dirty_materials = NULL; - -#ifndef NO_THREADS - memdelete(material_mutex); -#endif -} - -void CanvasItemMaterial::_update_shader() { - - dirty_materials->remove(&element); - - MaterialKey mk = _compute_key(); - if (mk.key == current_key.key) - return; //no update required in the end - - if (shader_map.has(current_key)) { - shader_map[current_key].users--; - if (shader_map[current_key].users == 0) { - //deallocate shader, as it's no longer in use - VS::get_singleton()->free(shader_map[current_key].shader); - shader_map.erase(current_key); - } - } - - current_key = mk; - - if (shader_map.has(mk)) { - - VS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader); - shader_map[mk].users++; - return; - } - - //must create a shader! - - String code = "shader_type canvas_item;\nrender_mode "; - switch (blend_mode) { - case BLEND_MODE_MIX: code += "blend_mix"; break; - case BLEND_MODE_ADD: code += "blend_add"; break; - case BLEND_MODE_SUB: code += "blend_sub"; break; - case BLEND_MODE_MUL: code += "blend_mul"; break; - case BLEND_MODE_PREMULT_ALPHA: code += "blend_premul_alpha"; break; - case BLEND_MODE_DISABLED: code += "blend_disabled"; break; - } - - switch (light_mode) { - case LIGHT_MODE_NORMAL: break; - case LIGHT_MODE_UNSHADED: code += ",unshaded"; break; - case LIGHT_MODE_LIGHT_ONLY: code += ",light_only"; break; - } - - code += ";\n"; - - if (particles_animation) { - - code += "uniform int particles_anim_h_frames;\n"; - code += "uniform int particles_anim_v_frames;\n"; - code += "uniform bool particles_anim_loop;\n"; - - code += "void vertex() {\n"; - - code += "\tfloat h_frames = float(particles_anim_h_frames);\n"; - code += "\tfloat v_frames = float(particles_anim_v_frames);\n"; - - code += "\tVERTEX.xy /= vec2(h_frames, v_frames);\n"; - - code += "\tfloat particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n"; - code += "\tfloat particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; - code += "\tif (!particles_anim_loop) {\n"; - code += "\t\tparticle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; - code += "\t} else {\n"; - code += "\t\tparticle_frame = mod(particle_frame, particle_total_frames);\n"; - code += "\t}"; - code += "\tUV /= vec2(h_frames, v_frames);\n"; - code += "\tUV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n"; - code += "}\n"; - } - - ShaderData shader_data; - shader_data.shader = VS::get_singleton()->shader_create(); - shader_data.users = 1; - - VS::get_singleton()->shader_set_code(shader_data.shader, code); - - shader_map[mk] = shader_data; - - VS::get_singleton()->material_set_shader(_get_material(), shader_data.shader); -} - -void CanvasItemMaterial::flush_changes() { - - if (material_mutex) - material_mutex->lock(); - - while (dirty_materials->first()) { - - dirty_materials->first()->self()->_update_shader(); - } - - if (material_mutex) - material_mutex->unlock(); -} - -void CanvasItemMaterial::_queue_shader_change() { - - if (material_mutex) - material_mutex->lock(); - - if (!element.in_list()) { - dirty_materials->add(&element); - } - - if (material_mutex) - material_mutex->unlock(); -} - -bool CanvasItemMaterial::_is_shader_dirty() const { - - bool dirty = false; - - if (material_mutex) - material_mutex->lock(); - - dirty = element.in_list(); - - if (material_mutex) - material_mutex->unlock(); - - return dirty; -} -void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) { - - blend_mode = p_blend_mode; - _queue_shader_change(); -} - -CanvasItemMaterial::BlendMode CanvasItemMaterial::get_blend_mode() const { - return blend_mode; -} - -void CanvasItemMaterial::set_light_mode(LightMode p_light_mode) { - - light_mode = p_light_mode; - _queue_shader_change(); -} - -CanvasItemMaterial::LightMode CanvasItemMaterial::get_light_mode() const { - - return light_mode; -} - -void CanvasItemMaterial::set_particles_animation(bool p_particles_anim) { - particles_animation = p_particles_anim; - _queue_shader_change(); - _change_notify(); -} - -bool CanvasItemMaterial::get_particles_animation() const { - return particles_animation; -} - -void CanvasItemMaterial::set_particles_anim_h_frames(int p_frames) { - - particles_anim_h_frames = p_frames; - VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames); -} - -int CanvasItemMaterial::get_particles_anim_h_frames() const { - - return particles_anim_h_frames; -} -void CanvasItemMaterial::set_particles_anim_v_frames(int p_frames) { - - particles_anim_v_frames = p_frames; - VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames); -} - -int CanvasItemMaterial::get_particles_anim_v_frames() const { - - return particles_anim_v_frames; -} - -void CanvasItemMaterial::set_particles_anim_loop(bool p_loop) { - - particles_anim_loop = p_loop; - VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop); -} - -bool CanvasItemMaterial::get_particles_anim_loop() const { - - return particles_anim_loop; -} - -void CanvasItemMaterial::_validate_property(PropertyInfo &property) const { - if (property.name.begins_with("particles_anim_") && !particles_animation) { - property.usage = 0; - } -} - -RID CanvasItemMaterial::get_shader_rid() const { - - ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); - return shader_map[current_key].shader; -} - -Shader::Mode CanvasItemMaterial::get_shader_mode() const { - - return Shader::MODE_CANVAS_ITEM; -} - -void CanvasItemMaterial::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &CanvasItemMaterial::set_blend_mode); - ClassDB::bind_method(D_METHOD("get_blend_mode"), &CanvasItemMaterial::get_blend_mode); - - ClassDB::bind_method(D_METHOD("set_light_mode", "light_mode"), &CanvasItemMaterial::set_light_mode); - ClassDB::bind_method(D_METHOD("get_light_mode"), &CanvasItemMaterial::get_light_mode); - - ClassDB::bind_method(D_METHOD("set_particles_animation", "particles_anim"), &CanvasItemMaterial::set_particles_animation); - ClassDB::bind_method(D_METHOD("get_particles_animation"), &CanvasItemMaterial::get_particles_animation); - - ClassDB::bind_method(D_METHOD("set_particles_anim_h_frames", "frames"), &CanvasItemMaterial::set_particles_anim_h_frames); - ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames"), &CanvasItemMaterial::get_particles_anim_h_frames); - - ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames", "frames"), &CanvasItemMaterial::set_particles_anim_v_frames); - ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &CanvasItemMaterial::get_particles_anim_v_frames); - - ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &CanvasItemMaterial::set_particles_anim_loop); - ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &CanvasItemMaterial::get_particles_anim_loop); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,Premult Alpha"), "set_blend_mode", "get_blend_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mode", PROPERTY_HINT_ENUM, "Normal,Unshaded,Light Only"), "set_light_mode", "get_light_mode"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_animation"), "set_particles_animation", "get_particles_animation"); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_anim_loop"), "set_particles_anim_loop", "get_particles_anim_loop"); - - BIND_ENUM_CONSTANT(BLEND_MODE_MIX); - BIND_ENUM_CONSTANT(BLEND_MODE_ADD); - BIND_ENUM_CONSTANT(BLEND_MODE_SUB); - BIND_ENUM_CONSTANT(BLEND_MODE_MUL); - BIND_ENUM_CONSTANT(BLEND_MODE_PREMULT_ALPHA); - - BIND_ENUM_CONSTANT(LIGHT_MODE_NORMAL); - BIND_ENUM_CONSTANT(LIGHT_MODE_UNSHADED); - BIND_ENUM_CONSTANT(LIGHT_MODE_LIGHT_ONLY); -} - -CanvasItemMaterial::CanvasItemMaterial() : - element(this) { - - blend_mode = BLEND_MODE_MIX; - light_mode = LIGHT_MODE_NORMAL; - particles_animation = false; - - set_particles_anim_h_frames(1); - set_particles_anim_v_frames(1); - set_particles_anim_loop(false); - - current_key.key = 0; - current_key.invalid_key = 1; - _queue_shader_change(); -} - -CanvasItemMaterial::~CanvasItemMaterial() { - - if (material_mutex) - material_mutex->lock(); - - if (shader_map.has(current_key)) { - shader_map[current_key].users--; - if (shader_map[current_key].users == 0) { - //deallocate shader, as it's no longer in use - VS::get_singleton()->free(shader_map[current_key].shader); - shader_map.erase(current_key); - } - - VS::get_singleton()->material_set_shader(_get_material(), RID()); - } - - if (material_mutex) - material_mutex->unlock(); -} - -/////////////////////////////////////////////////////////////////// -#ifdef TOOLS_ENABLED -bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - if (_edit_use_rect()) { - return _edit_get_rect().has_point(p_point); - } else { - return p_point.length() < p_tolerance; - } -} - -Transform2D CanvasItem::_edit_get_transform() const { - return Transform2D(_edit_get_rotation(), _edit_get_position() + _edit_get_pivot()); -} -#endif - -bool CanvasItem::is_visible_in_tree() const { - - if (!is_inside_tree()) - return false; - - const CanvasItem *p = this; - - while (p) { - if (!p->visible) - return false; - p = p->get_parent_item(); - } - - return true; -} - -void CanvasItem::_propagate_visibility_changed(bool p_visible) { - - if (p_visible && first_draw) { //avoid propagating it twice - first_draw = false; - } - notification(NOTIFICATION_VISIBILITY_CHANGED); - - if (p_visible) - update(); //todo optimize - else - emit_signal(SceneStringNames::get_singleton()->hide); - _block(); - - for (int i = 0; i < get_child_count(); i++) { - - CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i)); - - if (c && c->visible) //should the toplevels stop propagation? i think so but.. - c->_propagate_visibility_changed(p_visible); - } - - _unblock(); -} - -void CanvasItem::show() { - - if (visible) - return; - - visible = true; - VisualServer::get_singleton()->canvas_item_set_visible(canvas_item, true); - - if (!is_inside_tree()) - return; - - _propagate_visibility_changed(true); - _change_notify("visible"); -} - -void CanvasItem::hide() { - - if (!visible) - return; - - visible = false; - VisualServer::get_singleton()->canvas_item_set_visible(canvas_item, false); - - if (!is_inside_tree()) - return; - - _propagate_visibility_changed(false); - _change_notify("visible"); -} - -CanvasItem *CanvasItem::current_item_drawn = NULL; -CanvasItem *CanvasItem::get_current_item_drawn() { - return current_item_drawn; -} - -void CanvasItem::_update_callback() { - - if (!is_inside_tree()) { - pending_update = false; - return; - } - - VisualServer::get_singleton()->canvas_item_clear(get_canvas_item()); - //todo updating = true - only allow drawing here - if (is_visible_in_tree()) { //todo optimize this!! - if (first_draw) { - notification(NOTIFICATION_VISIBILITY_CHANGED); - first_draw = false; - } - drawing = true; - current_item_drawn = this; - notification(NOTIFICATION_DRAW); - emit_signal(SceneStringNames::get_singleton()->draw); - if (get_script_instance()) { - get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_draw, NULL, 0); - } - current_item_drawn = NULL; - drawing = false; - } - //todo updating = false - pending_update = false; // don't change to false until finished drawing (avoid recursive update) -} - -Transform2D CanvasItem::get_global_transform_with_canvas() const { - - if (canvas_layer) - return canvas_layer->get_transform() * get_global_transform(); - else if (is_inside_tree()) - return get_viewport()->get_canvas_transform() * get_global_transform(); - else - return get_global_transform(); -} - -Transform2D CanvasItem::get_global_transform() const { -#ifdef DEBUG_ENABLED - ERR_FAIL_COND_V(!is_inside_tree(), get_transform()); -#endif - if (global_invalid) { - - const CanvasItem *pi = get_parent_item(); - if (pi) - global_transform = pi->get_global_transform() * get_transform(); - else - global_transform = get_transform(); - - global_invalid = false; - } - - return global_transform; -} - -void CanvasItem::_toplevel_raise_self() { - - if (!is_inside_tree()) - return; - - if (canvas_layer) - VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item, canvas_layer->get_sort_index()); - else - VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_viewport()->gui_get_canvas_sort_index()); -} - -void CanvasItem::_enter_canvas() { - - if ((!Object::cast_to<CanvasItem>(get_parent())) || toplevel) { - - Node *n = this; - - canvas_layer = NULL; - - while (n) { - - canvas_layer = Object::cast_to<CanvasLayer>(n); - if (canvas_layer) { - break; - } - if (Object::cast_to<Viewport>(n)) { - break; - } - n = n->get_parent(); - } - - RID canvas; - if (canvas_layer) - canvas = canvas_layer->get_canvas(); - else - canvas = get_viewport()->find_world_2d()->get_canvas(); - - VisualServer::get_singleton()->canvas_item_set_parent(canvas_item, canvas); - - group = "root_canvas" + itos(canvas.get_id()); - - add_to_group(group); - if (canvas_layer) - canvas_layer->reset_sort_index(); - else - get_viewport()->gui_reset_canvas_sort_index(); - - get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE, group, "_toplevel_raise_self"); - - } else { - - CanvasItem *parent = get_parent_item(); - canvas_layer = parent->canvas_layer; - VisualServer::get_singleton()->canvas_item_set_parent(canvas_item, parent->get_canvas_item()); - VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index()); - } - - pending_update = false; - update(); - - notification(NOTIFICATION_ENTER_CANVAS); -} - -void CanvasItem::_exit_canvas() { - - notification(NOTIFICATION_EXIT_CANVAS, true); //reverse the notification - VisualServer::get_singleton()->canvas_item_set_parent(canvas_item, RID()); - canvas_layer = NULL; - group = ""; -} - -void CanvasItem::_notification(int p_what) { - - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - - first_draw = true; - if (get_parent()) { - CanvasItem *ci = Object::cast_to<CanvasItem>(get_parent()); - if (ci) - C = ci->children_items.push_back(this); - } - _enter_canvas(); - if (!block_transform_notify && !xform_change.in_list()) { - get_tree()->xform_change_list.add(&xform_change); - } - } break; - case NOTIFICATION_MOVED_IN_PARENT: { - - if (!is_inside_tree()) - break; - - if (group != "") { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE, group, "_toplevel_raise_self"); - } else { - CanvasItem *p = get_parent_item(); - ERR_FAIL_COND(!p); - VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index()); - } - - } break; - case NOTIFICATION_EXIT_TREE: { - if (xform_change.in_list()) - get_tree()->xform_change_list.remove(&xform_change); - _exit_canvas(); - if (C) { - Object::cast_to<CanvasItem>(get_parent())->children_items.erase(C); - C = NULL; - } - global_invalid = true; - } break; - case NOTIFICATION_DRAW: - case NOTIFICATION_TRANSFORM_CHANGED: { - - } break; - case NOTIFICATION_VISIBILITY_CHANGED: { - - emit_signal(SceneStringNames::get_singleton()->visibility_changed); - } break; - } -} - -void CanvasItem::set_visible(bool p_visible) { - - if (p_visible) - show(); - else - hide(); -} -bool CanvasItem::is_visible() const { - - return visible; -} - -void CanvasItem::update() { - - if (!is_inside_tree()) - return; - if (pending_update) - return; - - pending_update = true; - - MessageQueue::get_singleton()->push_call(this, "_update_callback"); -} - -void CanvasItem::set_modulate(const Color &p_modulate) { - - if (modulate == p_modulate) - return; - - modulate = p_modulate; - VisualServer::get_singleton()->canvas_item_set_modulate(canvas_item, modulate); -} -Color CanvasItem::get_modulate() const { - - return modulate; -} - -void CanvasItem::set_as_toplevel(bool p_toplevel) { - - if (toplevel == p_toplevel) - return; - - if (!is_inside_tree()) { - toplevel = p_toplevel; - return; - } - - _exit_canvas(); - toplevel = p_toplevel; - _enter_canvas(); -} - -bool CanvasItem::is_set_as_toplevel() const { - - return toplevel; -} - -CanvasItem *CanvasItem::get_parent_item() const { - - if (toplevel) - return NULL; - - return Object::cast_to<CanvasItem>(get_parent()); -} - -void CanvasItem::set_self_modulate(const Color &p_self_modulate) { - - if (self_modulate == p_self_modulate) - return; - - self_modulate = p_self_modulate; - VisualServer::get_singleton()->canvas_item_set_self_modulate(canvas_item, self_modulate); -} -Color CanvasItem::get_self_modulate() const { - - return self_modulate; -} - -void CanvasItem::set_light_mask(int p_light_mask) { - - if (light_mask == p_light_mask) - return; - - light_mask = p_light_mask; - VS::get_singleton()->canvas_item_set_light_mask(canvas_item, p_light_mask); -} - -int CanvasItem::get_light_mask() const { - - return light_mask; -} - -void CanvasItem::item_rect_changed(bool p_size_changed) { - - if (p_size_changed) - update(); - emit_signal(SceneStringNames::get_singleton()->item_rect_changed); -} - -void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width, bool p_antialiased) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width, p_antialiased); -} - -void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - Vector<Color> colors; - colors.push_back(p_color); - VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, colors, p_width, p_antialiased); -} - -void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width, p_antialiased); -} - -void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width, bool p_antialiased) { - - Vector<Point2> points; - points.resize(p_point_count); - const float delta_angle = p_end_angle - p_start_angle; - for (int i = 0; i < p_point_count; i++) { - float theta = (i / (p_point_count - 1.0f)) * delta_angle + p_start_angle; - points.set(i, p_center + Vector2(Math::cos(theta), Math::sin(theta)) * p_radius); - } - - draw_polyline(points, p_color, p_width, p_antialiased); -} - -void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - Vector<Color> colors; - colors.push_back(p_color); - VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width, p_antialiased); -} - -void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased); -} - -void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width, bool p_antialiased) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - if (p_filled) { - if (p_width != 1.0) { - WARN_PRINT("The draw_rect() \"width\" argument has no effect when \"filled\" is \"true\"."); - } - - if (p_antialiased) { - WARN_PRINT("The draw_rect() \"antialiased\" argument has no effect when \"filled\" is \"true\"."); - } - - VisualServer::get_singleton()->canvas_item_add_rect(canvas_item, p_rect, p_color); - } else { - // Thick lines are offset depending on their width to avoid partial overlapping. - // Thin lines don't require an offset, so don't apply one in this case - float offset; - if (p_width >= 2) { - offset = p_width / 2.0; - } else { - offset = 0.0; - } - - VisualServer::get_singleton()->canvas_item_add_line( - canvas_item, - p_rect.position + Size2(-offset, 0), - p_rect.position + Size2(p_rect.size.width + offset, 0), - p_color, - p_width, - p_antialiased); - VisualServer::get_singleton()->canvas_item_add_line( - canvas_item, - p_rect.position + Size2(p_rect.size.width, offset), - p_rect.position + Size2(p_rect.size.width, p_rect.size.height - offset), - p_color, - p_width, - p_antialiased); - VisualServer::get_singleton()->canvas_item_add_line( - canvas_item, - p_rect.position + Size2(p_rect.size.width + offset, p_rect.size.height), - p_rect.position + Size2(-offset, p_rect.size.height), - p_color, - p_width, - p_antialiased); - VisualServer::get_singleton()->canvas_item_add_line( - canvas_item, - p_rect.position + Size2(0, p_rect.size.height - offset), - p_rect.position + Size2(0, offset), - p_color, - p_width, - p_antialiased); - } -} - -void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - VisualServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color); -} - -void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref<Texture> &p_normal_map) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - ERR_FAIL_COND(p_texture.is_null()); - - p_texture->draw(canvas_item, p_pos, p_modulate, false, p_normal_map); -} - -void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map); -} -void CanvasItem::draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_clip_uv); -} - -void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect) { - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - ERR_FAIL_COND(p_style_box.is_null()); - - p_style_box->draw(canvas_item, p_rect); -} -void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, float p_width, const Ref<Texture> &p_normal_map) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); - RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - - VisualServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width, rid_normal); -} -void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - Transform2D xform(p_rot, p_offset); - xform.scale_basis(p_scale); - VisualServer::get_singleton()->canvas_item_add_set_transform(canvas_item, xform); -} - -void CanvasItem::draw_set_transform_matrix(const Transform2D &p_matrix) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - VisualServer::get_singleton()->canvas_item_add_set_transform(canvas_item, p_matrix); -} - -void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map, bool p_antialiased) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); - RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - - VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, p_colors, p_uvs, rid, rid_normal, p_antialiased); -} - -void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map, bool p_antialiased) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - Vector<Color> colors; - colors.push_back(p_color); - RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); - RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - - VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal, p_antialiased); -} - -void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, const Transform2D &p_transform, const Color &p_modulate) { - - ERR_FAIL_COND(p_mesh.is_null()); - RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); - RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - - VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), p_transform, p_modulate, texture_rid, normal_map_rid); -} -void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map) { - - ERR_FAIL_COND(p_multimesh.is_null()); - RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); - RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid, normal_map_rid); -} - -void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w) { - - ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - ERR_FAIL_COND(p_font.is_null()); - p_font->draw(canvas_item, p_pos, p_text, p_modulate, p_clip_w); -} - -float CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next, const Color &p_modulate) { - - ERR_FAIL_COND_V_MSG(!drawing, 0, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - - ERR_FAIL_COND_V(p_char.length() != 1, 0); - ERR_FAIL_COND_V(p_font.is_null(), 0); - - if (p_font->has_outline()) { - p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.c_str()[0], Color(1, 1, 1), true); - } - return p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.c_str()[0], p_modulate); -} - -void CanvasItem::_notify_transform(CanvasItem *p_node) { - - /* This check exists to avoid re-propagating the transform - * notification down the tree on dirty nodes. It provides - * optimization by avoiding redundancy (nodes are dirty, will get the - * notification anyway). - */ - - if (/*p_node->xform_change.in_list() &&*/ p_node->global_invalid) { - return; //nothing to do - } - - p_node->global_invalid = true; - - if (p_node->notify_transform && !p_node->xform_change.in_list()) { - if (!p_node->block_transform_notify) { - if (p_node->is_inside_tree()) - get_tree()->xform_change_list.add(&p_node->xform_change); - } - } - - for (List<CanvasItem *>::Element *E = p_node->children_items.front(); E; E = E->next()) { - - CanvasItem *ci = E->get(); - if (ci->toplevel) - continue; - _notify_transform(ci); - } -} - -Rect2 CanvasItem::get_viewport_rect() const { - - ERR_FAIL_COND_V(!is_inside_tree(), Rect2()); - return get_viewport()->get_visible_rect(); -} - -RID CanvasItem::get_canvas() const { - - ERR_FAIL_COND_V(!is_inside_tree(), RID()); - - if (canvas_layer) - return canvas_layer->get_canvas(); - else - return get_viewport()->find_world_2d()->get_canvas(); -} - -ObjectID CanvasItem::get_canvas_layer_instance_id() const { - - if (canvas_layer) { - return canvas_layer->get_instance_id(); - } else { - return 0; - } -} - -CanvasItem *CanvasItem::get_toplevel() const { - - CanvasItem *ci = const_cast<CanvasItem *>(this); - while (!ci->toplevel && Object::cast_to<CanvasItem>(ci->get_parent())) { - ci = Object::cast_to<CanvasItem>(ci->get_parent()); - } - - return ci; -} - -Ref<World2D> CanvasItem::get_world_2d() const { - - ERR_FAIL_COND_V(!is_inside_tree(), Ref<World2D>()); - - CanvasItem *tl = get_toplevel(); - - if (tl->get_viewport()) { - return tl->get_viewport()->find_world_2d(); - } else { - return Ref<World2D>(); - } -} - -RID CanvasItem::get_viewport_rid() const { - - ERR_FAIL_COND_V(!is_inside_tree(), RID()); - return get_viewport()->get_viewport_rid(); -} - -void CanvasItem::set_block_transform_notify(bool p_enable) { - block_transform_notify = p_enable; -} - -bool CanvasItem::is_block_transform_notify_enabled() const { - - return block_transform_notify; -} - -void CanvasItem::set_draw_behind_parent(bool p_enable) { - - if (behind == p_enable) - return; - behind = p_enable; - VisualServer::get_singleton()->canvas_item_set_draw_behind_parent(canvas_item, behind); -} - -bool CanvasItem::is_draw_behind_parent_enabled() const { - - return behind; -} - -void CanvasItem::set_material(const Ref<Material> &p_material) { - - material = p_material; - RID rid; - if (material.is_valid()) - rid = material->get_rid(); - VS::get_singleton()->canvas_item_set_material(canvas_item, rid); - _change_notify(); //properties for material exposed -} - -void CanvasItem::set_use_parent_material(bool p_use_parent_material) { - - use_parent_material = p_use_parent_material; - VS::get_singleton()->canvas_item_set_use_parent_material(canvas_item, p_use_parent_material); -} - -bool CanvasItem::get_use_parent_material() const { - - return use_parent_material; -} - -Ref<Material> CanvasItem::get_material() const { - - return material; -} - -Vector2 CanvasItem::make_canvas_position_local(const Vector2 &screen_point) const { - - ERR_FAIL_COND_V(!is_inside_tree(), screen_point); - - Transform2D local_matrix = (get_canvas_transform() * get_global_transform()).affine_inverse(); - - return local_matrix.xform(screen_point); -} - -Ref<InputEvent> CanvasItem::make_input_local(const Ref<InputEvent> &p_event) const { - - ERR_FAIL_COND_V(p_event.is_null(), p_event); - ERR_FAIL_COND_V(!is_inside_tree(), p_event); - - return p_event->xformed_by((get_canvas_transform() * get_global_transform()).affine_inverse()); -} - -Vector2 CanvasItem::get_global_mouse_position() const { - - ERR_FAIL_COND_V(!get_viewport(), Vector2()); - return get_canvas_transform().affine_inverse().xform(get_viewport()->get_mouse_position()); -} - -Vector2 CanvasItem::get_local_mouse_position() const { - - ERR_FAIL_COND_V(!get_viewport(), Vector2()); - - return get_global_transform().affine_inverse().xform(get_global_mouse_position()); -} - -void CanvasItem::force_update_transform() { - ERR_FAIL_COND(!is_inside_tree()); - if (!xform_change.in_list()) { - return; - } - - get_tree()->xform_change_list.remove(&xform_change); - - notification(NOTIFICATION_TRANSFORM_CHANGED); -} - -void CanvasItem::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_toplevel_raise_self"), &CanvasItem::_toplevel_raise_self); - ClassDB::bind_method(D_METHOD("_update_callback"), &CanvasItem::_update_callback); - -#ifdef TOOLS_ENABLED - ClassDB::bind_method(D_METHOD("_edit_set_state", "state"), &CanvasItem::_edit_set_state); - ClassDB::bind_method(D_METHOD("_edit_get_state"), &CanvasItem::_edit_get_state); - ClassDB::bind_method(D_METHOD("_edit_set_position", "position"), &CanvasItem::_edit_set_position); - ClassDB::bind_method(D_METHOD("_edit_get_position"), &CanvasItem::_edit_get_position); - ClassDB::bind_method(D_METHOD("_edit_set_scale", "scale"), &CanvasItem::_edit_set_scale); - ClassDB::bind_method(D_METHOD("_edit_get_scale"), &CanvasItem::_edit_get_scale); - ClassDB::bind_method(D_METHOD("_edit_set_rect", "rect"), &CanvasItem::_edit_set_rect); - ClassDB::bind_method(D_METHOD("_edit_get_rect"), &CanvasItem::_edit_get_rect); - ClassDB::bind_method(D_METHOD("_edit_use_rect"), &CanvasItem::_edit_use_rect); - ClassDB::bind_method(D_METHOD("_edit_set_rotation", "degrees"), &CanvasItem::_edit_set_rotation); - ClassDB::bind_method(D_METHOD("_edit_get_rotation"), &CanvasItem::_edit_get_rotation); - ClassDB::bind_method(D_METHOD("_edit_use_rotation"), &CanvasItem::_edit_use_rotation); - ClassDB::bind_method(D_METHOD("_edit_set_pivot", "pivot"), &CanvasItem::_edit_set_pivot); - ClassDB::bind_method(D_METHOD("_edit_get_pivot"), &CanvasItem::_edit_get_pivot); - ClassDB::bind_method(D_METHOD("_edit_use_pivot"), &CanvasItem::_edit_use_pivot); - ClassDB::bind_method(D_METHOD("_edit_get_transform"), &CanvasItem::_edit_get_transform); -#endif - - ClassDB::bind_method(D_METHOD("get_canvas_item"), &CanvasItem::get_canvas_item); - - ClassDB::bind_method(D_METHOD("set_visible", "visible"), &CanvasItem::set_visible); - ClassDB::bind_method(D_METHOD("is_visible"), &CanvasItem::is_visible); - ClassDB::bind_method(D_METHOD("is_visible_in_tree"), &CanvasItem::is_visible_in_tree); - ClassDB::bind_method(D_METHOD("show"), &CanvasItem::show); - ClassDB::bind_method(D_METHOD("hide"), &CanvasItem::hide); - - ClassDB::bind_method(D_METHOD("update"), &CanvasItem::update); - - ClassDB::bind_method(D_METHOD("set_as_toplevel", "enable"), &CanvasItem::set_as_toplevel); - ClassDB::bind_method(D_METHOD("is_set_as_toplevel"), &CanvasItem::is_set_as_toplevel); - - ClassDB::bind_method(D_METHOD("set_light_mask", "light_mask"), &CanvasItem::set_light_mask); - ClassDB::bind_method(D_METHOD("get_light_mask"), &CanvasItem::get_light_mask); - - ClassDB::bind_method(D_METHOD("set_modulate", "modulate"), &CanvasItem::set_modulate); - ClassDB::bind_method(D_METHOD("get_modulate"), &CanvasItem::get_modulate); - ClassDB::bind_method(D_METHOD("set_self_modulate", "self_modulate"), &CanvasItem::set_self_modulate); - ClassDB::bind_method(D_METHOD("get_self_modulate"), &CanvasItem::get_self_modulate); - - ClassDB::bind_method(D_METHOD("set_draw_behind_parent", "enable"), &CanvasItem::set_draw_behind_parent); - ClassDB::bind_method(D_METHOD("is_draw_behind_parent_enabled"), &CanvasItem::is_draw_behind_parent_enabled); - - ClassDB::bind_method(D_METHOD("_set_on_top", "on_top"), &CanvasItem::_set_on_top); - ClassDB::bind_method(D_METHOD("_is_on_top"), &CanvasItem::_is_on_top); - //ClassDB::bind_method(D_METHOD("get_transform"),&CanvasItem::get_transform); - - ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_arc", "center", "radius", "start_angle", "end_angle", "point_count", "color", "width", "antialiased"), &CanvasItem::draw_arc, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width", "antialiased"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::draw_circle); - ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate", "normal_map"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose", "normal_map"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture", "rect", "src_rect", "modulate", "transpose", "normal_map", "clip_uv"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("draw_style_box", "style_box", "rect"), &CanvasItem::draw_style_box); - ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture", "width", "normal_map"), &CanvasItem::draw_primitive, DEFVAL(Variant()), DEFVAL(1.0), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture", "normal_map", "antialiased"), &CanvasItem::draw_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture", "normal_map", "antialiased"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_string", "font", "position", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("draw_char", "font", "position", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1))); - ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map", "transform", "modulate"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>()), DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1))); - ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture", "normal_map"), &CanvasItem::draw_multimesh, DEFVAL(Ref<Texture>())); - - ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform); - ClassDB::bind_method(D_METHOD("draw_set_transform_matrix", "xform"), &CanvasItem::draw_set_transform_matrix); - ClassDB::bind_method(D_METHOD("get_transform"), &CanvasItem::get_transform); - ClassDB::bind_method(D_METHOD("get_global_transform"), &CanvasItem::get_global_transform); - ClassDB::bind_method(D_METHOD("get_global_transform_with_canvas"), &CanvasItem::get_global_transform_with_canvas); - ClassDB::bind_method(D_METHOD("get_viewport_transform"), &CanvasItem::get_viewport_transform); - ClassDB::bind_method(D_METHOD("get_viewport_rect"), &CanvasItem::get_viewport_rect); - ClassDB::bind_method(D_METHOD("get_canvas_transform"), &CanvasItem::get_canvas_transform); - ClassDB::bind_method(D_METHOD("get_local_mouse_position"), &CanvasItem::get_local_mouse_position); - ClassDB::bind_method(D_METHOD("get_global_mouse_position"), &CanvasItem::get_global_mouse_position); - ClassDB::bind_method(D_METHOD("get_canvas"), &CanvasItem::get_canvas); - ClassDB::bind_method(D_METHOD("get_world_2d"), &CanvasItem::get_world_2d); - //ClassDB::bind_method(D_METHOD("get_viewport"),&CanvasItem::get_viewport); - - ClassDB::bind_method(D_METHOD("set_material", "material"), &CanvasItem::set_material); - ClassDB::bind_method(D_METHOD("get_material"), &CanvasItem::get_material); - - ClassDB::bind_method(D_METHOD("set_use_parent_material", "enable"), &CanvasItem::set_use_parent_material); - ClassDB::bind_method(D_METHOD("get_use_parent_material"), &CanvasItem::get_use_parent_material); - - ClassDB::bind_method(D_METHOD("set_notify_local_transform", "enable"), &CanvasItem::set_notify_local_transform); - ClassDB::bind_method(D_METHOD("is_local_transform_notification_enabled"), &CanvasItem::is_local_transform_notification_enabled); - - ClassDB::bind_method(D_METHOD("set_notify_transform", "enable"), &CanvasItem::set_notify_transform); - ClassDB::bind_method(D_METHOD("is_transform_notification_enabled"), &CanvasItem::is_transform_notification_enabled); - - ClassDB::bind_method(D_METHOD("force_update_transform"), &CanvasItem::force_update_transform); - - ClassDB::bind_method(D_METHOD("make_canvas_position_local", "screen_point"), &CanvasItem::make_canvas_position_local); - ClassDB::bind_method(D_METHOD("make_input_local", "event"), &CanvasItem::make_input_local); - - BIND_VMETHOD(MethodInfo("_draw")); - - ADD_GROUP("Visibility", ""); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "self_modulate"), "set_self_modulate", "get_self_modulate"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_behind_parent"), "set_draw_behind_parent", "is_draw_behind_parent_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_on_top", PROPERTY_HINT_NONE, "", 0), "_set_on_top", "_is_on_top"); //compatibility - ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_light_mask", "get_light_mask"); - - ADD_GROUP("Material", ""); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial"), "set_material", "get_material"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_parent_material"), "set_use_parent_material", "get_use_parent_material"); - //exporting these things doesn't really make much sense i think - // ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toplevel", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_as_toplevel", "is_set_as_toplevel"); - // ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),"set_transform_notify","is_transform_notify_enabled"); - - ADD_SIGNAL(MethodInfo("draw")); - ADD_SIGNAL(MethodInfo("visibility_changed")); - ADD_SIGNAL(MethodInfo("hide")); - ADD_SIGNAL(MethodInfo("item_rect_changed")); - - BIND_ENUM_CONSTANT(BLEND_MODE_MIX); - BIND_ENUM_CONSTANT(BLEND_MODE_ADD); - BIND_ENUM_CONSTANT(BLEND_MODE_SUB); - BIND_ENUM_CONSTANT(BLEND_MODE_MUL); - BIND_ENUM_CONSTANT(BLEND_MODE_PREMULT_ALPHA); - BIND_ENUM_CONSTANT(BLEND_MODE_DISABLED); - - BIND_CONSTANT(NOTIFICATION_TRANSFORM_CHANGED); - BIND_CONSTANT(NOTIFICATION_DRAW); - BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED); - BIND_CONSTANT(NOTIFICATION_ENTER_CANVAS); - BIND_CONSTANT(NOTIFICATION_EXIT_CANVAS); -} - -Transform2D CanvasItem::get_canvas_transform() const { - - ERR_FAIL_COND_V(!is_inside_tree(), Transform2D()); - - if (canvas_layer) - return canvas_layer->get_transform(); - else if (Object::cast_to<CanvasItem>(get_parent())) - return Object::cast_to<CanvasItem>(get_parent())->get_canvas_transform(); - else - return get_viewport()->get_canvas_transform(); -} - -Transform2D CanvasItem::get_viewport_transform() const { - - ERR_FAIL_COND_V(!is_inside_tree(), Transform2D()); - - if (canvas_layer) { - - if (get_viewport()) { - return get_viewport()->get_final_transform() * canvas_layer->get_transform(); - } else { - return canvas_layer->get_transform(); - } - - } else { - return get_viewport()->get_final_transform() * get_viewport()->get_canvas_transform(); - } -} - -void CanvasItem::set_notify_local_transform(bool p_enable) { - notify_local_transform = p_enable; -} - -bool CanvasItem::is_local_transform_notification_enabled() const { - return notify_local_transform; -} - -void CanvasItem::set_notify_transform(bool p_enable) { - if (notify_transform == p_enable) - return; - - notify_transform = p_enable; - - if (notify_transform && is_inside_tree()) { - //this ensures that invalid globals get resolved, so notifications can be received - get_global_transform(); - } -} - -bool CanvasItem::is_transform_notification_enabled() const { - return notify_transform; -} - -int CanvasItem::get_canvas_layer() const { - - if (canvas_layer) - return canvas_layer->get_layer(); - else - return 0; -} - -CanvasItem::CanvasItem() : - xform_change(this) { - - canvas_item = VisualServer::get_singleton()->canvas_item_create(); - visible = true; - pending_update = false; - modulate = Color(1, 1, 1, 1); - self_modulate = Color(1, 1, 1, 1); - toplevel = false; - first_draw = false; - drawing = false; - behind = false; - block_transform_notify = false; - //viewport=NULL; - canvas_layer = NULL; - use_parent_material = false; - global_invalid = true; - notify_local_transform = false; - notify_transform = false; - light_mask = 1; - - C = NULL; -} - -CanvasItem::~CanvasItem() { - - VisualServer::get_singleton()->free(canvas_item); -} diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h deleted file mode 100644 index 8814d99edd..0000000000 --- a/scene/2d/canvas_item.h +++ /dev/null @@ -1,397 +0,0 @@ -/*************************************************************************/ -/* canvas_item.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 CANVAS_ITEM_H -#define CANVAS_ITEM_H - -#include "scene/main/node.h" -#include "scene/main/scene_tree.h" -#include "scene/resources/material.h" -#include "scene/resources/multimesh.h" -#include "scene/resources/shader.h" -#include "scene/resources/texture.h" - -class CanvasLayer; -class Viewport; -class Font; - -class StyleBox; - -class CanvasItemMaterial : public Material { - - GDCLASS(CanvasItemMaterial, Material); - -public: - enum BlendMode { - BLEND_MODE_MIX, - BLEND_MODE_ADD, - BLEND_MODE_SUB, - BLEND_MODE_MUL, - BLEND_MODE_PREMULT_ALPHA, - BLEND_MODE_DISABLED - }; - - enum LightMode { - LIGHT_MODE_NORMAL, - LIGHT_MODE_UNSHADED, - LIGHT_MODE_LIGHT_ONLY - }; - -private: - union MaterialKey { - - struct { - uint32_t blend_mode : 4; - uint32_t light_mode : 4; - uint32_t particles_animation : 1; - uint32_t invalid_key : 1; - }; - - uint32_t key; - - bool operator<(const MaterialKey &p_key) const { - return key < p_key.key; - } - }; - - struct ShaderNames { - StringName particles_anim_h_frames; - StringName particles_anim_v_frames; - StringName particles_anim_loop; - }; - - static ShaderNames *shader_names; - - struct ShaderData { - RID shader; - int users; - }; - - static Map<MaterialKey, ShaderData> shader_map; - - MaterialKey current_key; - - _FORCE_INLINE_ MaterialKey _compute_key() const { - - MaterialKey mk; - mk.key = 0; - mk.blend_mode = blend_mode; - mk.light_mode = light_mode; - mk.particles_animation = particles_animation; - return mk; - } - - static Mutex *material_mutex; - static SelfList<CanvasItemMaterial>::List *dirty_materials; - SelfList<CanvasItemMaterial> element; - - void _update_shader(); - _FORCE_INLINE_ void _queue_shader_change(); - _FORCE_INLINE_ bool _is_shader_dirty() const; - - BlendMode blend_mode; - LightMode light_mode; - bool particles_animation; - - int particles_anim_h_frames; - int particles_anim_v_frames; - bool particles_anim_loop; - -protected: - static void _bind_methods(); - void _validate_property(PropertyInfo &property) const; - -public: - void set_blend_mode(BlendMode p_blend_mode); - BlendMode get_blend_mode() const; - - void set_light_mode(LightMode p_light_mode); - LightMode get_light_mode() const; - - void set_particles_animation(bool p_particles_anim); - bool get_particles_animation() const; - - void set_particles_anim_h_frames(int p_frames); - int get_particles_anim_h_frames() const; - void set_particles_anim_v_frames(int p_frames); - int get_particles_anim_v_frames() const; - - void set_particles_anim_loop(bool p_loop); - bool get_particles_anim_loop() const; - - static void init_shaders(); - static void finish_shaders(); - static void flush_changes(); - - RID get_shader_rid() const; - - virtual Shader::Mode get_shader_mode() const; - - CanvasItemMaterial(); - virtual ~CanvasItemMaterial(); -}; - -VARIANT_ENUM_CAST(CanvasItemMaterial::BlendMode) -VARIANT_ENUM_CAST(CanvasItemMaterial::LightMode) - -class CanvasItem : public Node { - - GDCLASS(CanvasItem, Node); - -public: - enum BlendMode { - - BLEND_MODE_MIX, //default - BLEND_MODE_ADD, - BLEND_MODE_SUB, - BLEND_MODE_MUL, - BLEND_MODE_PREMULT_ALPHA, - BLEND_MODE_DISABLED - }; - -private: - mutable SelfList<Node> xform_change; - - RID canvas_item; - String group; - - CanvasLayer *canvas_layer; - - Color modulate; - Color self_modulate; - - List<CanvasItem *> children_items; - List<CanvasItem *>::Element *C; - - int light_mask; - - bool first_draw; - bool visible; - bool pending_update; - bool toplevel; - bool drawing; - bool block_transform_notify; - bool behind; - bool use_parent_material; - bool notify_local_transform; - bool notify_transform; - - Ref<Material> material; - - mutable Transform2D global_transform; - mutable bool global_invalid; - - void _toplevel_raise_self(); - - void _propagate_visibility_changed(bool p_visible); - - void _update_callback(); - - void _enter_canvas(); - void _exit_canvas(); - - void _notify_transform(CanvasItem *p_node); - - void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); } - bool _is_on_top() const { return !is_draw_behind_parent_enabled(); } - - static CanvasItem *current_item_drawn; - -protected: - _FORCE_INLINE_ void _notify_transform() { - if (!is_inside_tree()) return; - _notify_transform(this); - if (!block_transform_notify && notify_local_transform) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); - } - - void item_rect_changed(bool p_size_changed = true); - - void _notification(int p_what); - static void _bind_methods(); - -public: - enum { - NOTIFICATION_TRANSFORM_CHANGED = SceneTree::NOTIFICATION_TRANSFORM_CHANGED, //unique - NOTIFICATION_DRAW = 30, - NOTIFICATION_VISIBILITY_CHANGED = 31, - NOTIFICATION_ENTER_CANVAS = 32, - NOTIFICATION_EXIT_CANVAS = 33, - NOTIFICATION_LOCAL_TRANSFORM_CHANGED = 35, - NOTIFICATION_WORLD_2D_CHANGED = 36, - - }; - - /* EDITOR */ -#ifdef TOOLS_ENABLED - // Select the node - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; - - // Save and restore a CanvasItem state - virtual void _edit_set_state(const Dictionary &p_state){}; - virtual Dictionary _edit_get_state() const { return Dictionary(); }; - - // Used to move the node - virtual void _edit_set_position(const Point2 &p_position) = 0; - virtual Point2 _edit_get_position() const = 0; - - // Used to scale the node - virtual void _edit_set_scale(const Size2 &p_scale) = 0; - virtual Size2 _edit_get_scale() const = 0; - - // Used to rotate the node - virtual bool _edit_use_rotation() const { return false; }; - virtual void _edit_set_rotation(float p_rotation){}; - virtual float _edit_get_rotation() const { return 0.0; }; - - // Used to resize/move the node - virtual bool _edit_use_rect() const { return false; }; // MAYBE REPLACE BY A _edit_get_editmode() - virtual void _edit_set_rect(const Rect2 &p_rect){}; - virtual Rect2 _edit_get_rect() const { return Rect2(0, 0, 0, 0); }; - virtual Size2 _edit_get_minimum_size() const { return Size2(-1, -1); }; // LOOKS WEIRD - - // Used to set a pivot - virtual bool _edit_use_pivot() const { return false; }; - virtual void _edit_set_pivot(const Point2 &p_pivot){}; - virtual Point2 _edit_get_pivot() const { return Point2(); }; - - virtual Transform2D _edit_get_transform() const; -#endif - - /* VISIBILITY */ - - void set_visible(bool p_visible); - bool is_visible() const; - bool is_visible_in_tree() const; - void show(); - void hide(); - - void update(); - - virtual void set_light_mask(int p_light_mask); - int get_light_mask() const; - - void set_modulate(const Color &p_modulate); - Color get_modulate() const; - - void set_self_modulate(const Color &p_self_modulate); - Color get_self_modulate() const; - - /* DRAWING API */ - - void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); - void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); - void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); - void draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); - void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); - void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); - void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, float p_width = 1.0, bool p_antialiased = false); - void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color); - void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref<Texture> &p_normal_map = Ref<Texture>()); - void draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()); - void draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = false); - void draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect); - void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture = Ref<Texture>(), float p_width = 1, const Ref<Texture> &p_normal_map = Ref<Texture>()); - void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false); - void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false); - - void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1)); - void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map); - - void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1); - float draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", const Color &p_modulate = Color(1, 1, 1)); - - void draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale); - void draw_set_transform_matrix(const Transform2D &p_matrix); - - static CanvasItem *get_current_item_drawn(); - - /* RECT / TRANSFORM */ - - void set_as_toplevel(bool p_toplevel); - bool is_set_as_toplevel() const; - - void set_draw_behind_parent(bool p_enable); - bool is_draw_behind_parent_enabled() const; - - CanvasItem *get_parent_item() const; - - virtual Transform2D get_transform() const = 0; - - virtual Transform2D get_global_transform() const; - virtual Transform2D get_global_transform_with_canvas() const; - - CanvasItem *get_toplevel() const; - _FORCE_INLINE_ RID get_canvas_item() const { - return canvas_item; - } - - void set_block_transform_notify(bool p_enable); - bool is_block_transform_notify_enabled() const; - - Transform2D get_canvas_transform() const; - Transform2D get_viewport_transform() const; - Rect2 get_viewport_rect() const; - RID get_viewport_rid() const; - RID get_canvas() const; - ObjectID get_canvas_layer_instance_id() const; - Ref<World2D> get_world_2d() const; - - virtual void set_material(const Ref<Material> &p_material); - Ref<Material> get_material() const; - - virtual void set_use_parent_material(bool p_use_parent_material); - bool get_use_parent_material() const; - - Ref<InputEvent> make_input_local(const Ref<InputEvent> &p_event) const; - Vector2 make_canvas_position_local(const Vector2 &screen_point) const; - - Vector2 get_global_mouse_position() const; - Vector2 get_local_mouse_position() const; - - void set_notify_local_transform(bool p_enable); - bool is_local_transform_notification_enabled() const; - - void set_notify_transform(bool p_enable); - bool is_transform_notification_enabled() const; - - void force_update_transform(); - - // Used by control nodes to retrieve the parent's anchorable area - virtual Rect2 get_anchorable_rect() const { return Rect2(0, 0, 0, 0); }; - - int get_canvas_layer() const; - - CanvasItem(); - ~CanvasItem(); -}; - -VARIANT_ENUM_CAST(CanvasItem::BlendMode); - -#endif // CANVAS_ITEM_H diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp index 25db434918..56643542a8 100644 --- a/scene/2d/canvas_modulate.cpp +++ b/scene/2d/canvas_modulate.cpp @@ -31,27 +31,23 @@ #include "canvas_modulate.h" void CanvasModulate::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_CANVAS) { - if (is_visible_in_tree()) { - VS::get_singleton()->canvas_set_modulate(get_canvas(), color); + 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()) { - VS::get_singleton()->canvas_set_modulate(get_canvas(), Color(1, 1, 1, 1)); + 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()) { - VS::get_singleton()->canvas_set_modulate(get_canvas(), color); + RS::get_singleton()->canvas_set_modulate(get_canvas(), color); add_to_group("_canvas_modulate_" + itos(get_canvas().get_id())); } else { - VS::get_singleton()->canvas_set_modulate(get_canvas(), Color(1, 1, 1, 1)); + RS::get_singleton()->canvas_set_modulate(get_canvas(), Color(1, 1, 1, 1)); remove_from_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,21 +63,20 @@ void CanvasModulate::_bind_methods() { } void CanvasModulate::set_color(const Color &p_color) { - color = p_color; if (is_visible_in_tree()) { - VS::get_singleton()->canvas_set_modulate(get_canvas(), color); + 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(); + } List<Node *> nodes; get_tree()->get_nodes_in_group("_canvas_modulate_" + itos(get_canvas().get_id()), &nodes); 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 3e9e63a7f0..fe16d4089a 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -31,26 +31,25 @@ #include "collision_object_2d.h" #include "scene/scene_string_names.h" -#include "servers/physics_2d_server.h" +#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) - Physics2DServer::get_singleton()->area_set_transform(rid, global_transform); - else - Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, global_transform); + if (area) { + PhysicsServer2D::get_singleton()->area_set_transform(rid, global_transform); + } else { + PhysicsServer2D::get_singleton()->body_set_state(rid, PhysicsServer2D::BODY_STATE_TRANSFORM, global_transform); + } RID space = get_world_2d()->get_space(); if (area) { - Physics2DServer::get_singleton()->area_set_space(rid, space); - } else - Physics2DServer::get_singleton()->body_set_space(rid, space); + PhysicsServer2D::get_singleton()->area_set_space(rid, space); + } 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) - Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, get_canvas_layer_instance_id()); - else - Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, get_canvas_layer_instance_id()); + if (area) { + PhysicsServer2D::get_singleton()->area_attach_canvas_instance_id(rid, get_canvas_layer_instance_id()); + } 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) - Physics2DServer::get_singleton()->area_set_transform(rid, global_transform); - else - Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, global_transform); + if (area) { + PhysicsServer2D::get_singleton()->area_set_transform(rid, global_transform); + } else { + PhysicsServer2D::get_singleton()->body_set_state(rid, PhysicsServer2D::BODY_STATE_TRANSFORM, global_transform); + } } break; case NOTIFICATION_EXIT_TREE: { - if (area) { - Physics2DServer::get_singleton()->area_set_space(rid, RID()); - } else - Physics2DServer::get_singleton()->body_set_space(rid, RID()); + PhysicsServer2D::get_singleton()->area_set_space(rid, RID()); + } else { + PhysicsServer2D::get_singleton()->body_set_space(rid, RID()); + } } break; case NOTIFICATION_EXIT_CANVAS: { - - if (area) - Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, 0); - else - Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, 0); + if (area) { + PhysicsServer2D::get_singleton()->area_attach_canvas_instance_id(rid, ObjectID()); + } 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); @@ -136,71 +132,66 @@ void CollisionObject2D::shape_owner_set_disabled(uint32_t p_owner, bool p_disabl sd.disabled = p_disabled; for (int i = 0; i < sd.shapes.size(); i++) { if (area) { - Physics2DServer::get_singleton()->area_set_shape_disabled(rid, sd.shapes[i].index, p_disabled); + PhysicsServer2D::get_singleton()->area_set_shape_disabled(rid, sd.shapes[i].index, p_disabled); } else { - Physics2DServer::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled); + PhysicsServer2D::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled); } } } 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)); ShapeData &sd = shapes[p_owner]; sd.one_way_collision = p_enable; for (int i = 0; i < sd.shapes.size(); i++) { - Physics2DServer::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin); + PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin); } } 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)); ShapeData &sd = shapes[p_owner]; sd.one_way_collision_margin = p_margin; for (int i = 0; i < sd.shapes.size(); i++) { - Physics2DServer::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin); + PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin); } } 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]; @@ -218,28 +208,26 @@ void CollisionObject2D::shape_owner_set_transform(uint32_t p_owner, const Transf sd.xform = p_transform; for (int i = 0; i < sd.shapes.size(); i++) { if (area) { - Physics2DServer::get_singleton()->area_set_shape_transform(rid, sd.shapes[i].index, sd.xform); + PhysicsServer2D::get_singleton()->area_set_shape_transform(rid, sd.shapes[i].index, sd.xform); } else { - Physics2DServer::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, sd.xform); + PhysicsServer2D::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, sd.xform); } } } -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), NULL); + 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()); @@ -248,29 +236,29 @@ void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2 s.index = total_subshapes; s.shape = p_shape; if (area) { - Physics2DServer::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled); + PhysicsServer2D::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled); } else { - Physics2DServer::get_singleton()->body_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled); + PhysicsServer2D::get_singleton()->body_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled); } sd.shapes.push_back(s); 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,15 +266,14 @@ 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()); int index_to_remove = shapes[p_owner].shapes[p_shape].index; if (area) { - Physics2DServer::get_singleton()->area_remove_shape(rid, index_to_remove); + PhysicsServer2D::get_singleton()->area_remove_shape(rid, index_to_remove); } else { - Physics2DServer::get_singleton()->body_remove_shape(rid, index_to_remove); + PhysicsServer2D::get_singleton()->body_remove_shape(rid, index_to_remove); } shapes[p_owner].shapes.remove(p_shape); @@ -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) - Physics2DServer::get_singleton()->area_set_pickable(rid, is_pickable); - else - Physics2DServer::get_singleton()->body_set_pickable(rid, is_pickable); + if (area) { + PhysicsServer2D::get_singleton()->area_set_pickable(rid, is_pickable); + } 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,21 +421,18 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) { only_update_transform_changes = false; if (p_area) { - - Physics2DServer::get_singleton()->area_attach_object_instance_id(rid, get_instance_id()); + PhysicsServer2D::get_singleton()->area_attach_object_instance_id(rid, get_instance_id()); } else { - Physics2DServer::get_singleton()->body_attach_object_instance_id(rid, get_instance_id()); + PhysicsServer2D::get_singleton()->body_attach_object_instance_id(rid, get_instance_id()); } } CollisionObject2D::CollisionObject2D() { - //owner= set_notify_transform(true); } CollisionObject2D::~CollisionObject2D() { - - Physics2DServer::get_singleton()->free(rid); + PhysicsServer2D::get_singleton()->free(rid); } diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index 8874f61bb7..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 { @@ -60,7 +58,7 @@ class CollisionObject2D : public Node2D { disabled = false; one_way_collision = false; one_way_collision_margin = 0; - owner = NULL; + owner = nullptr; } }; @@ -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 d9cc94c6eb..d23398713a 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -32,25 +32,25 @@ #include "collision_object_2d.h" #include "core/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(); + Vector<Vector<Vector2>> decomp = _decompose_in_convex(); for (int i = 0; i < decomp.size(); i++) { Ref<ConvexPolygonShape2D> convex = memnew(ConvexPolygonShape2D); convex->set_points(decomp[i]); @@ -58,45 +58,41 @@ void CollisionPolygon2D::_build_polygon() { } } else { - Ref<ConcavePolygonShape2D> concave = memnew(ConcavePolygonShape2D); - PoolVector<Vector2> segments; + Vector<Vector2> segments; segments.resize(polygon.size() * 2); - PoolVector<Vector2>::Write w = segments.write(); + Vector2 *w = segments.ptrw(); for (int i = 0; i < polygon.size(); i++) { w[(i << 1) + 0] = polygon[i]; w[(i << 1) + 1] = polygon[(i + 1) % polygon.size()]; } - w.release(); concave->set_segments(segments); parent->shape_owner_add_shape(owner_id, concave); } } -Vector<Vector<Vector2> > CollisionPolygon2D::_decompose_in_convex() { - Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon_in_convex(polygon); +Vector<Vector<Vector2>> CollisionPolygon2D::_decompose_in_convex() { + 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); @@ -107,19 +103,17 @@ void CollisionPolygon2D::_notification(int p_what) { /*if (Engine::get_singleton()->is_editor_hint()) { //display above all else set_z_as_relative(false); - set_z_index(VS::CANVAS_ITEM_Z_MAX - 1); + set_z_index(RS::CANVAS_ITEM_Z_MAX - 1); }*/ } break; case NOTIFICATION_ENTER_TREE: { - if (parent) { _update_in_shape_owner(); } } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - if (parent) { _update_in_shape_owner(true); } @@ -130,17 +124,15 @@ void CollisionPolygon2D::_notification(int p_what) { parent->remove_shape_owner(owner_id); } owner_id = 0; - parent = NULL; + parent = nullptr; } 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 @@ -149,11 +141,10 @@ void CollisionPolygon2D::_notification(int p_what) { #define DEBUG_DECOMPOSE #if defined(TOOLS_ENABLED) && defined(DEBUG_DECOMPOSE) - Vector<Vector<Vector2> > decomp = _decompose_in_convex(); + Vector<Vector<Vector2>> decomp = _decompose_in_convex(); 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); } @@ -172,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 } @@ -182,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; @@ -209,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) { @@ -223,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; } @@ -238,13 +225,11 @@ 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 { - 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."); } @@ -277,7 +262,6 @@ void CollisionPolygon2D::set_one_way_collision(bool p_enable) { } bool CollisionPolygon2D::is_one_way_collision_enabled() const { - return one_way_collision; } @@ -291,8 +275,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); @@ -306,21 +290,20 @@ void CollisionPolygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_one_way_collision_margin"), &CollisionPolygon2D::get_one_way_collision_margin); ADD_PROPERTY(PropertyInfo(Variant::INT, "build_mode", PROPERTY_HINT_ENUM, "Solids,Segments"), "set_build_mode", "get_build_mode"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_way_collision"), "set_one_way_collision", "is_one_way_collision_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1"), "set_one_way_collision_margin", "get_one_way_collision_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1"), "set_one_way_collision_margin", "get_one_way_collision_margin"); BIND_ENUM_CONSTANT(BUILD_SOLIDS); BIND_ENUM_CONSTANT(BUILD_SEGMENTS); } CollisionPolygon2D::CollisionPolygon2D() { - aabb = Rect2(-10, -10, 20, 20); build_mode = BUILD_SOLIDS; set_notify_local_transform(true); - parent = NULL; + parent = nullptr; owner_id = 0; disabled = false; one_way_collision = false; diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index d8dfec8fd2..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: @@ -56,7 +55,7 @@ protected: bool one_way_collision; float one_way_collision_margin; - Vector<Vector<Vector2> > _decompose_in_convex(); + Vector<Vector<Vector2>> _decompose_in_convex(); void _build_polygon(); @@ -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 eace4c64fc..d022c857f3 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -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); @@ -73,19 +69,17 @@ void CollisionShape2D::_notification(int p_what) { /*if (Engine::get_singleton()->is_editor_hint()) { //display above all else set_z_as_relative(false); - set_z_index(VS::CANVAS_ITEM_Z_MAX - 1); + set_z_index(RS::CANVAS_ITEM_Z_MAX - 1); }*/ } break; case NOTIFICATION_ENTER_TREE: { - if (parent) { _update_in_shape_owner(); } } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - if (parent) { _update_in_shape_owner(true); } @@ -96,11 +90,10 @@ void CollisionShape2D::_notification(int p_what) { parent->remove_shape_owner(owner_id); } owner_id = 0; - parent = NULL; + parent = nullptr; } break; case NOTIFICATION_DRAW: { - if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) { break; } @@ -130,15 +123,16 @@ void CollisionShape2D::_notification(int p_what) { draw_col = draw_col.darkened(0.25); } Vector2 line_to(0, 20); - draw_line(Vector2(), line_to, draw_col, 2, true); + draw_line(Vector2(), line_to, draw_col, 2); Vector<Vector2> pts; float tsize = 8; pts.push_back(line_to + (Vector2(0, tsize))); pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); Vector<Color> cols; - for (int i = 0; i < 3; i++) + 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()) - shape->disconnect("changed", this, "_shape_changed"); + 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()) - shape->connect("changed", this, "_shape_changed"); + 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); @@ -237,20 +231,18 @@ void CollisionShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_one_way_collision_enabled"), &CollisionShape2D::is_one_way_collision_enabled); ClassDB::bind_method(D_METHOD("set_one_way_collision_margin", "margin"), &CollisionShape2D::set_one_way_collision_margin); ClassDB::bind_method(D_METHOD("get_one_way_collision_margin"), &CollisionShape2D::get_one_way_collision_margin); - ClassDB::bind_method(D_METHOD("_shape_changed"), &CollisionShape2D::_shape_changed); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_way_collision"), "set_one_way_collision", "is_one_way_collision_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1"), "set_one_way_collision_margin", "get_one_way_collision_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1"), "set_one_way_collision_margin", "get_one_way_collision_margin"); } CollisionShape2D::CollisionShape2D() { - rect = Rect2(-Point2(10, 10), Point2(20, 20)); set_notify_local_transform(true); owner_id = 0; - parent = NULL; + parent = nullptr; disabled = false; one_way_collision = false; one_way_collision_margin = 1.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 f59e3461b1..dd21fcfe22 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -30,155 +30,156 @@ #include "cpu_particles_2d.h" -#include "scene/2d/canvas_item.h" -#include "scene/2d/particles_2d.h" +#include "core/core_string_names.h" +#include "scene/2d/gpu_particles_2d.h" +#include "scene/main/canvas_item.h" #include "scene/resources/particles_material.h" -#include "servers/visual_server.h" +#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); { - PoolVector<Particle>::Write w = particles.write(); + Particle *w = particles.ptrw(); for (int i = 0; i < p_amount; i++) { w[i].active = false; } } - particle_data.resize((8 + 4 + 1) * p_amount); - VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_2D, VS::MULTIMESH_COLOR_8BIT, VS::MULTIMESH_CUSTOM_DATA_FLOAT); + particle_data.resize((8 + 4 + 4) * p_amount); + RS::get_singleton()->multimesh_allocate(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_2D, true, true); 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(); } else { tex_size = Size2(1, 1); } - PoolVector<Vector2> vertices; + Vector<Vector2> vertices; vertices.push_back(-tex_size * 0.5); vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, 0)); vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, tex_size.y)); vertices.push_back(-tex_size * 0.5 + Vector2(0, tex_size.y)); - PoolVector<Vector2> uvs; - uvs.push_back(Vector2(0, 0)); - uvs.push_back(Vector2(1, 0)); - uvs.push_back(Vector2(1, 1)); - uvs.push_back(Vector2(0, 1)); - PoolVector<Color> colors; + Vector<Vector2> uvs; + AtlasTexture *atlas_texure = Object::cast_to<AtlasTexture>(*texture); + if (atlas_texure && atlas_texure->get_atlas().is_valid()) { + Rect2 region_rect = atlas_texure->get_region(); + Size2 atlas_size = atlas_texure->get_atlas()->get_size(); + uvs.push_back(Vector2(region_rect.position.x / atlas_size.x, region_rect.position.y / atlas_size.y)); + uvs.push_back(Vector2((region_rect.position.x + region_rect.size.x) / atlas_size.x, region_rect.position.y / atlas_size.y)); + uvs.push_back(Vector2((region_rect.position.x + region_rect.size.x) / atlas_size.x, (region_rect.position.y + region_rect.size.y) / atlas_size.y)); + uvs.push_back(Vector2(region_rect.position.x / atlas_size.x, (region_rect.position.y + region_rect.size.y) / atlas_size.y)); + } else { + uvs.push_back(Vector2(0, 0)); + uvs.push_back(Vector2(1, 0)); + uvs.push_back(Vector2(1, 1)); + uvs.push_back(Vector2(0, 1)); + } + Vector<Color> colors; colors.push_back(Color(1, 1, 1, 1)); colors.push_back(Color(1, 1, 1, 1)); colors.push_back(Color(1, 1, 1, 1)); colors.push_back(Color(1, 1, 1, 1)); - PoolVector<int> indices; + Vector<int> indices; indices.push_back(0); indices.push_back(1); indices.push_back(2); @@ -187,36 +188,52 @@ void CPUParticles2D::_update_mesh_texture() { indices.push_back(0); Array arr; - arr.resize(VS::ARRAY_MAX); - arr[VS::ARRAY_VERTEX] = vertices; - arr[VS::ARRAY_TEX_UV] = uvs; - arr[VS::ARRAY_COLOR] = colors; - arr[VS::ARRAY_INDEX] = indices; + arr.resize(RS::ARRAY_MAX); + arr[RS::ARRAY_VERTEX] = vertices; + arr[RS::ARRAY_TEX_UV] = uvs; + arr[RS::ARRAY_COLOR] = colors; + arr[RS::ARRAY_INDEX] = indices; - VS::get_singleton()->mesh_clear(mesh); - VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VS::PRIMITIVE_TRIANGLES, arr); + RS::get_singleton()->mesh_clear(mesh); + RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr); } -void CPUParticles2D::set_texture(const Ref<Texture> &p_texture) { +void CPUParticles2D::set_texture(const Ref<Texture2D> &p_texture) { + if (p_texture == texture) { + return; + } + + if (texture.is_valid()) { + texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CPUParticles2D::_texture_changed)); + } texture = p_texture; + + if (texture.is_valid()) { + texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CPUParticles2D::_texture_changed)); + } + update(); _update_mesh_texture(); } -Ref<Texture> CPUParticles2D::get_texture() const { +void CPUParticles2D::_texture_changed() { + if (texture.is_valid()) { + update(); + _update_mesh_texture(); + } +} +Ref<Texture2D> CPUParticles2D::get_texture() const { return texture; } -void CPUParticles2D::set_normalmap(const Ref<Texture> &p_normalmap) { - +void CPUParticles2D::set_normalmap(const Ref<Texture2D> &p_normalmap) { normalmap = p_normalmap; update(); } -Ref<Texture> CPUParticles2D::get_normalmap() const { - +Ref<Texture2D> CPUParticles2D::get_normalmap() const { return normalmap; } @@ -237,7 +254,6 @@ bool CPUParticles2D::get_fractional_delta() const { } String CPUParticles2D::get_configuration_warning() const { - String warnings; CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr()); @@ -245,8 +261,9 @@ String CPUParticles2D::get_configuration_warning() const { 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."); } } @@ -255,7 +272,6 @@ String CPUParticles2D::get_configuration_warning() const { } void CPUParticles2D::restart() { - time = 0; inactive_time = 0; frame_remainder = 0; @@ -264,7 +280,7 @@ void CPUParticles2D::restart() { { int pc = particles.size(); - PoolVector<Particle>::Write w = particles.write(); + Particle *w = particles.ptrw(); for (int i = 0; i < pc; i++) { w[i].active = false; @@ -275,62 +291,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; @@ -361,7 +370,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); @@ -375,30 +383,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; } @@ -419,67 +423,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 PoolVector<Vector2> &p_points) { - +void CPUParticles2D::set_emission_points(const Vector<Vector2> &p_points) { emission_points = p_points; } -void CPUParticles2D::set_emission_normals(const PoolVector<Vector2> &p_normals) { - +void CPUParticles2D::set_emission_normals(const Vector<Vector2> &p_normals) { emission_normals = p_normals; } -void CPUParticles2D::set_emission_colors(const PoolVector<Color> &p_colors) { - +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; } -PoolVector<Vector2> CPUParticles2D::get_emission_points() const { +Vector<Vector2> CPUParticles2D::get_emission_points() const { return emission_points; } -PoolVector<Vector2> CPUParticles2D::get_emission_normals() const { +Vector<Vector2> CPUParticles2D::get_emission_normals() const { return emission_normals; } -PoolVector<Color> CPUParticles2D::get_emission_colors() const { - +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; } @@ -510,7 +505,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; @@ -520,18 +514,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; @@ -557,12 +552,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; @@ -599,13 +594,12 @@ void CPUParticles2D::_update_internal() { } void CPUParticles2D::_particles_process(float p_delta) { - p_delta *= speed_scale; int pcount = particles.size(); - PoolVector<Particle>::Write w = particles.write(); + Particle *w = particles.ptrw(); - Particle *parray = w.ptr(); + Particle *parray = w; float prev_time = time; time += p_delta; @@ -629,11 +623,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; @@ -687,7 +681,6 @@ void CPUParticles2D::_particles_process(float p_delta) { } if (restart) { - if (!emitting) { p.active = false; continue; @@ -746,17 +739,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) { @@ -778,7 +775,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; @@ -862,7 +858,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; @@ -921,7 +916,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(); } @@ -933,7 +927,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; @@ -943,122 +939,104 @@ void CPUParticles2D::_particles_process(float p_delta) { } void CPUParticles2D::_update_particle_data_buffer() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); - { - - int pc = particles.size(); + int pc = particles.size(); - PoolVector<int>::Write ow; - int *order = NULL; + int *ow; + int *order = nullptr; - PoolVector<float>::Write w = particle_data.write(); - PoolVector<Particle>::Read r = particles.read(); - float *ptr = w.ptr(); + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + float *ptr = w; - if (draw_order != DRAW_ORDER_INDEX) { - ow = particle_order.write(); - order = ow.ptr(); - - for (int i = 0; i < pc; i++) { - order[i] = i; - } - if (draw_order == DRAW_ORDER_LIFETIME) { - SortArray<int, SortLifetime> sorter; - sorter.compare.particles = r.ptr(); - sorter.sort(order, pc); - } - } + if (draw_order != DRAW_ORDER_INDEX) { + ow = particle_order.ptrw(); + order = ow; for (int i = 0; i < pc; i++) { + order[i] = i; + } + if (draw_order == DRAW_ORDER_LIFETIME) { + SortArray<int, SortLifetime> sorter; + sorter.compare.particles = r; + sorter.sort(order, pc); + } + } - int idx = order ? order[i] : i; + for (int i = 0; i < pc; i++) { + int idx = order ? order[i] : i; - Transform2D t = r[idx].transform; + Transform2D t = r[idx].transform; - if (!local_coords) { - t = inv_emission_transform * t; - } + if (!local_coords) { + t = inv_emission_transform * t; + } - if (r[idx].active) { + if (r[idx].active) { + ptr[0] = t.elements[0][0]; + ptr[1] = t.elements[1][0]; + ptr[2] = 0; + ptr[3] = t.elements[2][0]; + ptr[4] = t.elements[0][1]; + ptr[5] = t.elements[1][1]; + ptr[6] = 0; + ptr[7] = t.elements[2][1]; - ptr[0] = t.elements[0][0]; - ptr[1] = t.elements[1][0]; - ptr[2] = 0; - ptr[3] = t.elements[2][0]; - ptr[4] = t.elements[0][1]; - ptr[5] = t.elements[1][1]; - ptr[6] = 0; - ptr[7] = t.elements[2][1]; + } else { + zeromem(ptr, sizeof(float) * 8); + } - } else { - zeromem(ptr, sizeof(float) * 8); - } + Color c = r[idx].color; - Color c = r[idx].color; - uint8_t *data8 = (uint8_t *)&ptr[8]; - data8[0] = CLAMP(c.r * 255.0, 0, 255); - data8[1] = CLAMP(c.g * 255.0, 0, 255); - data8[2] = CLAMP(c.b * 255.0, 0, 255); - data8[3] = CLAMP(c.a * 255.0, 0, 255); + ptr[8] = c.r; + ptr[9] = c.g; + ptr[10] = c.b; + ptr[11] = c.a; - ptr[9] = r[idx].custom[0]; - ptr[10] = r[idx].custom[1]; - ptr[11] = r[idx].custom[2]; - ptr[12] = r[idx].custom[3]; + ptr[12] = r[idx].custom[0]; + ptr[13] = r[idx].custom[1]; + ptr[14] = r[idx].custom[2]; + ptr[15] = r[idx].custom[3]; - ptr += 13; - } + ptr += 16; } - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif } void CPUParticles2D::_set_redraw(bool p_redraw) { - if (redraw == p_redraw) + if (redraw == p_redraw) { return; + } redraw = p_redraw; -#ifndef NO_THREADS - update_mutex->lock(); -#endif - if (redraw) { - VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true); - - VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); - } else { - if (VS::get_singleton()->is_connected("frame_pre_draw", this, "_update_render_thread")) { - VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); - } - VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); - VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); + { + MutexLock lock(update_mutex); + + if (redraw) { + RS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &CPUParticles2D::_update_render_thread)); + RS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true); + + RS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); + } else { + if (RS::get_singleton()->is_connected("frame_pre_draw", callable_mp(this, &CPUParticles2D::_update_render_thread))) { + RS::get_singleton()->disconnect("frame_pre_draw", callable_mp(this, &CPUParticles2D::_update_render_thread)); + } + RS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); + + RS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); + } } -#ifndef NO_THREADS - update_mutex->unlock(); -#endif + update(); // redraw to update render list } void CPUParticles2D::_update_render_thread() { + MutexLock lock(update_mutex); -#ifndef NO_THREADS - update_mutex->lock(); -#endif - - VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data); - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif + 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); } @@ -1069,11 +1047,13 @@ 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()) { @@ -1085,7 +1065,7 @@ void CPUParticles2D::_notification(int p_what) { normrid = normalmap->get_rid(); } - VS::get_singleton()->canvas_item_add_multimesh(get_canvas_item(), multimesh, texrid, normrid); + RS::get_singleton()->canvas_item_add_multimesh(get_canvas_item(), multimesh, texrid, normrid); } if (p_what == NOTIFICATION_INTERNAL_PROCESS) { @@ -1093,23 +1073,19 @@ 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(); - PoolVector<float>::Write w = particle_data.write(); - PoolVector<Particle>::Read r = particles.read(); - float *ptr = w.ptr(); + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + 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; @@ -1123,16 +1099,15 @@ void CPUParticles2D::_notification(int p_what) { zeromem(ptr, sizeof(float) * 8); } - ptr += 13; + ptr += 16; } } } } void CPUParticles2D::convert_from_particles(Node *p_particles) { - - Particles2D *particles = Object::cast_to<Particles2D>(p_particles); - ERR_FAIL_COND_MSG(!particles, "Only Particles2D nodes can be converted to CPUParticles2D."); + GPUParticles2D *particles = Object::cast_to<GPUParticles2D>(p_particles); + ERR_FAIL_COND_MSG(!particles, "Only GPUParticles2D nodes can be converted to CPUParticles2D."); set_emitting(particles->is_emitting()); set_amount(particles->get_amount()); @@ -1154,8 +1129,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)); @@ -1183,7 +1159,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)); @@ -1204,7 +1181,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); @@ -1246,21 +1222,21 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); // No visibility_rect property contrarily to Particles2D, it's updated automatically. 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, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normalmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normalmap", "get_normalmap"); + 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); @@ -1314,71 +1290,69 @@ void CPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles); - ClassDB::bind_method(D_METHOD("_update_render_thread"), &CPUParticles2D::_update_render_thread); - 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::REAL, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius"); + 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::POOL_VECTOR2_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); ADD_GROUP("Flags", "flag_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY); ADD_GROUP("Direction", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "direction"), "set_direction", "get_direction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); ADD_GROUP("Gravity", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity"), "set_gravity", "get_gravity"); ADD_GROUP("Initial Velocity", "initial_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ORBIT_VELOCITY); ADD_GROUP("Linear Accel", "linear_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_LINEAR_ACCEL); ADD_GROUP("Radial Accel", "radial_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_RADIAL_ACCEL); ADD_GROUP("Tangential Accel", "tangential_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL); ADD_GROUP("Damping", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param", "get_param", PARAM_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param", "get_param", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING); ADD_GROUP("Angle", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE); ADD_GROUP("Scale", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_amount_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_SCALE); ADD_GROUP("Color", ""); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); ADD_GROUP("Hue Variation", "hue_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION); ADD_GROUP("Animation", "anim_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_OFFSET); BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY); @@ -1409,7 +1383,6 @@ void CPUParticles2D::_bind_methods() { } CPUParticles2D::CPUParticles2D() { - time = 0; inactive_time = 0; frame_remainder = 0; @@ -1417,9 +1390,9 @@ CPUParticles2D::CPUParticles2D() { redraw = false; emitting = false; - mesh = VisualServer::get_singleton()->mesh_create(); - multimesh = VisualServer::get_singleton()->multimesh_create(); - VisualServer::get_singleton()->multimesh_set_mesh(multimesh, mesh); + mesh = RenderingServer::get_singleton()->mesh_create(); + multimesh = RenderingServer::get_singleton()->multimesh_create(); + RenderingServer::get_singleton()->multimesh_set_mesh(multimesh, mesh); set_emitting(true); set_one_shot(false); @@ -1466,18 +1439,10 @@ CPUParticles2D::CPUParticles2D() { set_color(Color(1, 1, 1, 1)); -#ifndef NO_THREADS - update_mutex = Mutex::create(); -#endif - _update_mesh_texture(); } CPUParticles2D::~CPUParticles2D() { - VS::get_singleton()->free(multimesh); - VS::get_singleton()->free(mesh); - -#ifndef NO_THREADS - memdelete(update_mutex); -#endif + RS::get_singleton()->free(multimesh); + RS::get_singleton()->free(mesh); } diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 085ec99ea0..dfc875ceb0 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -108,9 +108,9 @@ private: RID mesh; RID multimesh; - PoolVector<Particle> particles; - PoolVector<float> particle_data; - PoolVector<int> particle_order; + Vector<Particle> particles; + Vector<float> particle_data; + Vector<int> particle_order; struct SortLifetime { const Particle *particles; @@ -124,7 +124,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]); } }; @@ -147,8 +146,8 @@ private: DrawOrder draw_order; - Ref<Texture> texture; - Ref<Texture> normalmap; + Ref<Texture2D> texture; + Ref<Texture2D> normalmap; //////// @@ -167,9 +166,9 @@ private: EmissionShape emission_shape; float emission_sphere_radius; Vector2 emission_rect_extents; - PoolVector<Vector2> emission_points; - PoolVector<Vector2> emission_normals; - PoolVector<Color> emission_colors; + Vector<Vector2> emission_points; + Vector<Vector2> emission_normals; + Vector<Color> emission_colors; int emission_point_count; Vector2 gravity; @@ -178,7 +177,7 @@ private: void _particles_process(float p_delta); void _update_particle_data_buffer(); - Mutex *update_mutex; + Mutex update_mutex; void _update_render_thread(); @@ -186,10 +185,12 @@ private: void _set_redraw(bool p_redraw); + void _texture_changed(); + 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); @@ -228,11 +229,11 @@ public: void set_draw_passes(int p_count); int get_draw_passes() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_normalmap(const Ref<Texture> &p_normalmap); - Ref<Texture> get_normalmap() const; + void set_normalmap(const Ref<Texture2D> &p_normalmap); + Ref<Texture2D> get_normalmap() const; /////////////////// @@ -263,23 +264,23 @@ public: void set_emission_shape(EmissionShape p_shape); void set_emission_sphere_radius(float p_radius); void set_emission_rect_extents(Vector2 p_extents); - void set_emission_points(const PoolVector<Vector2> &p_points); - void set_emission_normals(const PoolVector<Vector2> &p_normals); - void set_emission_colors(const PoolVector<Color> &p_colors); + void set_emission_points(const Vector<Vector2> &p_points); + void set_emission_normals(const Vector<Vector2> &p_normals); + void set_emission_colors(const Vector<Color> &p_colors); void set_emission_point_count(int p_count); EmissionShape get_emission_shape() const; float get_emission_sphere_radius() const; Vector2 get_emission_rect_extents() const; - PoolVector<Vector2> get_emission_points() const; - PoolVector<Vector2> get_emission_normals() const; - PoolVector<Color> get_emission_colors() const; + Vector<Vector2> get_emission_points() const; + Vector<Vector2> get_emission_normals() const; + Vector<Color> get_emission_colors() const; int get_emission_point_count() const; 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/particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 746feeaa82..0814fbb549 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* particles_2d.cpp */ +/* gpu_particles_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "particles_2d.h" +#include "gpu_particles_2d.h" #include "core/os/os.h" #include "scene/resources/particles_material.h" @@ -38,9 +38,8 @@ #include "core/engine.h" #endif -void Particles2D::set_emitting(bool p_emitting) { - - VS::get_singleton()->particles_set_emitting(particles, p_emitting); +void GPUParticles2D::set_emitting(bool p_emitting) { + RS::get_singleton()->particles_set_emitting(particles, p_emitting); if (p_emitting && one_shot) { set_process_internal(true); @@ -49,51 +48,50 @@ void Particles2D::set_emitting(bool p_emitting) { } } -void Particles2D::set_amount(int p_amount) { - +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; - VS::get_singleton()->particles_set_amount(particles, amount); + RS::get_singleton()->particles_set_amount(particles, amount); } -void Particles2D::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; - VS::get_singleton()->particles_set_lifetime(particles, lifetime); + RS::get_singleton()->particles_set_lifetime(particles, lifetime); } -void Particles2D::set_one_shot(bool p_enable) { - +void GPUParticles2D::set_one_shot(bool p_enable) { one_shot = p_enable; - VS::get_singleton()->particles_set_one_shot(particles, one_shot); + RS::get_singleton()->particles_set_one_shot(particles, one_shot); if (is_emitting()) { - set_process_internal(true); - if (!one_shot) - VisualServer::get_singleton()->particles_restart(particles); + if (!one_shot) { + RenderingServer::get_singleton()->particles_restart(particles); + } } - if (!one_shot) + if (!one_shot) { set_process_internal(false); + } } -void Particles2D::set_pre_process_time(float p_time) { +void GPUParticles2D::set_pre_process_time(float p_time) { pre_process_time = p_time; - VS::get_singleton()->particles_set_pre_process_time(particles, pre_process_time); + RS::get_singleton()->particles_set_pre_process_time(particles, pre_process_time); } -void Particles2D::set_explosiveness_ratio(float p_ratio) { +void GPUParticles2D::set_explosiveness_ratio(float p_ratio) { explosiveness_ratio = p_ratio; - VS::get_singleton()->particles_set_explosiveness_ratio(particles, explosiveness_ratio); + RS::get_singleton()->particles_set_explosiveness_ratio(particles, explosiveness_ratio); } -void Particles2D::set_randomness_ratio(float p_ratio) { +void GPUParticles2D::set_randomness_ratio(float p_ratio) { randomness_ratio = p_ratio; - VS::get_singleton()->particles_set_randomness_ratio(particles, randomness_ratio); + RS::get_singleton()->particles_set_randomness_ratio(particles, randomness_ratio); } -void Particles2D::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; @@ -101,34 +99,32 @@ void Particles2D::set_visibility_rect(const Rect2 &p_visibility_rect) { aabb.size.x = p_visibility_rect.size.x; aabb.size.y = p_visibility_rect.size.y; - VS::get_singleton()->particles_set_custom_aabb(particles, aabb); + RS::get_singleton()->particles_set_custom_aabb(particles, aabb); _change_notify("visibility_rect"); update(); } -void Particles2D::set_use_local_coordinates(bool p_enable) { +void GPUParticles2D::set_use_local_coordinates(bool p_enable) { local_coords = p_enable; - VS::get_singleton()->particles_set_use_local_coordinates(particles, local_coords); + RS::get_singleton()->particles_set_use_local_coordinates(particles, local_coords); set_notify_transform(!p_enable); if (!p_enable && is_inside_tree()) { _update_particle_emission_transform(); } } -void Particles2D::_update_particle_emission_transform() { - +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)); xf.basis.set_axis(1, Vector3(xf2d.get_axis(1).x, xf2d.get_axis(1).y, 0)); xf.set_origin(Vector3(xf2d.get_origin().x, xf2d.get_origin().y, 0)); - VS::get_singleton()->particles_set_emission_transform(particles, xf); + RS::get_singleton()->particles_set_emission_transform(particles, xf); } -void Particles2D::set_process_material(const Ref<Material> &p_material) { - +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,109 +133,103 @@ void Particles2D::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(); - VS::get_singleton()->particles_set_process_material(particles, material_rid); + } + RS::get_singleton()->particles_set_process_material(particles, material_rid); update_configuration_warning(); } -void Particles2D::set_speed_scale(float p_scale) { - +void GPUParticles2D::set_speed_scale(float p_scale) { speed_scale = p_scale; - VS::get_singleton()->particles_set_speed_scale(particles, p_scale); + RS::get_singleton()->particles_set_speed_scale(particles, p_scale); } -bool Particles2D::is_emitting() const { - - return VS::get_singleton()->particles_get_emitting(particles); +bool GPUParticles2D::is_emitting() const { + return RS::get_singleton()->particles_get_emitting(particles); } -int Particles2D::get_amount() const { +int GPUParticles2D::get_amount() const { return amount; } -float Particles2D::get_lifetime() const { +float GPUParticles2D::get_lifetime() const { return lifetime; } -bool Particles2D::get_one_shot() const { - +bool GPUParticles2D::get_one_shot() const { return one_shot; } -float Particles2D::get_pre_process_time() const { +float GPUParticles2D::get_pre_process_time() const { return pre_process_time; } -float Particles2D::get_explosiveness_ratio() const { +float GPUParticles2D::get_explosiveness_ratio() const { return explosiveness_ratio; } -float Particles2D::get_randomness_ratio() const { +float GPUParticles2D::get_randomness_ratio() const { return randomness_ratio; } -Rect2 Particles2D::get_visibility_rect() const { +Rect2 GPUParticles2D::get_visibility_rect() const { return visibility_rect; } -bool Particles2D::get_use_local_coordinates() const { +bool GPUParticles2D::get_use_local_coordinates() const { return local_coords; } -Ref<Material> Particles2D::get_process_material() const { +Ref<Material> GPUParticles2D::get_process_material() const { return process_material; } -float Particles2D::get_speed_scale() const { - +float GPUParticles2D::get_speed_scale() const { return speed_scale; } -void Particles2D::set_draw_order(DrawOrder p_order) { - +void GPUParticles2D::set_draw_order(DrawOrder p_order) { draw_order = p_order; - VS::get_singleton()->particles_set_draw_order(particles, VS::ParticlesDrawOrder(p_order)); + RS::get_singleton()->particles_set_draw_order(particles, RS::ParticlesDrawOrder(p_order)); } -Particles2D::DrawOrder Particles2D::get_draw_order() const { - +GPUParticles2D::DrawOrder GPUParticles2D::get_draw_order() const { return draw_order; } -void Particles2D::set_fixed_fps(int p_count) { +void GPUParticles2D::set_fixed_fps(int p_count) { fixed_fps = p_count; - VS::get_singleton()->particles_set_fixed_fps(particles, p_count); + RS::get_singleton()->particles_set_fixed_fps(particles, p_count); } -int Particles2D::get_fixed_fps() const { +int GPUParticles2D::get_fixed_fps() const { return fixed_fps; } -void Particles2D::set_fractional_delta(bool p_enable) { +void GPUParticles2D::set_fractional_delta(bool p_enable) { fractional_delta = p_enable; - VS::get_singleton()->particles_set_fractional_delta(particles, p_enable); + RS::get_singleton()->particles_set_fractional_delta(particles, p_enable); } -bool Particles2D::get_fractional_delta() const { +bool GPUParticles2D::get_fractional_delta() const { return fractional_delta; } -String Particles2D::get_configuration_warning() const { - - if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { - return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles\" option for this purpose."); +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; 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 Particles2D::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."); } } @@ -257,9 +248,8 @@ String Particles2D::get_configuration_warning() const { return warnings; } -Rect2 Particles2D::capture_rect() const { - - AABB aabb = VS::get_singleton()->particles_get_current_aabb(particles); +Rect2 GPUParticles2D::capture_rect() const { + AABB aabb = RS::get_singleton()->particles_get_current_aabb(particles); Rect2 r; r.position.x = aabb.position.x; r.position.y = aabb.position.y; @@ -268,49 +258,47 @@ Rect2 Particles2D::capture_rect() const { return r; } -void Particles2D::set_texture(const Ref<Texture> &p_texture) { +void GPUParticles2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; update(); } -Ref<Texture> Particles2D::get_texture() const { +Ref<Texture2D> GPUParticles2D::get_texture() const { return texture; } -void Particles2D::set_normal_map(const Ref<Texture> &p_normal_map) { - +void GPUParticles2D::set_normal_map(const Ref<Texture2D> &p_normal_map) { normal_map = p_normal_map; update(); } -Ref<Texture> Particles2D::get_normal_map() const { +Ref<Texture2D> GPUParticles2D::get_normal_map() const { return normal_map; } -void Particles2D::_validate_property(PropertyInfo &property) const { +void GPUParticles2D::_validate_property(PropertyInfo &property) const { } -void Particles2D::restart() { - VS::get_singleton()->particles_restart(particles); - VS::get_singleton()->particles_set_emitting(particles, true); +void GPUParticles2D::restart() { + RS::get_singleton()->particles_restart(particles); + RS::get_singleton()->particles_set_emitting(particles, true); } -void Particles2D::_notification(int p_what) { - +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()) + if (normal_map.is_valid()) { normal_rid = normal_map->get_rid(); + } - VS::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, normal_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 @@ -318,10 +306,9 @@ void Particles2D::_notification(int p_what) { if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) { if (can_process()) { - VS::get_singleton()->particles_set_speed_scale(particles, speed_scale); + RS::get_singleton()->particles_set_speed_scale(particles, speed_scale); } else { - - VS::get_singleton()->particles_set_speed_scale(particles, 0); + RS::get_singleton()->particles_set_speed_scale(particles, 0); } } @@ -330,7 +317,6 @@ void Particles2D::_notification(int p_what) { } if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - if (one_shot && !is_emitting()) { _change_notify(); set_process_internal(false); @@ -338,58 +324,57 @@ void Particles2D::_notification(int p_what) { } } -void Particles2D::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &Particles2D::set_emitting); - ClassDB::bind_method(D_METHOD("set_amount", "amount"), &Particles2D::set_amount); - ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &Particles2D::set_lifetime); - ClassDB::bind_method(D_METHOD("set_one_shot", "secs"), &Particles2D::set_one_shot); - ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &Particles2D::set_pre_process_time); - ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &Particles2D::set_explosiveness_ratio); - ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &Particles2D::set_randomness_ratio); - ClassDB::bind_method(D_METHOD("set_visibility_rect", "visibility_rect"), &Particles2D::set_visibility_rect); - ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &Particles2D::set_use_local_coordinates); - ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &Particles2D::set_fixed_fps); - ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &Particles2D::set_fractional_delta); - ClassDB::bind_method(D_METHOD("set_process_material", "material"), &Particles2D::set_process_material); - ClassDB::bind_method(D_METHOD("set_speed_scale", "scale"), &Particles2D::set_speed_scale); - - ClassDB::bind_method(D_METHOD("is_emitting"), &Particles2D::is_emitting); - ClassDB::bind_method(D_METHOD("get_amount"), &Particles2D::get_amount); - ClassDB::bind_method(D_METHOD("get_lifetime"), &Particles2D::get_lifetime); - ClassDB::bind_method(D_METHOD("get_one_shot"), &Particles2D::get_one_shot); - ClassDB::bind_method(D_METHOD("get_pre_process_time"), &Particles2D::get_pre_process_time); - ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &Particles2D::get_explosiveness_ratio); - ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &Particles2D::get_randomness_ratio); - ClassDB::bind_method(D_METHOD("get_visibility_rect"), &Particles2D::get_visibility_rect); - ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &Particles2D::get_use_local_coordinates); - ClassDB::bind_method(D_METHOD("get_fixed_fps"), &Particles2D::get_fixed_fps); - ClassDB::bind_method(D_METHOD("get_fractional_delta"), &Particles2D::get_fractional_delta); - ClassDB::bind_method(D_METHOD("get_process_material"), &Particles2D::get_process_material); - ClassDB::bind_method(D_METHOD("get_speed_scale"), &Particles2D::get_speed_scale); - - ClassDB::bind_method(D_METHOD("set_draw_order", "order"), &Particles2D::set_draw_order); - ClassDB::bind_method(D_METHOD("get_draw_order"), &Particles2D::get_draw_order); - - ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Particles2D::set_texture); - ClassDB::bind_method(D_METHOD("get_texture"), &Particles2D::get_texture); - - ClassDB::bind_method(D_METHOD("set_normal_map", "texture"), &Particles2D::set_normal_map); - ClassDB::bind_method(D_METHOD("get_normal_map"), &Particles2D::get_normal_map); - - ClassDB::bind_method(D_METHOD("capture_rect"), &Particles2D::capture_rect); - - ClassDB::bind_method(D_METHOD("restart"), &Particles2D::restart); +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); + ClassDB::bind_method(D_METHOD("set_one_shot", "secs"), &GPUParticles2D::set_one_shot); + ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &GPUParticles2D::set_pre_process_time); + ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &GPUParticles2D::set_explosiveness_ratio); + ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &GPUParticles2D::set_randomness_ratio); + ClassDB::bind_method(D_METHOD("set_visibility_rect", "visibility_rect"), &GPUParticles2D::set_visibility_rect); + ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &GPUParticles2D::set_use_local_coordinates); + ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &GPUParticles2D::set_fixed_fps); + ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &GPUParticles2D::set_fractional_delta); + ClassDB::bind_method(D_METHOD("set_process_material", "material"), &GPUParticles2D::set_process_material); + ClassDB::bind_method(D_METHOD("set_speed_scale", "scale"), &GPUParticles2D::set_speed_scale); + + ClassDB::bind_method(D_METHOD("is_emitting"), &GPUParticles2D::is_emitting); + ClassDB::bind_method(D_METHOD("get_amount"), &GPUParticles2D::get_amount); + ClassDB::bind_method(D_METHOD("get_lifetime"), &GPUParticles2D::get_lifetime); + ClassDB::bind_method(D_METHOD("get_one_shot"), &GPUParticles2D::get_one_shot); + ClassDB::bind_method(D_METHOD("get_pre_process_time"), &GPUParticles2D::get_pre_process_time); + ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &GPUParticles2D::get_explosiveness_ratio); + ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &GPUParticles2D::get_randomness_ratio); + ClassDB::bind_method(D_METHOD("get_visibility_rect"), &GPUParticles2D::get_visibility_rect); + ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &GPUParticles2D::get_use_local_coordinates); + ClassDB::bind_method(D_METHOD("get_fixed_fps"), &GPUParticles2D::get_fixed_fps); + ClassDB::bind_method(D_METHOD("get_fractional_delta"), &GPUParticles2D::get_fractional_delta); + ClassDB::bind_method(D_METHOD("get_process_material"), &GPUParticles2D::get_process_material); + ClassDB::bind_method(D_METHOD("get_speed_scale"), &GPUParticles2D::get_speed_scale); + + ClassDB::bind_method(D_METHOD("set_draw_order", "order"), &GPUParticles2D::set_draw_order); + ClassDB::bind_method(D_METHOD("get_draw_order"), &GPUParticles2D::get_draw_order); + + 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); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); @@ -399,16 +384,15 @@ void Particles2D::_bind_methods() { ADD_GROUP("Process Material", "process_"); 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, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::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); } -Particles2D::Particles2D() { - - particles = VS::get_singleton()->particles_create(); +GPUParticles2D::GPUParticles2D() { + particles = RS::get_singleton()->particles_create(); one_shot = false; // Needed so that set_emitting doesn't access uninitialized values set_emitting(true); @@ -426,7 +410,6 @@ Particles2D::Particles2D() { set_speed_scale(1); } -Particles2D::~Particles2D() { - - VS::get_singleton()->free(particles); +GPUParticles2D::~GPUParticles2D() { + RS::get_singleton()->free(particles); } diff --git a/scene/2d/particles_2d.h b/scene/2d/gpu_particles_2d.h index 56c328fc38..3258237f92 100644 --- a/scene/2d/particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* particles_2d.h */ +/* gpu_particles_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -35,9 +35,9 @@ #include "scene/2d/node_2d.h" #include "scene/resources/texture.h" -class Particles2D : public Node2D { +class GPUParticles2D : public Node2D { private: - GDCLASS(Particles2D, Node2D); + GDCLASS(GPUParticles2D, Node2D); public: enum DrawOrder { @@ -64,14 +64,14 @@ private: DrawOrder draw_order; - Ref<Texture> texture; - Ref<Texture> normal_map; + 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: @@ -108,20 +108,20 @@ public: void set_draw_order(DrawOrder p_order); DrawOrder get_draw_order() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_normal_map(const Ref<Texture> &p_normal_map); - Ref<Texture> get_normal_map() 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; - Particles2D(); - ~Particles2D(); + GPUParticles2D(); + ~GPUParticles2D(); }; -VARIANT_ENUM_CAST(Particles2D::DrawOrder) +VARIANT_ENUM_CAST(GPUParticles2D::DrawOrder) #endif // PARTICLES_2D_H diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 656ff45654..8df72d7aac 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -32,78 +32,79 @@ #include "core/engine.h" #include "physics_body_2d.h" -#include "servers/physics_2d_server.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) - Physics2DServer::get_singleton()->joint_disable_collisions_between_bodies(joint, false); + if (ba.is_valid() && bb.is_valid() && exclude_from_collision) { + PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false); + } - Physics2DServer::get_singleton()->free(joint); + PhysicsServer2D::get_singleton()->free(joint); joint = RID(); ba = RID(); 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 *)NULL; - Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL; + 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; + } - Physics2DServer::get_singleton()->get_singleton()->joint_set_param(joint, Physics2DServer::JOINT_PARAM_BIAS, bias); + PhysicsServer2D::get_singleton()->get_singleton()->joint_set_param(joint, PhysicsServer2D::JOINT_PARAM_BIAS, bias); ba = body_a->get_rid(); bb = body_b->get_rid(); - Physics2DServer::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision); + PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision); } 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()) - Physics2DServer::get_singleton()->get_singleton()->joint_set_param(joint, Physics2DServer::JOINT_PARAM_BIAS, bias); + 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); @@ -158,12 +156,11 @@ void Joint2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_a", "get_node_a"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_b", "get_node_b"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0,0.9,0.001"), "set_bias", "get_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0,0.9,0.001"), "set_bias", "get_bias"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_collision"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision"); } 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,35 +187,31 @@ void PinJoint2D::_notification(int p_what) { } RID PinJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) { - - RID pj = Physics2DServer::get_singleton()->pin_joint_create(get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID()); - Physics2DServer::get_singleton()->pin_joint_set_param(pj, Physics2DServer::PIN_JOINT_SOFTNESS, softness); + 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()) - Physics2DServer::get_singleton()->pin_joint_set_param(get_joint(), Physics2DServer::PIN_JOINT_SOFTNESS, p_softness); + 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); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "softness", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_softness", "get_softness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "softness", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_softness", "get_softness"); } 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,50 +239,43 @@ 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)); Vector2 anchor_B = gt.xform(Vector2(0, initial_offset)); - return Physics2DServer::get_singleton()->groove_joint_create(groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid()); + return PhysicsServer2D::get_singleton()->groove_joint_create(groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid()); } 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); ClassDB::bind_method(D_METHOD("get_initial_offset"), &GrooveJoint2D::get_initial_offset); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_length", "get_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "initial_offset", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_initial_offset", "get_initial_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_length", "get_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "initial_offset", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_initial_offset", "get_initial_offset"); } 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 = Physics2DServer::get_singleton()->damped_spring_joint_create(anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid()); - if (rest_length) - Physics2DServer::get_singleton()->damped_string_joint_set_param(dsj, Physics2DServer::DAMPED_STRING_REST_LENGTH, rest_length); - Physics2DServer::get_singleton()->damped_string_joint_set_param(dsj, Physics2DServer::DAMPED_STRING_STIFFNESS, stiffness); - Physics2DServer::get_singleton()->damped_string_joint_set_param(dsj, Physics2DServer::DAMPED_STRING_DAMPING, damping); + 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_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()) - Physics2DServer::get_singleton()->damped_string_joint_set_param(get_joint(), Physics2DServer::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()) - Physics2DServer::get_singleton()->damped_string_joint_set_param(get_joint(), Physics2DServer::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()) - Physics2DServer::get_singleton()->damped_string_joint_set_param(get_joint(), Physics2DServer::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); @@ -394,14 +372,13 @@ void DampedSpringJoint2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_damping", "damping"), &DampedSpringJoint2D::set_damping); ClassDB::bind_method(D_METHOD("get_damping"), &DampedSpringJoint2D::get_damping); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_length", "get_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rest_length", PROPERTY_HINT_EXP_RANGE, "0,65535,1"), "set_rest_length", "get_rest_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "stiffness", PROPERTY_HINT_EXP_RANGE, "0.1,64,0.1"), "set_stiffness", "get_stiffness"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "damping", PROPERTY_HINT_EXP_RANGE, "0.01,16,0.01"), "set_damping", "get_damping"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_length", "get_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rest_length", PROPERTY_HINT_EXP_RANGE, "0,65535,1"), "set_rest_length", "get_rest_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "stiffness", PROPERTY_HINT_EXP_RANGE, "0.1,64,0.1"), "set_stiffness", "get_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_EXP_RANGE, "0.01,16,0.01"), "set_damping", "get_damping"); } 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 1bffaf8084..1e7e9f6b6a 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -31,7 +31,7 @@ #include "light_2d.h" #include "core/engine.h" -#include "servers/visual_server.h" +#include "servers/rendering_server.h" #ifdef TOOLS_ENABLED Dictionary Light2D::_edit_get_state() const { @@ -59,8 +59,9 @@ bool Light2D::_edit_use_pivot() const { } Rect2 Light2D::_edit_get_rect() const { - if (texture.is_null()) + if (texture.is_null()) { return Rect2(); + } Size2 s = texture->get_size() * _scale; return Rect2(texture_offset - s / 2.0, s); @@ -72,17 +73,18 @@ bool Light2D::_edit_use_rect() const { #endif Rect2 Light2D::get_anchorable_rect() const { - if (texture.is_null()) + 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; @@ -100,226 +102,188 @@ void Light2D::_update_light_visibility() { } #endif - VS::get_singleton()->canvas_light_set_enabled(canvas_light, enabled && is_visible_in_tree() && editor_ok); + RS::get_singleton()->canvas_light_set_enabled(canvas_light, enabled && is_visible_in_tree() && editor_ok); } 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<Texture> &p_texture) { - +void Light2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; - if (texture.is_valid()) - VS::get_singleton()->canvas_light_set_texture(canvas_light, texture->get_rid()); - else - VS::get_singleton()->canvas_light_set_texture(canvas_light, RID()); + 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<Texture> Light2D::get_texture() const { - +Ref<Texture2D> Light2D::get_texture() const { return texture; } void Light2D::set_texture_offset(const Vector2 &p_offset) { - texture_offset = p_offset; - VS::get_singleton()->canvas_light_set_texture_offset(canvas_light, texture_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; - VS::get_singleton()->canvas_light_set_color(canvas_light, 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; - VS::get_singleton()->canvas_light_set_height(canvas_light, 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; - VS::get_singleton()->canvas_light_set_energy(canvas_light, 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; } - VS::get_singleton()->canvas_light_set_scale(canvas_light, _scale); + 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; - VS::get_singleton()->canvas_light_set_z_range(canvas_light, z_min, z_max); + 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; - VS::get_singleton()->canvas_light_set_z_range(canvas_light, z_min, z_max); + 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; - VS::get_singleton()->canvas_light_set_layer_range(canvas_light, layer_min, layer_max); + 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; - VS::get_singleton()->canvas_light_set_layer_range(canvas_light, layer_min, layer_max); + 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; - VS::get_singleton()->canvas_light_set_item_cull_mask(canvas_light, item_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; - VS::get_singleton()->canvas_light_set_item_shadow_cull_mask(canvas_light, item_shadow_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; - VS::get_singleton()->canvas_light_set_mode(canvas_light, VS::CanvasLightMode(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; - VS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light, shadow); + 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; - VS::get_singleton()->canvas_light_set_shadow_buffer_size(canvas_light, shadow_buffer_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_gradient_length(float p_multiplier) { - - shadow_gradient_length = p_multiplier; - VS::get_singleton()->canvas_light_set_shadow_gradient_length(canvas_light, p_multiplier); -} - -float Light2D::get_shadow_gradient_length() const { - - return shadow_gradient_length; -} - void Light2D::set_shadow_filter(ShadowFilter p_filter) { + ERR_FAIL_INDEX(p_filter, SHADOW_FILTER_MAX); shadow_filter = p_filter; - VS::get_singleton()->canvas_light_set_shadow_filter(canvas_light, VS::CanvasLightShadowFilter(p_filter)); + RS::get_singleton()->canvas_light_set_shadow_filter(canvas_light, RS::CanvasLightShadowFilter(p_filter)); } Light2D::ShadowFilter Light2D::get_shadow_filter() const { - return shadow_filter; } void Light2D::set_shadow_color(const Color &p_shadow_color) { shadow_color = p_shadow_color; - VS::get_singleton()->canvas_light_set_shadow_color(canvas_light, shadow_color); + RS::get_singleton()->canvas_light_set_shadow_color(canvas_light, shadow_color); } Color Light2D::get_shadow_color() const { @@ -327,31 +291,25 @@ Color Light2D::get_shadow_color() const { } void Light2D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - - VS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, get_canvas()); + RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, get_canvas()); _update_light_visibility(); } if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { - - VS::get_singleton()->canvas_light_set_transform(canvas_light, get_global_transform()); + 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) { - - VS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, RID()); + 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."); } @@ -360,18 +318,15 @@ String Light2D::get_configuration_warning() const { } void Light2D::set_shadow_smooth(float p_amount) { - shadow_smooth = p_amount; - VS::get_singleton()->canvas_light_set_shadow_smooth(canvas_light, shadow_smooth); + 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); @@ -426,9 +381,6 @@ void Light2D::_bind_methods() { 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); - ClassDB::bind_method(D_METHOD("set_shadow_gradient_length", "multiplier"), &Light2D::set_shadow_gradient_length); - ClassDB::bind_method(D_METHOD("get_shadow_gradient_length"), &Light2D::get_shadow_gradient_length); - ClassDB::bind_method(D_METHOD("set_shadow_filter", "filter"), &Light2D::set_shadow_filter); ClassDB::bind_method(D_METHOD("get_shadow_filter"), &Light2D::get_shadow_filter); @@ -437,16 +389,16 @@ void Light2D::_bind_methods() { 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, "Texture"), "set_texture", "get_texture"); + 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::REAL, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); + 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::REAL, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); + 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_GROUP("Range", "range_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "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(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::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(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_max", "get_z_range_max"); + 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"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_layer_max", PROPERTY_HINT_RANGE, "-512,512,1"), "set_layer_range_max", "get_layer_range_max"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_cull_mask", "get_item_cull_mask"); @@ -455,9 +407,8 @@ void Light2D::_bind_methods() { 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::REAL, "shadow_gradient_length", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_shadow_gradient_length", "get_shadow_gradient_length"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF7,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); + 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); @@ -466,16 +417,12 @@ void Light2D::_bind_methods() { BIND_ENUM_CONSTANT(MODE_MASK); BIND_ENUM_CONSTANT(SHADOW_FILTER_NONE); - BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF3); BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF5); - BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF7); - BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF9); BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF13); } Light2D::Light2D() { - - canvas_light = VisualServer::get_singleton()->canvas_light_create(); + canvas_light = RenderingServer::get_singleton()->canvas_light_create(); enabled = true; editor_only = false; shadow = false; @@ -490,7 +437,6 @@ Light2D::Light2D() { item_shadow_mask = 1; mode = MODE_ADD; shadow_buffer_size = 2048; - shadow_gradient_length = 0; energy = 1.0; shadow_color = Color(0, 0, 0, 0); shadow_filter = SHADOW_FILTER_NONE; @@ -500,6 +446,5 @@ Light2D::Light2D() { } Light2D::~Light2D() { - - VisualServer::get_singleton()->free(canvas_light); + RenderingServer::get_singleton()->free(canvas_light); } diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 65db5c6ee6..45444800fe 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -34,7 +34,6 @@ #include "scene/2d/node_2d.h" class Light2D : public Node2D { - GDCLASS(Light2D, Node2D); public: @@ -47,11 +46,9 @@ public: enum ShadowFilter { SHADOW_FILTER_NONE, - SHADOW_FILTER_PCF3, SHADOW_FILTER_PCF5, - SHADOW_FILTER_PCF7, - SHADOW_FILTER_PCF9, SHADOW_FILTER_PCF13, + SHADOW_FILTER_MAX }; private: @@ -72,9 +69,8 @@ private: int item_shadow_mask; int shadow_buffer_size; float shadow_smooth; - float shadow_gradient_length; Mode mode; - Ref<Texture> texture; + Ref<Texture2D> texture; Vector2 texture_offset; ShadowFilter shadow_filter; @@ -86,17 +82,17 @@ protected: 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_enabled(bool p_enabled); bool is_enabled() const; @@ -104,8 +100,8 @@ public: void set_editor_only(bool p_editor_only); bool is_editor_only() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() 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; @@ -149,9 +145,6 @@ public: void set_shadow_buffer_size(int p_size); int get_shadow_buffer_size() const; - void set_shadow_gradient_length(float p_multiplier); - float get_shadow_gradient_length() const; - void set_shadow_filter(ShadowFilter p_filter); ShadowFilter get_shadow_filter() const; @@ -161,7 +154,7 @@ public: void set_shadow_smooth(float p_amount); float get_shadow_smooth() const; - String get_configuration_warning() const; + String get_configuration_warning() const override; Light2D(); ~Light2D(); diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 0e8e8f6679..023cfa6d03 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "light_occluder_2d.h" +#include "core/math/geometry_2d.h" #include "core/engine.h" @@ -36,17 +37,17 @@ #ifdef TOOLS_ENABLED Rect2 OccluderPolygon2D::_edit_get_rect() const { - if (rect_cache_dirty) { if (closed) { - PoolVector<Vector2>::Read r = polygon.read(); + 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; - PoolVector<Vector2>::Read points = polygon.read(); + 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; @@ -84,52 +85,46 @@ bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double } #endif -void OccluderPolygon2D::set_polygon(const PoolVector<Vector2> &p_polygon) { - +void OccluderPolygon2D::set_polygon(const Vector<Vector2> &p_polygon) { polygon = p_polygon; rect_cache_dirty = true; - VS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon, p_polygon, closed); + RS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon, p_polygon, closed); emit_changed(); } -PoolVector<Vector2> OccluderPolygon2D::get_polygon() const { - +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()) - VS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon, polygon, closed); + 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; - VS::get_singleton()->canvas_occluder_polygon_set_cull_mode(occ_polygon, VS::CanvasOccluderPolygonCullMode(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); @@ -141,7 +136,7 @@ void OccluderPolygon2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "closed"), "set_closed", "is_closed"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode", PROPERTY_HINT_ENUM, "Disabled,ClockWise,CounterClockWise"), "set_cull_mode", "get_cull_mode"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); BIND_ENUM_CONSTANT(CULL_DISABLED); BIND_ENUM_CONSTANT(CULL_CLOCKWISE); @@ -149,49 +144,39 @@ void OccluderPolygon2D::_bind_methods() { } OccluderPolygon2D::OccluderPolygon2D() { - - occ_polygon = VS::get_singleton()->canvas_occluder_polygon_create(); + occ_polygon = RS::get_singleton()->canvas_occluder_polygon_create(); closed = true; cull = CULL_DISABLED; rect_cache_dirty = true; } OccluderPolygon2D::~OccluderPolygon2D() { - - VS::get_singleton()->free(occ_polygon); + 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) { - - VS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder, get_canvas()); - VS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform()); - VS::get_singleton()->canvas_light_occluder_set_enabled(occluder, is_visible_in_tree()); + 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) { - - VS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform()); + RS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform()); } if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { - - VS::get_singleton()->canvas_light_occluder_set_enabled(occluder, is_visible_in_tree()); + 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()) { - - PoolVector<Vector2> poly = occluder_polygon->get_polygon(); + Vector<Vector2> poly = occluder_polygon->get_polygon(); if (poly.size()) { if (occluder_polygon->is_closed()) { @@ -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(); - PoolVector<Vector2>::Read r = poly.read(); + 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,61 +196,56 @@ void LightOccluder2D::_notification(int p_what) { } if (p_what == NOTIFICATION_EXIT_CANVAS) { - - VS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder, RID()); + 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()) - occluder_polygon->disconnect("changed", this, "_poly_changed"); + 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()) - VS::get_singleton()->canvas_light_occluder_set_polygon(occluder, occluder_polygon->get_rid()); - else - VS::get_singleton()->canvas_light_occluder_set_polygon(occluder, RID()); + if (occluder_polygon.is_valid()) { + RS::get_singleton()->canvas_light_occluder_set_polygon(occluder, occluder_polygon->get_rid()); + } else { + RS::get_singleton()->canvas_light_occluder_set_polygon(occluder, RID()); + } #ifdef DEBUG_ENABLED - if (occluder_polygon.is_valid()) - occluder_polygon->connect("changed", this, "_poly_changed"); + 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; - VS::get_singleton()->canvas_light_occluder_set_light_mask(occluder, 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 { - if (!occluder_polygon.is_valid()) { return TTR("An occluder polygon must be set (or drawn) for this occluder to take effect."); } @@ -280,27 +258,22 @@ String LightOccluder2D::get_configuration_warning() const { } 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); ClassDB::bind_method(D_METHOD("set_occluder_light_mask", "mask"), &LightOccluder2D::set_occluder_light_mask); ClassDB::bind_method(D_METHOD("get_occluder_light_mask"), &LightOccluder2D::get_occluder_light_mask); - ClassDB::bind_method("_poly_changed", &LightOccluder2D::_poly_changed); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D"), "set_occluder_polygon", "get_occluder_polygon"); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask"); } LightOccluder2D::LightOccluder2D() { - - occluder = VS::get_singleton()->canvas_light_occluder_create(); + occluder = RS::get_singleton()->canvas_light_occluder_create(); mask = 1; set_notify_transform(true); } LightOccluder2D::~LightOccluder2D() { - - VS::get_singleton()->free(occluder); + RS::get_singleton()->free(occluder); } diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index b20e347c35..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: @@ -46,7 +45,7 @@ public: private: RID occ_polygon; - PoolVector<Vector2> polygon; + Vector<Vector2> polygon; bool closed; CullMode cull; @@ -62,8 +61,8 @@ public: virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; #endif - void set_polygon(const PoolVector<Vector2> &p_polygon); - PoolVector<Vector2> get_polygon() const; + void set_polygon(const Vector<Vector2> &p_polygon); + Vector<Vector2> get_polygon() const; void set_closed(bool p_closed); bool is_closed() const; @@ -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 c31840c8e1..b120b115b0 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -29,9 +29,10 @@ /*************************************************************************/ #include "line_2d.h" -#include "line_builder.h" #include "core/core_string_names.h" +#include "core/math/geometry_2d.h" +#include "line_builder.h" // Needed so we can bind functions VARIANT_ENUM_CAST(Line2D::LineJointMode) @@ -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,27 +70,28 @@ 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; - PoolVector<Vector2>::Read points = _points.read(); + 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; } #endif -void Line2D::set_points(const PoolVector<Vector2> &p_points) { +void Line2D::set_points(const Vector<Vector2> &p_points) { _points = p_points; update(); } 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(); } @@ -101,14 +103,14 @@ float Line2D::get_width() const { void Line2D::set_curve(const Ref<Curve> &p_curve) { // Cleanup previous connection if any if (_curve.is_valid()) { - _curve->disconnect(CoreStringNames::get_singleton()->changed, this, "_curve_changed"); + _curve->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_curve_changed)); } _curve = p_curve; // Connect to the curve so the line will update when it is changed if (_curve.is_valid()) { - _curve->connect(CoreStringNames::get_singleton()->changed, this, "_curve_changed"); + _curve->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_curve_changed)); } update(); @@ -118,7 +120,7 @@ Ref<Curve> Line2D::get_curve() const { return _curve; } -PoolVector<Vector2> Line2D::get_points() const { +Vector<Vector2> Line2D::get_points() const { return _points; } @@ -146,7 +148,7 @@ void Line2D::clear_points() { void Line2D::add_point(Vector2 p_pos, int p_atpos) { if (p_atpos < 0 || _points.size() < p_atpos) { - _points.append(p_pos); + _points.push_back(p_pos); } else { _points.insert(p_atpos, p_pos); } @@ -168,17 +170,16 @@ 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, this, "_gradient_changed"); + _gradient->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_gradient_changed)); } _gradient = p_gradient; // Connect to the gradient so the line will update when the ColorRamp is changed if (_gradient.is_valid()) { - _gradient->connect(CoreStringNames::get_singleton()->changed, this, "_gradient_changed"); + _gradient->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_gradient_changed)); } update(); @@ -188,12 +189,12 @@ Ref<Gradient> Line2D::get_gradient() const { return _gradient; } -void Line2D::set_texture(const Ref<Texture> &p_texture) { +void Line2D::set_texture(const Ref<Texture2D> &p_texture) { _texture = p_texture; update(); } -Ref<Texture> Line2D::get_texture() const { +Ref<Texture2D> Line2D::get_texture() const { return _texture; } @@ -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 @@ -282,7 +286,7 @@ void Line2D::_draw() { points.resize(_points.size()); int len = points.size(); { - PoolVector<Vector2>::Read points_read = _points.read(); + const Vector2 *points_read = _points.ptr(); for (int i = 0; i < len; ++i) { points.write[i] = points_read[i]; } @@ -311,14 +315,13 @@ void Line2D::_draw() { lb.build(); - VS::get_singleton()->canvas_item_add_triangle_array( + RS::get_singleton()->canvas_item_add_triangle_array( get_canvas_item(), lb.indices, lb.vertices, lb.colors, lb.uvs, Vector<int>(), Vector<float>(), - texture_rid, -1, RID(), - _antialiased, true); + texture_rid); // DEBUG // Draw wireframe @@ -351,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); @@ -401,20 +403,20 @@ void Line2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &Line2D::set_antialiased); ClassDB::bind_method(D_METHOD("get_antialiased"), &Line2D::get_antialiased); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "points"), "set_points", "get_points"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "width"), "set_width", "get_width"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "points"), "set_points", "get_points"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width"), "set_width", "get_width"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "width_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_color"), "set_default_color", "get_default_color"); ADD_GROUP("Fill", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile,Stretch"), "set_texture_mode", "get_texture_mode"); ADD_GROUP("Capping", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_mode", PROPERTY_HINT_ENUM, "Sharp,Bevel,Round"), "set_joint_mode", "get_joint_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "begin_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_begin_cap_mode", "get_begin_cap_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "end_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_end_cap_mode", "get_end_cap_mode"); ADD_GROUP("Border", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sharp_limit"), "set_sharp_limit", "get_sharp_limit"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sharp_limit"), "set_sharp_limit", "get_sharp_limit"); ADD_PROPERTY(PropertyInfo(Variant::INT, "round_precision"), "set_round_precision", "get_round_precision"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "get_antialiased"); @@ -429,7 +431,4 @@ void Line2D::_bind_methods() { BIND_ENUM_CONSTANT(LINE_TEXTURE_NONE); BIND_ENUM_CONSTANT(LINE_TEXTURE_TILE); BIND_ENUM_CONSTANT(LINE_TEXTURE_STRETCH); - - ClassDB::bind_method(D_METHOD("_gradient_changed"), &Line2D::_gradient_changed); - ClassDB::bind_method(D_METHOD("_curve_changed"), &Line2D::_curve_changed); } diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index 3c7239f67c..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,15 +56,15 @@ 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(); - void set_points(const PoolVector<Vector2> &p_points); - PoolVector<Vector2> get_points() const; + void set_points(const Vector<Vector2> &p_points); + Vector<Vector2> get_points() const; void set_point_position(int i, Vector2 pos); Vector2 get_point_position(int i) const; @@ -89,8 +88,8 @@ public: void set_gradient(const Ref<Gradient> &gradient); Ref<Gradient> get_gradient() const; - void set_texture(const Ref<Texture> &texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &texture); + Ref<Texture2D> get_texture() const; void set_texture_mode(const LineTextureMode mode); LineTextureMode get_texture_mode() const; @@ -124,7 +123,7 @@ private: void _curve_changed(); private: - PoolVector<Vector2> _points; + Vector<Vector2> _points; LineJointMode _joint_mode; LineCapMode _begin_cap_mode; LineCapMode _end_cap_mode; @@ -132,7 +131,7 @@ private: Ref<Curve> _curve; Color _default_color; Ref<Gradient> _gradient; - Ref<Texture> _texture; + Ref<Texture2D> _texture; LineTextureMode _texture_mode; float _sharp_limit; int _round_precision; diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp index 3385f2fbe0..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; } @@ -95,9 +96,9 @@ static inline Vector2 interpolate(const Rect2 &r, const Vector2 &v) { LineBuilder::LineBuilder() { joint_mode = Line2D::LINE_JOINT_SHARP; width = 10; - curve = NULL; + curve = nullptr; default_color = Color(0.4, 0.5, 1); - gradient = NULL; + gradient = nullptr; sharp_limit = 2.f; round_precision = 8; begin_cap_mode = Line2D::LINE_CAP_NONE; @@ -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(); @@ -147,8 +147,8 @@ void LineBuilder::build() { float current_distance1 = 0.f; float total_distance = 0.f; float width_factor = 1.f; - _interpolate_color = gradient != NULL; - bool retrieve_curve = curve != NULL; + _interpolate_color = gradient != nullptr; + bool retrieve_curve = curve != nullptr; bool distance_required = _interpolate_color || retrieve_curve || texture_mode == Line2D::LINE_TEXTURE_TILE || @@ -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/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 93432ec40b..897595ad1f 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -31,7 +31,6 @@ #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); @@ -40,7 +39,6 @@ void MeshInstance2D::_notification(int p_what) { } 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); @@ -53,50 +51,44 @@ void MeshInstance2D::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::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"); } 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<Texture> &p_texture) { - - if (p_texture == texture) +void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { + if (p_texture == texture) { return; + } texture = p_texture; update(); emit_signal("texture_changed"); _change_notify("texture"); } -void MeshInstance2D::set_normal_map(const Ref<Texture> &p_texture) { - +void MeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) { normal_map = p_texture; update(); } -Ref<Texture> MeshInstance2D::get_normal_map() const { - +Ref<Texture2D> MeshInstance2D::get_normal_map() const { return normal_map; } -Ref<Texture> MeshInstance2D::get_texture() const { - +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 51f75a3ead..f10ab17a7c 100644 --- a/scene/2d/mesh_instance_2d.h +++ b/scene/2d/mesh_instance_2d.h @@ -38,8 +38,8 @@ class MeshInstance2D : public Node2D { Ref<Mesh> mesh; - Ref<Texture> texture; - Ref<Texture> normal_map; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; protected: void _notification(int p_what); @@ -47,17 +47,17 @@ 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); Ref<Mesh> get_mesh() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_normal_map(const Ref<Texture> &p_texture); - Ref<Texture> get_normal_map() const; + void set_normal_map(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_normal_map() const; MeshInstance2D(); }; diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 028459e778..b99c0a3fa9 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -31,7 +31,6 @@ #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); @@ -40,7 +39,6 @@ void MultiMeshInstance2D::_notification(int p_what) { } 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); @@ -53,50 +51,44 @@ void MultiMeshInstance2D::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multimesh", PROPERTY_HINT_RESOURCE_TYPE, "MultiMesh"), "set_multimesh", "get_multimesh"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::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"); } 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<Texture> &p_texture) { - - if (p_texture == texture) +void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { + if (p_texture == texture) { return; + } texture = p_texture; update(); emit_signal("texture_changed"); _change_notify("texture"); } -Ref<Texture> MultiMeshInstance2D::get_texture() const { - +Ref<Texture2D> MultiMeshInstance2D::get_texture() const { return texture; } -void MultiMeshInstance2D::set_normal_map(const Ref<Texture> &p_texture) { - +void MultiMeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) { normal_map = p_texture; update(); } -Ref<Texture> MultiMeshInstance2D::get_normal_map() const { - +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 c3f3e52920..aadedac42a 100644 --- a/scene/2d/multimesh_instance_2d.h +++ b/scene/2d/multimesh_instance_2d.h @@ -39,8 +39,8 @@ class MultiMeshInstance2D : public Node2D { Ref<MultiMesh> multimesh; - Ref<Texture> texture; - Ref<Texture> normal_map; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; protected: void _notification(int p_what); @@ -48,17 +48,17 @@ 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); Ref<MultiMesh> get_multimesh() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_normal_map(const Ref<Texture> &p_texture); - Ref<Texture> get_normal_map() const; + void set_normal_map(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_normal_map() const; MultiMeshInstance2D(); ~MultiMeshInstance2D(); diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp index 9209cc5074..039c6f2e53 100644 --- a/scene/2d/navigation_2d.cpp +++ b/scene/2d/navigation_2d.cpp @@ -29,710 +29,64 @@ /*************************************************************************/ #include "navigation_2d.h" +#include "servers/navigation_server_2d.h" -#define USE_ENTRY_POINT - -void Navigation2D::_navpoly_link(int p_id) { - - ERR_FAIL_COND(!navpoly_map.has(p_id)); - NavMesh &nm = navpoly_map[p_id]; - ERR_FAIL_COND(nm.linked); - - PoolVector<Vector2> vertices = nm.navpoly->get_vertices(); - int len = vertices.size(); - if (len == 0) - return; - - PoolVector<Vector2>::Read r = vertices.read(); - - for (int i = 0; i < nm.navpoly->get_polygon_count(); i++) { - - //build - - List<Polygon>::Element *P = nm.polygons.push_back(Polygon()); - Polygon &p = P->get(); - p.owner = &nm; - - Vector<int> poly = nm.navpoly->get_polygon(i); - int plen = poly.size(); - const int *indices = poly.ptr(); - bool valid = true; - p.edges.resize(plen); - - Vector2 center; - float sum = 0; - - for (int j = 0; j < plen; j++) { - - int idx = indices[j]; - if (idx < 0 || idx >= len) { - valid = false; - break; - } - - Polygon::Edge e; - Vector2 ep = nm.xform.xform(r[idx]); - center += ep; - e.point = _get_point(ep); - p.edges.write[j] = e; - - int idxn = indices[(j + 1) % plen]; - if (idxn < 0 || idxn >= len) { - valid = false; - break; - } - - Vector2 epn = nm.xform.xform(r[idxn]); - - sum += (epn.x - ep.x) * (epn.y + ep.y); - } - - p.clockwise = sum > 0; - - if (!valid) { - nm.polygons.pop_back(); - ERR_CONTINUE(!valid); - } - - p.center = center / plen; - - //connect - - for (int j = 0; j < plen; j++) { - - int next = (j + 1) % plen; - EdgeKey ek(p.edges[j].point, p.edges[next].point); - - Map<EdgeKey, Connection>::Element *C = connections.find(ek); - if (!C) { +void Navigation2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_rid"), &Navigation2D::get_rid); - Connection c; - c.A = &p; - c.A_edge = j; - c.B = NULL; - c.B_edge = -1; - connections[ek] = c; - } else { + ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation2D::get_closest_point); + ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation2D::get_closest_point_owner); - if (C->get().B != NULL) { - ConnectionPending pending; - pending.polygon = &p; - pending.edge = j; - p.edges.write[j].P = C->get().pending.push_back(pending); - continue; - } + ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation2D::set_cell_size); + ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation2D::get_cell_size); - C->get().B = &p; - C->get().B_edge = j; - C->get().A->edges.write[C->get().A_edge].C = &p; - C->get().A->edges.write[C->get().A_edge].C_edge = j; - p.edges.write[j].C = C->get().A; - p.edges.write[j].C_edge = C->get().A_edge; - //connection successful. - } - } - } + ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation2D::set_edge_connection_margin); + ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation2D::get_edge_connection_margin); - nm.linked = true; + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin"); } -void Navigation2D::_navpoly_unlink(int p_id) { - - ERR_FAIL_COND(!navpoly_map.has(p_id)); - NavMesh &nm = navpoly_map[p_id]; - ERR_FAIL_COND(!nm.linked); - - for (List<Polygon>::Element *E = nm.polygons.front(); E; E = E->next()) { - - Polygon &p = E->get(); - - int ec = p.edges.size(); - Polygon::Edge *edges = p.edges.ptrw(); - - for (int i = 0; i < ec; i++) { - int next = (i + 1) % ec; - - EdgeKey ek(edges[i].point, edges[next].point); - Map<EdgeKey, Connection>::Element *C = connections.find(ek); - ERR_CONTINUE(!C); - - if (edges[i].P) { - C->get().pending.erase(edges[i].P); - edges[i].P = NULL; - - } else if (C->get().B) { - //disconnect - - C->get().B->edges.write[C->get().B_edge].C = NULL; - C->get().B->edges.write[C->get().B_edge].C_edge = -1; - C->get().A->edges.write[C->get().A_edge].C = NULL; - C->get().A->edges.write[C->get().A_edge].C_edge = -1; - - if (C->get().A == &E->get()) { - - C->get().A = C->get().B; - C->get().A_edge = C->get().B_edge; - } - C->get().B = NULL; - C->get().B_edge = -1; - - if (C->get().pending.size()) { - //reconnect if something is pending - ConnectionPending cp = C->get().pending.front()->get(); - C->get().pending.pop_front(); - - C->get().B = cp.polygon; - C->get().B_edge = cp.edge; - C->get().A->edges.write[C->get().A_edge].C = cp.polygon; - C->get().A->edges.write[C->get().A_edge].C_edge = cp.edge; - cp.polygon->edges.write[cp.edge].C = C->get().A; - cp.polygon->edges.write[cp.edge].C_edge = C->get().A_edge; - cp.polygon->edges.write[cp.edge].P = NULL; - } - - } else { - connections.erase(C); - //erase - } - } +void Navigation2D::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + NavigationServer2D::get_singleton()->map_set_active(map, true); + } break; + case NOTIFICATION_EXIT_TREE: { + NavigationServer2D::get_singleton()->map_set_active(map, false); + } break; } - - nm.polygons.clear(); - - nm.linked = false; } -int Navigation2D::navpoly_add(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner) { - - int id = last_id++; - NavMesh nm; - nm.linked = false; - nm.navpoly = p_mesh; - nm.xform = p_xform; - nm.owner = p_owner; - navpoly_map[id] = nm; - - _navpoly_link(id); - - return id; -} - -void Navigation2D::navpoly_set_transform(int p_id, const Transform2D &p_xform) { - - ERR_FAIL_COND(!navpoly_map.has(p_id)); - NavMesh &nm = navpoly_map[p_id]; - if (nm.xform == p_xform) - return; //bleh - _navpoly_unlink(p_id); - nm.xform = p_xform; - _navpoly_link(p_id); -} -void Navigation2D::navpoly_remove(int p_id) { - - ERR_FAIL_COND(!navpoly_map.has(p_id)); - _navpoly_unlink(p_id); - navpoly_map.erase(p_id); +void Navigation2D::set_cell_size(float p_cell_size) { + cell_size = p_cell_size; + NavigationServer2D::get_singleton()->map_set_cell_size(map, cell_size); } -Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) { - - Polygon *begin_poly = NULL; - Polygon *end_poly = NULL; - Vector2 begin_point; - Vector2 end_point; - float begin_d = 1e20; - float end_d = 1e20; - - //look for point inside triangle - - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - if (begin_d || end_d) { - for (int i = 2; i < p.edges.size(); i++) { - - if (begin_d > 0) { - - if (Geometry::is_point_in_triangle(p_start, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { - - begin_poly = &p; - begin_point = p_start; - begin_d = 0; - if (end_d == 0) - break; - } - } - - if (end_d > 0) { - - if (Geometry::is_point_in_triangle(p_end, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { - - end_poly = &p; - end_point = p_end; - end_d = 0; - if (begin_d == 0) - break; - } - } - } - } - - p.prev_edge = -1; - } - } - - //start or end not inside triangle.. look for closest segment :| - if (begin_d || end_d) { - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - int es = p.edges.size(); - for (int i = 0; i < es; i++) { - - Vector2 edge[2] = { - _get_vertex(p.edges[i].point), - _get_vertex(p.edges[(i + 1) % es].point) - }; - - if (begin_d > 0) { - Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_start, edge); - float d = spoint.distance_to(p_start); - if (d < begin_d) { - begin_poly = &p; - begin_point = spoint; - begin_d = d; - } - } - - if (end_d > 0) { - Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_end, edge); - float d = spoint.distance_to(p_end); - if (d < end_d) { - end_poly = &p; - end_point = spoint; - end_d = d; - } - } - } - } - } - } - - if (!begin_poly || !end_poly) { - - return Vector<Vector2>(); //no path - } - - if (begin_poly == end_poly) { - - Vector<Vector2> path; - path.resize(2); - path.write[0] = begin_point; - path.write[1] = end_point; - return path; - } - - bool found_route = false; - - List<Polygon *> open_list; - - begin_poly->entry = p_start; - - for (int i = 0; i < begin_poly->edges.size(); i++) { - - if (begin_poly->edges[i].C) { - - begin_poly->edges[i].C->prev_edge = begin_poly->edges[i].C_edge; -#ifdef USE_ENTRY_POINT - Vector2 edge[2] = { - _get_vertex(begin_poly->edges[i].point), - _get_vertex(begin_poly->edges[(i + 1) % begin_poly->edges.size()].point) - }; - - Vector2 entry = Geometry::get_closest_point_to_segment_2d(begin_poly->entry, edge); - begin_poly->edges[i].C->distance = begin_poly->entry.distance_to(entry); - begin_poly->edges[i].C->entry = entry; -#else - begin_poly->edges[i].C->distance = begin_poly->center.distance_to(begin_poly->edges[i].C->center); -#endif - open_list.push_back(begin_poly->edges[i].C); - - if (begin_poly->edges[i].C == end_poly) { - found_route = true; - } - } - } - - while (!found_route) { - - if (open_list.size() == 0) { - break; - } - //check open list - - List<Polygon *>::Element *least_cost_poly = NULL; - float least_cost = 1e30; - - //this could be faster (cache previous results) - for (List<Polygon *>::Element *E = open_list.front(); E; E = E->next()) { - - Polygon *p = E->get(); - - float cost = p->distance; - -#ifdef USE_ENTRY_POINT - int es = p->edges.size(); - - float shortest_distance = 1e30; - - for (int i = 0; i < es; i++) { - Polygon::Edge &e = p->edges.write[i]; - - if (!e.C) - continue; - - Vector2 edge[2] = { - _get_vertex(p->edges[i].point), - _get_vertex(p->edges[(i + 1) % es].point) - }; - - Vector2 edge_point = Geometry::get_closest_point_to_segment_2d(p->entry, edge); - float dist = p->entry.distance_to(edge_point); - if (dist < shortest_distance) - shortest_distance = dist; - } - - cost += shortest_distance; -#else - cost += p->center.distance_to(end_point); -#endif - if (cost < least_cost) { - least_cost_poly = E; - least_cost = cost; - } - } - - Polygon *p = least_cost_poly->get(); - //open the neighbours for search - int es = p->edges.size(); - - for (int i = 0; i < es; i++) { - - Polygon::Edge &e = p->edges.write[i]; - - if (!e.C) - continue; - -#ifdef USE_ENTRY_POINT - Vector2 edge[2] = { - _get_vertex(p->edges[i].point), - _get_vertex(p->edges[(i + 1) % es].point) - }; - - Vector2 edge_entry = Geometry::get_closest_point_to_segment_2d(p->entry, edge); - float distance = p->entry.distance_to(edge_entry) + p->distance; - -#else - - float distance = p->center.distance_to(e.C->center) + p->distance; - -#endif - - if (e.C->prev_edge != -1) { - //oh this was visited already, can we win the cost? - - if (e.C->distance > distance) { - - e.C->prev_edge = e.C_edge; - e.C->distance = distance; -#ifdef USE_ENTRY_POINT - e.C->entry = edge_entry; -#endif - } - } else { - //add to open neighbours - - e.C->prev_edge = e.C_edge; - e.C->distance = distance; -#ifdef USE_ENTRY_POINT - e.C->entry = edge_entry; -#endif - - open_list.push_back(e.C); - - if (e.C == end_poly) { - //oh my reached end! stop algorithm - found_route = true; - break; - } - } - } - - if (found_route) - break; - - open_list.erase(least_cost_poly); - } - - if (found_route) { - - Vector<Vector2> path; - - if (p_optimize) { - //string pulling - - Vector2 apex_point = end_point; - Vector2 portal_left = apex_point; - Vector2 portal_right = apex_point; - Polygon *left_poly = end_poly; - Polygon *right_poly = end_poly; - Polygon *p = end_poly; - - while (p) { - - Vector2 left; - Vector2 right; - -//#define CLOCK_TANGENT(m_a,m_b,m_c) ( ((m_a)-(m_c)).cross((m_a)-(m_b)) ) -#define CLOCK_TANGENT(m_a, m_b, m_c) ((((m_a).x - (m_c).x) * ((m_b).y - (m_c).y) - ((m_b).x - (m_c).x) * ((m_a).y - (m_c).y))) - - if (p == begin_poly) { - left = begin_point; - right = begin_point; - } else { - int prev = p->prev_edge; - int prev_n = (p->prev_edge + 1) % p->edges.size(); - left = _get_vertex(p->edges[prev].point); - right = _get_vertex(p->edges[prev_n].point); - - if (p->clockwise) { - SWAP(left, right); - } - /*if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){ - SWAP(left,right); - }*/ - } - - bool skip = false; - - /* - print_line("-----\nAPEX: "+(apex_point-end_point)); - print_line("LEFT:"); - print_line("\tPortal: "+(portal_left-end_point)); - print_line("\tPoint: "+(left-end_point)); - print_line("\tLeft Tangent: "+rtos(CLOCK_TANGENT(apex_point,portal_left,left))); - print_line("\tLeft Distance: "+rtos(portal_left.distance_squared_to(apex_point))); - print_line("\tLeft Test: "+rtos(CLOCK_TANGENT(apex_point,left,portal_right))); - print_line("RIGHT:"); - print_line("\tPortal: "+(portal_right-end_point)); - print_line("\tPoint: "+(right-end_point)); - print_line("\tRight Tangent: "+rtos(CLOCK_TANGENT(apex_point,portal_right,right))); - print_line("\tRight Distance: "+rtos(portal_right.distance_squared_to(apex_point))); - print_line("\tRight Test: "+rtos(CLOCK_TANGENT(apex_point,right,portal_left))); - */ - - if (CLOCK_TANGENT(apex_point, portal_left, left) >= 0) { - //process - if (portal_left.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, left, portal_right) > 0) { - left_poly = p; - portal_left = left; - } else { - - apex_point = portal_right; - p = right_poly; - left_poly = p; - portal_left = apex_point; - portal_right = apex_point; - if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point)) - path.push_back(apex_point); - skip = true; - } - } - - if (!skip && CLOCK_TANGENT(apex_point, portal_right, right) <= 0) { - //process - if (portal_right.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, right, portal_left) < 0) { - right_poly = p; - portal_right = right; - } else { - - apex_point = portal_left; - p = left_poly; - right_poly = p; - portal_right = apex_point; - portal_left = apex_point; - if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point)) - path.push_back(apex_point); - } - } - - if (p != begin_poly) - p = p->edges[p->prev_edge].C; - else - p = NULL; - } - - } else { - //midpoints - Polygon *p = end_poly; - - while (true) { - int prev = p->prev_edge; - int prev_n = (p->prev_edge + 1) % p->edges.size(); - Vector2 point = (_get_vertex(p->edges[prev].point) + _get_vertex(p->edges[prev_n].point)) * 0.5; - path.push_back(point); - p = p->edges[prev].C; - if (p == begin_poly) - break; - } - } - - if (!path.size() || !path[path.size() - 1].is_equal_approx(begin_point)) { - path.push_back(begin_point); // Add the begin point - } else { - path.write[path.size() - 1] = begin_point; // Replace first midpoint by the exact begin point - } - - path.invert(); - - if (path.size() <= 1 || !path[path.size() - 1].is_equal_approx(end_point)) { - path.push_back(end_point); // Add the end point - } else { - path.write[path.size() - 1] = end_point; // Replace last midpoint by the exact end point - } - - return path; - } - - return Vector<Vector2>(); +void Navigation2D::set_edge_connection_margin(float p_edge_connection_margin) { + edge_connection_margin = p_edge_connection_margin; + NavigationServer2D::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin); } -Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) { - - Vector2 closest_point = Vector2(); - float closest_point_d = 1e20; - - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - for (int i = 2; i < p.edges.size(); i++) { - - if (Geometry::is_point_in_triangle(p_point, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { - - return p_point; //inside triangle, nothing else to discuss - } - } - } - } - - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - int es = p.edges.size(); - for (int i = 0; i < es; i++) { - - Vector2 edge[2] = { - _get_vertex(p.edges[i].point), - _get_vertex(p.edges[(i + 1) % es].point) - }; - - Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_point, edge); - float d = spoint.distance_squared_to(p_point); - if (d < closest_point_d) { - - closest_point = spoint; - closest_point_d = d; - } - } - } - } - - return closest_point; +Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) const { + return NavigationServer2D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize); } -Object *Navigation2D::get_closest_point_owner(const Vector2 &p_point) { - - Object *owner = NULL; - Vector2 closest_point = Vector2(); - float closest_point_d = 1e20; - - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - for (int i = 2; i < p.edges.size(); i++) { - - if (Geometry::is_point_in_triangle(p_point, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { - - return E->get().owner; - } - } - } - } - - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - int es = p.edges.size(); - for (int i = 0; i < es; i++) { - - Vector2 edge[2] = { - _get_vertex(p.edges[i].point), - _get_vertex(p.edges[(i + 1) % es].point) - }; - - Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_point, edge); - float d = spoint.distance_squared_to(p_point); - if (d < closest_point_d) { - - closest_point = spoint; - closest_point_d = d; - owner = E->get().owner; - } - } - } - } - - return owner; +Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) const { + return NavigationServer2D::get_singleton()->map_get_closest_point(map, p_point); } -void Navigation2D::_bind_methods() { - - ClassDB::bind_method(D_METHOD("navpoly_add", "mesh", "xform", "owner"), &Navigation2D::navpoly_add, DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("navpoly_set_transform", "id", "xform"), &Navigation2D::navpoly_set_transform); - ClassDB::bind_method(D_METHOD("navpoly_remove", "id"), &Navigation2D::navpoly_remove); - - ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true)); - ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation2D::get_closest_point); - ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation2D::get_closest_point_owner); +RID Navigation2D::get_closest_point_owner(const Vector2 &p_point) const { + return NavigationServer2D::get_singleton()->map_get_closest_point_owner(map, p_point); } Navigation2D::Navigation2D() { + map = NavigationServer2D::get_singleton()->map_create(); + set_cell_size(10); // Ten pixels + set_edge_connection_margin(100); +} - ERR_FAIL_COND(sizeof(Point) != 8); - cell_size = 1; // one pixel - last_id = 1; +Navigation2D::~Navigation2D() { + NavigationServer2D::get_singleton()->free(map); } diff --git a/scene/2d/navigation_2d.h b/scene/2d/navigation_2d.h index 41b9aea35a..6046bddb32 100644 --- a/scene/2d/navigation_2d.h +++ b/scene/2d/navigation_2d.h @@ -31,144 +31,41 @@ #ifndef NAVIGATION_2D_H #define NAVIGATION_2D_H -#include "scene/2d/navigation_polygon.h" +#include "scene/2d/navigation_region_2d.h" #include "scene/2d/node_2d.h" class Navigation2D : public Node2D { - GDCLASS(Navigation2D, Node2D); - union Point { - - struct { - int64_t x : 32; - int64_t y : 32; - }; - - uint64_t key; - bool operator<(const Point &p_key) const { return key < p_key.key; } - }; - - struct EdgeKey { - - Point a; - Point b; - - bool operator<(const EdgeKey &p_key) const { - return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key); - }; - - EdgeKey(const Point &p_a = Point(), const Point &p_b = Point()) : - a(p_a), - b(p_b) { - if (a.key > b.key) { - SWAP(a, b); - } - } - }; - - struct NavMesh; - struct Polygon; - - struct ConnectionPending { - - Polygon *polygon; - int edge; - }; - - struct Polygon { - - struct Edge { - Point point; - Polygon *C; //connection - int C_edge; - List<ConnectionPending>::Element *P; - Edge() { - C = NULL; - C_edge = -1; - P = NULL; - } - }; - - Vector<Edge> edges; - - Vector2 center; - Vector2 entry; - - float distance; - int prev_edge; - - bool clockwise; - - NavMesh *owner; - }; - - struct Connection { + RID map; + real_t cell_size; + real_t edge_connection_margin; - Polygon *A; - int A_edge; - Polygon *B; - int B_edge; - - List<ConnectionPending> pending; - - Connection() { - A = NULL; - B = NULL; - A_edge = -1; - B_edge = -1; - } - }; - - Map<EdgeKey, Connection> connections; - - struct NavMesh { - - Object *owner; - Transform2D xform; - bool linked; - Ref<NavigationPolygon> navpoly; - List<Polygon> polygons; - }; - - _FORCE_INLINE_ Point _get_point(const Vector2 &p_pos) const { - - int x = int(Math::floor(p_pos.x / cell_size)); - int y = int(Math::floor(p_pos.y / cell_size)); +protected: + static void _bind_methods(); + void _notification(int p_what); - Point p; - p.key = 0; - p.x = x; - p.y = y; - return p; +public: + RID get_rid() const { + return map; } - _FORCE_INLINE_ Vector2 _get_vertex(const Point &p_point) const { - - return Vector2(p_point.x, p_point.y) * cell_size; + void set_cell_size(float p_cell_size); + float get_cell_size() const { + return cell_size; } - void _navpoly_link(int p_id); - void _navpoly_unlink(int p_id); - - float cell_size; - Map<int, NavMesh> navpoly_map; - int last_id; - -protected: - static void _bind_methods(); - -public: - //API should be as dynamic as possible - int navpoly_add(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner = NULL); - void navpoly_set_transform(int p_id, const Transform2D &p_xform); - void navpoly_remove(int p_id); + void set_edge_connection_margin(float p_edge_connection_margin); + float get_edge_connection_margin() const { + return edge_connection_margin; + } - Vector<Vector2> get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize = true); - Vector2 get_closest_point(const Vector2 &p_point); - Object *get_closest_point_owner(const Vector2 &p_point); + Vector<Vector2> get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize = true) const; + Vector2 get_closest_point(const Vector2 &p_point) const; + RID get_closest_point_owner(const Vector2 &p_point) const; Navigation2D(); + ~Navigation2D(); }; #endif // NAVIGATION_2D_H diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp new file mode 100644 index 0000000000..e5cdade4a4 --- /dev/null +++ b/scene/2d/navigation_agent_2d.cpp @@ -0,0 +1,340 @@ +/*************************************************************************/ +/* navigation_agent_2d.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 "navigation_agent_2d.h" + +#include "core/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); + + ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationAgent2D::set_radius); + ClassDB::bind_method(D_METHOD("get_radius"), &NavigationAgent2D::get_radius); + + ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent2D::set_navigation_node); + ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent2D::get_navigation_node); + + ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent2D::set_neighbor_dist); + ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent2D::get_neighbor_dist); + + ClassDB::bind_method(D_METHOD("set_max_neighbors", "max_neighbors"), &NavigationAgent2D::set_max_neighbors); + ClassDB::bind_method(D_METHOD("get_max_neighbors"), &NavigationAgent2D::get_max_neighbors); + + ClassDB::bind_method(D_METHOD("set_time_horizon", "time_horizon"), &NavigationAgent2D::set_time_horizon); + ClassDB::bind_method(D_METHOD("get_time_horizon"), &NavigationAgent2D::get_time_horizon); + + ClassDB::bind_method(D_METHOD("set_max_speed", "max_speed"), &NavigationAgent2D::set_max_speed); + ClassDB::bind_method(D_METHOD("get_max_speed"), &NavigationAgent2D::get_max_speed); + + ClassDB::bind_method(D_METHOD("set_path_max_distance", "max_speed"), &NavigationAgent2D::set_path_max_distance); + ClassDB::bind_method(D_METHOD("get_path_max_distance"), &NavigationAgent2D::get_path_max_distance); + + ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent2D::set_target_location); + ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent2D::get_target_location); + ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent2D::get_next_location); + ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent2D::distance_to_target); + ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent2D::set_velocity); + ClassDB::bind_method(D_METHOD("get_nav_path"), &NavigationAgent2D::get_nav_path); + ClassDB::bind_method(D_METHOD("get_nav_path_index"), &NavigationAgent2D::get_nav_path_index); + ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent2D::is_target_reached); + ClassDB::bind_method(D_METHOD("is_target_reachable"), &NavigationAgent2D::is_target_reachable); + ClassDB::bind_method(D_METHOD("is_navigation_finished"), &NavigationAgent2D::is_navigation_finished); + ClassDB::bind_method(D_METHOD("get_final_location"), &NavigationAgent2D::get_final_location); + + ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent2D::_avoidance_done); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01"), "set_target_desired_distance", "get_target_desired_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_dist", PROPERTY_HINT_RANGE, "0.1,100000,0.01"), "set_neighbor_dist", "get_neighbor_dist"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_time_horizon", "get_time_horizon"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,100000,0.01"), "set_max_speed", "get_max_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1"), "set_path_max_distance", "get_path_max_distance"); + + ADD_SIGNAL(MethodInfo("path_changed")); + ADD_SIGNAL(MethodInfo("target_reached")); + ADD_SIGNAL(MethodInfo("navigation_finished")); + ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR3, "safe_velocity"))); +} + +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"); + + // Search the navigation node and set it + { + Navigation2D *nav = nullptr; + Node *p = get_parent(); + while (p != nullptr) { + nav = Object::cast_to<Navigation2D>(p); + if (nav != nullptr) { + p = nullptr; + } else { + p = p->get_parent(); + } + } + + set_navigation(nav); + } + + set_physics_process_internal(true); + } break; + case NOTIFICATION_EXIT_TREE: { + agent_parent = nullptr; + set_navigation(nullptr); + set_physics_process_internal(false); + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + if (agent_parent) { + NavigationServer2D::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().get_origin()); + if (!target_reached) { + if (distance_to_target() < target_desired_distance) { + emit_signal("target_reached"); + target_reached = true; + } + } + } + } break; + } +} + +NavigationAgent2D::NavigationAgent2D() { + agent = NavigationServer2D::get_singleton()->agent_create(); + set_neighbor_dist(500.0); + set_max_neighbors(10); + set_time_horizon(20.0); + set_radius(10.0); + set_max_speed(200.0); +} + +NavigationAgent2D::~NavigationAgent2D() { + NavigationServer2D::get_singleton()->free(agent); + agent = RID(); // Pointless +} + +void NavigationAgent2D::set_navigation(Navigation2D *p_nav) { + if (navigation == p_nav) { + return; // Pointless + } + + navigation = p_nav; + NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid()); +} + +void NavigationAgent2D::set_navigation_node(Node *p_nav) { + Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav); + ERR_FAIL_COND(nav == nullptr); + set_navigation(nav); +} + +Node *NavigationAgent2D::get_navigation_node() const { + return Object::cast_to<Node>(navigation); +} + +void NavigationAgent2D::set_target_desired_distance(real_t p_dd) { + target_desired_distance = p_dd; +} + +void NavigationAgent2D::set_radius(real_t p_radius) { + radius = p_radius; + NavigationServer2D::get_singleton()->agent_set_radius(agent, radius); +} + +void NavigationAgent2D::set_neighbor_dist(real_t p_dist) { + neighbor_dist = p_dist; + NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, neighbor_dist); +} + +void NavigationAgent2D::set_max_neighbors(int p_count) { + max_neighbors = p_count; + NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, max_neighbors); +} + +void NavigationAgent2D::set_time_horizon(real_t p_time) { + time_horizon = p_time; + NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, time_horizon); +} + +void NavigationAgent2D::set_max_speed(real_t p_max_speed) { + max_speed = p_max_speed; + NavigationServer2D::get_singleton()->agent_set_max_speed(agent, max_speed); +} + +void NavigationAgent2D::set_path_max_distance(real_t p_pmd) { + path_max_distance = p_pmd; +} + +real_t NavigationAgent2D::get_path_max_distance() { + return path_max_distance; +} + +void NavigationAgent2D::set_target_location(Vector2 p_location) { + target_location = p_location; + navigation_path.clear(); + target_reached = false; + navigation_finished = false; + update_frame_id = 0; +} + +Vector2 NavigationAgent2D::get_target_location() const { + return target_location; +} + +Vector2 NavigationAgent2D::get_next_location() { + update_navigation(); + if (navigation_path.size() == 0) { + ERR_FAIL_COND_V(agent_parent == nullptr, Vector2()); + return agent_parent->get_global_transform().get_origin(); + } else { + return navigation_path[nav_path_index]; + } +} + +real_t NavigationAgent2D::distance_to_target() const { + ERR_FAIL_COND_V(agent_parent == nullptr, 0.0); + return agent_parent->get_global_transform().get_origin().distance_to(target_location); +} + +bool NavigationAgent2D::is_target_reached() const { + return target_reached; +} + +bool NavigationAgent2D::is_target_reachable() { + return target_desired_distance >= get_final_location().distance_to(target_location); +} + +bool NavigationAgent2D::is_navigation_finished() { + update_navigation(); + return navigation_finished; +} + +Vector2 NavigationAgent2D::get_final_location() { + update_navigation(); + if (navigation_path.size() == 0) { + return Vector2(); + } + return navigation_path[navigation_path.size() - 1]; +} + +void NavigationAgent2D::set_velocity(Vector2 p_velocity) { + target_velocity = p_velocity; + NavigationServer2D::get_singleton()->agent_set_target_velocity(agent, target_velocity); + NavigationServer2D::get_singleton()->agent_set_velocity(agent, prev_safe_velocity); + velocity_submitted = true; +} + +void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) { + const Vector2 velocity = Vector2(p_new_velocity.x, p_new_velocity.z); + prev_safe_velocity = velocity; + + if (!velocity_submitted) { + target_velocity = Vector2(); + return; + } + velocity_submitted = false; + + emit_signal("velocity_computed", velocity); +} + +String NavigationAgent2D::get_configuration_warning() const { + if (!Object::cast_to<Node2D>(get_parent())) { + return TTR("The NavigationAgent2D can be used only under a Node2D node"); + } + + return String(); +} + +void NavigationAgent2D::update_navigation() { + 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(); + + Vector2 o = agent_parent->get_global_transform().get_origin(); + + bool reload_path = false; + + if (NavigationServer2D::get_singleton()->agent_is_map_changed(agent)) { + reload_path = true; + } else if (navigation_path.size() == 0) { + reload_path = true; + } else { + // Check if too far from the navigation path + if (nav_path_index > 0) { + Vector2 segment[2]; + segment[0] = navigation_path[nav_path_index - 1]; + segment[1] = navigation_path[nav_path_index]; + 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; + } + } + } + + if (reload_path) { + navigation_path = NavigationServer2D::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true); + navigation_finished = false; + nav_path_index = 0; + emit_signal("path_changed"); + } + + if (navigation_path.size() == 0) { + return; + } + + // Check if we can advance the navigation path + if (navigation_finished == false) { + // Advances to the next far away location. + while (o.distance_to(navigation_path[nav_path_index]) < target_desired_distance) { + nav_path_index += 1; + if (nav_path_index == navigation_path.size()) { + nav_path_index -= 1; + navigation_finished = true; + emit_signal("navigation_finished"); + break; + } + } + } +} diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h new file mode 100644 index 0000000000..9474392ddf --- /dev/null +++ b/scene/2d/navigation_agent_2d.h @@ -0,0 +1,150 @@ +/*************************************************************************/ +/* navigation_agent_2d.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 NAVIGATION_AGENT_2D_H +#define NAVIGATION_AGENT_2D_H + +#include "core/vector.h" +#include "scene/main/node.h" + +class Node2D; +class Navigation2D; + +class NavigationAgent2D : public Node { + GDCLASS(NavigationAgent2D, Node); + + Node2D *agent_parent = nullptr; + Navigation2D *navigation = nullptr; + + RID agent; + + 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 = 3.0; + + Vector2 target_location; + Vector<Vector2> navigation_path; + int nav_path_index; + bool velocity_submitted = false; + Vector2 prev_safe_velocity; + /// The submitted target velocity + Vector2 target_velocity; + bool target_reached = false; + bool navigation_finished = true; + // No initialized on purpose + uint32_t update_frame_id; + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + NavigationAgent2D(); + virtual ~NavigationAgent2D(); + + void set_navigation(Navigation2D *p_nav); + const Navigation2D *get_navigation() const { + return navigation; + } + + void set_navigation_node(Node *p_nav); + Node *get_navigation_node() const; + + RID get_rid() const { + return agent; + } + + void set_target_desired_distance(real_t p_dd); + real_t get_target_desired_distance() const { + return target_desired_distance; + } + + void set_radius(real_t p_radius); + real_t get_radius() const { + return radius; + } + + void set_neighbor_dist(real_t p_dist); + real_t get_neighbor_dist() const { + return neighbor_dist; + } + + void set_max_neighbors(int p_count); + int get_max_neighbors() const { + return max_neighbors; + } + + void set_time_horizon(real_t p_time); + real_t get_time_horizon() const { + return time_horizon; + } + + void set_max_speed(real_t p_max_speed); + real_t get_max_speed() const { + return max_speed; + } + + void set_path_max_distance(real_t p_pmd); + real_t get_path_max_distance(); + + void set_target_location(Vector2 p_location); + Vector2 get_target_location() const; + + Vector2 get_next_location(); + + Vector<Vector2> get_nav_path() const { + return navigation_path; + } + + int get_nav_path_index() const { + return nav_path_index; + } + + real_t distance_to_target() const; + bool is_target_reached() const; + bool is_target_reachable(); + bool is_navigation_finished(); + Vector2 get_final_location(); + + void set_velocity(Vector2 p_velocity); + void _avoidance_done(Vector3 p_new_velocity); + + virtual String get_configuration_warning() const override; + +private: + void update_navigation(); +}; + +#endif diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp new file mode 100644 index 0000000000..568023bbe2 --- /dev/null +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -0,0 +1,153 @@ +/*************************************************************************/ +/* navigation_obstacle_2d.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 "navigation_obstacle_2d.h" + +#include "scene/2d/collision_shape_2d.h" +#include "scene/2d/navigation_2d.h" +#include "scene/2d/physics_body_2d.h" +#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); +} + +void NavigationObstacle2D::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + update_agent_shape(); + + // Search the navigation node and set it + { + Navigation2D *nav = nullptr; + Node *p = get_parent(); + while (p != nullptr) { + nav = Object::cast_to<Navigation2D>(p); + if (nav != nullptr) { + p = nullptr; + } else { + p = p->get_parent(); + } + } + + set_navigation(nav); + } + + set_physics_process_internal(true); + } break; + case NOTIFICATION_EXIT_TREE: { + set_navigation(nullptr); + set_physics_process_internal(false); + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + Node2D *node = Object::cast_to<Node2D>(get_parent()); + if (node) { + NavigationServer2D::get_singleton()->agent_set_position(agent, node->get_global_transform().get_origin()); + } + + } break; + } +} + +NavigationObstacle2D::NavigationObstacle2D() { + agent = NavigationServer2D::get_singleton()->agent_create(); +} + +NavigationObstacle2D::~NavigationObstacle2D() { + NavigationServer2D::get_singleton()->free(agent); + agent = RID(); // Pointless +} + +void NavigationObstacle2D::set_navigation(Navigation2D *p_nav) { + if (navigation == p_nav) { + return; // Pointless + } + + navigation = p_nav; + NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid()); +} + +void NavigationObstacle2D::set_navigation_node(Node *p_nav) { + Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav); + ERR_FAIL_COND(nav == nullptr); + set_navigation(nav); +} + +Node *NavigationObstacle2D::get_navigation_node() const { + return Object::cast_to<Node>(navigation); +} + +String NavigationObstacle2D::get_configuration_warning() const { + if (!Object::cast_to<Node2D>(get_parent())) { + return TTR("The NavigationObstacle2D only serves to provide collision avoidance to a Node2D object."); + } + + return String(); +} + +void NavigationObstacle2D::update_agent_shape() { + Node *node = get_parent(); + + // Estimate the radius of this physics body + real_t radius = 0.0; + for (int i(0); i < node->get_child_count(); i++) { + // For each collision shape + CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(node->get_child(i)); + if (cs) { + // Take the distance between the Body center to the shape center + real_t r = cs->get_transform().get_origin().length(); + if (cs->get_shape().is_valid()) { + // and add the enclosing shape radius + r += cs->get_shape()->get_enclosing_radius(); + } + Size2 s = cs->get_global_transform().get_scale(); + r *= MAX(s.x, s.y); + // Takes the biggest radius + radius = MAX(radius, r); + } + } + Node2D *node_2d = Object::cast_to<Node2D>(node); + if (node_2d) { + Vector2 s = node_2d->get_global_transform().get_scale(); + radius *= MAX(s.x, s.y); + } + + 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); + NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0); + NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0); + NavigationServer2D::get_singleton()->agent_set_radius(agent, radius); + NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0); +} diff --git a/scene/2d/path_texture.h b/scene/2d/navigation_obstacle_2d.h index 9cfa004cfb..d65f44bc0e 100644 --- a/scene/2d/path_texture.h +++ b/scene/2d/navigation_obstacle_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* path_texture.h */ +/* navigation_obstacle_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,37 +28,44 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PATH_TEXTURE_H -#define PATH_TEXTURE_H +#ifndef NAVIGATION_OBSTACLE_2D_H +#define NAVIGATION_OBSTACLE_2D_H -#include "scene/2d/node_2d.h" +#include "scene/main/node.h" -class PathTexture : public Node2D { - GDCLASS(PathTexture, Node2D); +class Navigation2D; - Ref<Texture> begin; - Ref<Texture> repeat; - Ref<Texture> end; - int subdivs; - bool overlap; +class NavigationObstacle2D : public Node { + GDCLASS(NavigationObstacle2D, Node); + + Navigation2D *navigation = nullptr; + + RID agent; + +protected: + static void _bind_methods(); + void _notification(int p_what); public: - void set_begin_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_begin_texture() const; + NavigationObstacle2D(); + virtual ~NavigationObstacle2D(); - void set_repeat_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_repeat_texture() const; + void set_navigation(Navigation2D *p_nav); + const Navigation2D *get_navigation() const { + return navigation; + } - void set_end_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_end_texture() const; + void set_navigation_node(Node *p_nav); + Node *get_navigation_node() const; - void set_subdivisions(int p_amount); - int get_subdivisions() const; + RID get_rid() const { + return agent; + } - void set_overlap(int p_amount); - int get_overlap() const; + virtual String get_configuration_warning() const override; - PathTexture(); +private: + void update_agent_shape(); }; -#endif // PATH_TEXTURE_H +#endif diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_region_2d.cpp index ea79f89dd9..671bda558d 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* navigation_polygon.cpp */ +/* navigation_region_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,27 +28,30 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "navigation_polygon.h" +#include "navigation_region_2d.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" #include "thirdparty/misc/triangulator.h" #ifdef TOOLS_ENABLED Rect2 NavigationPolygon::_edit_get_rect() const { - if (rect_cache_dirty) { item_rect = Rect2(); bool first = true; for (int i = 0; i < outlines.size(); i++) { - const PoolVector<Vector2> &outline = outlines[i]; + const Vector<Vector2> &outline = outlines[i]; const int outline_size = outline.size(); - if (outline_size < 3) + if (outline_size < 3) { continue; - PoolVector<Vector2>::Read p = outline.read(); + } + const Vector2 *p = outline.ptr(); for (int j = 0; j < outline_size; j++) { if (first) { item_rect = Rect2(p[j], Vector2(0, 0)); @@ -65,32 +68,38 @@ 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 PoolVector<Vector2> &outline = outlines[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 PoolVector<Vector2> &p_vertices) { - +void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) { + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } vertices = p_vertices; rect_cache_dirty = true; } -PoolVector<Vector2> NavigationPolygon::get_vertices() const { - +Vector<Vector2> NavigationPolygon::get_vertices() const { return vertices; } -void NavigationPolygon::_set_polygons(const Array &p_array) { - +void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array) { + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } polygons.resize(p_array.size()); for (int i = 0; i < p_array.size(); i++) { polygons.write[i].indices = p_array[i]; @@ -98,7 +107,6 @@ void NavigationPolygon::_set_polygons(const Array &p_array) { } Array NavigationPolygon::_get_polygons() const { - Array ret; ret.resize(polygons.size()); for (int i = 0; i < ret.size(); i++) { @@ -108,8 +116,7 @@ Array NavigationPolygon::_get_polygons() const { return ret; } -void NavigationPolygon::_set_outlines(const Array &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]; @@ -118,7 +125,6 @@ void NavigationPolygon::_set_outlines(const Array &p_array) { } Array NavigationPolygon::_get_outlines() const { - Array ret; ret.resize(outlines.size()); for (int i = 0; i < ret.size(); i++) { @@ -129,79 +135,110 @@ Array NavigationPolygon::_get_outlines() const { } void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) { - Polygon polygon; polygon.indices = p_polygon; polygons.push_back(polygon); + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } } -void NavigationPolygon::add_outline_at_index(const PoolVector<Vector2> &p_outline, int p_index) { - +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); + navmesh.unref(); + } } -void NavigationPolygon::add_outline(const PoolVector<Vector2> &p_outline) { +Ref<NavigationMesh> NavigationPolygon::get_mesh() { + MutexLock lock(navmesh_generation); + + if (navmesh.is_null()) { + navmesh.instance(); + Vector<Vector3> verts; + { + verts.resize(get_vertices().size()); + Vector3 *w = verts.ptrw(); + + const Vector2 *r = get_vertices().ptr(); + for (int i(0); i < get_vertices().size(); i++) { + w[i] = Vector3(r[i].x, 0.0, r[i].y); + } + } + navmesh->set_vertices(verts); + + for (int i(0); i < get_polygon_count(); i++) { + navmesh->add_polygon(get_polygon(i)); + } + } + + return navmesh; +} + +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(); } -void NavigationPolygon::set_outline(int p_idx, const PoolVector<Vector2> &p_outline) { +void NavigationPolygon::set_outline(int p_idx, const Vector<Vector2> &p_outline) { ERR_FAIL_INDEX(p_idx, outlines.size()); outlines.write[p_idx] = p_outline; rect_cache_dirty = true; } void NavigationPolygon::remove_outline(int p_idx) { - ERR_FAIL_INDEX(p_idx, outlines.size()); outlines.remove(p_idx); rect_cache_dirty = true; } -PoolVector<Vector2> NavigationPolygon::get_outline(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, outlines.size(), PoolVector<Vector2>()); +Vector<Vector2> NavigationPolygon::get_outline(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, outlines.size(), Vector<Vector2>()); return outlines[p_idx]; } 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(); + } List<TriangulatorPoly> in_poly, out_poly; Vector2 outside_point(-1e10, -1e10); for (int i = 0; i < outlines.size(); i++) { - - PoolVector<Vector2> ol = outlines[i]; + Vector<Vector2> ol = outlines[i]; int olsize = ol.size(); - if (olsize < 3) + if (olsize < 3) { continue; - PoolVector<Vector2>::Read r = ol.read(); + } + const Vector2 *r = ol.ptr(); for (int j = 0; j < olsize; j++) { outside_point.x = MAX(r[j].x, outside_point.x); outside_point.y = MAX(r[j].y, outside_point.y); @@ -211,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++) { - - PoolVector<Vector2> ol = outlines[i]; + Vector<Vector2> ol = outlines[i]; int olsize = ol.size(); - if (olsize < 3) + if (olsize < 3) { continue; - PoolVector<Vector2>::Read r = ol.read(); + } + 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 + } - PoolVector<Vector2> ol2 = outlines[k]; + Vector<Vector2> ol2 = outlines[k]; int olsize2 = ol2.size(); - if (olsize2 < 3) + if (olsize2 < 3) { continue; - PoolVector<Vector2>::Read r2 = ol2.read(); + } + 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], NULL)) { + if (Geometry2D::segment_intersects_segment(r[0], outside_point, r2[l], r2[(l + 1) % olsize2], nullptr)) { interscount++; } } @@ -247,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); } @@ -259,7 +296,7 @@ void NavigationPolygon::make_polygons_from_outlines() { TriangulatorPartition tpart; if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed! - ERR_PRINTS("NavigationPolygon: Convex partition failed!"); + ERR_PRINT("NavigationPolygon: Convex partition failed!"); return; } @@ -268,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()); @@ -290,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); @@ -314,77 +348,58 @@ void NavigationPolygon::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_outlines", "outlines"), &NavigationPolygon::_set_outlines); ClassDB::bind_method(D_METHOD("_get_outlines"), &NavigationPolygon::_get_outlines); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_polygons", "_get_polygons"); 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) { -} - -void NavigationPolygonInstance::set_enabled(bool p_enabled) { - - if (enabled == p_enabled) +void NavigationRegion2D::set_enabled(bool p_enabled) { + if (enabled == p_enabled) { return; + } enabled = p_enabled; - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } if (!enabled) { - - if (nav_id != -1) { - navigation->navpoly_remove(nav_id); - nav_id = -1; - } + NavigationServer2D::get_singleton()->region_set_map(region, RID()); } else { - if (navigation) { - - if (navpoly.is_valid()) { - - nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); - } + 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 NavigationPolygonInstance::is_enabled() const { - +bool NavigationRegion2D::is_enabled() const { return enabled; } ///////////////////////////// #ifdef TOOLS_ENABLED -Rect2 NavigationPolygonInstance::_edit_get_rect() const { - +Rect2 NavigationRegion2D::_edit_get_rect() const { return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2(); } -bool NavigationPolygonInstance::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - +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 NavigationPolygonInstance::_notification(int p_what) { - +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 && navpoly.is_valid()) { - - nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); + if (enabled) { + NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid()); } break; } @@ -394,31 +409,22 @@ void NavigationPolygonInstance::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - - if (navigation && nav_id != -1) { - navigation->navpoly_set_transform(nav_id, get_relative_transform_to_parent(navigation)); - } + NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform()); } break; case NOTIFICATION_EXIT_TREE: { - if (navigation) { - - if (nav_id != -1) { - navigation->navpoly_remove(nav_id); - nav_id = -1; - } + NavigationServer2D::get_singleton()->region_set_map(region, RID()); } - navigation = NULL; + 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()) { - - PoolVector<Vector2> verts = navpoly->get_vertices(); + Vector<Vector2> verts = navpoly->get_vertices(); int vsize = verts.size(); - if (vsize < 3) + if (vsize < 3) { return; + } Color color; if (enabled) { @@ -431,7 +437,7 @@ void NavigationPolygonInstance::_notification(int p_what) { vertices.resize(vsize); colors.resize(vsize); { - PoolVector<Vector2>::Read vr = verts.read(); + const Vector2 *vr = verts.ptr(); for (int i = 0; i < vsize; i++) { vertices.write[i] = vr[i]; colors.write[i] = color; @@ -444,72 +450,61 @@ void NavigationPolygonInstance::_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); } } } - VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, vertices, colors); + RS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, vertices, colors); } } break; } } -void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) { - +void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) { if (p_navpoly == navpoly) { return; } - if (navigation && nav_id != -1) { - navigation->navpoly_remove(nav_id); - nav_id = -1; - } - if (navpoly.is_valid()) { - navpoly->disconnect(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed"); + navpoly->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NavigationRegion2D::_navpoly_changed)); } + navpoly = p_navpoly; + NavigationServer2D::get_singleton()->region_set_navpoly(region, p_navpoly); + if (navpoly.is_valid()) { - navpoly->connect(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed"); + navpoly->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NavigationRegion2D::_navpoly_changed)); } _navpoly_changed(); - if (navigation && navpoly.is_valid() && enabled) { - nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); - } - _change_notify("navpoly"); update_configuration_warning(); } -Ref<NavigationPolygon> NavigationPolygonInstance::get_navigation_polygon() const { - +Ref<NavigationPolygon> NavigationRegion2D::get_navigation_polygon() const { return navpoly; } -void NavigationPolygonInstance::_navpoly_changed() { - - if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) +void NavigationRegion2D::_navpoly_changed() { + if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) { update(); + } } -String NavigationPolygonInstance::get_configuration_warning() const { - - if (!is_visible_in_tree() || !is_inside_tree()) +String NavigationRegion2D::get_configuration_warning() const { + if (!is_visible_in_tree() || !is_inside_tree()) { return String(); + } 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."); } const Node2D *c = this; while (c) { - if (Object::cast_to<Navigation2D>(c)) { return String(); } @@ -517,27 +512,27 @@ String NavigationPolygonInstance::get_configuration_warning() const { c = Object::cast_to<Node2D>(c->get_parent()); } - return TTR("NavigationPolygonInstance must be a child or grandchild to a Navigation2D node. It only provides navigation data."); + return TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data."); } -void NavigationPolygonInstance::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navpoly"), &NavigationPolygonInstance::set_navigation_polygon); - ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationPolygonInstance::get_navigation_polygon); +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); - ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationPolygonInstance::set_enabled); - ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationPolygonInstance::is_enabled); + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion2D::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion2D::is_enabled); - ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationPolygonInstance::_navpoly_changed); + ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationRegion2D::_navpoly_changed); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navpoly", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); } -NavigationPolygonInstance::NavigationPolygonInstance() { - - navigation = NULL; - nav_id = -1; - enabled = true; +NavigationRegion2D::NavigationRegion2D() { set_notify_transform(true); + region = NavigationServer2D::get_singleton()->region_create(); +} + +NavigationRegion2D::~NavigationRegion2D() { + NavigationServer2D::get_singleton()->free(region); } diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_region_2d.h index cbc1711a32..ba92d27a95 100644 --- a/scene/2d/navigation_polygon.h +++ b/scene/2d/navigation_region_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* navigation_polygon.h */ +/* navigation_region_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,32 +28,36 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NAVIGATION_POLYGON_H -#define NAVIGATION_POLYGON_H +#ifndef NAVIGATION_REGION_2D_H +#define NAVIGATION_REGION_2D_H #include "scene/2d/node_2d.h" +#include "scene/resources/navigation_mesh.h" class NavigationPolygon : public Resource { - GDCLASS(NavigationPolygon, Resource); - PoolVector<Vector2> vertices; + Vector<Vector2> vertices; struct Polygon { Vector<int> indices; }; Vector<Polygon> polygons; - Vector<PoolVector<Vector2> > outlines; + Vector<Vector<Vector2>> outlines; mutable Rect2 item_rect; - mutable bool rect_cache_dirty; + mutable bool rect_cache_dirty = true; + + Mutex navmesh_generation; + // Navigation mesh + Ref<NavigationMesh> navmesh; protected: static void _bind_methods(); - void _set_polygons(const Array &p_array); + void _set_polygons(const TypedArray<Vector<int32_t>> &p_array); Array _get_polygons() const; - void _set_outlines(const Array &p_array); + void _set_outlines(const TypedArray<Vector<Vector2>> &p_array); Array _get_outlines() const; public: @@ -62,16 +66,16 @@ public: bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; #endif - void set_vertices(const PoolVector<Vector2> &p_vertices); - PoolVector<Vector2> get_vertices() const; + void set_vertices(const Vector<Vector2> &p_vertices); + Vector<Vector2> get_vertices() const; void add_polygon(const Vector<int> &p_polygon); int get_polygon_count() const; - void add_outline(const PoolVector<Vector2> &p_outline); - void add_outline_at_index(const PoolVector<Vector2> &p_outline, int p_index); - void set_outline(int p_idx, const PoolVector<Vector2> &p_outline); - PoolVector<Vector2> get_outline(int p_idx) const; + void add_outline(const Vector<Vector2> &p_outline); + void add_outline_at_index(const Vector<Vector2> &p_outline, int p_index); + void set_outline(int p_idx, const Vector<Vector2> &p_outline); + Vector<Vector2> get_outline(int p_idx) const; void remove_outline(int p_idx); int get_outline_count() const; @@ -81,18 +85,20 @@ public: Vector<int> get_polygon(int p_idx); void clear_polygons(); - NavigationPolygon(); + Ref<NavigationMesh> get_mesh(); + + NavigationPolygon() {} + ~NavigationPolygon() {} }; class Navigation2D; -class NavigationPolygonInstance : public Node2D { - - GDCLASS(NavigationPolygonInstance, Node2D); +class NavigationRegion2D : public Node2D { + GDCLASS(NavigationRegion2D, Node2D); - bool enabled; - int nav_id; - Navigation2D *navigation; + bool enabled = true; + RID region; + Navigation2D *navigation = nullptr; Ref<NavigationPolygon> navpoly; void _navpoly_changed(); @@ -103,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); @@ -113,9 +119,10 @@ 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; - NavigationPolygonInstance(); + NavigationRegion2D(); + ~NavigationRegion2D(); }; -#endif // NAVIGATIONPOLYGON_H +#endif // NAVIGATION_REGION_2D_H diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 7deebe9b27..72250e96b3 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -32,30 +32,32 @@ #include "core/message_queue.h" #include "scene/gui/control.h" -#include "scene/main/viewport.h" -#include "servers/visual_server.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; - VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat); + 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,98 +332,95 @@ void Node2D::set_global_scale(const Size2 &p_scale) { } void Node2D::set_transform(const Transform2D &p_transform) { - _mat = p_transform; _xform_dirty = true; - VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat); + 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 < VS::CANVAS_ITEM_Z_MIN); - ERR_FAIL_COND(p_z > VS::CANVAS_ITEM_Z_MAX); + ERR_FAIL_COND(p_z < RS::CANVAS_ITEM_Z_MIN); + ERR_FAIL_COND(p_z > RS::CANVAS_ITEM_Z_MAX); z_index = p_z; - VS::get_singleton()->canvas_item_set_z_index(get_canvas_item(), z_index); + RS::get_singleton()->canvas_item_set_z_index(get_canvas_item(), z_index); _change_notify("z_index"); } void Node2D::set_z_as_relative(bool p_enabled) { - - if (z_relative == p_enabled) + if (z_relative == p_enabled) { return; + } z_relative = p_enabled; - VS::get_singleton()->canvas_item_set_z_as_relative_to_parent(get_canvas_item(), 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); @@ -440,26 +458,28 @@ void Node2D::_bind_methods() { ADD_GROUP("Transform", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "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::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"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "global_rotation", PROPERTY_HINT_NONE, "", 0), "set_global_rotation", "get_global_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "global_rotation_degrees", PROPERTY_HINT_NONE, "", 0), "set_global_rotation_degrees", "get_global_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "global_rotation", PROPERTY_HINT_NONE, "", 0), "set_global_rotation", "get_global_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "global_rotation_degrees", PROPERTY_HINT_NONE, "", 0), "set_global_rotation_degrees", "get_global_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_scale", PROPERTY_HINT_NONE, "", 0), "set_global_scale", "get_global_scale"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); ADD_GROUP("Z Index", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_index", "get_z_index"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "z_index", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_index", "get_z_index"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "z_as_relative"), "set_z_as_relative", "is_z_relative"); } 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 00202481a6..e20f746447 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -31,15 +31,15 @@ #ifndef NODE2D_H #define NODE2D_H -#include "scene/2d/canvas_item.h" +#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 5aea1025ef..4ed335dec8 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -34,7 +34,6 @@ #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,53 +60,47 @@ 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(); - VisualServer::get_singleton()->canvas_set_item_mirroring(c, ci, mirrorScale); + RenderingServer::get_singleton()->canvas_set_item_mirroring(c, ci, mirrorScale); } } 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,7 +136,6 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_sc } String ParallaxLayer::get_configuration_warning() const { - if (!Object::cast_to<ParallaxBackground>(get_parent())) { return TTR("ParallaxLayer node only works when set as child of a ParallaxBackground node."); } @@ -152,7 +144,6 @@ String ParallaxLayer::get_configuration_warning() const { } 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 6ae008548e..f2f549e851 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -31,6 +31,7 @@ #include "path_2d.h" #include "core/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,17 +100,15 @@ 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, true); + draw_line(prev_p, p, color, line_width); prev_p = p; } } @@ -120,56 +116,53 @@ void Path2D::_notification(int p_what) { } void Path2D::_curve_changed() { + if (!is_inside_tree()) { + return; + } + + if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) { + return; + } - if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) - update(); + update(); } void Path2D::set_curve(const Ref<Curve2D> &p_curve) { - if (curve.is_valid()) { - curve->disconnect("changed", this, "_curve_changed"); + curve->disconnect("changed", callable_mp(this, &Path2D::_curve_changed)); } curve = p_curve; if (curve.is_valid()) { - curve->connect("changed", this, "_curve_changed"); + curve->connect("changed", callable_mp(this, &Path2D::_curve_changed)); } _curve_changed(); } 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); - ClassDB::bind_method(D_METHOD("_curve_changed"), &Path2D::_curve_changed); - - 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) { @@ -215,7 +208,6 @@ void PathFollow2D::_update_transform() { set_rotation(tangent_to_curve.angle()); } else { - pos.x += h_offset; pos.y += v_offset; } @@ -224,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(); @@ -236,38 +225,34 @@ void PathFollow2D::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - - path = NULL; + 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(); + } if (!Object::cast_to<Path2D>(get_parent())) { return TTR("PathFollow2D only works when set as a child of a Path2D node."); @@ -277,7 +262,6 @@ String PathFollow2D::get_configuration_warning() const { } 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); @@ -302,30 +286,27 @@ void PathFollow2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lookahead", "lookahead"), &PathFollow2D::set_lookahead); ClassDB::bind_method(D_METHOD("get_lookahead"), &PathFollow2D::get_lookahead); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater"), "set_offset", "get_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset"), "set_h_offset", "get_h_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset"), "set_v_offset", "get_v_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotate"), "set_rotate", "is_rotating"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cubic_interp"), "set_cubic_interpolation", "get_cubic_interpolation"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"), "set_lookahead", "get_lookahead"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"), "set_lookahead", "get_lookahead"); } void PathFollow2D::set_offset(float p_offset) { - offset = p_offset; if (path) { - if (path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { + if (path->get_curve().is_valid()) { float path_length = path->get_curve()->get_baked_length(); if (loop) { - while (offset > path_length) - offset -= path_length; - - while (offset < 0) - offset += path_length; - + offset = Math::fposmod(offset, path_length); + if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) { + offset = path_length; + } } else { offset = CLAMP(offset, 0, path_length); } @@ -338,85 +319,75 @@ 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; - path = NULL; + path = nullptr; rotate = true; cubic = true; loop = true; 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/path_texture.cpp b/scene/2d/path_texture.cpp deleted file mode 100644 index df59c9e2bb..0000000000 --- a/scene/2d/path_texture.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************/ -/* path_texture.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 "path_texture.h" - -void PathTexture::set_begin_texture(const Ref<Texture> &p_texture) { - - begin = p_texture; - update(); -} - -Ref<Texture> PathTexture::get_begin_texture() const { - - return begin; -} - -void PathTexture::set_repeat_texture(const Ref<Texture> &p_texture) { - - repeat = p_texture; - update(); -} -Ref<Texture> PathTexture::get_repeat_texture() const { - - return repeat; -} - -void PathTexture::set_end_texture(const Ref<Texture> &p_texture) { - - end = p_texture; - update(); -} -Ref<Texture> PathTexture::get_end_texture() const { - - return end; -} - -void PathTexture::set_subdivisions(int p_amount) { - - ERR_FAIL_INDEX(p_amount, 32); - subdivs = p_amount; - update(); -} - -int PathTexture::get_subdivisions() const { - - return subdivs; -} - -void PathTexture::set_overlap(int p_amount) { - - overlap = p_amount; - update(); -} -int PathTexture::get_overlap() const { - - return overlap; -} - -PathTexture::PathTexture() { - - overlap = 0; - subdivs = 1; -} diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index d42bd6adaf..0a9de20664 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -43,18 +43,15 @@ 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); @@ -80,72 +77,66 @@ void PhysicsBody2D::_bind_methods() { } void PhysicsBody2D::set_collision_layer(uint32_t p_layer) { - collision_layer = p_layer; - Physics2DServer::get_singleton()->body_set_collision_layer(get_rid(), 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; - Physics2DServer::get_singleton()->body_set_collision_mask(get_rid(), 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(Physics2DServer::BodyMode p_mode) : - CollisionObject2D(Physics2DServer::get_singleton()->body_create(), false) { - - Physics2DServer::get_singleton()->body_set_mode(get_rid(), p_mode); +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; set_pickable(false); } -Array PhysicsBody2D::get_collision_exceptions() { +TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() { List<RID> exceptions; - Physics2DServer::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); + PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; for (List<RID>::Element *E = exceptions.front(); E; E = E->next()) { RID body = E->get(); - ObjectID instance_id = Physics2DServer::get_singleton()->body_get_object_instance_id(body); + ObjectID instance_id = PhysicsServer2D::get_singleton()->body_get_object_instance_id(body); Object *obj = ObjectDB::get_instance(instance_id); PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(obj); ret.append(physics_body); @@ -154,110 +145,48 @@ Array 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 PhysicsBody type."); - Physics2DServer::get_singleton()->body_add_collision_exception(get_rid(), physics_body->get_rid()); + ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody2D type."); + PhysicsServer2D::get_singleton()->body_add_collision_exception(get_rid(), physics_body->get_rid()); } 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 PhysicsBody type."); - Physics2DServer::get_singleton()->body_remove_collision_exception(get_rid(), physics_body->get_rid()); + ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody2D type."); + PhysicsServer2D::get_singleton()->body_remove_collision_exception(get_rid(), physics_body->get_rid()); } void StaticBody2D::set_constant_linear_velocity(const Vector2 &p_vel) { - constant_linear_velocity = p_vel; - Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); + 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; - Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); + 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; } -#ifndef DISABLE_DEPRECATED -void StaticBody2D::set_friction(real_t p_friction) { - - if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1."); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_friction(p_friction); -} - -real_t StaticBody2D::get_friction() const { - - WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 1; - } - - return physics_material_override->get_friction(); -} - -void StaticBody2D::set_bounce(real_t p_bounce) { - - if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND_MSG(p_bounce < 0 || p_bounce > 1, "Bounce must be between 0 and 1."); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_bounce(p_bounce); -} - -real_t StaticBody2D::get_bounce() const { - - WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 0; - } - - return physics_material_override->get_bounce(); -} -#endif // DISABLE_DEPRECATED - void StaticBody2D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { if (physics_material_override.is_valid()) { - if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics")) - physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, callable_mp(this, &StaticBody2D::_reload_physics_characteristics))) { + physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &StaticBody2D::_reload_physics_characteristics)); + } } physics_material_override = p_physics_material_override; if (physics_material_override.is_valid()) { - physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + physics_material_override->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &StaticBody2D::_reload_physics_characteristics)); } _reload_physics_characteristics(); } @@ -267,37 +196,21 @@ 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); ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody2D::get_constant_angular_velocity); -#ifndef DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_friction", "friction"), &StaticBody2D::set_friction); - ClassDB::bind_method(D_METHOD("get_friction"), &StaticBody2D::get_friction); - - ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &StaticBody2D::set_bounce); - ClassDB::bind_method(D_METHOD("get_bounce"), &StaticBody2D::get_bounce); -#endif // DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody2D::set_physics_material_override); ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody2D::get_physics_material_override); - ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &StaticBody2D::_reload_physics_characteristics); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); -#ifndef DISABLE_DEPRECATED - ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); -#endif // DISABLE_DEPRECATED + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); } StaticBody2D::StaticBody2D() : - PhysicsBody2D(Physics2DServer::BODY_MODE_STATIC) { - + PhysicsBody2D(PhysicsServer2D::BODY_MODE_STATIC) { constant_angular_velocity = 0; } @@ -306,16 +219,15 @@ StaticBody2D::~StaticBody2D() { void StaticBody2D::_reload_physics_characteristics() { if (physics_material_override.is_null()) { - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_BOUNCE, 0); - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_FRICTION, 1); + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_BOUNCE, 0); + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_FRICTION, 1); } else { - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_BOUNCE, physics_material_override->computed_bounce()); - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_FRICTION, physics_material_override->computed_friction()); + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_BOUNCE, physics_material_override->computed_bounce()); + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_FRICTION, physics_material_override->computed_friction()); } } 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); @@ -331,7 +243,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); } @@ -339,7 +250,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); @@ -354,7 +264,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); } @@ -362,7 +271,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; @@ -376,13 +284,12 @@ 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(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree, make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree, make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree), make_binds(objid)); if (E->get().in_scene) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } @@ -391,29 +298,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, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); - if (in_scene) + 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) { emit_signal(SceneStringNames::get_singleton()->body_exited, node); + } } contact_monitor->body_map.erase(E); @@ -425,51 +333,48 @@ 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<Physics2DTestMotionResult> &p_result) { - - Physics2DServer::MotionResult *r = NULL; - if (p_result.is_valid()) +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()) { r = p_result->get_result_ptr(); - return Physics2DServer::get_singleton()->body_test_motion(get_rid(), get_global_transform(), p_motion, p_infinite_inertia, p_margin, r); + } + 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<Physics2DDirectBodyState>(p_state); + state = Object::cast_to<PhysicsDirectBodyState2D>(p_state); #else - state = (Physics2DDirectBodyState *)p_state; //trust it + state = (PhysicsDirectBodyState2D *)p_state; //trust it #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++; } @@ -483,7 +388,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); @@ -502,7 +406,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; @@ -516,11 +419,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++; @@ -531,154 +431,86 @@ 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); } contact_monitor->locked = false; } - state = NULL; + state = nullptr; } void RigidBody2D::set_mode(Mode p_mode) { - mode = p_mode; switch (p_mode) { - case MODE_RIGID: { - - Physics2DServer::get_singleton()->body_set_mode(get_rid(), Physics2DServer::BODY_MODE_RIGID); + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_RIGID); } break; case MODE_STATIC: { - - Physics2DServer::get_singleton()->body_set_mode(get_rid(), Physics2DServer::BODY_MODE_STATIC); + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_STATIC); } break; case MODE_KINEMATIC: { - - Physics2DServer::get_singleton()->body_set_mode(get_rid(), Physics2DServer::BODY_MODE_KINEMATIC); + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_KINEMATIC); } break; case MODE_CHARACTER: { - Physics2DServer::get_singleton()->body_set_mode(get_rid(), Physics2DServer::BODY_MODE_CHARACTER); + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_CHARACTER); } break; } } 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"); - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_MASS, mass); + 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); - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_INERTIA, p_inertia); + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_INERTIA, p_inertia); } real_t RigidBody2D::get_inertia() const { - - return Physics2DServer::get_singleton()->body_get_param(get_rid(), Physics2DServer::BODY_PARAM_INERTIA); + 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); } -#ifndef DISABLE_DEPRECATED -void RigidBody2D::set_friction(real_t p_friction) { - - if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1."); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_friction(p_friction); -} -real_t RigidBody2D::get_friction() const { - - WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 1; - } - - return physics_material_override->get_friction(); -} - -void RigidBody2D::set_bounce(real_t p_bounce) { - - if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_bounce(p_bounce); -} -real_t RigidBody2D::get_bounce() const { - - WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 0; - } - - return physics_material_override->get_bounce(); -} -#endif // DISABLE_DEPRECATED - void RigidBody2D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { if (physics_material_override.is_valid()) { - if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics")) - physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody2D::_reload_physics_characteristics))) { + physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody2D::_reload_physics_characteristics)); + } } physics_material_override = p_physics_material_override; if (physics_material_override.is_valid()) { - physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + physics_material_override->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody2D::_reload_physics_characteristics)); } _reload_physics_characteristics(); } @@ -688,39 +520,35 @@ Ref<PhysicsMaterial> RigidBody2D::get_physics_material_override() const { } void RigidBody2D::set_gravity_scale(real_t p_gravity_scale) { - gravity_scale = p_gravity_scale; - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_GRAVITY_SCALE, 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; - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_LINEAR_DAMP, 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; - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_ANGULAR_DAMP, 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); @@ -728,148 +556,130 @@ void RigidBody2D::set_axis_velocity(const Vector2 &p_axis) { if (state) { set_linear_velocity(v); } else { - Physics2DServer::get_singleton()->body_set_axis_velocity(get_rid(), p_axis); + PhysicsServer2D::get_singleton()->body_set_axis_velocity(get_rid(), p_axis); linear_velocity = v; } } void RigidBody2D::set_linear_velocity(const Vector2 &p_velocity) { - linear_velocity = p_velocity; - if (state) + if (state) { state->set_linear_velocity(linear_velocity); - else { - - Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_LINEAR_VELOCITY, linear_velocity); + } 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 - Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_ANGULAR_VELOCITY, angular_velocity); + } 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; - Physics2DServer::get_singleton()->body_set_omit_force_integration(get_rid(), 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; - Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_SLEEPING, 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; - Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_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; - Physics2DServer::get_singleton()->body_set_max_contacts_reported(get_rid(), 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; } void RigidBody2D::apply_central_impulse(const Vector2 &p_impulse) { - Physics2DServer::get_singleton()->body_apply_central_impulse(get_rid(), 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) { - - Physics2DServer::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) { - Physics2DServer::get_singleton()->body_apply_torque_impulse(get_rid(), p_torque); + PhysicsServer2D::get_singleton()->body_apply_torque_impulse(get_rid(), p_torque); } void RigidBody2D::set_applied_force(const Vector2 &p_force) { - - Physics2DServer::get_singleton()->body_set_applied_force(get_rid(), p_force); + PhysicsServer2D::get_singleton()->body_set_applied_force(get_rid(), p_force); }; Vector2 RigidBody2D::get_applied_force() const { - - return Physics2DServer::get_singleton()->body_get_applied_force(get_rid()); + return PhysicsServer2D::get_singleton()->body_get_applied_force(get_rid()); }; void RigidBody2D::set_applied_torque(const float p_torque) { - - Physics2DServer::get_singleton()->body_set_applied_torque(get_rid(), p_torque); + PhysicsServer2D::get_singleton()->body_set_applied_torque(get_rid(), p_torque); }; float RigidBody2D::get_applied_torque() const { - - return Physics2DServer::get_singleton()->body_get_applied_torque(get_rid()); + return PhysicsServer2D::get_singleton()->body_get_applied_torque(get_rid()); }; void RigidBody2D::add_central_force(const Vector2 &p_force) { - Physics2DServer::get_singleton()->body_add_central_force(get_rid(), 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) { - - Physics2DServer::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) { - Physics2DServer::get_singleton()->body_add_torque(get_rid(), p_torque); + PhysicsServer2D::get_singleton()->body_add_torque(get_rid(), p_torque); } void RigidBody2D::set_continuous_collision_detection_mode(CCDMode p_mode) { - ccd_mode = p_mode; - Physics2DServer::get_singleton()->body_set_continuous_collision_detection_mode(get_rid(), Physics2DServer::CCDMode(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; } -Array RigidBody2D::get_colliding_bodies() const { - +TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const { ERR_FAIL_COND_V(!contact_monitor, Array()); - Array ret; + TypedArray<Node2D> ret; ret.resize(contact_monitor->body_map.size()); int idx = 0; for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { @@ -885,43 +695,37 @@ Array 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); if (node) { - - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); + 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)); } } memdelete(contact_monitor); - contact_monitor = NULL; + contact_monitor = nullptr; } else { - contact_monitor = memnew(ContactMonitor); contact_monitor->locked = false; } } bool RigidBody2D::is_contact_monitor_enabled() const { - - return contact_monitor != NULL; + 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()) { @@ -939,7 +743,6 @@ void RigidBody2D::_notification(int p_what) { } String RigidBody2D::get_configuration_warning() const { - Transform2D t = get_transform(); String warning = CollisionObject2D::get_configuration_warning(); @@ -955,7 +758,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); @@ -968,19 +770,9 @@ void RigidBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_weight", "weight"), &RigidBody2D::set_weight); ClassDB::bind_method(D_METHOD("get_weight"), &RigidBody2D::get_weight); -#ifndef DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_friction", "friction"), &RigidBody2D::set_friction); - ClassDB::bind_method(D_METHOD("get_friction"), &RigidBody2D::get_friction); - - ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &RigidBody2D::set_bounce); - ClassDB::bind_method(D_METHOD("get_bounce"), &RigidBody2D::get_bounce); -#endif // DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidBody2D::set_physics_material_override); ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidBody2D::get_physics_material_override); - ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &RigidBody2D::_reload_physics_characteristics); - ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &RigidBody2D::set_gravity_scale); ClassDB::bind_method(D_METHOD("get_gravity_scale"), &RigidBody2D::get_gravity_scale); @@ -1009,8 +801,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); @@ -1020,7 +812,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); @@ -1032,23 +824,17 @@ void RigidBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("test_motion", "motion", "infinite_inertia", "margin", "result"), &RigidBody2D::_test_motion, DEFVAL(true), DEFVAL(0.08), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("_direct_state_changed"), &RigidBody2D::_direct_state_changed); - ClassDB::bind_method(D_METHOD("_body_enter_tree"), &RigidBody2D::_body_enter_tree); - ClassDB::bind_method(D_METHOD("_body_exit_tree"), &RigidBody2D::_body_exit_tree); ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody2D::get_colliding_bodies); - BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "Physics2DDirectBodyState"))); + BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState2D"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "inertia", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", 0), "set_inertia", "get_inertia"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight"); -#ifndef DISABLE_DEPRECATED - ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); -#endif // DISABLE_DEPRECATED + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inertia", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", 0), "set_inertia", "get_inertia"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator"); ADD_PROPERTY(PropertyInfo(Variant::INT, "continuous_cd", PROPERTY_HINT_ENUM, "Disabled,Cast Ray,Cast Shape"), "set_continuous_collision_detection_mode", "get_continuous_collision_detection_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "contacts_reported", PROPERTY_HINT_RANGE, "0,64,1,or_greater"), "set_max_contacts_reported", "get_max_contacts_reported"); @@ -1057,13 +843,13 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); ADD_GROUP("Linear", "linear_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); ADD_GROUP("Angular", "angular_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_GROUP("Applied Forces", "applied_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "applied_torque"), "set_applied_torque", "get_applied_torque"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "applied_torque"), "set_applied_torque", "get_applied_torque"); ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); @@ -1082,8 +868,7 @@ void RigidBody2D::_bind_methods() { } RigidBody2D::RigidBody2D() : - PhysicsBody2D(Physics2DServer::BODY_MODE_RIGID) { - + PhysicsBody2D(PhysicsServer2D::BODY_MODE_RIGID) { mode = MODE_RIGID; mass = 1; @@ -1093,39 +878,38 @@ RigidBody2D::RigidBody2D() : angular_damp = -1; max_contacts_reported = 0; - state = NULL; + state = nullptr; angular_velocity = 0; sleeping = false; ccd_mode = CCD_MODE_DISABLED; custom_integrator = false; - contact_monitor = NULL; + contact_monitor = nullptr; can_sleep = true; - Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); + PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } RigidBody2D::~RigidBody2D() { - - if (contact_monitor) + if (contact_monitor) { memdelete(contact_monitor); + } } void RigidBody2D::_reload_physics_characteristics() { if (physics_material_override.is_null()) { - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_BOUNCE, 0); - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_FRICTION, 1); + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_BOUNCE, 0); + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_FRICTION, 1); } else { - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_BOUNCE, physics_material_override->computed_bounce()); - Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_FRICTION, physics_material_override->computed_friction()); + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_BOUNCE, physics_material_override->computed_bounce()); + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_FRICTION, physics_material_override->computed_friction()); } } ////////////////////////// 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)) { @@ -1143,13 +927,12 @@ Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p } bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) { - - Physics2DServer::SeparationResult sep_res[8]; //max 8 rays + PhysicsServer2D::SeparationResult sep_res[8]; //max 8 rays Transform2D gt = get_global_transform(); Vector2 recover; - int hits = Physics2DServer::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin); + int hits = PhysicsServer2D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin); int deepest = -1; float deepest_depth; for (int i = 0; i < hits; i++) { @@ -1180,13 +963,12 @@ 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."); } Transform2D gt = get_global_transform(); - Physics2DServer::MotionResult result; - bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result, p_exclude_raycast_shapes); + PhysicsServer2D::MotionResult result; + bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result, p_exclude_raycast_shapes); if (colliding) { r_collision.collider_metadata = result.collider_metadata; @@ -1213,14 +995,14 @@ 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()) { //this approach makes sure there is less delay between the actual body velocity and the one we saved - Physics2DDirectBodyState *bs = Physics2DServer::get_singleton()->body_get_direct_state(on_floor_body); + PhysicsDirectBodyState2D *bs = PhysicsServer2D::get_singleton()->body_get_direct_state(on_floor_body); if (bs) { current_floor_velocity = bs->get_linear_velocity(); } @@ -1238,7 +1020,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; @@ -1263,11 +1044,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; @@ -1275,14 +1056,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; @@ -1294,8 +1075,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; } @@ -1304,10 +1086,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; } @@ -1317,8 +1099,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; @@ -1326,7 +1108,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 { @@ -1344,47 +1126,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 Physics2DServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, margin); + 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(); } @@ -1394,7 +1169,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); @@ -1410,21 +1184,21 @@ 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) { - Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); + PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); set_only_update_transform_changes(true); set_notify_local_transform(true); } else { - Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, ""); + PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), nullptr, ""); set_only_update_transform_changes(false); set_notify_local_transform(false); } @@ -1435,11 +1209,11 @@ 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; + } - Physics2DDirectBodyState *state = Object::cast_to<Physics2DDirectBodyState>(p_state); + PhysicsDirectBodyState2D *state = Object::cast_to<PhysicsDirectBodyState2D>(p_state); last_valid_transform = state->get_transform(); set_notify_local_transform(false); @@ -1463,15 +1237,15 @@ void KinematicBody2D::_notification(int p_what) { if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) { //used by sync to physics, send the new transform to the physics Transform2D new_transform = get_global_transform(); - Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_TRANSFORM, new_transform); + PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_TRANSFORM, new_transform); //but then revert changes set_notify_local_transform(false); set_global_transform(last_valid_transform); 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)); @@ -1495,13 +1269,12 @@ void KinematicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody2D::_direct_state_changed); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "motion/sync_to_physics"), "set_sync_to_physics", "is_sync_to_physics_enabled"); } KinematicBody2D::KinematicBody2D() : - PhysicsBody2D(Physics2DServer::BODY_MODE_KINEMATIC) { - + PhysicsBody2D(PhysicsServer2D::BODY_MODE_KINEMATIC) { margin = 0.08; on_floor = false; @@ -1509,14 +1282,15 @@ KinematicBody2D::KinematicBody2D() : on_wall = false; sync_to_physics = false; } + KinematicBody2D::~KinematicBody2D() { if (motion_cache.is_valid()) { - motion_cache->owner = NULL; + motion_cache->owner = nullptr; } for (int i = 0; i < slide_colliders.size(); i++) { if (slide_colliders[i].is_valid()) { - slide_colliders.write[i]->owner = NULL; + slide_colliders.write[i]->owner = nullptr; } } } @@ -1524,38 +1298,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 NULL; + 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) { + if (collision.collider.is_valid()) { return ObjectDB::get_instance(collision.collider); } - return NULL; + 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); @@ -1565,23 +1343,22 @@ Object *KinematicCollision2D::get_collider_shape() const { } } - return NULL; + 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); @@ -1608,8 +1385,7 @@ void KinematicCollision2D::_bind_methods() { } KinematicCollision2D::KinematicCollision2D() { - collision.collider = 0; collision.collider_shape = 0; collision.local_shape = 0; - owner = NULL; + owner = nullptr; } diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 6766bafde3..e83ab6557d 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -34,12 +34,11 @@ #include "core/vset.h" #include "scene/2d/collision_object_2d.h" #include "scene/resources/physics_material.h" -#include "servers/physics_2d_server.h" +#include "servers/physics_server_2d.h" class KinematicCollision2D; class PhysicsBody2D : public CollisionObject2D { - GDCLASS(PhysicsBody2D, CollisionObject2D); uint32_t collision_layer; @@ -50,7 +49,7 @@ class PhysicsBody2D : public CollisionObject2D { protected: void _notification(int p_what); - PhysicsBody2D(Physics2DServer::BodyMode p_mode); + PhysicsBody2D(PhysicsServer2D::BodyMode p_mode); static void _bind_methods(); @@ -67,7 +66,7 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray<PhysicsBody2D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -75,7 +74,6 @@ public: }; class StaticBody2D : public PhysicsBody2D { - GDCLASS(StaticBody2D, PhysicsBody2D); Vector2 constant_linear_velocity; @@ -87,13 +85,6 @@ protected: static void _bind_methods(); public: -#ifndef DISABLE_DEPRECATED - void set_friction(real_t p_friction); - real_t get_friction() const; - - void set_bounce(real_t p_bounce); - real_t get_bounce() const; -#endif void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override); Ref<PhysicsMaterial> get_physics_material_override() const; @@ -111,7 +102,6 @@ private: }; class RigidBody2D : public PhysicsBody2D { - GDCLASS(RigidBody2D, PhysicsBody2D); public: @@ -130,7 +120,7 @@ public: private: bool can_sleep; - Physics2DDirectBodyState *state; + PhysicsDirectBodyState2D *state; Mode mode; real_t mass; @@ -150,13 +140,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; } @@ -168,19 +158,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; }; @@ -192,7 +179,7 @@ private: void _body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape); void _direct_state_changed(Object *p_state); - bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, float p_margin = 0.08, const Ref<Physics2DTestMotionResult> &p_result = Ref<Physics2DTestMotionResult>()); + bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, float p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>()); protected: void _notification(int p_what); @@ -211,14 +198,6 @@ public: void set_weight(real_t p_weight); real_t get_weight() const; -#ifndef DISABLE_DEPRECATED - void set_friction(real_t p_friction); - real_t get_friction() const; - - void set_bounce(real_t p_bounce); - real_t get_bounce() const; -#endif - void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override); Ref<PhysicsMaterial> get_physics_material_override() const; @@ -258,7 +237,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); @@ -268,12 +247,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); - Array get_colliding_bodies() const; //function for script + TypedArray<Node2D> get_colliding_bodies() const; //function for script - virtual String get_configuration_warning() const; + virtual String get_configuration_warning() const override; RigidBody2D(); ~RigidBody2D(); @@ -286,7 +265,6 @@ VARIANT_ENUM_CAST(RigidBody2D::Mode); VARIANT_ENUM_CAST(RigidBody2D::CCDMode); class KinematicBody2D : public PhysicsBody2D { - GDCLASS(KinematicBody2D, PhysicsBody2D); public: @@ -315,10 +293,10 @@ private: bool sync_to_physics; Vector<Collision> colliders; - Vector<Ref<KinematicCollision2D> > slide_colliders; + Vector<Ref<KinematicCollision2D>> slide_colliders; Ref<KinematicCollision2D> motion_cache; - _FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const; + _FORCE_INLINE_ bool _ignores_mode(PhysicsServer2D::BodyMode) const; Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false); Ref<KinematicCollision2D> _get_slide_collision(int p_bounce); @@ -359,7 +337,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 a6da027e0a..13b62816a4 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 @@ -61,14 +61,15 @@ bool Polygon2D::_edit_use_pivot() const { Rect2 Polygon2D::_edit_get_rect() const { if (rect_cache_dirty) { int l = polygon.size(); - PoolVector<Vector2>::Read r = polygon.read(); + const Vector2 *r = polygon.ptr(); 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,36 +95,34 @@ 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 = NULL; + Skeleton2D *skeleton_node = nullptr; if (has_node(skeleton)) { skeleton_node = Object::cast_to<Skeleton2D>(get_node(skeleton)); } - ObjectID new_skeleton_id = 0; + ObjectID new_skeleton_id; if (skeleton_node) { - VS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), skeleton_node->get_skeleton()); + RS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), skeleton_node->get_skeleton()); new_skeleton_id = skeleton_node->get_instance_id(); } else { - VS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), RID()); + RS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), RID()); } if (new_skeleton_id != current_skeleton_id) { Object *old_skeleton = ObjectDB::get_instance(current_skeleton_id); if (old_skeleton) { - old_skeleton->disconnect("bone_setup_changed", this, "_skeleton_bone_setup_changed"); + old_skeleton->disconnect("bone_setup_changed", callable_mp(this, &Polygon2D::_skeleton_bone_setup_changed)); } if (skeleton_node) { - skeleton_node->connect("bone_setup_changed", this, "_skeleton_bone_setup_changed"); + skeleton_node->connect("bone_setup_changed", callable_mp(this, &Polygon2D::_skeleton_bone_setup_changed)); } current_skeleton_id = new_skeleton_id; @@ -147,25 +145,24 @@ void Polygon2D::_notification(int p_what) { points.resize(len); { - - PoolVector<Vector2>::Read polyr = polygon.read(); + const Vector2 *polyr = polygon.ptr(); for (int i = 0; i < len; i++) { points.write[i] = polyr[i] + offset; } } 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,8 +210,7 @@ void Polygon2D::_notification(int p_what) { uvs.resize(len); if (points.size() == uv.size()) { - - PoolVector<Vector2>::Read uvr = uv.read(); + const Vector2 *uvr = uv.ptr(); for (int i = 0; i < len; i++) { uvs.write[i] = texmat.xform(uvr[i]) / tex_size; @@ -257,10 +250,11 @@ void Polygon2D::_notification(int p_what) { } int bone_index = bone->get_index_in_skeleton(); - PoolVector<float>::Read r = bone_weights[i].weights.read(); + 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++) { @@ -296,7 +291,7 @@ void Polygon2D::_notification(int p_what) { Vector<Color> colors; if (vertex_colors.size() == points.size()) { colors.resize(len); - PoolVector<Color>::Read color_r = vertex_colors.read(); + const Color *color_r = vertex_colors.ptr(); for (int i = 0; i < len; i++) { colors.write[i] = color_r[i]; } @@ -304,23 +299,21 @@ void Polygon2D::_notification(int p_what) { colors.push_back(color); } - // Vector<int> indices = Geometry::triangulate_polygon(points); - // VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID()); - if (invert || polygons.size() == 0) { - Vector<int> indices = Geometry::triangulate_polygon(points); + Vector<int> indices = Geometry2D::triangulate_polygon(points); if (indices.size()) { - VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, RID(), antialiased); + 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)); } } else { //draw individual polygons Vector<int> total_indices; for (int i = 0; i < polygons.size(); i++) { - PoolVector<int> src_indices = polygons[i]; + Vector<int> src_indices = polygons[i]; int ic = src_indices.size(); - if (ic < 3) + if (ic < 3) { continue; - PoolVector<int>::Read r = src_indices.read(); + } + const int *r = src_indices.ptr(); Vector<Vector2> tmp_points; tmp_points.resize(ic); @@ -330,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(); @@ -344,7 +337,7 @@ void Polygon2D::_notification(int p_what) { } if (total_indices.size()) { - VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), total_indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, RID(), antialiased); + RS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), total_indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID()); } } @@ -352,19 +345,17 @@ void Polygon2D::_notification(int p_what) { } } -void Polygon2D::set_polygon(const PoolVector<Vector2> &p_polygon) { +void Polygon2D::set_polygon(const Vector<Vector2> &p_polygon) { polygon = p_polygon; rect_cache_dirty = true; update(); } -PoolVector<Vector2> Polygon2D::get_polygon() const { - +Vector<Vector2> Polygon2D::get_polygon() const { return polygon; } void Polygon2D::set_internal_vertex_count(int p_count) { - internal_vertices = p_count; } @@ -372,50 +363,43 @@ int Polygon2D::get_internal_vertex_count() const { return internal_vertices; } -void Polygon2D::set_uv(const PoolVector<Vector2> &p_uv) { - +void Polygon2D::set_uv(const Vector<Vector2> &p_uv) { uv = p_uv; update(); } -PoolVector<Vector2> Polygon2D::get_uv() const { - +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 PoolVector<Color> &p_colors) { - +void Polygon2D::set_vertex_colors(const Vector<Color> &p_colors) { vertex_colors = p_colors; update(); } -PoolVector<Color> Polygon2D::get_vertex_colors() const { +Vector<Color> Polygon2D::get_vertex_colors() const { return vertex_colors; } -void Polygon2D::set_texture(const Ref<Texture> &p_texture) { - +void Polygon2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; /*if (texture.is_valid()) { @@ -428,82 +412,110 @@ void Polygon2D::set_texture(const Ref<Texture> &p_texture) { }*/ update(); } -Ref<Texture> Polygon2D::get_texture() const { +Ref<Texture2D> Polygon2D::get_texture() const { return texture; } -void Polygon2D::set_texture_offset(const Vector2 &p_offset) { +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(); @@ -511,31 +523,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 PoolVector<float> &p_weights) { - +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; } -PoolVector<float> Polygon2D::get_bone_weights(int p_index) const { - ERR_FAIL_INDEX_V(p_index, bone_weights.size(), PoolVector<float>()); +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); } @@ -544,11 +556,12 @@ void Polygon2D::clear_bones() { bone_weights.clear(); } -void Polygon2D::set_bone_weights(int p_index, const PoolVector<float> &p_weights) { +void Polygon2D::set_bone_weights(int p_index, const Vector<float> &p_weights) { ERR_FAIL_INDEX(p_index, bone_weights.size()); 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; @@ -563,8 +576,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) { @@ -573,8 +586,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(); } @@ -584,7 +598,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); @@ -603,6 +616,18 @@ 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); @@ -645,37 +670,39 @@ void Polygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_bones", "bones"), &Polygon2D::_set_bones); ClassDB::bind_method(D_METHOD("_get_bones"), &Polygon2D::_get_bones); - ClassDB::bind_method(D_METHOD("_skeleton_bone_setup_changed"), &Polygon2D::_skeleton_bone_setup_changed); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "get_antialiased"); - ADD_GROUP("Texture", ""); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_GROUP("Texture", "texture_"); + ADD_GROUP("Texture2D", ""); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_GROUP("Texture2D", "texture_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_offset"), "set_texture_offset", "get_texture_offset"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_scale"), "set_texture_scale", "get_texture_scale"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "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::REAL, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation"); + 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"); ADD_GROUP("Invert", "invert_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert_enable"), "set_invert", "get_invert"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "invert_border", PROPERTY_HINT_RANGE, "0.1,16384,0.1"), "set_invert_border", "get_invert_border"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "invert_border", PROPERTY_HINT_RANGE, "0.1,16384,0.1"), "set_invert_border", "get_invert_border"); ADD_GROUP("Data", ""); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons"), "set_polygons", "get_polygons"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_bones", "_get_bones"); ADD_PROPERTY(PropertyInfo(Variant::INT, "internal_vertex_count", PROPERTY_HINT_RANGE, "0,1000"), "set_internal_vertex_count", "get_internal_vertex_count"); } Polygon2D::Polygon2D() { - - invert = 0; + invert = false; invert_border = 100; antialiased = false; tex_rot = 0; @@ -684,5 +711,7 @@ Polygon2D::Polygon2D() { color = Color(1, 1, 1); rect_cache_dirty = true; internal_vertices = 0; - current_skeleton_id = 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 07b8828532..c5ff05aace 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -34,24 +34,28 @@ #include "scene/2d/node_2d.h" class Polygon2D : public Node2D { - GDCLASS(Polygon2D, Node2D); - PoolVector<Vector2> polygon; - PoolVector<Vector2> uv; - PoolVector<Color> vertex_colors; + Vector<Vector2> polygon; + Vector<Vector2> uv; + Vector<Color> vertex_colors; Array polygons; int internal_vertices; struct Bone { NodePath path; - PoolVector<float> weights; + Vector<float> weights; }; Vector<Bone> bone_weights; Color color; - Ref<Texture> texture; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; + Ref<Texture2D> specular_map; + Color specular_color; + float shininess; + Size2 tex_scale; Vector2 tex_ofs; bool tex_tile; @@ -78,26 +82,26 @@ 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 PoolVector<Vector2> &p_polygon); - PoolVector<Vector2> get_polygon() const; + void set_polygon(const Vector<Vector2> &p_polygon); + Vector<Vector2> get_polygon() const; void set_internal_vertex_count(int p_count); int get_internal_vertex_count() const; - void set_uv(const PoolVector<Vector2> &p_uv); - PoolVector<Vector2> get_uv() const; + void set_uv(const Vector<Vector2> &p_uv); + Vector<Vector2> get_uv() const; void set_polygons(const Array &p_polygons); Array get_polygons() const; @@ -105,11 +109,23 @@ public: void set_color(const Color &p_color); Color get_color() const; - void set_vertex_colors(const PoolVector<Color> &p_colors); - PoolVector<Color> get_vertex_colors() const; + void set_vertex_colors(const Vector<Color> &p_colors); + Vector<Color> get_vertex_colors() const; + + 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_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_shininess(float p_shininess); + float get_shininess() const; void set_texture_offset(const Vector2 &p_offset); Vector2 get_texture_offset() const; @@ -135,13 +151,13 @@ public: void set_offset(const Vector2 &p_offset); Vector2 get_offset() const; - void add_bone(const NodePath &p_path = NodePath(), const PoolVector<float> &p_weights = PoolVector<float>()); + void add_bone(const NodePath &p_path = NodePath(), const Vector<float> &p_weights = Vector<float>()); int get_bone_count() const; NodePath get_bone_path(int p_index) const; - PoolVector<float> get_bone_weights(int p_index) const; + Vector<float> get_bone_weights(int p_index) const; void erase_bone(int p_idx); void clear_bones(); - void set_bone_weights(int p_index, const PoolVector<float> &p_weights); + void set_bone_weights(int p_index, const Vector<float> &p_weights); void set_bone_path(int p_index, const NodePath &p_path); void set_skeleton(const NodePath &p_skeleton); diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index cdeb905c0c..a94a9f7085 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -36,7 +36,6 @@ 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,11 +89,10 @@ 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); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gizmo_extents", PROPERTY_HINT_RANGE, "0,1000,0.1,or_greater", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_gizmo_extents", "_get_gizmo_extents"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gizmo_extents", PROPERTY_HINT_RANGE, "0,1000,0.1,or_greater", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_gizmo_extents", "_get_gizmo_extents"); } Position2D::Position2D() { 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 5098d5115a..a00db36077 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -33,140 +33,135 @@ #include "collision_object_2d.h" #include "core/engine.h" #include "physics_body_2d.h" -#include "servers/physics_2d_server.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 == 0) - return 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, true); + 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(); @@ -205,19 +201,19 @@ void RayCast2D::_update_raycast_state() { Ref<World2D> w2d = get_world_2d(); ERR_FAIL_COND(w2d.is_null()); - Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(w2d->get_space()); + PhysicsDirectSpaceState2D *dss = PhysicsServer2D::get_singleton()->space_get_direct_state(w2d->get_space()); ERR_FAIL_COND(!dss); Transform2D gt = get_global_transform(); - Vector2 to = cast_to; - if (to == Vector2()) + Vector2 to = target_position; + if (to == Vector2()) { to = Vector2(0, 0.01); + } - Physics2DDirectSpaceState::RayResult rr; + 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; @@ -225,7 +221,7 @@ void RayCast2D::_update_raycast_state() { against_shape = rr.shape; } else { collided = false; - against = 0; + against = ObjectID(); against_shape = 0; } } @@ -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; - against = 0; + 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 53072f942d..3104436dbe 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -32,8 +32,7 @@ #include "scene/scene_string_names.h" void RemoteTransform2D::_update_cache() { - - cache = 0; + cache = ObjectID(); if (has_node(remote_node)) { Node *node = get_node(remote_node); if (!node || this == node || node->is_a_parent_of(this) || this->is_a_parent_of(node)) { @@ -45,23 +44,25 @@ void RemoteTransform2D::_update_cache() { } void RemoteTransform2D::_update_remote() { - - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } - if (!cache) + 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) { - + 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,7 +186,6 @@ void RemoteTransform2D::force_update_cache() { } String RemoteTransform2D::get_configuration_warning() const { - 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."); } @@ -194,7 +194,6 @@ String RemoteTransform2D::get_configuration_warning() const { } 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,12 +218,10 @@ void RemoteTransform2D::_bind_methods() { } RemoteTransform2D::RemoteTransform2D() { - use_global_coordinates = true; update_remote_position = true; update_remote_rotation = true; update_remote_scale = true; - cache = 0; set_notify_transform(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 6f64464cc9..ea37c8dfe7 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 = NULL; + 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(); } @@ -73,13 +74,13 @@ void Bone2D::_notification(int p_what) { } } skeleton->_make_bone_setup_dirty(); - skeleton = NULL; + skeleton = nullptr; } - parent_bone = NULL; + 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); @@ -90,13 +91,14 @@ void Bone2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_default_length"), &Bone2D::get_default_length); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "rest"), "set_rest", "get_rest"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "default_length", PROPERTY_HINT_RANGE, "1,1024,1"), "set_default_length", "get_default_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "default_length", PROPERTY_HINT_RANGE, "1,1024,1"), "set_default_length", "get_default_length"); } 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,8 +132,8 @@ 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()) { @@ -157,8 +157,8 @@ String Bone2D::get_configuration_warning() const { } Bone2D::Bone2D() { - skeleton = NULL; - parent_bone = NULL; + skeleton = nullptr; + parent_bone = nullptr; skeleton_index = -1; default_length = 16; set_notify_local_transform(true); @@ -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,12 +181,12 @@ void Skeleton2D::_make_bone_setup_dirty() { } void Skeleton2D::_update_bone_setup() { - - if (!bone_setup_dirty) + if (!bone_setup_dirty) { return; + } bone_setup_dirty = false; - VS::get_singleton()->skeleton_allocate(skeleton, bones.size(), true); + RS::get_singleton()->skeleton_allocate(skeleton, bones.size(), true); bones.sort(); //sorty so they are always in the same order/index @@ -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; - VS::get_singleton()->skeleton_bone_set_transform_2d(skeleton, i, final_xform); + 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,35 +253,34 @@ int Skeleton2D::get_bone_count() const { } Bone2D *Skeleton2D::get_bone(int p_idx) { - - ERR_FAIL_COND_V(!is_inside_tree(), NULL); - ERR_FAIL_INDEX_V(p_idx, bones.size(), NULL); + ERR_FAIL_COND_V(!is_inside_tree(), nullptr); + ERR_FAIL_INDEX_V(p_idx, bones.size(), nullptr); return bones[p_idx].bone; } 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(); } if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { - VS::get_singleton()->skeleton_set_base_transform_2d(skeleton, get_global_transform()); + RS::get_singleton()->skeleton_set_base_transform_2d(skeleton, get_global_transform()); } } 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); @@ -300,11 +296,10 @@ Skeleton2D::Skeleton2D() { bone_setup_dirty = true; transform_dirty = true; - skeleton = VS::get_singleton()->skeleton_create(); + skeleton = RS::get_singleton()->skeleton_create(); set_notify_transform(true); } Skeleton2D::~Skeleton2D() { - - VS::get_singleton()->free(skeleton); + 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.cpp b/scene/2d/sprite_2d.cpp index 55daed0585..d1be93e55d 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* sprite.cpp */ +/* sprite_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,57 +28,56 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "sprite.h" +#include "sprite_2d.h" + #include "core/core_string_names.h" #include "core/os/os.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED -Dictionary Sprite::_edit_get_state() const { +Dictionary Sprite2D::_edit_get_state() const { Dictionary state = Node2D::_edit_get_state(); state["offset"] = offset; return state; } -void Sprite::_edit_set_state(const Dictionary &p_state) { +void Sprite2D::_edit_set_state(const Dictionary &p_state) { Node2D::_edit_set_state(p_state); set_offset(p_state["offset"]); } -void Sprite::_edit_set_pivot(const Point2 &p_pivot) { +void Sprite2D::_edit_set_pivot(const Point2 &p_pivot) { set_offset(get_offset() - p_pivot); set_position(get_transform().xform(p_pivot)); } -Point2 Sprite::_edit_get_pivot() const { +Point2 Sprite2D::_edit_get_pivot() const { return Vector2(); } -bool Sprite::_edit_use_pivot() const { +bool Sprite2D::_edit_use_pivot() const { return true; } -bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - +bool Sprite2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return is_pixel_opaque(p_point); } -Rect2 Sprite::_edit_get_rect() const { +Rect2 Sprite2D::_edit_get_rect() const { return get_rect(); } -bool Sprite::_edit_use_rect() const { +bool Sprite2D::_edit_use_rect() const { return texture.is_valid(); } #endif -Rect2 Sprite::get_anchorable_rect() const { +Rect2 Sprite2D::get_anchorable_rect() const { return get_rect(); } -void Sprite::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const { - +void Sprite2D::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const { Rect2 base_rect; if (region) { @@ -97,28 +96,29 @@ void Sprite::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_cli 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()) { 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 Sprite::_notification(int p_what) { - +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(); @@ -130,24 +130,26 @@ void Sprite::_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, 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); } break; } } -void Sprite::set_texture(const Ref<Texture> &p_texture) { - - if (p_texture == texture) +void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) { + if (p_texture == texture) { return; + } - if (texture.is_valid()) - texture->disconnect(CoreStringNames::get_singleton()->changed, this, "_texture_changed"); + if (texture.is_valid()) { + texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite2D::_texture_changed)); + } texture = p_texture; - if (texture.is_valid()) - texture->connect(CoreStringNames::get_singleton()->changed, this, "_texture_changed"); + if (texture.is_valid()) { + texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite2D::_texture_changed)); + } update(); emit_signal("texture_changed"); @@ -155,113 +157,131 @@ void Sprite::set_texture(const Ref<Texture> &p_texture) { _change_notify("texture"); } -void Sprite::set_normal_map(const Ref<Texture> &p_texture) { - +void Sprite2D::set_normal_map(const Ref<Texture2D> &p_texture) { normal_map = p_texture; update(); } -Ref<Texture> Sprite::get_normal_map() const { - +Ref<Texture2D> Sprite2D::get_normal_map() const { return normal_map; } -Ref<Texture> Sprite::get_texture() const { +void Sprite2D::set_specular_map(const Ref<Texture2D> &p_texture) { + specular = p_texture; + update(); +} - return texture; +Ref<Texture2D> Sprite2D::get_specular_map() const { + return specular; } -void Sprite::set_centered(bool p_center) { +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 Sprite::is_centered() const { - +bool Sprite2D::is_centered() const { return centered; } -void Sprite::set_offset(const Point2 &p_offset) { - +void Sprite2D::set_offset(const Point2 &p_offset) { offset = p_offset; update(); item_rect_changed(); _change_notify("offset"); } -Point2 Sprite::get_offset() const { +Point2 Sprite2D::get_offset() const { return offset; } -void Sprite::set_flip_h(bool p_flip) { - +void Sprite2D::set_flip_h(bool p_flip) { hflip = p_flip; update(); } -bool Sprite::is_flipped_h() const { +bool Sprite2D::is_flipped_h() const { return hflip; } -void Sprite::set_flip_v(bool p_flip) { - +void Sprite2D::set_flip_v(bool p_flip) { vflip = p_flip; update(); } -bool Sprite::is_flipped_v() const { +bool Sprite2D::is_flipped_v() const { return vflip; } -void Sprite::set_region(bool p_region) { - - if (p_region == region) +void Sprite2D::set_region(bool p_region) { + if (p_region == region) { return; + } region = p_region; update(); } -bool Sprite::is_region() const { - +bool Sprite2D::is_region() const { return region; } -void Sprite::set_region_rect(const Rect2 &p_region_rect) { - - if (region_rect == p_region_rect) +void Sprite2D::set_region_rect(const Rect2 &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 Sprite::get_region_rect() const { - +Rect2 Sprite2D::get_region_rect() const { return region_rect; } -void Sprite::set_region_filter_clip(bool p_enable) { +void Sprite2D::set_region_filter_clip(bool p_enable) { region_filter_clip = p_enable; update(); } -bool Sprite::is_region_filter_clip_enabled() const { +bool Sprite2D::is_region_filter_clip_enabled() const { return region_filter_clip; } -void Sprite::set_frame(int p_frame) { - +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; @@ -270,73 +290,76 @@ void Sprite::set_frame(int p_frame) { emit_signal(SceneStringNames::get_singleton()->frame_changed); } -int Sprite::get_frame() const { - +int Sprite2D::get_frame() const { return frame; } -void Sprite::set_frame_coords(const Vector2 &p_coord) { +void Sprite2D::set_frame_coords(const Vector2 &p_coord) { ERR_FAIL_INDEX(int(p_coord.x), hframes); ERR_FAIL_INDEX(int(p_coord.y), vframes); set_frame(int(p_coord.y) * hframes + int(p_coord.x)); } -Vector2 Sprite::get_frame_coords() const { +Vector2 Sprite2D::get_frame_coords() const { return Vector2(frame % hframes, frame / hframes); } -void Sprite::set_vframes(int p_amount) { - +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 Sprite::get_vframes() const { +int Sprite2D::get_vframes() const { return vframes; } -void Sprite::set_hframes(int p_amount) { - +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 Sprite::get_hframes() const { +int Sprite2D::get_hframes() const { return hframes; } -bool Sprite::is_pixel_opaque(const Point2 &p_point) const { - - if (texture.is_null()) +bool Sprite2D::is_pixel_opaque(const Point2 &p_point) const { + 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; - - bool is_repeat = texture->get_flags() & Texture::FLAG_REPEAT; - bool is_mirrored_repeat = texture->get_flags() & Texture::FLAG_MIRRORED_REPEAT; +#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) +#endif + bool is_repeat = false; + bool is_mirrored_repeat = false; if (is_repeat) { int mirror_x = 0; int mirror_y = 0; @@ -360,10 +383,10 @@ bool Sprite::is_pixel_opaque(const Point2 &p_point) const { return texture->is_pixel_opaque((int)q.x, (int)q.y); } -Rect2 Sprite::get_rect() const { - - if (texture.is_null()) +Rect2 Sprite2D::get_rect() const { + if (texture.is_null()) { return Rect2(0, 0, 1, 1); + } Size2i s; @@ -376,17 +399,18 @@ Rect2 Sprite::get_rect() const { s = s / Point2(hframes, vframes); 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 Sprite::_validate_property(PropertyInfo &property) const { - +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"; @@ -398,8 +422,7 @@ void Sprite::_validate_property(PropertyInfo &property) const { } } -void Sprite::_texture_changed() { - +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()) { @@ -407,66 +430,76 @@ void Sprite::_texture_changed() { } } -void Sprite::_bind_methods() { +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_texture", "texture"), &Sprite::set_texture); - ClassDB::bind_method(D_METHOD("get_texture"), &Sprite::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_normal_map", "normal_map"), &Sprite::set_normal_map); - ClassDB::bind_method(D_METHOD("get_normal_map"), &Sprite::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_centered", "centered"), &Sprite::set_centered); - ClassDB::bind_method(D_METHOD("is_centered"), &Sprite::is_centered); + 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_offset", "offset"), &Sprite::set_offset); - ClassDB::bind_method(D_METHOD("get_offset"), &Sprite::get_offset); + 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_flip_h", "flip_h"), &Sprite::set_flip_h); - ClassDB::bind_method(D_METHOD("is_flipped_h"), &Sprite::is_flipped_h); + ClassDB::bind_method(D_METHOD("set_centered", "centered"), &Sprite2D::set_centered); + ClassDB::bind_method(D_METHOD("is_centered"), &Sprite2D::is_centered); - ClassDB::bind_method(D_METHOD("set_flip_v", "flip_v"), &Sprite::set_flip_v); - ClassDB::bind_method(D_METHOD("is_flipped_v"), &Sprite::is_flipped_v); + ClassDB::bind_method(D_METHOD("set_offset", "offset"), &Sprite2D::set_offset); + ClassDB::bind_method(D_METHOD("get_offset"), &Sprite2D::get_offset); - ClassDB::bind_method(D_METHOD("set_region", "enabled"), &Sprite::set_region); - ClassDB::bind_method(D_METHOD("is_region"), &Sprite::is_region); + ClassDB::bind_method(D_METHOD("set_flip_h", "flip_h"), &Sprite2D::set_flip_h); + ClassDB::bind_method(D_METHOD("is_flipped_h"), &Sprite2D::is_flipped_h); - ClassDB::bind_method(D_METHOD("is_pixel_opaque", "pos"), &Sprite::is_pixel_opaque); + ClassDB::bind_method(D_METHOD("set_flip_v", "flip_v"), &Sprite2D::set_flip_v); + ClassDB::bind_method(D_METHOD("is_flipped_v"), &Sprite2D::is_flipped_v); - ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &Sprite::set_region_rect); - ClassDB::bind_method(D_METHOD("get_region_rect"), &Sprite::get_region_rect); + ClassDB::bind_method(D_METHOD("set_region", "enabled"), &Sprite2D::set_region); + ClassDB::bind_method(D_METHOD("is_region"), &Sprite2D::is_region); - ClassDB::bind_method(D_METHOD("set_region_filter_clip", "enabled"), &Sprite::set_region_filter_clip); - ClassDB::bind_method(D_METHOD("is_region_filter_clip_enabled"), &Sprite::is_region_filter_clip_enabled); + ClassDB::bind_method(D_METHOD("is_pixel_opaque", "pos"), &Sprite2D::is_pixel_opaque); - ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite::set_frame); - ClassDB::bind_method(D_METHOD("get_frame"), &Sprite::get_frame); + ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &Sprite2D::set_region_rect); + ClassDB::bind_method(D_METHOD("get_region_rect"), &Sprite2D::get_region_rect); - ClassDB::bind_method(D_METHOD("set_frame_coords", "coords"), &Sprite::set_frame_coords); - ClassDB::bind_method(D_METHOD("get_frame_coords"), &Sprite::get_frame_coords); + ClassDB::bind_method(D_METHOD("set_region_filter_clip", "enabled"), &Sprite2D::set_region_filter_clip); + ClassDB::bind_method(D_METHOD("is_region_filter_clip_enabled"), &Sprite2D::is_region_filter_clip_enabled); - ClassDB::bind_method(D_METHOD("set_vframes", "vframes"), &Sprite::set_vframes); - ClassDB::bind_method(D_METHOD("get_vframes"), &Sprite::get_vframes); + ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite2D::set_frame); + ClassDB::bind_method(D_METHOD("get_frame"), &Sprite2D::get_frame); - ClassDB::bind_method(D_METHOD("set_hframes", "hframes"), &Sprite::set_hframes); - ClassDB::bind_method(D_METHOD("get_hframes"), &Sprite::get_hframes); + ClassDB::bind_method(D_METHOD("set_frame_coords", "coords"), &Sprite2D::set_frame_coords); + ClassDB::bind_method(D_METHOD("get_frame_coords"), &Sprite2D::get_frame_coords); - ClassDB::bind_method(D_METHOD("get_rect"), &Sprite::get_rect); + ClassDB::bind_method(D_METHOD("set_vframes", "vframes"), &Sprite2D::set_vframes); + ClassDB::bind_method(D_METHOD("get_vframes"), &Sprite2D::get_vframes); - ClassDB::bind_method(D_METHOD("_texture_changed"), &Sprite::_texture_changed); + ClassDB::bind_method(D_METHOD("set_hframes", "hframes"), &Sprite2D::set_hframes); + ClassDB::bind_method(D_METHOD("get_hframes"), &Sprite2D::get_hframes); + + ClassDB::bind_method(D_METHOD("get_rect"), &Sprite2D::get_rect); ADD_SIGNAL(MethodInfo("frame_changed")); ADD_SIGNAL(MethodInfo("texture_changed")); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::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"); @@ -476,13 +509,14 @@ void Sprite::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_filter_clip"), "set_region_filter_clip", "is_region_filter_clip_enabled"); } -Sprite::Sprite() { - +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; @@ -490,5 +524,5 @@ Sprite::Sprite() { hframes = 1; } -Sprite::~Sprite() { +Sprite2D::~Sprite2D() { } diff --git a/scene/2d/sprite.h b/scene/2d/sprite_2d.h index d72bf3168d..f6b752575f 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* sprite.h */ +/* sprite_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SPRITE_H -#define SPRITE_H +#ifndef SPRITE_2D_H +#define SPRITE_2D_H #include "scene/2d/node_2d.h" #include "scene/resources/texture.h" -class Sprite : public Node2D { +class Sprite2D : public Node2D { + GDCLASS(Sprite2D, Node2D); - GDCLASS(Sprite, Node2D); - - Ref<Texture> texture; - Ref<Texture> normal_map; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; + Ref<Texture2D> specular; + Color specular_color; + float shininess; bool centered; Point2 offset; @@ -64,29 +66,38 @@ 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; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + 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_normal_map(const Ref<Texture> &p_texture); - Ref<Texture> get_normal_map() const; + void set_shininess(float p_shininess); + float get_shininess() const; void set_centered(bool p_center); bool is_centered() const; @@ -122,10 +133,10 @@ public: int get_hframes() const; Rect2 get_rect() const; - virtual Rect2 get_anchorable_rect() const; + virtual Rect2 get_anchorable_rect() const override; - Sprite(); - ~Sprite(); + Sprite2D(); + ~Sprite2D(); }; #endif // SPRITE_H diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index b6db025d44..c2951559a4 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -35,25 +35,22 @@ #include "core/method_bind_ext.gen.inc" #include "core/os/os.h" #include "scene/2d/area_2d.h" -#include "servers/physics_2d_server.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; @@ -78,15 +75,12 @@ 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()) { - - navigation->navpoly_remove(F->get().id); + NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID()); } q.navpoly_ids.clear(); } @@ -97,24 +91,22 @@ void TileMap::_notification(int p_what) { } for (Map<PosKey, Quadrant::Occluder>::Element *F = q.occluder_instances.front(); F; F = F->next()) { - VS::get_singleton()->free(F->get().id); + RS::get_singleton()->free(F->get().id); } q.occluder_instances.clear(); } - collision_parent = NULL; - navigation = NULL; + collision_parent = nullptr; + navigation = nullptr; } break; case NOTIFICATION_TRANSFORM_CHANGED: { - //move stuff _update_quadrant_transform(); } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - if (use_parent) { _recreate_quadrants(); } @@ -124,59 +116,56 @@ 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(); - Physics2DServer::get_singleton()->body_set_space(q.body, p_space); + PhysicsServer2D::get_singleton()->body_set_space(q.body, 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); if (!use_parent) { xform = global_transform * xform; - Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform); + PhysicsServer2D::get_singleton()->body_set_state(q.body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); } if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - - navigation->navpoly_set_transform(F->get().id, nav_rel * F->get().xform); + NavigationServer2D::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform); } } for (Map<PosKey, Quadrant::Occluder>::Element *F = q.occluder_instances.front(); F; F = F->next()) { - VS::get_singleton()->canvas_light_occluder_set_transform(F->get().id, global_transform * F->get().xform); + RS::get_singleton()->canvas_light_occluder_set_transform(F->get().id, global_transform * F->get().xform); } } } void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { - if (tile_set.is_valid()) { - tile_set->disconnect("changed", this, "_recreate_quadrants"); + tile_set->disconnect("changed", callable_mp(this, &TileMap::_recreate_quadrants)); tile_set->remove_change_receptor(this); } @@ -184,7 +173,7 @@ void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { tile_set = p_tileset; if (tile_set.is_valid()) { - tile_set->connect("changed", this, "_recreate_quadrants"); + tile_set->connect("changed", callable_mp(this, &TileMap::_recreate_quadrants)); tile_set->add_change_receptor(this); } else { clear(); @@ -195,12 +184,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(); @@ -210,12 +197,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(); @@ -225,17 +210,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) { @@ -297,7 +279,7 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const } void TileMap::_add_shape(int &shape_idx, const Quadrant &p_q, const Ref<Shape2D> &p_shape, const TileSet::ShapeData &p_shape_data, const Transform2D &p_xform, const Vector2 &p_metadata) { - Physics2DServer *ps = Physics2DServer::get_singleton(); + PhysicsServer2D *ps = PhysicsServer2D::get_singleton(); if (!use_parent) { ps->body_add_shape(p_q.body, p_shape->get_rid(), p_xform); @@ -313,7 +295,7 @@ void TileMap::_add_shape(int &shape_idx, const Quadrant &p_q, const Ref<Shape2D> int real_index = collision_parent->shape_owner_get_shape_index(p_q.shape_owner_id, shape_idx); RID rid = collision_parent->get_rid(); - if (Object::cast_to<Area2D>(collision_parent) != NULL) { + if (Object::cast_to<Area2D>(collision_parent) != nullptr) { ps->area_set_shape_transform(rid, real_index, get_transform() * xform); } else { ps->body_set_shape_transform(rid, real_index, get_transform() * xform); @@ -325,20 +307,21 @@ 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; } - VisualServer *vs = VisualServer::get_singleton(); - Physics2DServer *ps = Physics2DServer::get_singleton(); + RenderingServer *vs = RenderingServer::get_singleton(); + 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; @@ -357,11 +340,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()); } @@ -376,14 +357,13 @@ void TileMap::update_dirty_quadrants() { if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { - - navigation->navpoly_remove(E->get().id); + NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID()); } q.navpoly_ids.clear(); } for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) { - VS::get_singleton()->free(E->get().id); + RS::get_singleton()->free(E->get().id); } q.occluder_instances.clear(); Ref<ShaderMaterial> prev_material; @@ -392,20 +372,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<Texture> tex = tile_set->tile_get_texture(c.id); + } + 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); @@ -419,10 +400,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; @@ -431,14 +412,16 @@ 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); - vs->canvas_item_set_z_index(debug_canvas_item, VS::CANVAS_ITEM_Z_MAX - 1); + vs->canvas_item_set_z_index(debug_canvas_item, RS::CANVAS_ITEM_Z_MAX - 1); q.canvas_items.push_back(debug_canvas_item); prev_debug_canvas_item = debug_canvas_item; } @@ -462,10 +445,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(); @@ -475,11 +459,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; + } } } @@ -508,40 +494,42 @@ 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<Texture> normal_map = tile_set->tile_get_normal_map(c.id); + 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, @@ -549,7 +537,7 @@ void TileMap::update_dirty_quadrants() { if (r == Rect2()) { tex->draw_rect(canvas_item, rect, false, modulate, c.transpose, normal_map); } else { - tex->draw_rect_region(canvas_item, rect, r, modulate, c.transpose, normal_map, clip_uv); + 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); } Vector<TileSet::ShapeData> shapes = tile_set->tile_get_shapes(c.id); @@ -611,10 +599,13 @@ void TileMap::update_dirty_quadrants() { xform.set_origin(offset.floor() + q.pos); _fix_cell_transform(xform, c, npoly_ofs, s); - int pid = navigation->navpoly_add(navpoly, nav_rel * xform); + RID region = NavigationServer2D::get_singleton()->region_create(); + NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid()); + NavigationServer2D::get_singleton()->region_set_transform(region, nav_rel * xform); + NavigationServer2D::get_singleton()->region_set_navpoly(region, navpoly); Quadrant::NavPoly np; - np.id = pid; + np.region = region; np.xform = xform; q.navpoly_ids[E->key()] = np; @@ -622,10 +613,10 @@ void TileMap::update_dirty_quadrants() { RID debug_navigation_item = vs->canvas_item_create(); vs->canvas_item_set_parent(debug_navigation_item, canvas_item); vs->canvas_item_set_z_as_relative_to_parent(debug_navigation_item, false); - vs->canvas_item_set_z_index(debug_navigation_item, VS::CANVAS_ITEM_Z_MAX - 2); // Display one below collision debug + vs->canvas_item_set_z_index(debug_navigation_item, RS::CANVAS_ITEM_Z_MAX - 2); // Display one below collision debug if (debug_navigation_item.is_valid()) { - PoolVector<Vector2> navigation_polygon_vertices = navpoly->get_vertices(); + Vector<Vector2> navigation_polygon_vertices = navpoly->get_vertices(); int vsize = navigation_polygon_vertices.size(); if (vsize > 2) { @@ -634,7 +625,7 @@ void TileMap::update_dirty_quadrants() { vertices.resize(vsize); colors.resize(vsize); { - PoolVector<Vector2>::Read vr = navigation_polygon_vertices.read(); + const Vector2 *vr = navigation_polygon_vertices.ptr(); for (int j = 0; j < vsize; j++) { vertices.write[j] = vr[j]; colors.write[j] = debug_navigation_color; @@ -647,10 +638,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); @@ -681,11 +670,11 @@ void TileMap::update_dirty_quadrants() { xform.set_origin(offset.floor() + q.pos); _fix_cell_transform(xform, c, occluder_ofs, s); - RID orid = VS::get_singleton()->canvas_light_occluder_create(); - VS::get_singleton()->canvas_light_occluder_set_transform(orid, get_global_transform() * xform); - VS::get_singleton()->canvas_light_occluder_set_polygon(orid, occluder->get_rid()); - VS::get_singleton()->canvas_light_occluder_attach_to_canvas(orid, get_canvas()); - VS::get_singleton()->canvas_light_occluder_set_light_mask(orid, occluder_light_mask); + RID orid = RS::get_singleton()->canvas_light_occluder_create(); + RS::get_singleton()->canvas_light_occluder_set_transform(orid, get_global_transform() * xform); + RS::get_singleton()->canvas_light_occluder_set_polygon(orid, occluder->get_rid()); + RS::get_singleton()->canvas_light_occluder_attach_to_canvas(orid, get_canvas()); + RS::get_singleton()->canvas_light_occluder_set_light_mask(orid, occluder_light_mask); Quadrant::Occluder oc; oc.xform = xform; oc.id = orid; @@ -700,14 +689,11 @@ 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()) { - - VS::get_singleton()->canvas_item_set_draw_index(F->get(), index++); + RS::get_singleton()->canvas_item_set_draw_index(F->get(), index++); } } @@ -718,24 +704,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; @@ -747,36 +733,36 @@ 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 = VisualServer::get_singleton()->canvas_item_create(); + //q.canvas_item = RenderingServer::get_singleton()->canvas_item_create(); if (!use_parent) { - q.body = Physics2DServer::get_singleton()->body_create(); - Physics2DServer::get_singleton()->body_set_mode(q.body, use_kinematic ? Physics2DServer::BODY_MODE_KINEMATIC : Physics2DServer::BODY_MODE_STATIC); + q.body = PhysicsServer2D::get_singleton()->body_create(); + PhysicsServer2D::get_singleton()->body_set_mode(q.body, use_kinematic ? PhysicsServer2D::BODY_MODE_KINEMATIC : PhysicsServer2D::BODY_MODE_STATIC); - Physics2DServer::get_singleton()->body_attach_object_instance_id(q.body, get_instance_id()); - Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer); - Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask); - Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, friction); - Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, bounce); + PhysicsServer2D::get_singleton()->body_attach_object_instance_id(q.body, get_instance_id()); + PhysicsServer2D::get_singleton()->body_set_collision_layer(q.body, collision_layer); + PhysicsServer2D::get_singleton()->body_set_collision_mask(q.body, collision_mask); + PhysicsServer2D::get_singleton()->body_set_param(q.body, PhysicsServer2D::BODY_PARAM_FRICTION, friction); + PhysicsServer2D::get_singleton()->body_set_param(q.body, PhysicsServer2D::BODY_PARAM_BOUNCE, bounce); if (is_inside_tree()) { xform = get_global_transform() * xform; RID space = get_world_2d()->get_space(); - Physics2DServer::get_singleton()->body_set_space(q.body, space); + PhysicsServer2D::get_singleton()->body_set_space(q.body, space); } - Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform); + PhysicsServer2D::get_singleton()->body_set_state(q.body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); } else if (collision_parent) { xform = get_transform() * xform; q.shape_owner_id = collision_parent->create_shape_owner(this); @@ -790,32 +776,30 @@ 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) { - Physics2DServer::get_singleton()->free(q.body); + PhysicsServer2D::get_singleton()->free(q.body); } else if (collision_parent) { collision_parent->remove_shape_owner(q.shape_owner_id); } for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { - - VisualServer::get_singleton()->free(E->get()); + 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()) { - - navigation->navpoly_remove(E->get().id); + NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID()); } q.navpoly_ids.clear(); } for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) { - VS::get_singleton()->free(E->get().id); + RS::get_singleton()->free(E->get().id); } q.occluder_instances.clear(); @@ -824,16 +808,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"); @@ -841,25 +827,23 @@ 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 }; - Variant::CallError ce; + Callable::CallError ce; call("set_cell", args, 7, ce); } 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) { @@ -869,10 +853,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; @@ -890,8 +875,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(); @@ -908,16 +894,14 @@ 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); - if (dirty_bitmask.find(p) == NULL) { + if (dirty_bitmask.find(p) == nullptr) { dirty_bitmask.push_back(p); } } @@ -925,7 +909,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); @@ -934,15 +917,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; } @@ -954,11 +933,10 @@ 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); - if (E != NULL) { + if (E != nullptr) { int id = get_cell(p_x, p_y); if (tile_set->tile_get_tile_mode(id) == TileSet::AUTO_TILE) { uint16_t mask = 0; @@ -1026,11 +1004,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)); @@ -1042,7 +1018,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(); @@ -1050,10 +1025,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); } @@ -1061,58 +1034,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; @@ -1122,30 +1098,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); @@ -1161,64 +1136,55 @@ 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) { - - VS::get_singleton()->canvas_item_set_use_parent_material(p_canvas_item, get_use_parent_material() || get_material().is_valid()); + 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 PoolVector<int> &p_data) { - +void TileMap::_set_tile_data(const Vector<int> &p_data) { ERR_FAIL_COND(format > FORMAT_2); int c = p_data.size(); - PoolVector<int>::Read r = p_data.read(); + const int *r = p_data.ptr(); int offset = (format == FORMAT_2) ? 3 : 2; 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 @@ -1251,11 +1217,10 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) { } } -PoolVector<int> TileMap::_get_tile_data() const { - - PoolVector<int> data; +Vector<int> TileMap::_get_tile_data() const { + Vector<int> data; data.resize(tile_map.size() * 3); - PoolVector<int>::Write w = data.write(); + int *w = data.ptrw(); // Save in highest format @@ -1265,20 +1230,21 @@ PoolVector<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]); idx += 3; } - w.release(); - return data; } @@ -1294,69 +1260,63 @@ 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(); - Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer); + PhysicsServer2D::get_singleton()->body_set_collision_layer(q.body, collision_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(); - Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask); + PhysicsServer2D::get_singleton()->body_set_collision_mask(q.body, collision_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(); @@ -1366,7 +1326,7 @@ void TileMap::set_collision_use_parent(bool p_use_parent) { if (use_parent && is_inside_tree()) { collision_parent = Object::cast_to<CollisionObject2D>(get_parent()); } else { - collision_parent = NULL; + collision_parent = nullptr; } _recreate_quadrants(); @@ -1375,60 +1335,50 @@ 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(); - Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, p_friction); + PhysicsServer2D::get_singleton()->body_set_param(q.body, PhysicsServer2D::BODY_PARAM_FRICTION, 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(); - Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, p_bounce); + 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(); @@ -1440,7 +1390,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(); @@ -1448,7 +1397,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(); @@ -1456,25 +1404,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); @@ -1492,18 +1434,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; @@ -1513,7 +1451,6 @@ Transform2D TileMap::get_cell_transform() const { } break; case MODE_CUSTOM: { - return custom_transform; } break; } @@ -1522,7 +1459,6 @@ Transform2D TileMap::get_cell_transform() const { } void TileMap::set_custom_transform(const Transform2D &p_xform) { - _clear_quadrants(); custom_transform = p_xform; _recreate_quadrants(); @@ -1530,20 +1466,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; @@ -1562,7 +1494,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 @@ -1579,7 +1510,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; @@ -1591,7 +1521,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); @@ -1606,16 +1535,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; @@ -1649,22 +1575,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; - VS::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(); @@ -1672,12 +1595,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(); @@ -1685,31 +1606,26 @@ void TileMap::set_centered_textures(bool p_enable) { } bool TileMap::is_centered_textures_enabled() const { - return centered_textures; } -Array TileMap::get_used_cells() const { - - Array a; +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()) { - - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a[i++] = p; } return a; } -Array TileMap::get_used_cells_by_id(int p_id) const { - - Array a; +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) { - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a.push_back(p); } } @@ -1739,36 +1655,31 @@ 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()) { - VisualServer::get_singleton()->canvas_light_occluder_set_light_mask(F->get().id, occluder_light_mask); + RenderingServer::get_singleton()->canvas_light_occluder_set_light_mask(F->get().id, occluder_light_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()) { - VisualServer::get_singleton()->canvas_item_set_light_mask(F->get(), get_light_mask()); + RenderingServer::get_singleton()->canvas_item_set_light_mask(F->get(), get_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; @@ -1776,12 +1687,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) { @@ -1795,7 +1726,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); @@ -1823,8 +1753,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); @@ -1874,14 +1804,13 @@ 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)); ClassDB::bind_method(D_METHOD("world_to_map", "world_position"), &TileMap::world_to_map); ClassDB::bind_method(D_METHOD("_clear_quadrants"), &TileMap::_clear_quadrants); - ClassDB::bind_method(D_METHOD("_recreate_quadrants"), &TileMap::_recreate_quadrants); ClassDB::bind_method(D_METHOD("update_dirty_quadrants"), &TileMap::update_dirty_quadrants); ClassDB::bind_method(D_METHOD("update_bitmask_area", "position"), &TileMap::update_bitmask_area); @@ -1899,7 +1828,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"); @@ -1907,8 +1836,8 @@ void TileMap::_bind_methods() { ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_parent", PROPERTY_HINT_NONE, ""), "set_collision_use_parent", "get_collision_use_parent"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_kinematic", PROPERTY_HINT_NONE, ""), "set_collision_use_kinematic", "get_collision_use_kinematic"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_friction", "get_collision_friction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_friction", "get_collision_friction"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); @@ -1943,7 +1872,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; @@ -1958,10 +1886,10 @@ TileMap::TileMap() { mode = MODE_SQUARE; half_offset = HALF_OFFSET_DISABLED; use_parent = false; - collision_parent = NULL; + collision_parent = nullptr; use_kinematic = false; - navigation = NULL; - y_sort_mode = false; + navigation = nullptr; + use_y_sort = false; compatibility_mode = false; centered_textures = false; occluder_light_mask = 1; @@ -1975,9 +1903,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 0875d197eb..b9dd8f5405 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.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; @@ -139,7 +135,7 @@ private: SelfList<Quadrant> dirty_list; struct NavPoly { - int id; + RID region; Transform2D xform; }; @@ -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; @@ -220,8 +216,8 @@ private: _FORCE_INLINE_ int _get_quadrant_size() const; - void _set_tile_data(const PoolVector<int> &p_data); - PoolVector<int> _get_tile_data() const; + void _set_tile_data(const Vector<int> &p_data); + Vector<int> _get_tile_data() const; void _set_old_cell_size(int p_size) { set_cell_size(Size2(p_size, p_size)); } int _get_old_cell_size() const { return cell_size.x; } @@ -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; @@ -328,23 +324,27 @@ public: void set_centered_textures(bool p_enable); bool is_centered_textures_enabled() const; - Array get_used_cells() const; - Array get_used_cells_by_id(int p_id) const; + TypedArray<Vector2i> get_used_cells() 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 42d9f88a60..4597300db8 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -30,109 +30,102 @@ #include "touch_screen_button.h" -#include "core/input_map.h" -#include "core/os/input.h" +#include "core/input/input.h" +#include "core/input/input_map.h" #include "core/os/os.h" - -void TouchScreenButton::set_texture(const Ref<Texture> &p_texture) { - +#include "scene/main/window.h" +# +void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; update(); } -Ref<Texture> TouchScreenButton::get_texture() const { - +Ref<Texture2D> TouchScreenButton::get_texture() const { return texture; } -void TouchScreenButton::set_texture_pressed(const Ref<Texture> &p_texture_pressed) { - +void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pressed) { texture_pressed = p_texture_pressed; update(); } -Ref<Texture> TouchScreenButton::get_texture_pressed() const { - +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()) - shape->disconnect("changed", this, "update"); + if (shape.is_valid()) { + shape->disconnect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); + } shape = p_shape; - if (shape.is_valid()) - shape->connect("changed", this, "update"); + 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() && !OS::get_singleton()->has_touchscreen_ui_hint() && 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(); @@ -144,80 +137,79 @@ void TouchScreenButton::_notification(int p_what) { } break; case NOTIFICATION_ENTER_TREE: { - - if (!Engine::get_singleton()->is_editor_hint() && !OS::get_singleton()->has_touchscreen_ui_hint() && 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); @@ -231,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()); @@ -259,42 +249,41 @@ 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()) { - Input::get_singleton()->action_press(action); Ref<InputEventAction> iea; iea.instance(); iea->set_action(action); iea->set_pressed(true); - get_tree()->input_event(iea); + get_viewport()->input(iea, true); } emit_signal("pressed"); @@ -302,19 +291,16 @@ void TouchScreenButton::_press(int p_finger_pressed) { } void TouchScreenButton::_release(bool p_exiting_tree) { - finger_pressed = -1; if (action != StringName()) { - Input::get_singleton()->action_release(action); if (!p_exiting_tree) { - Ref<InputEventAction> iea; iea.instance(); iea->set_action(action); iea->set_pressed(false); - get_tree()->input_event(iea); + get_viewport()->input(iea, true); } } @@ -326,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()); } @@ -338,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()); } @@ -350,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); @@ -397,14 +381,14 @@ void TouchScreenButton::_bind_methods() { ClassDB::bind_method(D_METHOD("_input"), &TouchScreenButton::_input); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture_pressed", "get_texture_pressed"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_pressed", "get_texture_pressed"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "bitmask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_bitmask", "get_bitmask"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_centered"), "set_shape_centered", "is_shape_centered"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_visible"), "set_shape_visible", "is_shape_visible"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "passby_press"), "set_passby_press", "is_passby_press_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), "set_action", "get_action"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "action"), "set_action", "get_action"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_mode", PROPERTY_HINT_ENUM, "Always,TouchScreen Only"), "set_visibility_mode", "get_visibility_mode"); ADD_SIGNAL(MethodInfo("pressed")); @@ -415,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 28dba59402..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: @@ -47,8 +46,8 @@ public: }; private: - Ref<Texture> texture; - Ref<Texture> texture_pressed; + Ref<Texture2D> texture; + Ref<Texture2D> texture_pressed; Ref<BitMap> bitmask; Ref<Shape2D> shape; bool shape_centered; @@ -75,15 +74,15 @@ 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<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_texture_pressed(const Ref<Texture> &p_texture_pressed); - Ref<Texture> get_texture_pressed() const; + void set_texture_pressed(const Ref<Texture2D> &p_texture_pressed); + Ref<Texture2D> get_texture_pressed() const; void set_bitmask(const Ref<BitMap> &p_bitmask); Ref<BitMap> get_bitmask() const; @@ -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 0ac725b7dd..75154c7acb 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -31,11 +31,11 @@ #include "visibility_notifier_2d.h" #include "core/engine.h" -#include "particles_2d.h" -#include "scene/2d/animated_sprite.h" +#include "gpu_particles_2d.h" +#include "scene/2d/animated_sprite_2d.h" #include "scene/2d/physics_body_2d.h" #include "scene/animation/animation_player.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED @@ -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,120 +143,123 @@ 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; - if (enabler[ENABLER_FREEZE_BODIES]) { - + { 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(); } } - if (enabler[ENABLER_PAUSE_ANIMATIONS]) { - + { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); if (ap) { add = true; } } - if (enabler[ENABLER_PAUSE_ANIMATED_SPRITES]) { - - AnimatedSprite *as = Object::cast_to<AnimatedSprite>(p_node); + { + AnimatedSprite2D *as = Object::cast_to<AnimatedSprite2D>(p_node); if (as) { add = true; } } - if (enabler[ENABLER_PAUSE_PARTICLES]) { - - Particles2D *ps = Object::cast_to<Particles2D>(p_node); + { + GPUParticles2D *ps = Object::cast_to<GPUParticles2D>(p_node); if (ps) { add = true; } } if (add) { - - p_node->connect(SceneStringNames::get_singleton()->tree_exiting, this, "_node_removed", varray(p_node), CONNECT_ONESHOT); + 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); } 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, this, "_node_removed"); + } + E->key()->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler2D::_node_removed)); } nodes.clear(); @@ -275,51 +267,48 @@ 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); } } - { + if (enabler[ENABLER_PAUSE_ANIMATIONS]) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); if (ap) { - ap->set_active(p_enabled); } } - { - AnimatedSprite *as = Object::cast_to<AnimatedSprite>(p_node); - if (as) { + if (enabler[ENABLER_PAUSE_ANIMATED_SPRITES]) { + AnimatedSprite2D *as = Object::cast_to<AnimatedSprite2D>(p_node); - if (p_enabled) + if (as) { + if (p_enabled) { as->play(); - else + } else { as->stop(); + } } } - { - Particles2D *ps = Object::cast_to<Particles2D>(p_node); + if (enabler[ENABLER_PAUSE_PARTICLES]) { + 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); } @@ -333,7 +322,6 @@ String VisibilityEnabler2D::get_configuration_warning() const { } 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); @@ -355,20 +343,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 62f10a5c96..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; - VS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), sort_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; - VS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), true); + RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), true); } |