summaryrefslogtreecommitdiff
path: root/scene/2d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d')
-rw-r--r--scene/2d/animated_sprite.cpp2
-rw-r--r--scene/2d/camera_2d.cpp18
-rw-r--r--scene/2d/canvas_item.cpp55
-rw-r--r--scene/2d/canvas_item.h2
-rw-r--r--scene/2d/collision_object_2d.cpp2
-rw-r--r--scene/2d/collision_polygon_2d.cpp2
-rw-r--r--scene/2d/collision_shape_2d.cpp22
-rw-r--r--scene/2d/cpu_particles_2d.cpp25
-rw-r--r--scene/2d/cpu_particles_2d.h4
-rw-r--r--scene/2d/light_2d.cpp2
-rw-r--r--scene/2d/light_occluder_2d.cpp2
-rw-r--r--scene/2d/path_2d.cpp2
-rw-r--r--scene/2d/physics_body_2d.cpp2
-rw-r--r--scene/2d/polygon_2d.cpp2
-rw-r--r--scene/2d/ray_cast_2d.cpp19
-rw-r--r--scene/2d/remote_transform_2d.cpp7
-rw-r--r--scene/2d/remote_transform_2d.h2
-rw-r--r--scene/2d/skeleton_2d.cpp4
-rw-r--r--scene/2d/tile_map.cpp18
-rw-r--r--scene/2d/tile_map.h7
-rw-r--r--scene/2d/visibility_notifier_2d.cpp2
21 files changed, 137 insertions, 64 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index b7ace804ef..c7f622dee3 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -663,7 +663,7 @@ StringName AnimatedSprite::get_animation() const {
String AnimatedSprite::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.");
+ return TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite to display frames.");
}
return String();
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index a0d74dd283..6011941142 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -140,9 +140,6 @@ Transform2D Camera2D::get_camera_transform() {
Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2());
Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom);
- if (offset != Vector2())
- screen_rect.position += offset;
-
if (limit_smoothing_enabled) {
if (screen_rect.position.x < limit[MARGIN_LEFT])
camera_pos.x -= screen_rect.position.x - limit[MARGIN_LEFT];
@@ -193,21 +190,8 @@ Transform2D Camera2D::get_camera_transform() {
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;
- 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])
- screen_rect.position.y = limit[MARGIN_BOTTOM] - screen_rect.size.y;
-
- if (screen_rect.position.x < limit[MARGIN_LEFT])
- screen_rect.position.x = limit[MARGIN_LEFT];
-
- if (screen_rect.position.y < limit[MARGIN_TOP])
- screen_rect.position.y = limit[MARGIN_TOP];
- }
camera_screen_center = screen_rect.position + screen_rect.size * 0.5;
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 23f6404e3e..7368efd21a 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -759,7 +759,7 @@ void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vec
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) {
+void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width, bool p_antialiased) {
if (!drawing) {
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
@@ -767,13 +767,53 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
}
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 {
- VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position, p_rect.position + Size2(p_rect.size.width, 0), p_color);
- VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position, p_rect.position + Size2(0, p_rect.size.height), p_color);
- VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position + Point2(0, p_rect.size.height), p_rect.position + p_rect.size, p_color);
- VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position + Point2(p_rect.size.width, 0), p_rect.position + p_rect.size, p_color);
+ // 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 + Point2(-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 + Point2(0, offset),
+ p_rect.position + Size2(0, p_rect.size.height - offset),
+ p_color,
+ p_width,
+ p_antialiased);
+ VisualServer::get_singleton()->canvas_item_add_line(
+ canvas_item,
+ p_rect.position + Point2(-offset, p_rect.size.height),
+ p_rect.position + Size2(p_rect.size.width + offset, p_rect.size.height),
+ p_color,
+ p_width,
+ p_antialiased);
+ VisualServer::get_singleton()->canvas_item_add_line(
+ canvas_item,
+ p_rect.position + Point2(p_rect.size.width, offset),
+ p_rect.position + Size2(p_rect.size.width, p_rect.size.height - offset),
+ p_color,
+ p_width,
+ p_antialiased);
}
}
@@ -928,6 +968,9 @@ float CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const
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);
}
@@ -1158,7 +1201,7 @@ void CanvasItem::_bind_methods() {
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_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()));
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 2604eb04e4..9c6799a441 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -307,7 +307,7 @@ public:
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_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>());
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 36c88e395a..202c7c9cf2 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -389,7 +389,7 @@ String CollisionObject2D::get_configuration_warning() const {
if (shapes.empty()) {
if (!warning.empty()) {
- warning += "\n";
+ warning += "\n\n";
}
warning += TTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape2D or CollisionPolygon2D as a child to define its shape.");
}
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index ef7644fcab..bb144dda96 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -70,7 +70,7 @@ void CollisionPolygon2D::_build_polygon() {
w[(i << 1) + 1] = polygon[(i + 1) % polygon.size()];
}
- w = PoolVector<Vector2>::Write();
+ w.release();
concave->set_segments(segments);
parent->shape_owner_add_shape(owner_id, concave);
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index 5440a1d8c3..f79d79d039 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -97,15 +97,8 @@ void CollisionShape2D::_notification(int p_what) {
}
owner_id = 0;
parent = NULL;
- } break;
- /*
- case NOTIFICATION_TRANSFORM_CHANGED: {
-
- if (!is_inside_scene())
- break;
- _update_parent();
- } break;*/
+ } break;
case NOTIFICATION_DRAW: {
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) {
@@ -131,10 +124,13 @@ void CollisionShape2D::_notification(int p_what) {
rect = rect.grow(3);
if (one_way_collision) {
- Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4);
- dcol.a = 1.0;
+ // Draw an arrow indicating the one-way collision direction
+ draw_col = get_tree()->get_debug_collisions_color().inverted();
+ if (disabled) {
+ draw_col = draw_col.darkened(0.25);
+ }
Vector2 line_to(0, 20);
- draw_line(Vector2(), line_to, dcol, 3);
+ draw_line(Vector2(), line_to, draw_col, 2, true);
Vector<Vector2> pts;
float tsize = 8;
pts.push_back(line_to + (Vector2(0, tsize)));
@@ -142,9 +138,9 @@ void CollisionShape2D::_notification(int p_what) {
pts.push_back(line_to + (Vector2(-0.707 * tsize, 0)));
Vector<Color> cols;
for (int i = 0; i < 3; i++)
- cols.push_back(dcol);
+ cols.push_back(draw_col);
- draw_primitive(pts, cols, Vector<Vector2>()); //small arrow
+ draw_primitive(pts, cols, Vector<Vector2>());
}
} break;
}
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 2091085420..1bddc4d22f 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -83,6 +83,10 @@ void CPUParticles2D::set_randomness_ratio(float p_ratio) {
randomness_ratio = p_ratio;
}
+void CPUParticles2D::set_lifetime_randomness(float p_random) {
+
+ lifetime_randomness = p_random;
+}
void CPUParticles2D::set_use_local_coordinates(bool p_enable) {
local_coords = p_enable;
@@ -123,6 +127,10 @@ float CPUParticles2D::get_randomness_ratio() const {
return randomness_ratio;
}
+float CPUParticles2D::get_lifetime_randomness() const {
+
+ return lifetime_randomness;
+}
bool CPUParticles2D::get_use_local_coordinates() const {
@@ -611,6 +619,10 @@ void CPUParticles2D::_particles_process(float p_delta) {
}
}
+ if (p.time * (1.0 - explosiveness_ratio) > p.lifetime) {
+ restart = true;
+ }
+
if (restart) {
if (!emitting) {
@@ -654,6 +666,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
p.custom[3] = 0.0;
p.transform = Transform2D();
p.time = 0;
+ p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness);
p.base_color = Color(1, 1, 1, 1);
switch (emission_shape) {
@@ -661,8 +674,9 @@ void CPUParticles2D::_particles_process(float p_delta) {
//do none
} break;
case EMISSION_SHAPE_SPHERE: {
- Vector3 sphere_shape = Vector3(Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0).normalized() * emission_sphere_radius;
- p.transform[2] = Vector2(sphere_shape.x, sphere_shape.y);
+ float s = Math::randf(), t = 2.0 * Math_PI * Math::randf();
+ float radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
+ p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius;
} break;
case EMISSION_SHAPE_RECTANGLE: {
p.transform[2] = Vector2(Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0) * emission_rect_extents;
@@ -695,6 +709,8 @@ void CPUParticles2D::_particles_process(float p_delta) {
} else if (!p.active) {
continue;
+ } else if (p.time > p.lifetime) {
+ p.active = false;
} else {
uint32_t alt_seed = p.seed;
@@ -1152,6 +1168,7 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) {
Vector2 gravity = Vector2(material->get_gravity().x, material->get_gravity().y);
set_gravity(gravity);
+ set_lifetime_randomness(material->get_lifetime_randomness());
#define CONVERT_PARAM(m_param) \
set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \
@@ -1186,6 +1203,7 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &CPUParticles2D::set_pre_process_time);
ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &CPUParticles2D::set_explosiveness_ratio);
ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &CPUParticles2D::set_randomness_ratio);
+ ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "random"), &CPUParticles2D::set_lifetime_randomness);
ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &CPUParticles2D::set_use_local_coordinates);
ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &CPUParticles2D::set_fixed_fps);
ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &CPUParticles2D::set_fractional_delta);
@@ -1198,6 +1216,7 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_pre_process_time"), &CPUParticles2D::get_pre_process_time);
ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &CPUParticles2D::get_explosiveness_ratio);
ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &CPUParticles2D::get_randomness_ratio);
+ ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &CPUParticles2D::get_lifetime_randomness);
ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &CPUParticles2D::get_use_local_coordinates);
ClassDB::bind_method(D_METHOD("get_fixed_fps"), &CPUParticles2D::get_fixed_fps);
ClassDB::bind_method(D_METHOD("get_fractional_delta"), &CPUParticles2D::get_fractional_delta);
@@ -1224,6 +1243,7 @@ void CPUParticles2D::_bind_methods() {
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::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", "");
@@ -1403,6 +1423,7 @@ CPUParticles2D::CPUParticles2D() {
set_pre_process_time(0);
set_explosiveness_ratio(0);
set_randomness_ratio(0);
+ set_lifetime_randomness(0);
set_use_local_coordinates(true);
set_draw_order(DRAW_ORDER_INDEX);
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 8613a185b4..1cd22df9e7 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -96,6 +96,7 @@ private:
float hue_rot_rand;
float anim_offset_rand;
float time;
+ float lifetime;
Color base_color;
uint32_t seed;
@@ -139,6 +140,7 @@ private:
float pre_process_time;
float explosiveness_ratio;
float randomness_ratio;
+ float lifetime_randomness;
float speed_scale;
bool local_coords;
int fixed_fps;
@@ -200,6 +202,7 @@ public:
void set_pre_process_time(float p_time);
void set_explosiveness_ratio(float p_ratio);
void set_randomness_ratio(float p_ratio);
+ void set_lifetime_randomness(float p_random);
void set_visibility_aabb(const Rect2 &p_aabb);
void set_use_local_coordinates(bool p_enable);
void set_speed_scale(float p_scale);
@@ -211,6 +214,7 @@ public:
float get_pre_process_time() const;
float get_explosiveness_ratio() const;
float get_randomness_ratio() const;
+ float get_lifetime_randomness() const;
Rect2 get_visibility_aabb() const;
bool get_use_local_coordinates() const;
float get_speed_scale() const;
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 7f01ff8806..7b3eab175a 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -347,7 +347,7 @@ void Light2D::_notification(int p_what) {
String Light2D::get_configuration_warning() const {
if (!texture.is_valid()) {
- return TTR("A texture with the shape of the light must be supplied to the 'texture' property.");
+ return TTR("A texture with the shape of the light must be supplied to the \"Texture\" property.");
}
return String();
diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp
index 3a3f90ac4b..313b23b9d4 100644
--- a/scene/2d/light_occluder_2d.cpp
+++ b/scene/2d/light_occluder_2d.cpp
@@ -268,7 +268,7 @@ String LightOccluder2D::get_configuration_warning() const {
}
if (occluder_polygon.is_valid() && occluder_polygon->get_polygon().size() == 0) {
- return TTR("The occluder polygon for this occluder is empty. Please draw a polygon!");
+ return TTR("The occluder polygon for this occluder is empty. Please draw a polygon.");
}
return String();
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index e062067248..f2f53d4354 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -58,7 +58,7 @@ Rect2 Path2D::_edit_get_rect() const {
}
bool Path2D::_edit_use_rect() const {
- return true;
+ return curve.is_valid() && curve->get_point_count() != 0;
}
bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 95acf13fad..39b3375f09 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -963,7 +963,7 @@ String RigidBody2D::get_configuration_warning() const {
if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.elements[0].length() - 1.0) > 0.05 || ABS(t.elements[1].length() - 1.0) > 0.05)) {
if (warning != String()) {
- warning += "\n";
+ warning += "\n\n";
}
warning += TTR("Size changes to RigidBody2D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.");
}
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index f6f1bad581..32a0b732c0 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -76,7 +76,7 @@ Rect2 Polygon2D::_edit_get_rect() const {
}
bool Polygon2D::_edit_use_rect() const {
- return true;
+ return polygon.size() > 0;
}
bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 57dfe5176d..bf8d008bb2 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -100,6 +100,7 @@ Vector2 RayCast2D::get_collision_normal() const {
void RayCast2D::set_enabled(bool p_enabled) {
enabled = p_enabled;
+ update();
if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint())
set_physics_process_internal(p_enabled);
if (!p_enabled)
@@ -167,19 +168,25 @@ void RayCast2D::_notification(int p_what) {
xf.rotate(cast_to.angle());
xf.translate(Vector2(cast_to.length(), 0));
- //Vector2 tip = Vector2(0,s->get_length());
- Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4);
- draw_line(Vector2(), cast_to, dcol, 3);
+ // Draw an arrow indicating where the RayCast is pointing to
+ Color draw_col = get_tree()->get_debug_collisions_color();
+ if (!enabled) {
+ float g = draw_col.get_v();
+ draw_col.r = g;
+ draw_col.g = g;
+ draw_col.b = g;
+ }
+ draw_line(Vector2(), cast_to, draw_col, 2, true);
Vector<Vector2> pts;
- float tsize = 4;
+ float tsize = 8;
pts.push_back(xf.xform(Vector2(tsize, 0)));
pts.push_back(xf.xform(Vector2(0, 0.707 * tsize)));
pts.push_back(xf.xform(Vector2(0, -0.707 * tsize)));
Vector<Color> cols;
for (int i = 0; i < 3; i++)
- cols.push_back(dcol);
+ cols.push_back(draw_col);
- draw_primitive(pts, cols, Vector<Vector2>()); //small arrow
+ draw_primitive(pts, cols, Vector<Vector2>());
} break;
diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp
index 1c38a91877..fe8cc5a5fc 100644
--- a/scene/2d/remote_transform_2d.cpp
+++ b/scene/2d/remote_transform_2d.cpp
@@ -110,7 +110,7 @@ void RemoteTransform2D::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_READY: {
+ case NOTIFICATION_ENTER_TREE: {
_update_cache();
@@ -180,6 +180,10 @@ bool RemoteTransform2D::get_update_scale() const {
return update_remote_scale;
}
+void RemoteTransform2D::force_update_cache() {
+ _update_cache();
+}
+
String RemoteTransform2D::get_configuration_warning() const {
if (!has_node(remote_node) || !Object::cast_to<Node2D>(get_node(remote_node))) {
@@ -193,6 +197,7 @@ 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);
ClassDB::bind_method(D_METHOD("set_use_global_coordinates", "use_global_coordinates"), &RemoteTransform2D::set_use_global_coordinates);
ClassDB::bind_method(D_METHOD("get_use_global_coordinates"), &RemoteTransform2D::get_use_global_coordinates);
diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h
index 16a5417592..e85fe33fc6 100644
--- a/scene/2d/remote_transform_2d.h
+++ b/scene/2d/remote_transform_2d.h
@@ -69,6 +69,8 @@ public:
void set_update_scale(const bool p_update);
bool get_update_scale() const;
+ void force_update_cache();
+
virtual String get_configuration_warning() const;
RemoteTransform2D();
diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp
index aa15255384..bf43fca864 100644
--- a/scene/2d/skeleton_2d.cpp
+++ b/scene/2d/skeleton_2d.cpp
@@ -137,7 +137,7 @@ String Bone2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!skeleton) {
if (warning != String()) {
- warning += "\n";
+ warning += "\n\n";
}
if (parent_bone) {
warning += TTR("This Bone2D chain should end at a Skeleton2D node.");
@@ -148,7 +148,7 @@ String Bone2D::get_configuration_warning() const {
if (rest == Transform2D(0, 0, 0, 0, 0, 0)) {
if (warning != String()) {
- warning += "\n";
+ warning += "\n\n";
}
warning += TTR("This bone lacks a proper REST pose. Go to the Skeleton2D node and set one.");
}
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 22bc0e44e6..c79cd80e2e 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -861,7 +861,7 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_
if (!E && p_tile == INVALID_CELL)
return; //nothing to do
- PosKey qk(p_x / _get_quadrant_size(), p_y / _get_quadrant_size());
+ PosKey qk = pk.to_quadrant(_get_quadrant_size());
if (p_tile == INVALID_CELL) {
//erase existing
tile_map.erase(pk);
@@ -1020,7 +1020,7 @@ void TileMap::update_cell_bitmask(int p_x, int 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());
+ PosKey qk = p.to_quadrant(_get_quadrant_size());
Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
_make_quadrant_dirty(Q);
@@ -1117,7 +1117,7 @@ void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord)
c.autotile_coord_y = p_coord.y;
tile_map[pk] = c;
- PosKey qk(p_x / _get_quadrant_size(), p_y / _get_quadrant_size());
+ PosKey qk = pk.to_quadrant(_get_quadrant_size());
Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
if (!Q)
@@ -1144,7 +1144,7 @@ void TileMap::_recreate_quadrants() {
for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
- PosKey qk(E->key().x / _get_quadrant_size(), E->key().y / _get_quadrant_size());
+ PosKey qk = PosKey(E->key().x, E->key().y).to_quadrant(_get_quadrant_size());
Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
if (!Q) {
@@ -1275,13 +1275,17 @@ PoolVector<int> TileMap::_get_tile_data() const {
idx += 3;
}
- w = PoolVector<int>::Write();
+ w.release();
return data;
}
Rect2 TileMap::_edit_get_rect() const {
- const_cast<TileMap *>(this)->update_dirty_quadrants();
+ if (pending_update) {
+ const_cast<TileMap *>(this)->update_dirty_quadrants();
+ } else {
+ const_cast<TileMap *>(this)->_recompute_rect_cache();
+ }
return rect_cache;
}
@@ -1776,7 +1780,7 @@ String TileMap::get_configuration_warning() const {
if (use_parent && !collision_parent) {
if (!warning.empty()) {
- warning += "\n";
+ warning += "\n\n";
}
return TTR("TileMap with Use Parent on needs a parent CollisionObject2D to give shapes to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.");
}
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 6c9648ff32..e30b7eff83 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -94,6 +94,13 @@ private:
bool operator==(const PosKey &p_k) const { return (y == p_k.y && x == p_k.x); }
+ PosKey to_quadrant(const int &p_quadrant_size) const {
+ // rounding down, instead of simply rounding towards zero (truncating)
+ return PosKey(
+ x > 0 ? x / p_quadrant_size : (x - (p_quadrant_size - 1)) / p_quadrant_size,
+ y > 0 ? y / p_quadrant_size : (y - (p_quadrant_size - 1)) / p_quadrant_size);
+ }
+
PosKey(int16_t p_x, int16_t p_y) {
x = p_x;
y = p_y;
diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp
index 1cf037daf2..a1d074e6cd 100644
--- a/scene/2d/visibility_notifier_2d.cpp
+++ b/scene/2d/visibility_notifier_2d.cpp
@@ -327,7 +327,7 @@ void VisibilityEnabler2D::_node_removed(Node *p_node) {
String VisibilityEnabler2D::get_configuration_warning() const {
#ifdef TOOLS_ENABLED
if (is_inside_tree() && get_parent() && (get_parent()->get_filename() == String() && get_parent() != get_tree()->get_edited_scene_root())) {
- return TTR("VisibilityEnable2D works best when used with the edited scene root directly as parent.");
+ return TTR("VisibilityEnabler2D works best when used with the edited scene root directly as parent.");
}
#endif
return String();