diff options
Diffstat (limited to 'scene/2d')
42 files changed, 565 insertions, 595 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 5982556c18..de28fef929 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -247,16 +247,16 @@ SpriteFrames::SpriteFrames() { add_animation(SceneStringNames::get_singleton()->_default); } -void AnimatedSprite::edit_set_pivot(const Point2 &p_pivot) { +void AnimatedSprite::_edit_set_pivot(const Point2 &p_pivot) { set_offset(p_pivot); } -Point2 AnimatedSprite::edit_get_pivot() const { +Point2 AnimatedSprite::_edit_get_pivot() const { return get_offset(); } -bool AnimatedSprite::edit_has_pivot() const { +bool AnimatedSprite::_edit_use_pivot() const { return true; } @@ -355,38 +355,21 @@ void AnimatedSprite::_notification(int p_what) { case NOTIFICATION_DRAW: { - if (frames.is_null()) { - print_line("no draw no faemos"); + if (frames.is_null()) return; - } - - if (frame < 0) { - print_line("no draw frame <0"); + if (frame < 0) return; - } - - if (!frames->has_animation(animation)) { - print_line("no draw no anim: " + String(animation)); + if (!frames->has_animation(animation)) return; - } Ref<Texture> texture = frames->get_frame(animation, frame); - if (texture.is_null()) { - print_line("no draw texture is null"); + if (texture.is_null()) return; - } Ref<Texture> normal = frames->get_normal_frame(animation, frame); - //print_line("DECIDED TO DRAW"); - RID ci = get_canvas_item(); - /* - texture->draw(ci,Point2()); - break; - */ - Size2i s; s = texture->get_size(); Point2 ofs = offset; @@ -403,9 +386,7 @@ void AnimatedSprite::_notification(int p_what) { if (vflip) dst_rect.size.y = -dst_rect.size.y; - //texture->draw_rect(ci,dst_rect,false,modulate); texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal); - //VisualServer::get_singleton()->canvas_item_add_texture_rect_region(ci,dst_rect,texture->get_rid(),src_rect,modulate); } break; } @@ -509,17 +490,17 @@ bool AnimatedSprite::is_flipped_v() const { return vflip; } -Rect2 AnimatedSprite::get_item_rect() const { +Rect2 AnimatedSprite::_edit_get_rect() const { if (!frames.is_valid() || !frames->has_animation(animation) || frame < 0 || frame >= frames->get_frame_count(animation)) { - return Node2D::get_item_rect(); + return Node2D::_edit_get_rect(); } Ref<Texture> t; if (animation) t = frames->get_frame(animation, frame); if (t.is_null()) - return Node2D::get_item_rect(); + return Node2D::_edit_get_rect(); Size2i s = t->get_size(); Point2 ofs = offset; @@ -568,7 +549,7 @@ void AnimatedSprite::stop() { bool AnimatedSprite::is_playing() const { - return is_processing(); + return playing; } void AnimatedSprite::_reset_timeout() { diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h index 6c660d0381..a8d0db021a 100644 --- a/scene/2d/animated_sprite.h +++ b/scene/2d/animated_sprite.h @@ -149,9 +149,9 @@ protected: virtual void _validate_property(PropertyInfo &property) const; public: - virtual void edit_set_pivot(const Point2 &p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; + virtual void _edit_set_pivot(const Point2 &p_pivot); + virtual Point2 _edit_get_pivot() const; + virtual bool _edit_use_pivot() const; void set_sprite_frames(const Ref<SpriteFrames> &p_frames); Ref<SpriteFrames> get_sprite_frames() const; @@ -181,7 +181,7 @@ public: void set_modulate(const Color &p_color); Color get_modulate() const; - virtual Rect2 get_item_rect() const; + virtual Rect2 _edit_get_rect() const; virtual String get_configuration_warning() const; AnimatedSprite(); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 9ee77a710c..80f9bf0f9f 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -688,8 +688,8 @@ void Area2D::_bind_methods() { BIND_ENUM_CONSTANT(SPACE_OVERRIDE_REPLACE_COMBINE); } -Area2D::Area2D() - : CollisionObject2D(Physics2DServer::get_singleton()->area_create(), true) { +Area2D::Area2D() : + CollisionObject2D(Physics2DServer::get_singleton()->area_create(), true) { space_override = SPACE_OVERRIDE_DISABLED; set_gravity(98); diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 73e633139b..937a026e34 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -21,7 +21,7 @@ void AudioStreamPlayer2D::_mix_audio() { } //get data - AudioFrame *buffer = mix_buffer.ptr(); + AudioFrame *buffer = mix_buffer.ptrw(); int buffer_size = mix_buffer.size(); //mix @@ -134,7 +134,7 @@ void AudioStreamPlayer2D::_notification(int p_what) { Physics2DDirectSpaceState::ShapeResult sr[MAX_INTERSECT_AREAS]; - int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask, Physics2DDirectSpaceState::TYPE_MASK_AREA); + int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask); for (int i = 0; i < areas; i++) { diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp index 2858ddaad5..e4f52a227a 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -49,7 +49,7 @@ void BackBufferCopy::_update_copy_mode() { } } -Rect2 BackBufferCopy::get_item_rect() const { +Rect2 BackBufferCopy::_edit_get_rect() const { return rect; } diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h index 2424dd7b19..cfd632d755 100644 --- a/scene/2d/back_buffer_copy.h +++ b/scene/2d/back_buffer_copy.h @@ -52,14 +52,14 @@ protected: static void _bind_methods(); public: + Rect2 _edit_get_rect() const; + void set_rect(const Rect2 &p_rect); Rect2 get_rect() const; void set_copy_mode(CopyMode p_mode); CopyMode get_copy_mode() const; - Rect2 get_item_rect() const; - BackBufferCopy(); ~BackBufferCopy(); }; diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index d65a3bfe80..3164344d15 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -52,7 +52,11 @@ void Camera2D::_update_scroll() { if (viewport) { viewport->set_canvas_transform(xform); } - get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_camera_moved", xform); + + Size2 screen_size = viewport->get_visible_rect().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); }; } diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index fa45c61f68..82123d12ac 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -184,6 +184,11 @@ RID CanvasItemMaterial::get_shader_rid() const { 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); @@ -206,8 +211,8 @@ void CanvasItemMaterial::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_MODE_LIGHT_ONLY); } -CanvasItemMaterial::CanvasItemMaterial() - : element(this) { +CanvasItemMaterial::CanvasItemMaterial() : + element(this) { blend_mode = BLEND_MODE_MIX; light_mode = LIGHT_MODE_NORMAL; @@ -306,22 +311,7 @@ void CanvasItem::hide() { _change_notify("visible"); } -Variant CanvasItem::edit_get_state() const { - - return Variant(); -} -void CanvasItem::edit_set_state(const Variant &p_state) { -} - -void CanvasItem::edit_set_rect(const Rect2 &p_edit_rect) { - - //used by editors, implement at will -} - -void CanvasItem::edit_rotate(float p_rot) { -} - -Size2 CanvasItem::edit_get_minimum_size() const { +Size2 CanvasItem::_edit_get_minimum_size() const { return Size2(-1, -1); //no limit } @@ -633,6 +623,29 @@ void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vect VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width, p_antialiased); } + +void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) { + + if (!drawing) { + ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); + ERR_FAIL(); + } + + 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) { + + if (!drawing) { + ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); + ERR_FAIL(); + } + + 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) { if (!drawing) { @@ -941,15 +954,22 @@ 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); - - 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_rect", "rect"), &CanvasItem::edit_set_rect); - ClassDB::bind_method(D_METHOD("edit_rotate", "degrees"), &CanvasItem::edit_rotate); - - ClassDB::bind_method(D_METHOD("get_item_rect"), &CanvasItem::get_item_rect); - ClassDB::bind_method(D_METHOD("get_item_and_children_rect"), &CanvasItem::get_item_and_children_rect); - //ClassDB::bind_method(D_METHOD("get_transform"),&CanvasItem::get_transform); + 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_use_position"), &CanvasItem::_edit_use_position); + 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_get_item_and_children_rect"), &CanvasItem::_edit_get_item_and_children_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("get_canvas_item"), &CanvasItem::get_canvas_item); @@ -982,6 +1002,8 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw_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"), &CanvasItem::draw_rect, DEFVAL(true)); 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())); @@ -1119,14 +1141,14 @@ int CanvasItem::get_canvas_layer() const { return 0; } -Rect2 CanvasItem::get_item_and_children_rect() const { +Rect2 CanvasItem::_edit_get_item_and_children_rect() const { - Rect2 rect = get_item_rect(); + Rect2 rect = _edit_get_rect(); for (int i = 0; i < get_child_count(); i++) { CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i)); if (c) { - Rect2 sir = c->get_transform().xform(c->get_item_and_children_rect()); + Rect2 sir = c->get_transform().xform(c->_edit_get_item_and_children_rect()); rect = rect.merge(sir); } } @@ -1134,8 +1156,8 @@ Rect2 CanvasItem::get_item_and_children_rect() const { return rect; } -CanvasItem::CanvasItem() - : xform_change(this) { +CanvasItem::CanvasItem() : + xform_change(this) { canvas_item = VisualServer::get_singleton()->canvas_item_create(); visible = true; diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 1a043c204f..2384c0f370 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -123,6 +123,8 @@ public: RID get_shader_rid() const; + virtual Shader::Mode get_shader_mode() const; + CanvasItemMaterial(); virtual ~CanvasItemMaterial(); }; @@ -216,11 +218,31 @@ public: /* EDITOR */ - virtual Variant edit_get_state() const; - virtual void edit_set_state(const Variant &p_state); - virtual void edit_set_rect(const Rect2 &p_edit_rect); - virtual void edit_rotate(float p_rot); - virtual Size2 edit_get_minimum_size() const; + virtual void _edit_set_state(const Dictionary &p_state){}; + virtual Dictionary _edit_get_state() const { return Dictionary(); }; + + // Used to move/select the node + virtual void _edit_set_position(const Point2 &p_position){}; + virtual Point2 _edit_get_position() const { return Point2(); }; + virtual bool _edit_use_position() const { return false; }; + + // Used to resize/move/select the node + virtual void _edit_set_rect(const Rect2 &p_rect){}; + virtual Rect2 _edit_get_rect() const { return Rect2(-32, -32, 64, 64); }; + Rect2 _edit_get_item_and_children_rect() const; + virtual bool _edit_use_rect() const { return false; }; + + // Used to rotate the node + virtual void _edit_set_rotation(float p_rotation){}; + virtual float _edit_get_rotation() const { return 0.0; }; + virtual bool _edit_use_rotation() const { return false; }; + + // Used to set a pivot + virtual void _edit_set_pivot(const Point2 &p_pivot){}; + virtual Point2 _edit_get_pivot() const { return Point2(); }; + virtual bool _edit_use_pivot() const { return false; }; + + virtual Size2 _edit_get_minimum_size() const; /* VISIBILITY */ @@ -246,6 +268,8 @@ public: void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); + void draw_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); 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>()); @@ -272,14 +296,11 @@ public: CanvasItem *get_parent_item() const; - virtual Rect2 get_item_rect() const = 0; virtual Transform2D get_transform() const = 0; virtual Transform2D get_global_transform() const; virtual Transform2D get_global_transform_with_canvas() const; - Rect2 get_item_and_children_rect() const; - CanvasItem *get_toplevel() const; _FORCE_INLINE_ RID get_canvas_item() const { return canvas_item; } diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index a840744c78..92855299ae 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -243,7 +243,7 @@ CollisionPolygon2D::BuildMode CollisionPolygon2D::get_build_mode() const { return build_mode; } -Rect2 CollisionPolygon2D::get_item_rect() const { +Rect2 CollisionPolygon2D::_edit_get_rect() const { return aabb; } diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index c9ec860e36..2fb08a4599 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -69,7 +69,7 @@ public: void set_polygon(const Vector<Point2> &p_polygon); Vector<Point2> get_polygon() const; - virtual Rect2 get_item_rect() const; + virtual Rect2 _edit_get_rect() const; virtual String get_configuration_warning() const; diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 0758f4a9bf..f7cb5473e3 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -158,7 +158,7 @@ Ref<Shape2D> CollisionShape2D::get_shape() const { return shape; } -Rect2 CollisionShape2D::get_item_rect() const { +Rect2 CollisionShape2D::_edit_get_rect() const { return rect; } diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h index 04203a75b4..4745c659c8 100644 --- a/scene/2d/collision_shape_2d.h +++ b/scene/2d/collision_shape_2d.h @@ -51,9 +51,10 @@ protected: static void _bind_methods(); public: + virtual Rect2 _edit_get_rect() const; + void set_shape(const Ref<Shape2D> &p_shape); Ref<Shape2D> get_shape() const; - virtual Rect2 get_item_rect() const; void set_disabled(bool p_disabled); bool is_disabled() const; diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 516acefe2a..d2b987e037 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -32,21 +32,21 @@ #include "engine.h" #include "servers/visual_server.h" -void Light2D::edit_set_pivot(const Point2 &p_pivot) { +void Light2D::_edit_set_pivot(const Point2 &p_pivot) { set_texture_offset(p_pivot); } -Point2 Light2D::edit_get_pivot() const { +Point2 Light2D::_edit_get_pivot() const { return get_texture_offset(); } -bool Light2D::edit_has_pivot() const { +bool Light2D::_edit_use_pivot() const { return true; } -Rect2 Light2D::get_item_rect() const { +Rect2 Light2D::_edit_get_rect() const { if (texture.is_null()) return Rect2(0, 0, 1, 1); diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index f6bc943adb..9b9da8379f 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -84,9 +84,10 @@ protected: static void _bind_methods(); public: - virtual void edit_set_pivot(const Point2 &p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; + 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; void set_enabled(bool p_enabled); bool is_enabled() const; @@ -151,8 +152,6 @@ public: void set_shadow_smooth(float p_amount); float get_shadow_smooth() const; - virtual Rect2 get_item_rect() const; - String get_configuration_warning() const; Light2D(); diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index 9131223ff3..57a0e15447 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -37,8 +37,8 @@ VARIANT_ENUM_CAST(Line2D::LineJointMode) VARIANT_ENUM_CAST(Line2D::LineCapMode) VARIANT_ENUM_CAST(Line2D::LineTextureMode) -Line2D::Line2D() - : Node2D() { +Line2D::Line2D() : + Node2D() { _joint_mode = LINE_JOINT_SHARP; _begin_cap_mode = LINE_CAP_NONE; _end_cap_mode = LINE_CAP_NONE; diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp index 74d835dfb2..40013814f8 100644 --- a/scene/2d/navigation2d.cpp +++ b/scene/2d/navigation2d.cpp @@ -150,7 +150,7 @@ void Navigation2D::_navpoly_unlink(int p_id) { Polygon &p = E->get(); int ec = p.edges.size(); - Polygon::Edge *edges = p.edges.ptr(); + Polygon::Edge *edges = p.edges.ptrw(); for (int i = 0; i < ec; i++) { int next = (i + 1) % ec; @@ -205,7 +205,7 @@ void Navigation2D::_navpoly_unlink(int p_id) { nm.linked = false; } -int Navigation2D::navpoly_create(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner) { +int Navigation2D::navpoly_add(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner) { int id = last_id++; NavMesh nm; @@ -708,7 +708,7 @@ Object *Navigation2D::get_closest_point_owner(const Vector2 &p_point) { void Navigation2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("navpoly_create", "mesh", "xform", "owner"), &Navigation2D::navpoly_create, DEFVAL(Variant())); + 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); diff --git a/scene/2d/navigation2d.h b/scene/2d/navigation2d.h index e87b01f7c5..02dbcb0f96 100644 --- a/scene/2d/navigation2d.h +++ b/scene/2d/navigation2d.h @@ -57,9 +57,9 @@ class Navigation2D : public Node2D { 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) { + 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); } @@ -159,7 +159,7 @@ protected: public: //API should be as dynamic as possible - int navpoly_create(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner = NULL); + 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); diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index c53241e985..5a6a5128e6 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -293,7 +293,7 @@ void NavigationPolygonInstance::set_enabled(bool p_enabled) { if (navpoly.is_valid()) { - nav_id = navigation->navpoly_create(navpoly, get_relative_transform_to_parent(navigation), this); + nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); } } } @@ -324,7 +324,7 @@ void NavigationPolygonInstance::_notification(int p_what) { if (enabled && navpoly.is_valid()) { - nav_id = navigation->navpoly_create(navpoly, get_relative_transform_to_parent(navigation), this); + nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); } break; } @@ -419,7 +419,7 @@ void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolyg } if (navigation && navpoly.is_valid() && enabled) { - nav_id = navigation->navpoly_create(navpoly, get_relative_transform_to_parent(navigation), this); + nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); } //update_gizmo(); _change_notify("navpoly"); diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index c562a4652d..45f780e50e 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -34,35 +34,22 @@ #include "scene/main/viewport.h" #include "servers/visual_server.h" -void Node2D::edit_set_pivot(const Point2 &p_pivot) { -} - -Point2 Node2D::edit_get_pivot() const { - - return Point2(); -} -bool Node2D::edit_has_pivot() const { - - return false; -} +Dictionary Node2D::_edit_get_state() const { -Variant Node2D::edit_get_state() const { - - Array state; - state.push_back(get_position()); - state.push_back(get_rotation()); - state.push_back(get_scale()); + Dictionary state; + state["position"] = get_position(); + state["rotation"] = get_rotation(); + state["scale"] = get_scale(); return state; } -void Node2D::edit_set_state(const Variant &p_state) { +void Node2D::_edit_set_state(const Dictionary &p_state) { - Array state = p_state; - ERR_FAIL_COND(state.size() != 3); + Dictionary state = p_state; + pos = state["position"]; + angle = state["rotation"]; + _scale = state["scale"]; - pos = state[0]; - angle = state[1]; - _scale = state[2]; _update_transform(); _change_notify("rotation"); _change_notify("rotation_degrees"); @@ -70,9 +57,16 @@ void Node2D::edit_set_state(const Variant &p_state) { _change_notify("position"); } -void Node2D::edit_set_rect(const Rect2 &p_edit_rect) { +void Node2D::_edit_set_position(const Point2 &p_position) { + pos = p_position; +} + +Point2 Node2D::_edit_get_position() const { + return pos; +} - Rect2 r = get_item_rect(); +void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { + Rect2 r = _edit_get_rect(); Vector2 zero_offset; if (r.size.x != 0) @@ -101,14 +95,25 @@ void Node2D::edit_set_rect(const Rect2 &p_edit_rect) { _change_notify("position"); } -void Node2D::edit_rotate(float p_rot) { +bool Node2D::_edit_use_rect() const { + return true; +} - angle += p_rot; +void Node2D::_edit_set_rotation(float p_rotation) { + angle = p_rotation; _update_transform(); _change_notify("rotation"); _change_notify("rotation_degrees"); } +float Node2D::_edit_get_rotation() const { + return angle; +} + +bool Node2D::_edit_use_rotation() const { + return true; +} + void Node2D::_update_xform_values() { pos = _mat.elements[2]; @@ -205,17 +210,6 @@ Transform2D Node2D::get_transform() const { return _mat; } -Rect2 Node2D::get_item_rect() const { - - if (get_script_instance()) { - Variant::CallError err; - Rect2 r = get_script_instance()->call("_get_item_rect", NULL, 0, err); - if (err.error == Variant::CallError::CALL_OK) - return r; - } - return Rect2(Point2(-32, -32), Size2(64, 64)); -} - void Node2D::rotate(float p_radians) { set_rotation(get_rotation() + p_radians); @@ -439,8 +433,6 @@ void Node2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_z_as_relative", "enable"), &Node2D::set_z_as_relative); ClassDB::bind_method(D_METHOD("is_z_relative"), &Node2D::is_z_relative); - ClassDB::bind_method(D_METHOD("edit_set_pivot", "pivot"), &Node2D::edit_set_pivot); - ClassDB::bind_method(D_METHOD("get_relative_transform_to_parent", "parent"), &Node2D::get_relative_transform_to_parent); ADD_GROUP("Transform", ""); diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index eca1e96c82..e1e07f2895 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -56,13 +56,16 @@ protected: static void _bind_methods(); public: - virtual Variant edit_get_state() const; - virtual void edit_set_state(const Variant &p_state); - virtual void edit_set_rect(const Rect2 &p_edit_rect); - virtual void edit_rotate(float p_rot); - virtual void edit_set_pivot(const Point2 &p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; + virtual Dictionary _edit_get_state() const; + virtual void _edit_set_state(const Dictionary &p_state); + + virtual void _edit_set_position(const Point2 &p_position); + virtual Point2 _edit_get_position() const; + virtual void _edit_set_rect(const Rect2 &p_edit_rect); + virtual bool _edit_use_rect() const; + virtual void _edit_set_rotation(float p_rotation); + virtual float _edit_get_rotation() const; + virtual bool _edit_use_rotation() const; void set_position(const Point2 &p_pos); void set_rotation(float p_radians); @@ -85,7 +88,6 @@ public: float get_global_rotation() const; float get_global_rotation_degrees() const; Size2 get_global_scale() const; - virtual Rect2 get_item_rect() const; void set_transform(const Transform2D &p_transform); void set_global_transform(const Transform2D &p_transform); diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp index a13ce6278e..b9012e37b2 100644 --- a/scene/2d/parallax_background.cpp +++ b/scene/2d/parallax_background.cpp @@ -47,10 +47,12 @@ void ParallaxBackground::_notification(int p_what) { } } -void ParallaxBackground::_camera_moved(const Transform2D &p_transform) { +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))); - set_scroll_offset(p_transform.get_origin() / p_transform.get_scale()); + set_scroll_offset(p_transform.get_origin()); } void ParallaxBackground::set_scroll_scale(float p_scale) { @@ -106,9 +108,9 @@ void ParallaxBackground::_update_scroll() { continue; if (ignore_camera_zoom) - l->set_base_offset_and_scale(ofs, 1.0); + l->set_base_offset_and_scale(ofs, 1.0, screen_offset); else - l->set_base_offset_and_scale(ofs, scale); + l->set_base_offset_and_scale(ofs, scale, screen_offset); } } diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h index 0dad1daeab..e37ec0db99 100644 --- a/scene/2d/parallax_background.h +++ b/scene/2d/parallax_background.h @@ -42,6 +42,7 @@ class ParallaxBackground : public CanvasLayer { float scale; Point2 base_offset; Point2 base_scale; + Point2 screen_offset; String group_name; Point2 limit_begin; Point2 limit_end; @@ -51,7 +52,7 @@ class ParallaxBackground : public CanvasLayer { void _update_scroll(); protected: - void _camera_moved(const Transform2D &p_transform); + void _camera_moved(const Transform2D &p_transform, const Point2 &p_screen_offset); void _notification(int p_what); static void _bind_methods(); diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 8fe651cb5f..9da27caa4c 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -40,7 +40,7 @@ void ParallaxLayer::set_motion_scale(const Size2 &p_scale) { if (pb && is_inside_tree()) { Vector2 ofs = pb->get_final_offset(); float scale = pb->get_scroll_scale(); - set_base_offset_and_scale(ofs, scale); + set_base_offset_and_scale(ofs, scale, screen_offset); } } @@ -57,7 +57,7 @@ void ParallaxLayer::set_motion_offset(const Size2 &p_offset) { if (pb && is_inside_tree()) { Vector2 ofs = pb->get_final_offset(); float scale = pb->get_scroll_scale(); - set_base_offset_and_scale(ofs, scale); + set_base_offset_and_scale(ofs, scale, screen_offset); } } @@ -73,7 +73,8 @@ void ParallaxLayer::_update_mirroring() { RID c = pb->get_world_2d()->get_canvas(); RID ci = get_canvas_item(); - VisualServer::get_singleton()->canvas_set_item_mirroring(c, ci, mirroring); + Point2 mirrorScale = mirroring * get_scale(); + VisualServer::get_singleton()->canvas_set_item_mirroring(c, ci, mirrorScale); } } @@ -106,16 +107,19 @@ void ParallaxLayer::_notification(int p_what) { } } -void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_scale) { +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()) return; if (Engine::get_singleton()->is_editor_hint()) return; - Point2 new_ofs = ((orig_offset + p_offset) * motion_scale) * p_scale + motion_offset; + + Point2 new_ofs = (screen_offset + (p_offset - screen_offset) * motion_scale) + motion_offset * p_scale + orig_offset * p_scale; if (mirroring.x) { double den = mirroring.x * p_scale; + double before = new_ofs.x; new_ofs.x -= den * ceil(new_ofs.x / den); } @@ -125,7 +129,9 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_sc } set_position(new_ofs); - set_scale(Vector2(1, 1) * p_scale); + set_scale(Vector2(1, 1) * p_scale * orig_scale); + + _update_mirroring(); } String ParallaxLayer::get_configuration_warning() const { diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h index 95ca27c41a..6feb1fad67 100644 --- a/scene/2d/parallax_layer.h +++ b/scene/2d/parallax_layer.h @@ -43,6 +43,8 @@ class ParallaxLayer : public Node2D { Vector2 mirroring; void _update_mirroring(); + Point2 screen_offset; + protected: void _notification(int p_what); static void _bind_methods(); @@ -57,7 +59,7 @@ public: void set_mirroring(const Size2 &p_mirroring); Size2 get_mirroring() const; - void set_base_offset_and_scale(const Point2 &p_offset, float p_scale); + void set_base_offset_and_scale(const Point2 &p_offset, float p_scale, const Point2 &p_screen_offset); virtual String get_configuration_warning() const; ParallaxLayer(); diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index c146ac08c2..7d53557216 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -77,7 +77,7 @@ void Particles2D::set_randomness_ratio(float p_ratio) { void Particles2D::set_visibility_rect(const Rect2 &p_aabb) { visibility_rect = p_aabb; - Rect3 aabb; + AABB aabb; aabb.position.x = p_aabb.position.x; aabb.position.y = p_aabb.position.y; aabb.size.x = p_aabb.size.x; @@ -223,7 +223,7 @@ String Particles2D::get_configuration_warning() const { Rect2 Particles2D::capture_rect() const { - Rect3 aabb = VS::get_singleton()->particles_get_current_aabb(particles); + AABB aabb = VS::get_singleton()->particles_get_current_aabb(particles); Rect2 r; r.position.x = aabb.position.x; r.position.y = aabb.position.y; @@ -291,7 +291,7 @@ void Particles2D::_notification(int p_what) { texture_rid = texture->get_rid(); RID normal_rid; if (normal_map.is_valid()) - normal_rid = texture->get_rid(); + normal_rid = normal_map->get_rid(); VS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid, normal_rid, h_frames, v_frames); @@ -378,7 +378,7 @@ void Particles2D::_bind_methods() { 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", ""); - ADD_PROPERTY(PropertyInfo(Variant::RECT3, "visibility_rect"), "set_visibility_rect", "get_visibility_rect"); + ADD_PROPERTY(PropertyInfo(Variant::AABB, "visibility_rect"), "set_visibility_rect", "get_visibility_rect"); 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_GROUP("Process Material", "process_"); diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 8413be1ca9..4029ef137b 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -107,20 +107,51 @@ void PathFollow2D::_update_transform() { if (!c.is_valid()) return; - float o = offset; + float path_length = c->get_baked_length(); + float bounded_offset = offset; if (loop) - o = Math::fposmod(o, c->get_baked_length()); + bounded_offset = Math::fposmod(bounded_offset, path_length); + else + bounded_offset = CLAMP(bounded_offset, 0, path_length); - Vector2 pos = c->interpolate_baked(o, cubic); + Vector2 pos = c->interpolate_baked(bounded_offset, cubic); if (rotate) { + float ahead = bounded_offset + lookahead; + + if (loop && ahead >= path_length) { + // If our lookahead will loop, we need to check if the path is closed. + int point_count = c->get_point_count(); + if (point_count > 0) { + Vector2 start_point = c->get_point_position(0); + Vector2 end_point = c->get_point_position(point_count - 1); + if (start_point == end_point) { + // Since the path is closed we want to 'smooth off' + // the corner at the start/end. + // So we wrap the lookahead back round. + ahead = Math::fmod(ahead, path_length); + } + } + } + + Vector2 ahead_pos = c->interpolate_baked(ahead, cubic); + + Vector2 tangent_to_curve; + if (ahead_pos == pos) { + // This will happen at the end of non-looping or non-closed paths. + // We'll try a look behind instead, in order to get a meaningful angle. + tangent_to_curve = + (pos - c->interpolate_baked(bounded_offset - lookahead, cubic)).normalized(); + } else { + tangent_to_curve = (ahead_pos - pos).normalized(); + } + + Vector2 normal_of_curve = -tangent_to_curve.tangent(); - Vector2 n = (c->interpolate_baked(o + lookahead, cubic) - pos).normalized(); - Vector2 t = -n.tangent(); - pos += n * h_offset; - pos += t * v_offset; + pos += tangent_to_curve * h_offset; + pos += normal_of_curve * v_offset; - set_rotation(t.angle()); + set_rotation(tangent_to_curve.angle()); } else { diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 1287a800e3..a1a1101b11 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -132,8 +132,8 @@ 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) { +PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : + CollisionObject2D(Physics2DServer::get_singleton()->body_create(), false) { Physics2DServer::get_singleton()->body_set_mode(get_rid(), p_mode); collision_layer = 1; @@ -226,8 +226,8 @@ void StaticBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce"); } -StaticBody2D::StaticBody2D() - : PhysicsBody2D(Physics2DServer::BODY_MODE_STATIC) { +StaticBody2D::StaticBody2D() : + PhysicsBody2D(Physics2DServer::BODY_MODE_STATIC) { constant_angular_velocity = 0; bounce = 0; @@ -921,8 +921,8 @@ void RigidBody2D::_bind_methods() { BIND_ENUM_CONSTANT(CCD_MODE_CAST_SHAPE); } -RigidBody2D::RigidBody2D() - : PhysicsBody2D(Physics2DServer::BODY_MODE_RIGID) { +RigidBody2D::RigidBody2D() : + PhysicsBody2D(Physics2DServer::BODY_MODE_RIGID) { mode = MODE_RIGID; @@ -1028,7 +1028,10 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const on_floor = true; floor_velocity = collision.collider_vel; - if (collision.travel.length() < 1 && ABS((lv.x - floor_velocity.x)) < p_slope_stop_min_velocity) { + Vector2 rel_v = lv - floor_velocity; + Vector2 hv = rel_v - p_floor_direction * p_floor_direction.dot(rel_v); + + if (collision.travel.length() < 1 && hv.length() < p_slope_stop_min_velocity) { Transform2D gt = get_global_transform(); gt.elements[2] -= collision.travel; set_global_transform(gt); @@ -1141,8 +1144,8 @@ void KinematicBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } -KinematicBody2D::KinematicBody2D() - : PhysicsBody2D(Physics2DServer::BODY_MODE_KINEMATIC) { +KinematicBody2D::KinematicBody2D() : + PhysicsBody2D(Physics2DServer::BODY_MODE_KINEMATIC) { margin = 0.08; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index b5b5445684..3f2ad19e51 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "polygon_2d.h" -Rect2 Polygon2D::get_item_rect() const { +Rect2 Polygon2D::_edit_get_rect() const { if (rect_cache_dirty) { int l = polygon.size(); @@ -49,16 +49,16 @@ Rect2 Polygon2D::get_item_rect() const { return item_rect; } -void Polygon2D::edit_set_pivot(const Point2 &p_pivot) { +void Polygon2D::_edit_set_pivot(const Point2 &p_pivot) { set_offset(p_pivot); } -Point2 Polygon2D::edit_get_pivot() const { +Point2 Polygon2D::_edit_get_pivot() const { return get_offset(); } -bool Polygon2D::edit_has_pivot() const { +bool Polygon2D::_edit_use_pivot() const { return true; } diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index 0c2c049c18..d09e22f5ff 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -99,11 +99,11 @@ public: //editor stuff - virtual void edit_set_pivot(const Point2 &p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; + virtual void _edit_set_pivot(const Point2 &p_pivot); + virtual Point2 _edit_get_pivot() const; + virtual bool _edit_use_pivot() const; - virtual Rect2 get_item_rect() const; + virtual Rect2 _edit_get_rect() const; Polygon2D(); }; diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index cde665d422..1e729bc179 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -38,7 +38,7 @@ void Position2D::_draw_cross() { draw_line(Point2(0, -10), Point2(0, +10), Color(0.5, 1, 0.5)); } -Rect2 Position2D::get_item_rect() const { +Rect2 Position2D::_edit_get_rect() const { return Rect2(Point2(-10, -10), Size2(20, 20)); } diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h index af54fb919a..5961e447df 100644 --- a/scene/2d/position_2d.h +++ b/scene/2d/position_2d.h @@ -42,7 +42,7 @@ protected: void _notification(int p_what); public: - virtual Rect2 get_item_rect() const; + virtual Rect2 _edit_get_rect() const; Position2D(); }; diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index ff23b3183b..a809023083 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -56,11 +56,6 @@ uint32_t RayCast2D::get_collision_mask() const { return collision_mask; } -void RayCast2D::set_type_mask(uint32_t p_mask) { - - type_mask = p_mask; -} - void RayCast2D::set_collision_mask_bit(int p_bit, bool p_value) { uint32_t mask = get_collision_mask(); @@ -76,11 +71,6 @@ bool RayCast2D::get_collision_mask_bit(int p_bit) const { return get_collision_mask() & (1 << p_bit); } -uint32_t RayCast2D::get_type_mask() const { - - return type_mask; -} - bool RayCast2D::is_colliding() const { return collided; @@ -130,11 +120,11 @@ void RayCast2D::set_exclude_parent_body(bool p_exclude_parent_body) { if (!is_inside_tree()) return; - if (Object::cast_to<PhysicsBody2D>(get_parent())) { + if (Object::cast_to<CollisionObject2D>(get_parent())) { if (exclude_parent_body) - exclude.insert(Object::cast_to<PhysicsBody2D>(get_parent())->get_rid()); + exclude.insert(Object::cast_to<CollisionObject2D>(get_parent())->get_rid()); else - exclude.erase(Object::cast_to<PhysicsBody2D>(get_parent())->get_rid()); + exclude.erase(Object::cast_to<CollisionObject2D>(get_parent())->get_rid()); } } @@ -154,11 +144,11 @@ void RayCast2D::_notification(int p_what) { else set_physics_process(false); - if (Object::cast_to<PhysicsBody2D>(get_parent())) { + if (Object::cast_to<CollisionObject2D>(get_parent())) { if (exclude_parent_body) - exclude.insert(Object::cast_to<PhysicsBody2D>(get_parent())->get_rid()); + exclude.insert(Object::cast_to<CollisionObject2D>(get_parent())->get_rid()); else - exclude.erase(Object::cast_to<PhysicsBody2D>(get_parent())->get_rid()); + exclude.erase(Object::cast_to<CollisionObject2D>(get_parent())->get_rid()); } } break; case NOTIFICATION_EXIT_TREE: { @@ -218,7 +208,7 @@ void RayCast2D::_update_raycast_state() { Physics2DDirectSpaceState::RayResult rr; - if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask, type_mask)) { + if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask)) { collided = true; against = rr.collider_id; @@ -297,9 +287,6 @@ void RayCast2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &RayCast2D::set_collision_mask_bit); ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &RayCast2D::get_collision_mask_bit); - ClassDB::bind_method(D_METHOD("set_type_mask", "mask"), &RayCast2D::set_type_mask); - ClassDB::bind_method(D_METHOD("get_type_mask"), &RayCast2D::get_type_mask); - ClassDB::bind_method(D_METHOD("set_exclude_parent_body", "mask"), &RayCast2D::set_exclude_parent_body); ClassDB::bind_method(D_METHOD("get_exclude_parent_body"), &RayCast2D::get_exclude_parent_body); @@ -307,7 +294,6 @@ void RayCast2D::_bind_methods() { 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::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type_mask", PROPERTY_HINT_FLAGS, "Static,Kinematic,Rigid,Character,Area"), "set_type_mask", "get_type_mask"); } RayCast2D::RayCast2D() { @@ -317,7 +303,6 @@ RayCast2D::RayCast2D() { collided = false; against_shape = 0; collision_mask = 1; - type_mask = Physics2DDirectSpaceState::TYPE_MASK_COLLISION; cast_to = Vector2(0, 50); exclude_parent_body = true; } diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index c13ddfdc58..9d60a16c6a 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -44,7 +44,6 @@ class RayCast2D : public Node2D { Vector2 collision_normal; Set<RID> exclude; uint32_t collision_mask; - uint32_t type_mask; bool exclude_parent_body; Vector2 cast_to; @@ -67,9 +66,6 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; - void set_type_mask(uint32_t p_mask); - uint32_t get_type_mask() const; - void set_exclude_parent_body(bool p_exclude_parent_body); bool get_exclude_parent_body() const; diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp index bf7c5a3ba4..d5fcda90d5 100644 --- a/scene/2d/screen_button.cpp +++ b/scene/2d/screen_button.cpp @@ -133,7 +133,7 @@ void TouchScreenButton::_notification(int p_what) { return; if (shape.is_valid()) { Color draw_col = get_tree()->get_debug_collisions_color(); - Vector2 pos = shape_centered ? get_item_rect().size * 0.5f : Vector2(); + Vector2 pos = shape_centered ? _edit_get_rect().size * 0.5f : Vector2(); draw_set_transform_matrix(get_canvas_transform().translated(pos)); shape->draw(get_canvas_item(), draw_col); } @@ -251,7 +251,7 @@ void TouchScreenButton::_input(const Ref<InputEvent> &p_event) { bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { Point2 coord = (get_global_transform_with_canvas()).affine_inverse().xform(p_point); - Rect2 item_rect = get_item_rect(); + Rect2 item_rect = _edit_get_rect(); bool touched = false; bool check_rect = true; @@ -322,13 +322,13 @@ void TouchScreenButton::_release(bool p_exiting_tree) { } } -Rect2 TouchScreenButton::get_item_rect() const { +Rect2 TouchScreenButton::_edit_get_rect() const { if (texture.is_null()) return Rect2(0, 0, 1, 1); /* if (texture.is_null()) - return CanvasItem::get_item_rect(); + return CanvasItem::_edit_get_rect(); */ return Rect2(Size2(), texture->get_size()); diff --git a/scene/2d/screen_button.h b/scene/2d/screen_button.h index 7647070b26..2e674c20b4 100644 --- a/scene/2d/screen_button.h +++ b/scene/2d/screen_button.h @@ -102,7 +102,7 @@ public: bool is_pressed() const; - Rect2 get_item_rect() const; + Rect2 _edit_get_rect() const; TouchScreenButton(); }; diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index c53faab5f9..df2265aae9 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -33,16 +33,16 @@ #include "scene/main/viewport.h" #include "scene/scene_string_names.h" -void Sprite::edit_set_pivot(const Point2 &p_pivot) { +void Sprite::_edit_set_pivot(const Point2 &p_pivot) { set_offset(p_pivot); } -Point2 Sprite::edit_get_pivot() const { +Point2 Sprite::_edit_get_pivot() const { return get_offset(); } -bool Sprite::edit_has_pivot() const { +bool Sprite::_edit_use_pivot() const { return true; } @@ -257,13 +257,13 @@ int Sprite::get_hframes() const { return hframes; } -Rect2 Sprite::get_item_rect() const { +Rect2 Sprite::_edit_get_rect() const { if (texture.is_null()) return Rect2(0, 0, 1, 1); /* if (texture.is_null()) - return CanvasItem::get_item_rect(); + return CanvasItem::_edit_get_rect(); */ Size2i s; @@ -368,224 +368,3 @@ Sprite::Sprite() { vframes = 1; hframes = 1; } - -//////////////////////////// VPSPRITE -/// -/// -/// - -#if 0 -void ViewportSprite::edit_set_pivot(const Point2& p_pivot) { - - set_offset(p_pivot); -} - -Point2 ViewportSprite::edit_get_pivot() const { - - return get_offset(); -} -bool ViewportSprite::edit_has_pivot() const { - - return true; -} - -void ViewportSprite::_notification(int p_what) { - - switch(p_what) { - - case NOTIFICATION_ENTER_TREE: { - - if (!viewport_path.is_empty()) { - - Node *n = get_node(viewport_path); - ERR_FAIL_COND(!n); - Viewport *vp=Object::cast_to<Viewport>(n); - ERR_FAIL_COND(!vp); - - Ref<RenderTargetTexture> rtt = vp->get_render_target_texture(); - texture=rtt; - texture->connect("changed",this,"update"); - item_rect_changed(); - } - } break; - case NOTIFICATION_EXIT_TREE: { - - if (texture.is_valid()) { - - texture->disconnect("changed",this,"update"); - texture=Ref<Texture>(); - } - } break; - case NOTIFICATION_DRAW: { - - if (texture.is_null()) - return; - - RID ci = get_canvas_item(); - - /* - texture->draw(ci,Point2()); - break; - */ - - Size2i s; - Rect2i src_rect; - - s = texture->get_size(); - - src_rect.size=s; - - Point2 ofs=offset; - if (centered) - ofs-=s/2; - - if (OS::get_singleton()->get_use_pixel_snap()) { - ofs=ofs.floor(); - } - Rect2 dst_rect(ofs,s); - texture->draw_rect_region(ci,dst_rect,src_rect,modulate); - - } break; - } -} - -void ViewportSprite::set_viewport_path(const NodePath& p_viewport) { - - viewport_path=p_viewport; - update(); - if (!is_inside_tree()) - return; - - if (texture.is_valid()) { - texture->disconnect("changed",this,"update"); - texture=Ref<Texture>(); - } - - if (viewport_path.is_empty()) - return; - - - Node *n = get_node(viewport_path); - ERR_FAIL_COND(!n); - Viewport *vp=Object::cast_to<Viewport>(n); - ERR_FAIL_COND(!vp); - - Ref<RenderTargetTexture> rtt = vp->get_render_target_texture(); - texture=rtt; - - if (texture.is_valid()) { - texture->connect("changed",this,"update"); - } - - item_rect_changed(); - -} - -NodePath ViewportSprite::get_viewport_path() const { - - return viewport_path; -} - -void ViewportSprite::set_centered(bool p_center) { - - centered=p_center; - update(); - item_rect_changed(); -} - -bool ViewportSprite::is_centered() const { - - return centered; -} - -void ViewportSprite::set_offset(const Point2& p_offset) { - - offset=p_offset; - update(); - item_rect_changed(); -} -Point2 ViewportSprite::get_offset() const { - - return offset; -} -void ViewportSprite::set_modulate(const Color& p_color) { - - modulate=p_color; - update(); -} - -Color ViewportSprite::get_modulate() const{ - - return modulate; -} - - -Rect2 ViewportSprite::get_item_rect() const { - - if (texture.is_null()) - return Rect2(0,0,1,1); - /* - if (texture.is_null()) - return CanvasItem::get_item_rect(); - */ - - Size2i s; - - s = texture->get_size(); - Point2 ofs=offset; - if (centered) - ofs-=s/2; - - if (s==Size2(0,0)) - s=Size2(1,1); - - return Rect2(ofs,s); -} - -String ViewportSprite::get_configuration_warning() const { - - if (!has_node(viewport_path) || !Object::cast_to<Viewport>(get_node(viewport_path))) { - return TTR("Path property must point to a valid Viewport node to work. Such Viewport must be set to 'render target' mode."); - } else { - - Node *n = get_node(viewport_path); - if (n) { - Viewport *vp = Object::cast_to<Viewport>(n); - if (!vp->is_set_as_render_target()) { - - return TTR("The Viewport set in the path property must be set as 'render target' in order for this sprite to work."); - } - } - } - - return String(); - -} - -void ViewportSprite::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_viewport_path","path"),&ViewportSprite::set_viewport_path); - ClassDB::bind_method(D_METHOD("get_viewport_path"),&ViewportSprite::get_viewport_path); - - ClassDB::bind_method(D_METHOD("set_centered","centered"),&ViewportSprite::set_centered); - ClassDB::bind_method(D_METHOD("is_centered"),&ViewportSprite::is_centered); - - ClassDB::bind_method(D_METHOD("set_offset","offset"),&ViewportSprite::set_offset); - ClassDB::bind_method(D_METHOD("get_offset"),&ViewportSprite::get_offset); - - ClassDB::bind_method(D_METHOD("set_modulate","modulate"),&ViewportSprite::set_modulate); - ClassDB::bind_method(D_METHOD("get_modulate"),&ViewportSprite::get_modulate); - - ADD_PROPERTYNZ( PropertyInfo( Variant::NODE_PATH, "viewport"), "set_viewport_path","get_viewport_path"); - ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "centered"), "set_centered","is_centered"); - ADD_PROPERTYNZ( PropertyInfo( Variant::VECTOR2, "offset"), "set_offset","get_offset"); - ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), "set_modulate","get_modulate"); - -} - -ViewportSprite::ViewportSprite() { - - centered=true; - modulate=Color(1,1,1,1); -} -#endif diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index 64d30325f2..1bef73c0a5 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -62,9 +62,10 @@ protected: virtual void _validate_property(PropertyInfo &property) const; public: - virtual void edit_set_pivot(const Point2 &p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; + 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; void set_texture(const Ref<Texture> &p_texture); Ref<Texture> get_texture() const; @@ -102,53 +103,7 @@ public: void set_hframes(int p_amount); int get_hframes() const; - virtual Rect2 get_item_rect() const; - Sprite(); }; -#if 0 -class ViewportSprite : public Node2D { - - GDCLASS( ViewportSprite, Node2D ); - - Ref<Texture> texture; - NodePath viewport_path; - - bool centered; - Point2 offset; - Color modulate; - -protected: - - void _notification(int p_what); - - static void _bind_methods(); - -public: - - virtual void edit_set_pivot(const Point2& p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; - - void set_viewport_path(const NodePath& p_viewport); - NodePath get_viewport_path() const; - - void set_centered(bool p_center); - bool is_centered() const; - - void set_offset(const Point2& p_offset); - Point2 get_offset() const; - - void set_modulate(const Color& p_color); - Color get_modulate() const; - - virtual Rect2 get_item_rect() const; - - virtual String get_configuration_warning() const; - - ViewportSprite(); -}; - -#endif #endif // SPRITE_H diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index dd4270ab26..bcdad177c5 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "tile_map.h" + #include "io/marshalls.h" #include "method_bind_ext.gen.inc" #include "os/os.h" @@ -169,10 +170,12 @@ void TileMap::set_cell_size(Size2 p_size) { _recreate_quadrants(); emit_signal("settings_changed"); } + Size2 TileMap::get_cell_size() const { return cell_size; } + void TileMap::set_quadrant_size(int p_size) { ERR_FAIL_COND(p_size < 1); @@ -182,32 +185,12 @@ void TileMap::set_quadrant_size(int p_size) { _recreate_quadrants(); emit_signal("settings_changed"); } + int TileMap::get_quadrant_size() const { return quadrant_size; } -void TileMap::set_center_x(bool p_enable) { - - center_x = p_enable; - _recreate_quadrants(); - emit_signal("settings_changed"); -} -bool TileMap::get_center_x() const { - - return center_x; -} -void TileMap::set_center_y(bool p_enable) { - - center_y = p_enable; - _recreate_quadrants(); - emit_signal("settings_changed"); -} -bool TileMap::get_center_y() const { - - return center_y; -} - void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc) { Size2 s = p_sc; @@ -215,6 +198,9 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) offset.y += cell_size.y; + else if (tile_origin == TILE_ORIGIN_CENTER) { + offset += cell_size / 2; + } if (s.y > s.x) { if ((p_cell.flip_h && (p_cell.flip_v || p_cell.transpose)) || (p_cell.flip_v && !p_cell.transpose)) @@ -235,6 +221,8 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const xform.elements[1].x = -xform.elements[1].x; if (tile_origin == TILE_ORIGIN_TOP_LEFT || tile_origin == TILE_ORIGIN_BOTTOM_LEFT) offset.x = s.x - offset.x; + else if (tile_origin == TILE_ORIGIN_CENTER) + offset.x = s.x - offset.x / 2; } if (p_cell.flip_v) { xform.elements[0].y = -xform.elements[0].y; @@ -242,10 +230,9 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const if (tile_origin == TILE_ORIGIN_TOP_LEFT) offset.y = s.y - offset.y; else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { - if (p_cell.transpose) - offset.y += s.y; - else - offset.y -= s.y; + offset.y += s.y; + } else if (tile_origin == TILE_ORIGIN_CENTER) { + offset.y += s.y; } } xform.elements[2].x += offset.x; @@ -365,6 +352,11 @@ void TileMap::_update_dirty_quadrants() { } Rect2 r = tile_set->tile_get_region(c.id); + if (tile_set->tile_get_is_autotile(c.id)) { + int spacing = tile_set->autotile_get_spacing(c.id); + r.size = tile_set->autotile_get_size(c.id); + r.position += (r.size + Vector2(spacing, spacing)) * Vector2(c.autotile_coord_x, c.autotile_coord_y); + } Size2 s = tex->get_size(); if (r == Rect2()) @@ -424,20 +416,18 @@ void TileMap::_update_dirty_quadrants() { } } else if (tile_origin == TILE_ORIGIN_CENTER) { - rect.position += tcenter; - Vector2 center = (s / 2) - tile_ofs; - center_ofs = tcenter - (s / 2); + rect.position += tile_ofs; if (c.flip_h) - rect.position.x -= s.x - center.x; + rect.position.x -= cell_size.x / 2; else - rect.position.x -= center.x; + rect.position.x += cell_size.x / 2; if (c.flip_v) - rect.position.y -= s.y - center.y; + rect.position.y -= cell_size.y / 2; else - rect.position.y -= center.y; + rect.position.y += cell_size.y / 2; } Ref<Texture> normal_map = tile_set->tile_get_normal_map(c.id); @@ -456,21 +446,23 @@ void TileMap::_update_dirty_quadrants() { for (int i = 0; i < shapes.size(); i++) { Ref<Shape2D> shape = shapes[i].shape; if (shape.is_valid()) { - Transform2D xform; - xform.set_origin(offset.floor()); - - Vector2 shape_ofs = tile_set->tile_get_shape_offset(c.id, i); - - _fix_cell_transform(xform, c, shape_ofs + center_ofs, s); - - if (debug_canvas_item.is_valid()) { - vs->canvas_item_add_set_transform(debug_canvas_item, xform); - shape->draw(debug_canvas_item, debug_collision_color); + if (!tile_set->tile_get_is_autotile(c.id) || (shapes[i].autotile_coord.x == c.autotile_coord_x && shapes[i].autotile_coord.y == c.autotile_coord_y)) { + Transform2D xform; + xform.set_origin(offset.floor()); + + Vector2 shape_ofs = tile_set->tile_get_shape_offset(c.id, i); + + _fix_cell_transform(xform, c, shape_ofs + center_ofs, s); + + if (debug_canvas_item.is_valid()) { + vs->canvas_item_add_set_transform(debug_canvas_item, xform); + shape->draw(debug_canvas_item, debug_collision_color); + } + ps->body_add_shape(q.body, shape->get_rid(), xform); + ps->body_set_shape_metadata(q.body, shape_idx, Vector2(E->key().x, E->key().y)); + ps->body_set_shape_as_one_way_collision(q.body, shape_idx, shapes[i].one_way_collision); + shape_idx++; } - ps->body_add_shape(q.body, shape->get_rid(), xform); - ps->body_set_shape_metadata(q.body, shape_idx, Vector2(E->key().x, E->key().y)); - ps->body_set_shape_as_one_way_collision(q.body, shape_idx, shapes[i].one_way_collision); - shape_idx++; } } @@ -479,14 +471,22 @@ void TileMap::_update_dirty_quadrants() { } if (navigation) { - Ref<NavigationPolygon> navpoly = tile_set->tile_get_navigation_polygon(c.id); + Ref<NavigationPolygon> navpoly; + Vector2 npoly_ofs; + if (tile_set->tile_get_is_autotile(c.id)) { + navpoly = tile_set->autotile_get_navigation_polygon(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y)); + npoly_ofs = Vector2(); + } else { + navpoly = tile_set->tile_get_navigation_polygon(c.id); + npoly_ofs = tile_set->tile_get_navigation_polygon_offset(c.id); + } + if (navpoly.is_valid()) { - Vector2 npoly_ofs = tile_set->tile_get_navigation_polygon_offset(c.id); Transform2D xform; xform.set_origin(offset.floor() + q.pos); _fix_cell_transform(xform, c, npoly_ofs + center_ofs, s); - int pid = navigation->navpoly_create(navpoly, nav_rel * xform); + int pid = navigation->navpoly_add(navpoly, nav_rel * xform); Quadrant::NavPoly np; np.id = pid; @@ -495,9 +495,13 @@ void TileMap::_update_dirty_quadrants() { } } - Ref<OccluderPolygon2D> occluder = tile_set->tile_get_light_occluder(c.id); + Ref<OccluderPolygon2D> occluder; + if (tile_set->tile_get_is_autotile(c.id)) { + occluder = tile_set->autotile_get_light_occluder(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y)); + } else { + occluder = tile_set->tile_get_light_occluder(c.id); + } if (occluder.is_valid()) { - Vector2 occluder_ofs = tile_set->tile_get_occluder_offset(c.id); Transform2D xform; xform.set_origin(offset.floor() + q.pos); @@ -656,7 +660,7 @@ void TileMap::set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x, bool p_ set_cell(p_pos.x, p_pos.y, p_tile, p_flip_x, p_flip_y, p_transpose); } -void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose) { +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); @@ -692,7 +696,7 @@ 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) + 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 } @@ -702,15 +706,109 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_ c.flip_h = p_flip_x; c.flip_v = p_flip_y; c.transpose = p_transpose; + c.autotile_coord_x = (uint16_t)p_autotile_coord.x; + c.autotile_coord_y = (uint16_t)p_autotile_coord.y; _make_quadrant_dirty(Q); used_size_cache_dirty = true; } 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) { + dirty_bitmask.push_back(p); + } + } + } +} + +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); + } + } +} + +void TileMap::update_cell_bitmask(int p_x, int p_y) { + + PosKey p(p_x, p_y); + Map<PosKey, Cell>::Element *E = tile_map.find(p); + if (E != NULL) { + int id = get_cell(p_x, p_y); + if (tile_set->tile_get_is_autotile(id)) { + uint16_t mask = 0; + if (tile_set->autotile_get_bitmask_mode(id) == TileSet::BITMASK_2X2) { + if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) { + mask |= TileSet::BIND_TOPLEFT; + } + if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y))) { + mask |= TileSet::BIND_TOPRIGHT; + } + if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) { + mask |= TileSet::BIND_BOTTOMLEFT; + } + if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y))) { + mask |= TileSet::BIND_BOTTOMRIGHT; + } + } else if (tile_set->autotile_get_bitmask_mode(id) == TileSet::BITMASK_3X3) { + if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) { + mask |= TileSet::BIND_TOPLEFT; + } + if (tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1))) { + mask |= TileSet::BIND_TOP; + } + if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y))) { + mask |= TileSet::BIND_TOPRIGHT; + } + if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) { + mask |= TileSet::BIND_LEFT; + } + mask |= TileSet::BIND_CENTER; + if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y))) { + mask |= TileSet::BIND_RIGHT; + } + if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) { + mask |= TileSet::BIND_BOTTOMLEFT; + } + if (tile_set->is_tile_bound(id, get_cell(p_x, p_y + 1))) { + mask |= TileSet::BIND_BOTTOM; + } + if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y))) { + mask |= TileSet::BIND_BOTTOMRIGHT; + } + } + Vector2 coord = tile_set->autotile_get_subtile_for_bitmask(id, mask, this, Vector2(p_x, p_y)); + E->get().autotile_coord_x = (int)coord.x; + E->get().autotile_coord_y = (int)coord.y; + + PosKey qk(p_x / _get_quadrant_size(), p_y / _get_quadrant_size()); + Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk); + _make_quadrant_dirty(Q); + } else { + E->get().autotile_coord_x = 0; + E->get().autotile_coord_y = 0; + } + } +} + +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(); + } +} + int TileMap::get_cell(int p_x, int p_y) const { PosKey pk(p_x, p_y); @@ -756,6 +854,33 @@ bool TileMap::is_cell_transposed(int p_x, int p_y) const { 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) + return; + + Cell c = E->get(); + c.autotile_coord_x = p_coord.x; + c.autotile_coord_y = p_coord.y; + tile_map[pk] = c; +} + +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) + return Vector2(); + + return Vector2(E->get().autotile_coord_x, E->get().autotile_coord_y); +} + void TileMap::_recreate_quadrants() { _clear_quadrants(); @@ -823,11 +948,14 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) { int c = p_data.size(); PoolVector<int>::Read r = p_data.read(); - for (int i = 0; i < c; i += 2) { + 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[8]; - for (int j = 0; j < 8; j++) + uint8_t local[12]; + for (int j = 0; j < ((format == FORMAT_2) ? 12 : 8); j++) local[j] = ptr[j]; #ifdef BIG_ENDIAN_ENABLED @@ -836,6 +964,11 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) { SWAP(local[1], local[2]); SWAP(local[4], local[7]); SWAP(local[5], local[6]); + //TODO: ask someone to check this... + if (FORMAT == FORMAT_2) { + SWAP(local[8], local[11]); + SWAP(local[9], local[10]); + } #endif int16_t x = decode_uint16(&local[0]); @@ -845,24 +978,30 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) { bool flip_v = v & (1 << 30); bool transpose = v & (1 << 31); v &= (1 << 29) - 1; - + int16_t coord_x; + int16_t coord_y; + if (format == FORMAT_2) { + coord_x = decode_uint16(&local[8]); + coord_y = decode_uint16(&local[10]); + } /* if (x<-20 || y <-20 || x>4000 || y>4000) continue; */ - set_cell(x, y, v, flip_h, flip_v, transpose); + set_cell(x, y, v, flip_h, flip_v, transpose, Vector2(coord_x, coord_y)); } } PoolVector<int> TileMap::_get_tile_data() const { PoolVector<int> data; - data.resize(tile_map.size() * 2); + data.resize(tile_map.size() * 3); PoolVector<int>::Write w = data.write(); + format = FORMAT_2; + int idx = 0; for (const Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - uint8_t *ptr = (uint8_t *)&w[idx]; encode_uint16(E->key().x, &ptr[0]); encode_uint16(E->key().y, &ptr[2]); @@ -873,9 +1012,10 @@ PoolVector<int> TileMap::_get_tile_data() const { val |= (1 << 30); if (E->get().transpose) val |= (1 << 31); - encode_uint32(val, &ptr[4]); - idx += 2; + encode_uint16(E->get().autotile_coord_x, &ptr[8]); + encode_uint16(E->get().autotile_coord_y, &ptr[10]); + idx += 3; } w = PoolVector<int>::Write(); @@ -883,7 +1023,7 @@ PoolVector<int> TileMap::_get_tile_data() const { return data; } -Rect2 TileMap::get_item_rect() const { +Rect2 TileMap::_edit_get_rect() const { const_cast<TileMap *>(this)->_update_dirty_quadrants(); return rect_cache; @@ -1119,10 +1259,50 @@ Vector2 TileMap::_map_to_world(int p_x, int p_y, bool p_ignore_ofs) const { } return ret; } + +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()); + return true; + } + } else if (p_name == "tile_data") { + if (p_value.is_array()) { + _set_tile_data(p_value); + return true; + } + return false; + } + return false; +} + +bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { + + if (p_name == "format") { + r_ret = FORMAT_2; + return true; + } else if (p_name == "tile_data") { + r_ret = _get_tile_data(); + return true; + } + return false; +} + +void TileMap::_get_property_list(List<PropertyInfo> *p_list) const { + + PropertyInfo p(Variant::INT, "format", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR); + p_list->push_back(p); + + p = PropertyInfo(Variant::OBJECT, "tile_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR); + p_list->push_back(p); +} + 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); @@ -1276,12 +1456,6 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tile_origin", "origin"), &TileMap::set_tile_origin); ClassDB::bind_method(D_METHOD("get_tile_origin"), &TileMap::get_tile_origin); - ClassDB::bind_method(D_METHOD("set_center_x", "enable"), &TileMap::set_center_x); - ClassDB::bind_method(D_METHOD("get_center_x"), &TileMap::get_center_x); - - ClassDB::bind_method(D_METHOD("set_center_y", "enable"), &TileMap::set_center_y); - ClassDB::bind_method(D_METHOD("get_center_y"), &TileMap::get_center_y); - 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); @@ -1312,7 +1486,7 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_occluder_light_mask", "mask"), &TileMap::set_occluder_light_mask); ClassDB::bind_method(D_METHOD("get_occluder_light_mask"), &TileMap::get_occluder_light_mask); - ClassDB::bind_method(D_METHOD("set_cell", "x", "y", "tile", "flip_x", "flip_y", "transpose"), &TileMap::set_cell, DEFVAL(false), DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("set_cell", "x", "y", "tile", "flip_x", "flip_y", "transpose", "autotile_coord"), &TileMap::set_cell, DEFVAL(false), DEFVAL(false), DEFVAL(false), DEFVAL(Vector2())); ClassDB::bind_method(D_METHOD("set_cellv", "position", "tile", "flip_x", "flip_y", "transpose"), &TileMap::set_cellv, DEFVAL(false), DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_cell", "x", "y"), &TileMap::get_cell); ClassDB::bind_method(D_METHOD("get_cellv", "position"), &TileMap::get_cellv); @@ -1357,8 +1531,6 @@ void TileMap::_bind_methods() { ADD_GROUP("Occluder", "occluder_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "occluder_light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask"); - ADD_GROUP("", ""); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tile_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_tile_data", "_get_tile_data"); ADD_SIGNAL(MethodInfo("settings_changed")); @@ -1385,8 +1557,6 @@ TileMap::TileMap() { quadrant_order_dirty = false; quadrant_size = 16; cell_size = Size2(64, 64); - center_x = false; - center_y = false; collision_layer = 1; collision_mask = 1; friction = 1; @@ -1398,6 +1568,7 @@ TileMap::TileMap() { y_sort_mode = false; occluder_light_mask = 1; clip_uv = false; + format = FORMAT_1; //Always initialize with the lowest format fp_adjust = 0.00001; tile_origin = TILE_ORIGIN_TOP_LEFT; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 706b87cec3..e5608884c4 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -60,10 +60,14 @@ public: }; private: + enum DataFormat { + FORMAT_1 = 0, + FORMAT_2 + }; + Ref<TileSet> tile_set; Size2i cell_size; int quadrant_size; - bool center_x, center_y; Mode mode; Transform2D custom_transform; HalfOffset half_offset; @@ -81,6 +85,8 @@ private: //using a more precise comparison so the regions can be sorted later bool operator<(const PosKey &p_k) const { return (y == p_k.y) ? x < p_k.x : y < p_k.y; } + bool operator==(const PosKey &p_k) const { return (y == p_k.y && x == p_k.x); } + PosKey(int16_t p_x, int16_t p_y) { x = p_x; y = p_y; @@ -98,13 +104,17 @@ private: bool flip_h : 1; bool flip_v : 1; bool transpose : 1; + int16_t autotile_coord_x : 16; + int16_t autotile_coord_y : 16; }; - uint32_t _u32t; - Cell() { _u32t = 0; } + uint64_t _u64t; + Cell() { _u64t = 0; } }; Map<PosKey, Cell> tile_map; + List<PosKey> dirty_bitmask; + struct Quadrant { Vector2 pos; @@ -136,8 +146,8 @@ private: navpoly_ids = q.navpoly_ids; occluder_instances = q.occluder_instances; } - Quadrant(const Quadrant &q) - : dirty_list(this) { + Quadrant(const Quadrant &q) : + dirty_list(this) { pos = q.pos; canvas_items = q.canvas_items; body = q.body; @@ -145,8 +155,8 @@ private: occluder_instances = q.occluder_instances; navpoly_ids = q.navpoly_ids; } - Quadrant() - : dirty_list(this) {} + Quadrant() : + dirty_list(this) {} }; Map<PosKey, Quadrant> quadrant_map; @@ -167,6 +177,7 @@ private: float bounce; uint32_t collision_layer; uint32_t collision_mask; + mutable DataFormat format; TileOrigin tile_origin; @@ -198,6 +209,10 @@ private: _FORCE_INLINE_ Vector2 _map_to_world(int p_x, int p_y, bool p_ignore_ofs = false) const; protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + void _notification(int p_what); static void _bind_methods(); @@ -215,21 +230,23 @@ public: void set_quadrant_size(int p_size); int get_quadrant_size() const; - void set_center_x(bool p_enable); - bool get_center_x() const; - void set_center_y(bool p_enable); - bool get_center_y() const; - - void set_cell(int p_x, int p_y, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false); + void set_cell(int p_x, int p_y, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false, Vector2 p_autotile_coord = Vector2()); int get_cell(int p_x, int p_y) const; bool is_cell_x_flipped(int p_x, int p_y) const; bool is_cell_y_flipped(int p_x, int p_y) const; bool is_cell_transposed(int p_x, int p_y) const; + void set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord); + Vector2 get_cell_autotile_coord(int p_x, int p_y) const; void set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false); int get_cellv(const Vector2 &p_pos) const; - Rect2 get_item_rect() const; + Rect2 _edit_get_rect() const; + + void make_bitmask_area_dirty(const Vector2 &p_pos); + void update_bitmask_area(const Vector2 &p_pos); + void update_cell_bitmask(int p_x, int p_y); + void update_dirty_bitmask(); void set_collision_layer(uint32_t p_layer); uint32_t get_collision_layer() const; diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index b0fd57baf5..298bc2649e 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -83,7 +83,7 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) { _change_notify("rect"); } -Rect2 VisibilityNotifier2D::get_item_rect() const { +Rect2 VisibilityNotifier2D::_edit_get_rect() const { return rect; } diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index ee5152978b..6e06833912 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -54,13 +54,13 @@ protected: static void _bind_methods(); public: + virtual Rect2 _edit_get_rect() const; + void set_rect(const Rect2 &p_rect); Rect2 get_rect() const; bool is_on_screen() const; - virtual Rect2 get_item_rect() const; - VisibilityNotifier2D(); }; |