diff options
Diffstat (limited to 'scene')
76 files changed, 508 insertions, 212 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 28a8c4d658..917ced5feb 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -35,6 +35,7 @@ #define NORMAL_SUFFIX "_normal" +#ifdef TOOLS_ENABLED Dictionary AnimatedSprite::_edit_get_state() const { Dictionary state = Node2D::_edit_get_state(); state["offset"] = offset; @@ -72,6 +73,7 @@ bool AnimatedSprite::_edit_use_rect() const { t = frames->get_frame(animation, frame); return t.is_valid(); } +#endif Rect2 AnimatedSprite::get_anchorable_rect() const { return _get_rect(); diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h index 2017c62a48..cd00a4e181 100644 --- a/scene/2d/animated_sprite.h +++ b/scene/2d/animated_sprite.h @@ -156,6 +156,7 @@ protected: virtual void _validate_property(PropertyInfo &property) const; public: +#ifdef TOOLS_ENABLED virtual Dictionary _edit_get_state() const; virtual void _edit_set_state(const Dictionary &p_state); @@ -164,6 +165,7 @@ public: virtual bool _edit_use_pivot() const; virtual Rect2 _edit_get_rect() const; virtual bool _edit_use_rect() const; +#endif virtual Rect2 get_anchorable_rect() const; diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp index 1a6f30e0fd..faeb6b7169 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -50,6 +50,7 @@ void BackBufferCopy::_update_copy_mode() { } } +#ifdef TOOLS_ENABLED Rect2 BackBufferCopy::_edit_get_rect() const { return rect; @@ -58,6 +59,7 @@ Rect2 BackBufferCopy::_edit_get_rect() const { bool BackBufferCopy::_edit_use_rect() const { return true; } +#endif Rect2 BackBufferCopy::get_anchorable_rect() const { diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h index 91acd81e00..4b26bf1bdc 100644 --- a/scene/2d/back_buffer_copy.h +++ b/scene/2d/back_buffer_copy.h @@ -53,8 +53,10 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED Rect2 _edit_get_rect() const; virtual bool _edit_use_rect() const; +#endif void set_rect(const Rect2 &p_rect); Rect2 get_rect() const; diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 9895dba027..5631aa3355 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -351,7 +351,7 @@ CanvasItemMaterial::~CanvasItemMaterial() { } /////////////////////////////////////////////////////////////////// - +#ifdef TOOLS_ENABLED bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { if (_edit_use_rect()) { return _edit_get_rect().has_point(p_point); @@ -363,6 +363,7 @@ bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tole Transform2D CanvasItem::_edit_get_transform() const { return Transform2D(_edit_get_rotation(), _edit_get_position() + _edit_get_pivot()); } +#endif bool CanvasItem::is_visible_in_tree() const { @@ -1121,9 +1122,10 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("_toplevel_raise_self"), &CanvasItem::_toplevel_raise_self); ClassDB::bind_method(D_METHOD("_update_callback"), &CanvasItem::_update_callback); + +#ifdef TOOLS_ENABLED ClassDB::bind_method(D_METHOD("_edit_set_state", "state"), &CanvasItem::_edit_set_state); ClassDB::bind_method(D_METHOD("_edit_get_state"), &CanvasItem::_edit_get_state); - ClassDB::bind_method(D_METHOD("_edit_set_position", "position"), &CanvasItem::_edit_set_position); ClassDB::bind_method(D_METHOD("_edit_get_position"), &CanvasItem::_edit_get_position); ClassDB::bind_method(D_METHOD("_edit_set_scale", "scale"), &CanvasItem::_edit_set_scale); @@ -1138,6 +1140,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("_edit_get_pivot"), &CanvasItem::_edit_get_pivot); ClassDB::bind_method(D_METHOD("_edit_use_pivot"), &CanvasItem::_edit_use_pivot); ClassDB::bind_method(D_METHOD("_edit_get_transform"), &CanvasItem::_edit_get_transform); +#endif ClassDB::bind_method(D_METHOD("get_canvas_item"), &CanvasItem::get_canvas_item); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 82645051e8..8814d99edd 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -249,7 +249,7 @@ public: }; /* EDITOR */ - +#ifdef TOOLS_ENABLED // Select the node virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; @@ -282,6 +282,7 @@ public: virtual Point2 _edit_get_pivot() const { return Point2(); }; virtual Transform2D _edit_get_transform() const; +#endif /* VISIBILITY */ diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 3090c9956e..d9cc94c6eb 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -227,6 +227,7 @@ CollisionPolygon2D::BuildMode CollisionPolygon2D::get_build_mode() const { return build_mode; } +#ifdef TOOLS_ENABLED Rect2 CollisionPolygon2D::_edit_get_rect() const { return aabb; @@ -240,6 +241,7 @@ bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, doubl return Geometry::is_point_in_polygon(p_point, Variant(polygon)); } +#endif String CollisionPolygon2D::get_configuration_warning() const { diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index e5e18b2674..d8dfec8fd2 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -67,16 +67,18 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED + virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; +#endif + void set_build_mode(BuildMode p_mode); BuildMode get_build_mode() const; void set_polygon(const Vector<Point2> &p_polygon); Vector<Point2> get_polygon() const; - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; - virtual String get_configuration_warning() const; void set_disabled(bool p_disabled); diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 8296f35739..c325de00b8 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -422,7 +422,7 @@ bool CPUParticles2D::get_particle_flag(Flags p_flag) const { } void CPUParticles2D::set_emission_shape(EmissionShape p_shape) { - + ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX); emission_shape = p_shape; _change_notify(); } @@ -772,6 +772,9 @@ void CPUParticles2D::_particles_process(float p_delta) { p.base_color = emission_colors.get(random_idx); } } break; + case EMISSION_SHAPE_MAX: { // Max value for validity check. + break; + } } if (!local_coords) { @@ -1416,6 +1419,7 @@ void CPUParticles2D::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_RECTANGLE); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS); BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX); } CPUParticles2D::CPUParticles2D() { diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 6ffa1f0e97..cbaff70c2a 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -75,6 +75,7 @@ public: EMISSION_SHAPE_RECTANGLE, EMISSION_SHAPE_POINTS, EMISSION_SHAPE_DIRECTED_POINTS, + EMISSION_SHAPE_MAX }; private: diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 1843cbed67..1bffaf8084 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -33,6 +33,7 @@ #include "core/engine.h" #include "servers/visual_server.h" +#ifdef TOOLS_ENABLED Dictionary Light2D::_edit_get_state() const { Dictionary state = Node2D::_edit_get_state(); state["offset"] = get_texture_offset(); @@ -68,6 +69,7 @@ Rect2 Light2D::_edit_get_rect() const { bool Light2D::_edit_use_rect() const { return !texture.is_null(); } +#endif Rect2 Light2D::get_anchorable_rect() const { if (texture.is_null()) @@ -187,6 +189,10 @@ float Light2D::get_energy() const { void Light2D::set_texture_scale(float p_scale) { _scale = p_scale; + // Avoid having 0 scale values, can lead to errors in physics and rendering. + if (_scale == 0) { + _scale = CMP_EPSILON; + } VS::get_singleton()->canvas_light_set_scale(canvas_light, _scale); item_rect_changed(); } diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index f8476e8389..65db5c6ee6 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -85,6 +85,7 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED virtual Dictionary _edit_get_state() const; virtual void _edit_set_state(const Dictionary &p_state); @@ -93,6 +94,7 @@ public: virtual bool _edit_use_pivot() const; virtual Rect2 _edit_get_rect() const; virtual bool _edit_use_rect() const; +#endif virtual Rect2 get_anchorable_rect() const; diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 6a930683d1..0e8e8f6679 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -33,6 +33,8 @@ #include "core/engine.h" #define LINE_GRAB_WIDTH 8 + +#ifdef TOOLS_ENABLED Rect2 OccluderPolygon2D::_edit_get_rect() const { if (rect_cache_dirty) { @@ -80,6 +82,7 @@ bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double return false; } } +#endif void OccluderPolygon2D::set_polygon(const PoolVector<Vector2> &p_polygon) { @@ -215,6 +218,7 @@ void LightOccluder2D::_notification(int p_what) { } } +#ifdef TOOLS_ENABLED Rect2 LightOccluder2D::_edit_get_rect() const { return occluder_polygon.is_valid() ? occluder_polygon->_edit_get_rect() : Rect2(); @@ -224,6 +228,7 @@ bool LightOccluder2D::_edit_is_selected_on_click(const Point2 &p_point, double p return occluder_polygon.is_valid() ? occluder_polygon->_edit_is_selected_on_click(p_point, p_tolerance) : false; } +#endif void LightOccluder2D::set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polygon) { diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index 32d527093d..b20e347c35 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -57,8 +57,10 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; +#endif void set_polygon(const PoolVector<Vector2> &p_polygon); PoolVector<Vector2> get_polygon() const; @@ -91,8 +93,10 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; +#endif void set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polygon); Ref<OccluderPolygon2D> get_occluder_polygon() const; diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index 4a022f0a9c..c31840c8e1 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -50,6 +50,7 @@ Line2D::Line2D() { _antialiased = false; } +#ifdef TOOLS_ENABLED Rect2 Line2D::_edit_get_rect() const { if (_points.size() == 0) @@ -79,6 +80,7 @@ bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc return false; } +#endif void Line2D::set_points(const PoolVector<Vector2> &p_points) { _points = p_points; diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index bc2deba8c6..3c7239f67c 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -56,11 +56,13 @@ public: LINE_TEXTURE_STRETCH }; - Line2D(); - +#ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const; virtual bool _edit_use_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; +#endif + + Line2D(); void set_points(const PoolVector<Vector2> &p_points); PoolVector<Vector2> get_points() const; diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 8f9c4e2a4d..93432ec40b 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -94,6 +94,7 @@ Ref<Texture> MeshInstance2D::get_texture() const { return texture; } +#ifdef TOOLS_ENABLED Rect2 MeshInstance2D::_edit_get_rect() const { if (mesh.is_valid()) { @@ -103,6 +104,7 @@ Rect2 MeshInstance2D::_edit_get_rect() const { return Node2D::_edit_get_rect(); } +#endif MeshInstance2D::MeshInstance2D() { } diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h index e7f8b7c0c3..51f75a3ead 100644 --- a/scene/2d/mesh_instance_2d.h +++ b/scene/2d/mesh_instance_2d.h @@ -46,6 +46,10 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED + virtual Rect2 _edit_get_rect() const; +#endif + void set_mesh(const Ref<Mesh> &p_mesh); Ref<Mesh> get_mesh() const; @@ -55,8 +59,6 @@ public: void set_normal_map(const Ref<Texture> &p_texture); Ref<Texture> get_normal_map() const; - virtual Rect2 _edit_get_rect() const; - MeshInstance2D(); }; diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 69d687229b..028459e778 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -94,6 +94,7 @@ Ref<Texture> MultiMeshInstance2D::get_normal_map() const { return normal_map; } +#ifdef TOOLS_ENABLED Rect2 MultiMeshInstance2D::_edit_get_rect() const { if (multimesh.is_valid()) { @@ -103,6 +104,7 @@ Rect2 MultiMeshInstance2D::_edit_get_rect() const { return Node2D::_edit_get_rect(); } +#endif MultiMeshInstance2D::MultiMeshInstance2D() { } diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h index 253f4c77ca..c3f3e52920 100644 --- a/scene/2d/multimesh_instance_2d.h +++ b/scene/2d/multimesh_instance_2d.h @@ -47,6 +47,10 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED + virtual Rect2 _edit_get_rect() const; +#endif + void set_multimesh(const Ref<MultiMesh> &p_multimesh); Ref<MultiMesh> get_multimesh() const; @@ -56,8 +60,6 @@ public: void set_normal_map(const Ref<Texture> &p_texture); Ref<Texture> get_normal_map() const; - virtual Rect2 _edit_get_rect() const; - MultiMeshInstance2D(); ~MultiMeshInstance2D(); }; diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index bd930bdda5..ea79f89dd9 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -36,6 +36,7 @@ #include "thirdparty/misc/triangulator.h" +#ifdef TOOLS_ENABLED Rect2 NavigationPolygon::_edit_get_rect() const { if (rect_cache_dirty) { @@ -75,6 +76,7 @@ bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double } return false; } +#endif void NavigationPolygon::set_vertices(const PoolVector<Vector2> &p_vertices) { @@ -357,7 +359,7 @@ bool NavigationPolygonInstance::is_enabled() const { } ///////////////////////////// - +#ifdef TOOLS_ENABLED Rect2 NavigationPolygonInstance::_edit_get_rect() const { return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2(); @@ -367,6 +369,7 @@ bool NavigationPolygonInstance::_edit_is_selected_on_click(const Point2 &p_point return navpoly.is_valid() ? navpoly->_edit_is_selected_on_click(p_point, p_tolerance) : false; } +#endif void NavigationPolygonInstance::_notification(int p_what) { diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h index 9bbaa864f4..cbc1711a32 100644 --- a/scene/2d/navigation_polygon.h +++ b/scene/2d/navigation_polygon.h @@ -57,8 +57,10 @@ protected: Array _get_outlines() const; public: +#ifdef TOOLS_ENABLED Rect2 _edit_get_rect() const; bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; +#endif void set_vertices(const PoolVector<Vector2> &p_vertices); PoolVector<Vector2> get_vertices() const; @@ -100,8 +102,10 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; +#endif void set_enabled(bool p_enabled); bool is_enabled() const; diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index ad04dc8d9e..7deebe9b27 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -35,6 +35,7 @@ #include "scene/main/viewport.h" #include "servers/visual_server.h" +#ifdef TOOLS_ENABLED Dictionary Node2D::_edit_get_state() const { Dictionary state; @@ -44,6 +45,7 @@ Dictionary Node2D::_edit_get_state() const { return state; } + void Node2D::_edit_set_state(const Dictionary &p_state) { pos = p_state["position"]; @@ -119,6 +121,7 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { _change_notify("scale"); _change_notify("position"); } +#endif void Node2D::_update_xform_values() { @@ -170,6 +173,7 @@ void Node2D::set_scale(const Size2 &p_scale) { if (_xform_dirty) ((Node2D *)this)->_update_xform_values(); _scale = p_scale; + // Avoid having 0 scale values, can lead to errors in physics and rendering. if (_scale.x == 0) _scale.x = CMP_EPSILON; if (_scale.y == 0) diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index a03ccc5a80..00202481a6 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -55,6 +55,7 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED virtual Dictionary _edit_get_state() const; virtual void _edit_set_state(const Dictionary &p_state); @@ -69,6 +70,7 @@ public: virtual bool _edit_use_rotation() const; virtual void _edit_set_rect(const Rect2 &p_edit_rect); +#endif void set_position(const Point2 &p_pos); void set_rotation(float p_radians); diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index e6ae95af89..e9296b0fe7 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -37,6 +37,7 @@ #include "editor/editor_scale.h" #endif +#ifdef TOOLS_ENABLED Rect2 Path2D::_edit_get_rect() const { if (!curve.is_valid() || curve->get_point_count() == 0) @@ -85,6 +86,7 @@ bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc return false; } +#endif void Path2D::_notification(int p_what) { diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 21cb4374bd..35cf8211f4 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -47,9 +47,11 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const; virtual bool _edit_use_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; +#endif void set_curve(const Ref<Curve2D> &p_curve); Ref<Curve2D> get_curve() const; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 3fd0bef7e9..d42bd6adaf 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1212,7 +1212,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_ //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { Vector2 body_velocity = p_linear_velocity; Vector2 body_velocity_normal = body_velocity.normalized(); @@ -1234,6 +1234,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const on_ceiling = false; on_wall = false; colliders.clear(); + floor_normal = Vector2(); floor_velocity = Vector2(); while (p_max_slides) { @@ -1262,25 +1263,26 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const colliders.push_back(collision); motion = collision.remainder; - if (p_floor_direction == Vector2()) { + if (p_up_direction == Vector2()) { //all is a wall on_wall = true; } else { - if (Math::acos(collision.normal.dot(p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor + if (Math::acos(collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor on_floor = true; + floor_normal = collision.normal; on_floor_body = collision.collider_rid; floor_velocity = collision.collider_vel; if (p_stop_on_slope) { - if ((body_velocity_normal + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) { + if ((body_velocity_normal + p_up_direction).length() < 0.01 && collision.travel.length() < 1) { Transform2D gt = get_global_transform(); - gt.elements[2] -= collision.travel.slide(p_floor_direction); + gt.elements[2] -= collision.travel.slide(p_up_direction); set_global_transform(gt); return Vector2(); } } - } else if (Math::acos(collision.normal.dot(-p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling + } else if (Math::acos(collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling on_ceiling = true; } else { on_wall = true; @@ -1301,11 +1303,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const return body_velocity; } -Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { bool was_on_floor = on_floor; - Vector2 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); + Vector2 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); if (!was_on_floor || p_snap == Vector2()) { return ret; } @@ -1315,15 +1317,16 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { bool apply = true; - if (p_floor_direction != Vector2()) { - if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { + if (p_up_direction != Vector2()) { + if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) { on_floor = true; + floor_normal = col.normal; on_floor_body = col.collider_rid; floor_velocity = col.collider_vel; if (p_stop_on_slope) { // move and collide may stray the object a bit because of pre un-stucking, // so only ensure that motion happens on floor direction in this case. - col.travel = p_floor_direction * p_floor_direction.dot(col.travel); + col.travel = p_up_direction * p_up_direction.dot(col.travel); } } else { @@ -1353,6 +1356,11 @@ bool KinematicBody2D::is_on_ceiling() const { return on_ceiling; } +Vector2 KinematicBody2D::get_floor_normal() const { + + return floor_normal; +} + Vector2 KinematicBody2D::get_floor_velocity() const { return floor_velocity; @@ -1465,14 +1473,15 @@ void KinematicBody2D::_notification(int p_what) { void KinematicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody2D::is_on_floor); ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody2D::is_on_ceiling); ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody2D::is_on_wall); + ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody2D::get_floor_normal); ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody2D::get_floor_velocity); ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 7f2b42b554..6766bafde3 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -306,6 +306,7 @@ public: private: float margin; + Vector2 floor_normal; Vector2 floor_velocity; RID on_floor_body; bool on_floor; @@ -339,11 +340,12 @@ public: void set_safe_margin(float p_margin); float get_safe_margin() const; - Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); - Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); + Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); + Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; + Vector2 get_floor_normal() const; Vector2 get_floor_velocity() const; int get_slide_count() const; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 7b03193fe0..c480423eca 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -33,6 +33,7 @@ #include "core/math/geometry.h" #include "skeleton_2d.h" +#ifdef TOOLS_ENABLED Dictionary Polygon2D::_edit_get_state() const { Dictionary state = Node2D::_edit_get_state(); state["offset"] = offset; @@ -87,6 +88,7 @@ bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toler } return Geometry::is_point_in_polygon(p_point - get_offset(), polygon2d); } +#endif void Polygon2D::_skeleton_bone_setup_changed() { update(); diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index 84ad221760..07b8828532 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -77,6 +77,7 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED virtual Dictionary _edit_get_state() const; virtual void _edit_set_state(const Dictionary &p_state); @@ -87,6 +88,7 @@ public: virtual bool _edit_use_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; +#endif void set_polygon(const PoolVector<Vector2> &p_polygon); PoolVector<Vector2> get_polygon() const; diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index 49ef92b861..cdeb905c0c 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -43,6 +43,7 @@ void Position2D::_draw_cross() { draw_line(Point2(0, -extents), Point2(0, +extents), Color(0.53, 0.84, 0.01)); } +#ifdef TOOLS_ENABLED Rect2 Position2D::_edit_get_rect() const { float extents = get_gizmo_extents(); @@ -52,6 +53,7 @@ Rect2 Position2D::_edit_get_rect() const { bool Position2D::_edit_use_rect() const { return false; } +#endif void Position2D::_notification(int p_what) { diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h index 711c4ec02f..3ea636171d 100644 --- a/scene/2d/position_2d.h +++ b/scene/2d/position_2d.h @@ -44,8 +44,10 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const; virtual bool _edit_use_rect() const; +#endif void set_gizmo_extents(float p_extents); float get_gizmo_extents() const; diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 837444532c..55daed0585 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -34,6 +34,7 @@ #include "scene/main/viewport.h" #include "scene/scene_string_names.h" +#ifdef TOOLS_ENABLED Dictionary Sprite::_edit_get_state() const { Dictionary state = Node2D::_edit_get_state(); state["offset"] = offset; @@ -58,6 +59,11 @@ bool Sprite::_edit_use_pivot() const { return true; } +bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { + + return is_pixel_opaque(p_point); +} + Rect2 Sprite::_edit_get_rect() const { return get_rect(); } @@ -65,6 +71,7 @@ Rect2 Sprite::_edit_get_rect() const { bool Sprite::_edit_use_rect() const { return texture.is_valid(); } +#endif Rect2 Sprite::get_anchorable_rect() const { return get_rect(); @@ -305,11 +312,6 @@ int Sprite::get_hframes() const { return hframes; } -bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - - return is_pixel_opaque(p_point); -} - bool Sprite::is_pixel_opaque(const Point2 &p_point) const { if (texture.is_null()) diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index 2fd97f6611..d72bf3168d 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -67,6 +67,7 @@ protected: virtual void _validate_property(PropertyInfo &property) const; public: +#ifdef TOOLS_ENABLED virtual Dictionary _edit_get_state() const; virtual void _edit_set_state(const Dictionary &p_state); @@ -75,10 +76,11 @@ public: virtual bool _edit_use_pivot() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; - bool is_pixel_opaque(const Point2 &p_point) const; - virtual Rect2 _edit_get_rect() const; virtual bool _edit_use_rect() const; +#endif + + bool is_pixel_opaque(const Point2 &p_point) const; void set_texture(const Ref<Texture> &p_texture); Ref<Texture> get_texture() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 04ec13e415..b6db025d44 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1282,6 +1282,7 @@ PoolVector<int> TileMap::_get_tile_data() const { return data; } +#ifdef TOOLS_ENABLED Rect2 TileMap::_edit_get_rect() const { if (pending_update) { const_cast<TileMap *>(this)->update_dirty_quadrants(); @@ -1290,6 +1291,7 @@ Rect2 TileMap::_edit_get_rect() const { } return rect_cache; } +#endif void TileMap::set_collision_layer(uint32_t p_layer) { diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 53bb696ba2..0875d197eb 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -244,7 +244,9 @@ public: INVALID_CELL = -1 }; +#ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const; +#endif void set_tileset(const Ref<TileSet> &p_tileset); Ref<TileSet> get_tileset() const; diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index f6a888fa09..42d9f88a60 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -135,7 +135,9 @@ void TouchScreenButton::_notification(int p_what) { return; if (shape.is_valid()) { Color draw_col = get_tree()->get_debug_collisions_color(); - Vector2 pos = shape_centered ? _edit_get_rect().size * 0.5f : Vector2(); + + Vector2 size = texture.is_null() ? shape->get_rect().size : texture->get_size(); + Vector2 pos = shape_centered ? size * 0.5f : Vector2(); draw_set_transform_matrix(get_canvas_transform().translated(pos)); shape->draw(get_canvas_item(), draw_col); } @@ -251,9 +253,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 = _edit_get_rect(); bool touched = false; bool check_rect = true; @@ -261,7 +261,7 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { if (shape.is_valid()) { check_rect = false; - Transform2D xform = shape_centered ? Transform2D().translated(item_rect.size * 0.5f) : Transform2D(); + Transform2D xform = shape_centered ? Transform2D().translated(shape->get_rect().size * 0.5f) : Transform2D(); touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); } @@ -277,7 +277,7 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { if (!touched && check_rect) { if (texture.is_valid()) - touched = item_rect.has_point(coord); + touched = Rect2(Size2(), texture->get_size()).has_point(coord); } return touched; @@ -324,6 +324,7 @@ void TouchScreenButton::_release(bool p_exiting_tree) { } } +#ifdef TOOLS_ENABLED Rect2 TouchScreenButton::_edit_get_rect() const { if (texture.is_null()) return CanvasItem::_edit_get_rect(); @@ -334,6 +335,7 @@ Rect2 TouchScreenButton::_edit_get_rect() const { bool TouchScreenButton::_edit_use_rect() const { return !texture.is_null(); } +#endif Rect2 TouchScreenButton::get_anchorable_rect() const { if (texture.is_null()) diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h index 9c9fc6125a..28dba59402 100644 --- a/scene/2d/touch_screen_button.h +++ b/scene/2d/touch_screen_button.h @@ -74,6 +74,11 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED + virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; +#endif + void set_texture(const Ref<Texture> &p_texture); Ref<Texture> get_texture() const; @@ -103,8 +108,6 @@ public: bool is_pressed() const; - virtual Rect2 _edit_get_rect() const; - virtual bool _edit_use_rect() const; virtual Rect2 get_anchorable_rect() const; TouchScreenButton(); diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 223e57f39f..0ac725b7dd 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -38,6 +38,16 @@ #include "scene/main/viewport.h" #include "scene/scene_string_names.h" +#ifdef TOOLS_ENABLED +Rect2 VisibilityNotifier2D::_edit_get_rect() const { + return rect; +} + +bool VisibilityNotifier2D::_edit_use_rect() const { + return true; +} +#endif + void VisibilityNotifier2D::_enter_viewport(Viewport *p_viewport) { ERR_FAIL_COND(viewports.has(p_viewport)); @@ -84,15 +94,6 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) { _change_notify("rect"); } -Rect2 VisibilityNotifier2D::_edit_get_rect() const { - - return rect; -} - -bool VisibilityNotifier2D::_edit_use_rect() const { - return true; -} - Rect2 VisibilityNotifier2D::get_rect() const { return rect; diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index f9d4c238eb..a3b79d29e9 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -55,8 +55,10 @@ protected: static void _bind_methods(); public: +#ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const; virtual bool _edit_use_rect() const; +#endif void set_rect(const Rect2 &p_rect); Rect2 get_rect() const; diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 289dc0ba07..3a30755f7f 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -398,9 +398,9 @@ Vector3 Camera::project_position(const Point2 &p_point, float p_z_depth) const { CameraMatrix cm; if (mode == PROJECTION_ORTHOGONAL) - cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); + cm.set_orthogonal(size, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH); else - cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); + cm.set_perspective(fov, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH); Size2 vp_size; cm.get_viewport_size(vp_size.x, vp_size.y); diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 0ac424b09e..aa7a413548 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -405,7 +405,7 @@ bool CPUParticles::get_particle_flag(Flags p_flag) const { } void CPUParticles::set_emission_shape(EmissionShape p_shape) { - + ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX); emission_shape = p_shape; } @@ -784,6 +784,9 @@ void CPUParticles::_particles_process(float p_delta) { p.base_color = emission_colors.get(random_idx); } } break; + case EMISSION_SHAPE_MAX: { // Max value for validity check. + break; + } } if (!local_coords) { @@ -1488,6 +1491,7 @@ void CPUParticles::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_BOX); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS); BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX); } CPUParticles::CPUParticles() { diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h index 18f9718e70..d5a549b976 100644 --- a/scene/3d/cpu_particles.h +++ b/scene/3d/cpu_particles.h @@ -75,6 +75,7 @@ public: EMISSION_SHAPE_BOX, EMISSION_SHAPE_POINTS, EMISSION_SHAPE_DIRECTED_POINTS, + EMISSION_SHAPE_MAX }; private: diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 44dc3d0c26..caeae90238 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -1140,7 +1140,7 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_in //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { Vector3 body_velocity = p_linear_velocity; Vector3 body_velocity_normal = body_velocity.normalized(); @@ -1151,23 +1151,15 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve } } - Vector3 current_floor_velocity = floor_velocity; - if (on_floor && on_floor_body.is_valid()) { - //this approach makes sure there is less delay between the actual body velocity and the one we saved - PhysicsDirectBodyState *bs = PhysicsServer::get_singleton()->body_get_direct_state(on_floor_body); - if (bs) { - current_floor_velocity = bs->get_linear_velocity(); - } - } - // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky - Vector3 motion = (current_floor_velocity + body_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); + Vector3 motion = (floor_velocity + body_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); on_floor = false; on_floor_body = RID(); on_ceiling = false; on_wall = false; colliders.clear(); + floor_normal = Vector3(); floor_velocity = Vector3(); while (p_max_slides) { @@ -1196,25 +1188,26 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve colliders.push_back(collision); motion = collision.remainder; - if (p_floor_direction == Vector3()) { + if (p_up_direction == Vector3()) { //all is a wall on_wall = true; } else { - if (Math::acos(collision.normal.dot(p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor + if (Math::acos(collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor on_floor = true; + floor_normal = collision.normal; on_floor_body = collision.collider_rid; floor_velocity = collision.collider_vel; if (p_stop_on_slope) { - if ((body_velocity_normal + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) { + if ((body_velocity_normal + p_up_direction).length() < 0.01 && collision.travel.length() < 1) { Transform gt = get_global_transform(); - gt.origin -= collision.travel.slide(p_floor_direction); + gt.origin -= collision.travel.slide(p_up_direction); set_global_transform(gt); return Vector3(); } } - } else if (Math::acos(collision.normal.dot(-p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling + } else if (Math::acos(collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling on_ceiling = true; } else { on_wall = true; @@ -1241,11 +1234,11 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve return body_velocity; } -Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { bool was_on_floor = on_floor; - Vector3 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); + Vector3 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); if (!was_on_floor || p_snap == Vector3()) { return ret; } @@ -1256,15 +1249,16 @@ Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { bool apply = true; - if (p_floor_direction != Vector3()) { - if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { + if (p_up_direction != Vector3()) { + if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) { on_floor = true; + floor_normal = col.normal; on_floor_body = col.collider_rid; floor_velocity = col.collider_vel; if (p_stop_on_slope) { // move and collide may stray the object a bit because of pre un-stucking, // so only ensure that motion happens on floor direction in this case. - col.travel = col.travel.project(p_floor_direction); + col.travel = col.travel.project(p_up_direction); } } else { apply = false; //snapped with floor direction, but did not snap to a floor, do not snap. @@ -1293,6 +1287,11 @@ bool KinematicBody::is_on_ceiling() const { return on_ceiling; } +Vector3 KinematicBody::get_floor_normal() const { + + return floor_normal; +} + Vector3 KinematicBody::get_floor_velocity() const { return floor_velocity; @@ -1401,14 +1400,15 @@ void KinematicBody::_notification(int p_what) { void KinematicBody::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody::test_move, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody::is_on_floor); ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody::is_on_ceiling); ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall); + ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody::get_floor_normal); ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity); ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &KinematicBody::set_axis_lock); diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index 06b31804b2..05bcbe22f0 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -300,6 +300,7 @@ private: float margin; + Vector3 floor_normal; Vector3 floor_velocity; RID on_floor_body; bool on_floor; @@ -330,11 +331,12 @@ public: void set_safe_margin(float p_margin); float get_safe_margin() const; - Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); - Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); + Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); + Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; + Vector3 get_floor_normal() const; Vector3 get_floor_velocity() const; int get_slide_count() const; diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp index 99a266af0d..518c243dd0 100644 --- a/scene/animation/skeleton_ik.cpp +++ b/scene/animation/skeleton_ik.cpp @@ -320,7 +320,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove new_bone_pose.basis = new_bone_pose.basis * p_task->chain.tips[0].end_effector->goal_transform.basis; } - p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0); + p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0, true); if (!ci->children.empty()) ci = &ci->children.write[0]; diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 65912c1c07..b2020d44e8 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -165,7 +165,7 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) { _pressed(); } } else { - if (!p_event->is_pressed()) { + if ((p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_PRESS) || (!p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_RELEASE)) { _pressed(); } } diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp index 9f4353ceb6..64d6885bc8 100644 --- a/scene/gui/center_container.cpp +++ b/scene/gui/center_container.cpp @@ -54,7 +54,13 @@ Size2 CenterContainer::get_minimum_size() const { void CenterContainer::set_use_top_left(bool p_enable) { + if (use_top_left == p_enable) { + return; + } + use_top_left = p_enable; + + minimum_size_changed(); queue_sort(); } diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index bab8d9167b..01f4070883 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -573,9 +573,7 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) { } if (index < 0 || index >= presets.size()) return; - preset->set_tooltip("Color: #" + presets[index].to_html(presets[index].a < 1) + "\n" - "LMB: Set color\n" - "RMB: Remove preset"); + preset->set_tooltip(vformat(RTR("Color: #%s\nLMB: Set color\nRMB: Remove preset"), presets[index].to_html(presets[index].a < 1))); } } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 5e656eea70..4f499af186 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -47,6 +47,7 @@ #include "editor/plugins/canvas_item_editor_plugin.h" #endif +#ifdef TOOLS_ENABLED Dictionary Control::_edit_get_state() const { Dictionary s; @@ -155,6 +156,11 @@ bool Control::_edit_use_pivot() const { return true; } +Size2 Control::_edit_get_minimum_size() const { + return get_combined_minimum_size(); +} +#endif + void Control::set_custom_minimum_size(const Size2 &p_custom) { if (p_custom == data.custom_minimum_size) @@ -193,11 +199,6 @@ Size2 Control::get_combined_minimum_size() const { return data.minimum_size_cache; } -Size2 Control::_edit_get_minimum_size() const { - - return get_combined_minimum_size(); -} - Transform2D Control::_get_internal_transform() const { Transform2D rot_scale; @@ -2681,6 +2682,11 @@ Vector2 Control::get_pivot_offset() const { void Control::set_scale(const Vector2 &p_scale) { data.scale = p_scale; + // Avoid having 0 scale values, can lead to errors in physics and rendering. + if (data.scale.x == 0) + data.scale.x = CMP_EPSILON; + if (data.scale.y == 0) + data.scale.y = CMP_EPSILON; update(); _notify_transform(); } diff --git a/scene/gui/control.h b/scene/gui/control.h index a9831b9793..357858beb6 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -279,6 +279,7 @@ public: }; /* EDITOR */ +#ifdef TOOLS_ENABLED virtual Dictionary _edit_get_state() const; virtual void _edit_set_state(const Dictionary &p_state); @@ -301,6 +302,7 @@ public: virtual bool _edit_use_pivot() const; virtual Size2 _edit_get_minimum_size() const; +#endif void accept_event(); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index d1650fea1e..00ce57eb04 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -200,6 +200,13 @@ void GraphEdit::_update_scroll() { else v_scroll->show(); + Size2 hmin = h_scroll->get_combined_minimum_size(); + Size2 vmin = v_scroll->get_combined_minimum_size(); + + // Avoid scrollbar overlapping. + h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, v_scroll->is_visible() ? -vmin.width : 0); + v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, h_scroll->is_visible() ? -hmin.height : 0); + set_block_minimum_size_adjust(false); if (!awaiting_scroll_offset_update) { @@ -286,15 +293,15 @@ void GraphEdit::_notification(int p_what) { Size2 hmin = h_scroll->get_combined_minimum_size(); Size2 vmin = v_scroll->get_combined_minimum_size(); - v_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -vmin.width); - v_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); - v_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0); - v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); - h_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 0); h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); h_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, -hmin.height); h_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); + + v_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -vmin.width); + v_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); + v_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0); + v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); } if (p_what == NOTIFICATION_DRAW) { @@ -777,14 +784,8 @@ void GraphEdit::_top_layer_draw() { } if (box_selecting) { - top_layer->draw_rect( - box_selecting_rect, - get_color("box_selection_fill_color", "Editor")); - - top_layer->draw_rect( - box_selecting_rect, - get_color("box_selection_stroke_color", "Editor"), - false); + top_layer->draw_rect(box_selecting_rect, get_color("selection_fill")); + top_layer->draw_rect(box_selecting_rect, get_color("selection_stroke"), false); } } @@ -1358,6 +1359,7 @@ GraphEdit::GraphEdit() { v_scroll = memnew(VScrollBar); v_scroll->set_name("_v_scroll"); top_layer->add_child(v_scroll); + updating = false; connecting = false; right_disconnects = false; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 2a812caf9a..526950dbb3 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -993,7 +993,7 @@ void ItemList::_notification(int p_what) { } //ensure_selected_visible needs to be checked before we draw the list. - if (ensure_selected_visible && current >= 0 && current <= items.size()) { + if (ensure_selected_visible && current >= 0 && current < items.size()) { Rect2 r = items[current].rect_cache; int from = scroll_bar->get_value(); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 11172ac7a9..77913efd1c 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -35,9 +35,17 @@ void Label::set_autowrap(bool p_autowrap) { + if (autowrap == p_autowrap) { + return; + } + autowrap = p_autowrap; word_cache_dirty = true; update(); + + if (clip) { + minimum_size_changed(); + } } bool Label::has_autowrap() const { @@ -103,8 +111,7 @@ void Label::_notification(int p_what) { int lines_visible = (size.y + line_spacing) / font_h; - // ceiling to ensure autowrapping does not cut text - int space_w = Math::ceil(font->get_char_size(' ').width); + real_t space_w = font->get_char_size(' ').width; int chars_total = 0; int vbegin = 0, vsep = 0; @@ -225,6 +232,7 @@ void Label::_notification(int p_what) { return; } if (from->space_count) { + chars_total += from->space_count; /* spacing */ x_ofs += space_w * from->space_count; if (can_fill && align == ALIGN_FILL && spaces) { @@ -313,8 +321,8 @@ Size2 Label::get_minimum_size() const { int Label::get_longest_line_width() const { Ref<Font> font = get_font("font"); - int max_line_width = 0; - int line_width = 0; + real_t max_line_width = 0; + real_t line_width = 0; for (int i = 0; i < xl_text.size(); i++) { @@ -332,8 +340,7 @@ int Label::get_longest_line_width() const { } } else { - // ceiling to ensure autowrapping does not cut text - int char_width = Math::ceil(font->get_char_size(current, xl_text[i + 1]).width); + real_t char_width = font->get_char_size(current, xl_text[i + 1]).width; line_width += char_width; } } @@ -341,7 +348,8 @@ int Label::get_longest_line_width() const { if (line_width > max_line_width) max_line_width = line_width; - return max_line_width; + // ceiling to ensure autowrapping does not cut text + return Math::ceil(max_line_width); } int Label::get_line_count() const { @@ -388,12 +396,11 @@ void Label::regenerate_word_cache() { Ref<Font> font = get_font("font"); - int current_word_size = 0; + real_t current_word_size = 0; int word_pos = 0; - int line_width = 0; + real_t line_width = 0; int space_count = 0; - // ceiling to ensure autowrapping does not cut text - int space_width = Math::ceil(font->get_char_size(' ').width); + real_t space_width = font->get_char_size(' ').width; int line_spacing = get_constant("line_spacing"); line_count = 1; total_char_cache = 0; @@ -413,7 +420,7 @@ void Label::regenerate_word_cache() { bool separatable = (current >= 0x2E08 && current <= 0xFAFF) || (current >= 0xFE30 && current <= 0xFE4F); //current>=33 && (current < 65||current >90) && (current<97||current>122) && (current<48||current>57); bool insert_newline = false; - int char_width = 0; + real_t char_width = 0; if (current < 33) { @@ -454,8 +461,7 @@ void Label::regenerate_word_cache() { if (current_word_size == 0) { word_pos = i; } - // ceiling to ensure autowrapping does not cut text - char_width = Math::ceil(font->get_char_size(current, xl_text[i + 1]).width); + char_width = font->get_char_size(current, xl_text[i + 1]).width; current_word_size += char_width; line_width += char_width; total_char_cache++; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 8f5f6beac3..0f3328dac5 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -557,8 +557,11 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { if (editable) { selection_delete(); CharType ucodestr[2] = { (CharType)k->get_unicode(), 0 }; + int prev_len = text.length(); append_at_cursor(ucodestr); - _text_changed(); + if (text.length() != prev_len) { + _text_changed(); + } accept_event(); } @@ -961,11 +964,12 @@ void LineEdit::paste_text() { if (paste_buffer != "") { + int prev_len = text.length(); if (selection.enabled) selection_delete(); append_at_cursor(paste_buffer); if (!text_changed_dirty) { - if (is_inside_tree()) { + if (is_inside_tree() && text.length() != prev_len) { MessageQueue::get_singleton()->push_call(this, "_text_changed"); } text_changed_dirty = true; @@ -1189,7 +1193,7 @@ void LineEdit::delete_char() { set_cursor_position(get_cursor_position() - 1); if (align == ALIGN_CENTER || align == ALIGN_RIGHT) { - window_pos = CLAMP(window_pos - 1, 0, text.length() - 1); + window_pos = CLAMP(window_pos - 1, 0, MAX(text.length() - 1, 0)); } _text_changed(); @@ -1220,7 +1224,7 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) { } if (align == ALIGN_CENTER || align == ALIGN_RIGHT) { - window_pos = CLAMP(window_pos - (p_to_column - p_from_column), 0, text.length() - 1); + window_pos = CLAMP(window_pos - (p_to_column - p_from_column), 0, MAX(text.length() - 1, 0)); } if (!text_changed_dirty) { @@ -1235,6 +1239,11 @@ void LineEdit::set_text(String p_text) { clear_internal(); append_at_cursor(p_text); + + if (expand_to_text_length) { + minimum_size_changed(); + } + update(); cursor_pos = 0; window_pos = 0; @@ -1362,6 +1371,8 @@ void LineEdit::append_at_cursor(String p_text) { String post = text.substr(cursor_pos, text.length() - cursor_pos); text = pre + p_text + post; set_cursor_position(cursor_pos + p_text.length()); + } else { + emit_signal("text_change_rejected"); } } @@ -1476,6 +1487,7 @@ void LineEdit::set_editable(bool p_editable) { editable = p_editable; _generate_context_menu(); + minimum_size_changed(); update(); } @@ -1611,7 +1623,11 @@ bool LineEdit::get_expand_to_text_length() const { } void LineEdit::set_clear_button_enabled(bool p_enabled) { + if (clear_button_enabled == p_enabled) { + return; + } clear_button_enabled = p_enabled; + minimum_size_changed(); update(); } @@ -1647,6 +1663,7 @@ void LineEdit::set_right_icon(const Ref<Texture> &p_icon) { return; } right_icon = p_icon; + minimum_size_changed(); update(); } @@ -1781,6 +1798,7 @@ void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_right_icon"), &LineEdit::get_right_icon); ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text"))); + ADD_SIGNAL(MethodInfo("text_change_rejected")); ADD_SIGNAL(MethodInfo("text_entered", PropertyInfo(Variant::STRING, "new_text"))); BIND_ENUM_CONSTANT(ALIGN_LEFT); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 5b7d7403ae..6c2928c65c 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -253,24 +253,25 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & } \ } -#define ENSURE_WIDTH(m_width) \ - if (p_mode == PROCESS_CACHE) { \ - l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width)); \ - l.minimum_width = MAX(l.minimum_width, m_width); \ - } \ - if (wofs + m_width > p_width) { \ - line_wrapped = true; \ - if (p_mode == PROCESS_CACHE) { \ - if (spaces > 0) \ - spaces -= 1; \ - } \ - if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh && p_click_pos.x > p_ofs.x + wofs) { \ - if (r_outside) *r_outside = true; \ - *r_click_item = it; \ - *r_click_char = rchar; \ - RETURN; \ - } \ - NEW_LINE \ +#define ENSURE_WIDTH(m_width) \ + if (p_mode == PROCESS_CACHE) { \ + l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width)); \ + l.minimum_width = MAX(l.minimum_width, m_width); \ + } \ + if (wofs + m_width > p_width) { \ + line_wrapped = true; \ + if (p_mode == PROCESS_CACHE) { \ + if (spaces > 0) \ + spaces -= 1; \ + } \ + const bool x_in_range = (p_click_pos.x > p_ofs.x + wofs) && (!p_frame->cell || p_click_pos.x < p_ofs.x + p_width); \ + if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh && x_in_range) { \ + if (r_outside) *r_outside = true; \ + *r_click_item = it; \ + *r_click_char = rchar; \ + RETURN; \ + } \ + NEW_LINE \ } #define ADVANCE(m_width) \ @@ -934,6 +935,14 @@ void RichTextLabel::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_MOUSE_EXIT: { + if (meta_hovering) { + meta_hovering = NULL; + emit_signal("meta_hover_ended", current_meta); + current_meta = false; + update(); + } + } break; case NOTIFICATION_RESIZED: { main->first_invalid_line = 0; //invalidate ALL @@ -1063,10 +1072,10 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const int line = 0; Item *item = NULL; + bool outside; + ((RichTextLabel *)(this))->_find_click(main, p_pos, &item, &line, &outside); - ((RichTextLabel *)(this))->_find_click(main, p_pos, &item, &line); - - if (item && ((RichTextLabel *)(this))->_find_meta(item, NULL)) + if (item && !outside && ((RichTextLabel *)(this))->_find_meta(item, NULL)) return CURSOR_POINTING_HAND; return CURSOR_ARROW; diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index dc1183df74..509e6d19f6 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -219,16 +219,16 @@ void ScrollContainer::_update_scrollbar_position() { Size2 hmin = h_scroll->get_combined_minimum_size(); Size2 vmin = v_scroll->get_combined_minimum_size(); - v_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -vmin.width); - v_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); - v_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0); - v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); - h_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 0); h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); h_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, -hmin.height); h_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); + v_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -vmin.width); + v_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); + v_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0); + v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); + h_scroll->raise(); v_scroll->raise(); } @@ -317,6 +317,7 @@ void ScrollContainer::_notification(int p_what) { r.position += ofs; fit_child_in_rect(c, r); } + update(); }; @@ -408,13 +409,17 @@ void ScrollContainer::update_scrollbars() { Size2 hmin; Size2 vmin; - if (scroll_h) hmin = h_scroll->get_combined_minimum_size(); - if (scroll_v) vmin = v_scroll->get_combined_minimum_size(); + if (scroll_h) { + hmin = h_scroll->get_combined_minimum_size(); + } + if (scroll_v) { + vmin = v_scroll->get_combined_minimum_size(); + } Size2 min = child_max_size; - bool hide_scroll_v = !scroll_v || min.height <= size.height - hmin.height; - bool hide_scroll_h = !scroll_h || min.width <= size.width - vmin.width; + bool hide_scroll_v = !scroll_v || min.height <= size.height; + bool hide_scroll_h = !scroll_h || min.width <= size.width; if (hide_scroll_v) { @@ -449,6 +454,10 @@ void ScrollContainer::update_scrollbars() { scroll.x = h_scroll->get_value(); } + + // Avoid scrollbar overlapping. + h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, hide_scroll_v ? 0 : -vmin.width); + v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, hide_scroll_h ? 0 : -hmin.height); } void ScrollContainer::_scroll_moved(float) { @@ -461,8 +470,12 @@ void ScrollContainer::_scroll_moved(float) { }; void ScrollContainer::set_enable_h_scroll(bool p_enable) { + if (scroll_h == p_enable) { + return; + } scroll_h = p_enable; + minimum_size_changed(); queue_sort(); } @@ -472,8 +485,12 @@ bool ScrollContainer::is_h_scroll_enabled() const { } void ScrollContainer::set_enable_v_scroll(bool p_enable) { + if (scroll_v == p_enable) { + return; + } scroll_v = p_enable; + minimum_size_changed(); queue_sort(); } @@ -593,12 +610,11 @@ ScrollContainer::ScrollContainer() { h_scroll = memnew(HScrollBar); h_scroll->set_name("_h_scroll"); add_child(h_scroll); + h_scroll->connect("value_changed", this, "_scroll_moved"); v_scroll = memnew(VScrollBar); v_scroll->set_name("_v_scroll"); add_child(v_scroll); - - h_scroll->connect("value_changed", this, "_scroll_moved"); v_scroll->connect("value_changed", this, "_scroll_moved"); drag_speed = Vector2(); diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index d5da35955c..92377949f8 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -259,6 +259,10 @@ bool SpinBox::is_editable() const { return line_edit->is_editable(); } +void SpinBox::apply() { + _text_entered(line_edit->get_text()); +} + void SpinBox::_bind_methods() { //ClassDB::bind_method(D_METHOD("_value_changed"),&SpinBox::_value_changed); @@ -272,6 +276,7 @@ void SpinBox::_bind_methods() { ClassDB::bind_method(D_METHOD("get_prefix"), &SpinBox::get_prefix); ClassDB::bind_method(D_METHOD("set_editable", "editable"), &SpinBox::set_editable); ClassDB::bind_method(D_METHOD("is_editable"), &SpinBox::is_editable); + ClassDB::bind_method(D_METHOD("apply"), &SpinBox::apply); ClassDB::bind_method(D_METHOD("_line_edit_focus_exit"), &SpinBox::_line_edit_focus_exit); ClassDB::bind_method(D_METHOD("get_line_edit"), &SpinBox::get_line_edit); ClassDB::bind_method(D_METHOD("_line_edit_input"), &SpinBox::_line_edit_input); diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 13ba168ef3..04491c8477 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -88,6 +88,8 @@ public: void set_prefix(const String &p_prefix); String get_prefix() const; + void apply(); + SpinBox(); }; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index d7e469ca26..6de2f0b570 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -7070,6 +7070,10 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_smooth_scroll_enabled"), &TextEdit::is_smooth_scroll_enabled); ClassDB::bind_method(D_METHOD("set_v_scroll_speed", "speed"), &TextEdit::set_v_scroll_speed); ClassDB::bind_method(D_METHOD("get_v_scroll_speed"), &TextEdit::get_v_scroll_speed); + ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &TextEdit::set_v_scroll); + ClassDB::bind_method(D_METHOD("get_v_scroll"), &TextEdit::get_v_scroll); + ClassDB::bind_method(D_METHOD("set_h_scroll", "value"), &TextEdit::set_h_scroll); + ClassDB::bind_method(D_METHOD("get_h_scroll"), &TextEdit::get_h_scroll); ClassDB::bind_method(D_METHOD("add_keyword_color", "keyword", "color"), &TextEdit::add_keyword_color); ClassDB::bind_method(D_METHOD("has_keyword_color", "keyword"), &TextEdit::has_keyword_color); @@ -7105,6 +7109,8 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hiding_enabled"), "set_hiding_enabled", "is_hiding_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "wrap_enabled"), "set_wrap_enabled", "is_wrap_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "scroll_vertical"), "set_v_scroll", "get_v_scroll"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_horizontal"), "set_h_scroll", "get_h_scroll"); ADD_GROUP("Minimap", "minimap_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "minimap_draw"), "draw_minimap", "is_drawing_minimap"); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 1e2b7c094e..350959dcc3 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2680,7 +2680,8 @@ void Node::clear_internal_tree_resource_paths() { String Node::get_configuration_warning() const { - if (get_script_instance() && get_script_instance()->has_method("_get_configuration_warning")) { + if (get_script_instance() && get_script_instance()->get_script().is_valid() && + get_script_instance()->get_script()->is_tool() && get_script_instance()->has_method("_get_configuration_warning")) { return get_script_instance()->call("_get_configuration_warning"); } return String(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 9e9a25883e..a56903636f 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -30,6 +30,7 @@ #include "viewport.h" +#include "core/core_string_names.h" #include "core/os/input.h" #include "core/os/os.h" #include "core/project_settings.h" @@ -251,6 +252,27 @@ void Viewport::_collision_object_input_event(CollisionObject *p_object, Camera * physics_last_id = id; } +void Viewport::_own_world_changed() { + ERR_FAIL_COND(world.is_null()); + ERR_FAIL_COND(own_world.is_null()); + + if (is_inside_tree()) { + _propagate_exit_world(this); + } + + own_world = world->duplicate(); + + if (is_inside_tree()) { + _propagate_enter_world(this); + } + + if (is_inside_tree()) { + VisualServer::get_singleton()->viewport_set_scenario(viewport, find_world()->get_scenario()); + } + + _update_listener(); +} + void Viewport::_notification(int p_what) { switch (p_what) { @@ -1105,8 +1127,21 @@ void Viewport::set_world(const Ref<World> &p_world) { if (is_inside_tree()) _propagate_exit_world(this); + if (own_world.is_valid() && world.is_valid()) { + world->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed"); + } + world = p_world; + if (own_world.is_valid()) { + if (world.is_valid()) { + own_world = world->duplicate(); + world->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed"); + } else { + own_world = Ref<World>(memnew(World)); + } + } + if (is_inside_tree()) _propagate_enter_world(this); @@ -2826,10 +2861,19 @@ void Viewport::set_use_own_world(bool p_world) { if (is_inside_tree()) _propagate_exit_world(this); - if (!p_world) + if (!p_world) { own_world = Ref<World>(); - else - own_world = Ref<World>(memnew(World)); + if (world.is_valid()) { + world->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed"); + } + } else { + if (world.is_valid()) { + own_world = world->duplicate(); + world->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed"); + } else { + own_world = Ref<World>(memnew(World)); + } + } if (is_inside_tree()) _propagate_enter_world(this); @@ -3178,6 +3222,8 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("_subwindow_visibility_changed"), &Viewport::_subwindow_visibility_changed); + ClassDB::bind_method(D_METHOD("_own_world_changed"), &Viewport::_own_world_changed); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arvr"), "set_use_arvr", "use_arvr"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 396bbc91cd..79b606cda3 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -406,6 +406,8 @@ private: void _update_canvas_items(Node *p_node); + void _own_world_changed(); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 21fc9ccf6a..09d4505458 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -372,6 +372,28 @@ void register_scene_types() { ClassDB::register_class<AnimationPlayer>(); ClassDB::register_class<Tween>(); + ClassDB::register_class<AnimationTreePlayer>(); + ClassDB::register_class<AnimationTree>(); + ClassDB::register_class<AnimationNode>(); + ClassDB::register_class<AnimationRootNode>(); + ClassDB::register_class<AnimationNodeBlendTree>(); + ClassDB::register_class<AnimationNodeBlendSpace1D>(); + ClassDB::register_class<AnimationNodeBlendSpace2D>(); + ClassDB::register_class<AnimationNodeStateMachine>(); + ClassDB::register_class<AnimationNodeStateMachinePlayback>(); + + ClassDB::register_class<AnimationNodeStateMachineTransition>(); + ClassDB::register_class<AnimationNodeOutput>(); + ClassDB::register_class<AnimationNodeOneShot>(); + ClassDB::register_class<AnimationNodeAnimation>(); + ClassDB::register_class<AnimationNodeAdd2>(); + ClassDB::register_class<AnimationNodeAdd3>(); + ClassDB::register_class<AnimationNodeBlend2>(); + ClassDB::register_class<AnimationNodeBlend3>(); + ClassDB::register_class<AnimationNodeTimeScale>(); + ClassDB::register_class<AnimationNodeTimeSeek>(); + ClassDB::register_class<AnimationNodeTransition>(); + OS::get_singleton()->yield(); //may take time to init #ifndef _3D_DISABLED @@ -399,7 +421,6 @@ void register_scene_types() { ClassDB::register_class<GIProbeData>(); ClassDB::register_class<BakedLightmap>(); ClassDB::register_class<BakedLightmapData>(); - ClassDB::register_class<AnimationTreePlayer>(); ClassDB::register_class<Particles>(); ClassDB::register_class<CPUParticles>(); ClassDB::register_class<Position3D>(); @@ -410,27 +431,6 @@ void register_scene_types() { ClassDB::register_class<RootMotionView>(); ClassDB::set_class_enabled("RootMotionView", false); //disabled by default, enabled by editor - ClassDB::register_class<AnimationTree>(); - ClassDB::register_class<AnimationNode>(); - ClassDB::register_class<AnimationRootNode>(); - ClassDB::register_class<AnimationNodeBlendTree>(); - ClassDB::register_class<AnimationNodeBlendSpace1D>(); - ClassDB::register_class<AnimationNodeBlendSpace2D>(); - ClassDB::register_class<AnimationNodeStateMachine>(); - ClassDB::register_class<AnimationNodeStateMachinePlayback>(); - - ClassDB::register_class<AnimationNodeStateMachineTransition>(); - ClassDB::register_class<AnimationNodeOutput>(); - ClassDB::register_class<AnimationNodeOneShot>(); - ClassDB::register_class<AnimationNodeAnimation>(); - ClassDB::register_class<AnimationNodeAdd2>(); - ClassDB::register_class<AnimationNodeAdd3>(); - ClassDB::register_class<AnimationNodeBlend2>(); - ClassDB::register_class<AnimationNodeBlend3>(); - ClassDB::register_class<AnimationNodeTimeScale>(); - ClassDB::register_class<AnimationNodeTimeSeek>(); - ClassDB::register_class<AnimationNodeTransition>(); - OS::get_singleton()->yield(); //may take time to init ClassDB::register_virtual_class<CollisionObject>(); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 67351f07d2..cc76df62e5 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -851,6 +851,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("bg", "GraphEdit", make_stylebox(tree_bg_png, 4, 4, 4, 5)); theme->set_color("grid_minor", "GraphEdit", Color(1, 1, 1, 0.05)); theme->set_color("grid_major", "GraphEdit", Color(1, 1, 1, 0.2)); + theme->set_color("selection_fill", "GraphEdit", Color(1, 1, 1, 0.3)); + theme->set_color("selection_stroke", "GraphEdit", Color(1, 1, 1, 0.8)); theme->set_color("activity", "GraphEdit", Color(1, 1, 1)); theme->set_constant("bezier_len_pos", "GraphEdit", 80 * scale); theme->set_constant("bezier_len_neg", "GraphEdit", 160 * scale); diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 42fec3a0a7..8b619345d6 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -195,13 +195,13 @@ Error DynamicFontAtSize::_load() { if (FT_HAS_COLOR(face) && face->num_fixed_sizes > 0) { int best_match = 0; int diff = ABS(id.size - ((int64_t)face->available_sizes[0].width)); - scale_color_font = float(id.size) / face->available_sizes[0].width; + scale_color_font = float(id.size * oversampling) / face->available_sizes[0].width; for (int i = 1; i < face->num_fixed_sizes; i++) { int ndiff = ABS(id.size - ((int64_t)face->available_sizes[i].width)); if (ndiff < diff) { best_match = i; diff = ndiff; - scale_color_font = float(id.size) / face->available_sizes[i].width; + scale_color_font = float(id.size * oversampling) / face->available_sizes[i].width; } } FT_Select_Size(face, best_match); @@ -299,7 +299,7 @@ void DynamicFontAtSize::set_texture_flags(uint32_t p_flags) { } } -float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only) const { +float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only, bool p_outline) const { if (!valid) return 0; @@ -314,6 +314,20 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT float advance = 0.0; + // use normal character size if there's no outline character + if (p_outline && !ch->found) { + FT_GlyphSlot slot = face->glyph; + int error = FT_Load_Char(face, p_char, FT_HAS_COLOR(face) ? FT_LOAD_COLOR : FT_LOAD_DEFAULT); + if (!error) { + error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); + if (!error) { + Character character = Character::not_found(); + character = const_cast<DynamicFontAtSize *>(this)->_bitmap_to_character(slot->bitmap, slot->bitmap_top, slot->bitmap_left, slot->advance.x / 64.0); + advance = character.advance; + } + } + } + if (ch->found) { ERR_FAIL_COND_V(ch->texture_idx < -1 || ch->texture_idx >= font->textures.size(), 0); @@ -875,7 +889,7 @@ float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_ // If requested outline draw, but no outline is present, simply return advance without drawing anything bool advance_only = p_outline && outline_cache_id.outline_size == 0; - return font_at_size->draw_char(p_canvas_item, p_pos, p_char, p_next, color, fallbacks, advance_only) + spacing_char; + return font_at_size->draw_char(p_canvas_item, p_pos, p_char, p_next, color, fallbacks, advance_only, p_outline) + spacing_char; } void DynamicFont::set_fallback(int p_idx, const Ref<DynamicFontData> &p_data) { diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index ece150c4ce..2dafd3ce4f 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -192,7 +192,7 @@ public: Size2 get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const; - float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only = false) const; + float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only = false, bool p_outline = false) const; void set_texture_flags(uint32_t p_flags); void update_oversampling(); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 13721191c0..0599920303 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -75,6 +75,7 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { continue; Array a = surface_get_arrays(i); + ERR_FAIL_COND_V(a.empty(), Ref<TriangleMesh>()); int vc = surface_get_array_len(i); PoolVector<Vector3> vertices = a[ARRAY_VERTEX]; @@ -234,6 +235,7 @@ Ref<Shape> Mesh::create_convex_shape() const { for (int i = 0; i < get_surface_count(); i++) { Array a = surface_get_arrays(i); + ERR_FAIL_COND_V(a.empty(), Ref<ConvexPolygonShape>()); PoolVector<Vector3> v = a[ARRAY_VERTEX]; vertices.append_array(v); } @@ -273,6 +275,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { continue; Array a = surface_get_arrays(i); + ERR_FAIL_COND_V(a.empty(), Ref<ArrayMesh>()); if (i == 0) { arrays = a; @@ -378,6 +381,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { PoolVector<Vector3>::Write r = vertices.write(); if (indices.size()) { + ERR_FAIL_COND_V(indices.size() % 3 != 0, Ref<ArrayMesh>()); vc = indices.size(); ir = indices.write(); has_indices = true; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 5a2cd9a1c2..3e7d350eec 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -39,7 +39,7 @@ #include "scene/gui/control.h" #include "scene/main/instance_placeholder.h" -#define PACK_VERSION 2 +#define PACKED_SCENE_VERSION 2 bool SceneState::can_instance() const { @@ -1095,7 +1095,15 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) { if (p_dictionary.has("version")) version = p_dictionary["version"]; - ERR_FAIL_COND_MSG(version > PACK_VERSION, "Save format version too new."); + ERR_FAIL_COND_MSG(version > PACKED_SCENE_VERSION, "Save format version too new."); + + const int node_count = p_dictionary["node_count"]; + const PoolVector<int> snodes = p_dictionary["nodes"]; + ERR_FAIL_COND(snodes.size() < node_count); + + const int conn_count = p_dictionary["conn_count"]; + const PoolVector<int> sconns = p_dictionary["conns"]; + ERR_FAIL_COND(sconns.size() < conn_count); PoolVector<String> snames = p_dictionary["names"]; if (snames.size()) { @@ -1121,13 +1129,11 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) { variants.clear(); } - nodes.resize(p_dictionary["node_count"]); - int nc = nodes.size(); - if (nc) { - PoolVector<int> snodes = p_dictionary["nodes"]; + nodes.resize(node_count); + if (node_count) { PoolVector<int>::Read r = snodes.read(); int idx = 0; - for (int i = 0; i < nc; i++) { + for (int i = 0; i < node_count; i++) { NodeData &nd = nodes.write[i]; nd.parent = r[idx++]; nd.owner = r[idx++]; @@ -1151,15 +1157,11 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) { } } - connections.resize(p_dictionary["conn_count"]); - int cc = connections.size(); - - if (cc) { - - PoolVector<int> sconns = p_dictionary["conns"]; + connections.resize(conn_count); + if (conn_count) { PoolVector<int>::Read r = sconns.read(); int idx = 0; - for (int i = 0; i < cc; i++) { + for (int i = 0; i < conn_count; i++) { ConnectionData &cd = connections.write[i]; cd.from = r[idx++]; cd.to = r[idx++]; @@ -1283,9 +1285,7 @@ Dictionary SceneState::get_bundled_scene() const { d["base_scene"] = base_scene_idx; } - d["version"] = PACK_VERSION; - - //d["path"]=path; + d["version"] = PACKED_SCENE_VERSION; return d; } diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index a058f42cb2..412b5c259c 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -198,6 +198,9 @@ void ParticlesMaterial::_update_shader() { code += "uniform sampler2D emission_texture_color : hint_white;\n"; } } break; + case EMISSION_SHAPE_MAX: { // Max value for validity check. + break; + } } code += "uniform vec4 color_value : hint_color;\n"; @@ -283,7 +286,7 @@ void ParticlesMaterial::_update_shader() { code += " float degree_to_rad = pi / 180.0;\n"; code += "\n"; - if (emission_shape >= EMISSION_SHAPE_POINTS) { + if (emission_shape == EMISSION_SHAPE_POINTS || emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) { code += " int point = min(emission_texture_point_count - 1, int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));\n"; code += " ivec2 emission_tex_size = textureSize(emission_texture_points, 0);\n"; code += " ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);\n"; @@ -368,6 +371,9 @@ void ParticlesMaterial::_update_shader() { } } } break; + case EMISSION_SHAPE_MAX: { // Max value for validity check. + break; + } } code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; @@ -515,7 +521,7 @@ void ParticlesMaterial::_update_shader() { } else { code += " COLOR = hue_rot_mat * color_value;\n"; } - if (emission_color_texture.is_valid() && emission_shape >= EMISSION_SHAPE_POINTS) { + if (emission_color_texture.is_valid() && (emission_shape == EMISSION_SHAPE_POINTS || emission_shape == EMISSION_SHAPE_DIRECTED_POINTS)) { code += " COLOR *= texelFetch(emission_texture_color, emission_tex_ofs, 0);\n"; } if (trail_color_modifier.is_valid()) { @@ -894,7 +900,7 @@ bool ParticlesMaterial::get_flag(Flags p_flag) const { } void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) { - + ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX); emission_shape = p_shape; _change_notify(); _queue_shader_change(); @@ -1242,6 +1248,7 @@ void ParticlesMaterial::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_BOX); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS); BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX); } ParticlesMaterial::ParticlesMaterial() : diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 643c2cb10e..cc860b3812 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -69,6 +69,7 @@ public: EMISSION_SHAPE_BOX, EMISSION_SHAPE_POINTS, EMISSION_SHAPE_DIRECTED_POINTS, + EMISSION_SHAPE_MAX }; private: diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index c59fa8cab8..9408d1aa71 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -719,6 +719,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { bool rounded_corners = (corner_radius[0] > 0) || (corner_radius[1] > 0) || (corner_radius[2] > 0) || (corner_radius[3] > 0); bool aa_on = rounded_corners && anti_aliased; + float aa_size_grow = 0.5 * ((float)aa_size + 1.0); bool blend_on = blend_border && draw_border; @@ -744,7 +745,6 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { Rect2 border_style_rect = style_rect; if (aa_on) { - float aa_size_grow = 0.5 * ((aa_size + 1) / 2); for (int i = 0; i < 4; i++) { if (border_width[i] > 0) { border_style_rect = border_style_rect.grow_margin((Margin)i, -aa_size_grow); @@ -789,7 +789,6 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { } if (aa_on) { - float aa_size_grow = 0.5 * ((aa_size + 1) / 2); int aa_border_width[4]; int aa_fill_width[4]; if (draw_border) { @@ -804,6 +803,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { } } else { for (int i = 0; i < 4; i++) { + aa_border_width[i] = 0; aa_fill_width[i] = aa_size_grow; } } @@ -844,7 +844,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { } //COMPUTE UV COORDINATES - Rect2 uv_rect = style_rect.grow(aa_on ? aa_size : 0); + Rect2 uv_rect = style_rect.grow(aa_on ? aa_size_grow : 0); uvs.resize(verts.size()); for (int i = 0; i < verts.size(); i++) { uvs.write[i].x = (verts[i].x - uv_rect.position.x) / uv_rect.size.width; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index dc2b708ae7..4d23f0eb41 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -2271,6 +2271,7 @@ void TextureLayered::create(uint32_t p_width, uint32_t p_height, uint32_t p_dept void TextureLayered::set_layer_data(const Ref<Image> &p_image, int p_layer) { ERR_FAIL_COND(!texture.is_valid()); + ERR_FAIL_COND(!p_image.is_valid()); VS::get_singleton()->texture_set_data(texture, p_image, p_layer); } @@ -2282,6 +2283,7 @@ Ref<Image> TextureLayered::get_layer_data(int p_layer) const { void TextureLayered::set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap) { ERR_FAIL_COND(!texture.is_valid()); + ERR_FAIL_COND(!p_image.is_valid()); VS::get_singleton()->texture_set_data_partial(texture, p_image, 0, 0, p_image->get_width(), p_image->get_height(), p_x_ofs, p_y_ofs, p_mipmap, p_z); } diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 0035a138d7..f46fba3b5b 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -3685,12 +3685,33 @@ String VisualShaderNodeFresnel::get_output_port_name(int p_port) const { } String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + p_input_vars[0] + ", " + p_input_vars[1] + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + p_input_vars[0] + ", " + p_input_vars[1] + "), 0.0, 1.0), " + p_input_vars[3] + "));"; + + String normal; + String view; + if (p_input_vars[0] == String()) { + normal = "NORMAL"; + } else { + normal = p_input_vars[0]; + } + if (p_input_vars[1] == String()) { + view = "VIEW"; + } else { + view = p_input_vars[1]; + } + + return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));"; +} + +String VisualShaderNodeFresnel::get_input_port_default_hint(int p_port) const { + if (p_port == 0) { + return "default"; + } else if (p_port == 1) { + return "default"; + } + return ""; } VisualShaderNodeFresnel::VisualShaderNodeFresnel() { - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(2, false); set_input_port_default_value(3, 1.0); } diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 99b4c01d53..0f428088e0 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -1579,6 +1579,7 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; + virtual String get_input_port_default_hint(int p_port) const; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; VisualShaderNodeFresnel(); diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp index b498acd707..1099852098 100644 --- a/scene/resources/world.cpp +++ b/scene/resources/world.cpp @@ -268,12 +268,17 @@ RID World::get_scenario() const { } void World::set_environment(const Ref<Environment> &p_environment) { + if (environment == p_environment) { + return; + } environment = p_environment; if (environment.is_valid()) VS::get_singleton()->scenario_set_environment(scenario, environment->get_rid()); else VS::get_singleton()->scenario_set_environment(scenario, RID()); + + emit_changed(); } Ref<Environment> World::get_environment() const { @@ -282,12 +287,17 @@ Ref<Environment> World::get_environment() const { } void World::set_fallback_environment(const Ref<Environment> &p_environment) { + if (fallback_environment == p_environment) { + return; + } fallback_environment = p_environment; if (fallback_environment.is_valid()) VS::get_singleton()->scenario_set_fallback_environment(scenario, p_environment->get_rid()); else VS::get_singleton()->scenario_set_fallback_environment(scenario, RID()); + + emit_changed(); } Ref<Environment> World::get_fallback_environment() const { |