diff options
Diffstat (limited to 'scene')
46 files changed, 681 insertions, 371 deletions
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 6b842e6e6b..907fb7e6a9 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -76,10 +76,10 @@ void NavigationAgent2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent2D::set_navigation_map); ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent2D::get_navigation_map); - ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent2D::set_target_location); - ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent2D::get_target_location); + ClassDB::bind_method(D_METHOD("set_target_position", "position"), &NavigationAgent2D::set_target_position); + ClassDB::bind_method(D_METHOD("get_target_position"), &NavigationAgent2D::get_target_position); - ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent2D::get_next_location); + ClassDB::bind_method(D_METHOD("get_next_path_position"), &NavigationAgent2D::get_next_path_position); ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent2D::distance_to_target); ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent2D::set_velocity); ClassDB::bind_method(D_METHOD("get_current_navigation_result"), &NavigationAgent2D::get_current_navigation_result); @@ -88,12 +88,12 @@ void NavigationAgent2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent2D::is_target_reached); ClassDB::bind_method(D_METHOD("is_target_reachable"), &NavigationAgent2D::is_target_reachable); ClassDB::bind_method(D_METHOD("is_navigation_finished"), &NavigationAgent2D::is_navigation_finished); - ClassDB::bind_method(D_METHOD("get_final_location"), &NavigationAgent2D::get_final_location); + ClassDB::bind_method(D_METHOD("get_final_position"), &NavigationAgent2D::get_final_position); ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent2D::_avoidance_done); ADD_GROUP("Pathfinding", ""); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_location", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_location", "get_target_location"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_position", "get_target_position"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,suffix:px"), "set_path_desired_distance", "get_path_desired_distance"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,suffix:px"), "set_target_desired_distance", "get_target_desired_distance"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,1000,1,suffix:px"), "set_path_max_distance", "get_path_max_distance"); @@ -328,17 +328,17 @@ real_t NavigationAgent2D::get_path_max_distance() { return path_max_distance; } -void NavigationAgent2D::set_target_location(Vector2 p_location) { - target_location = p_location; +void NavigationAgent2D::set_target_position(Vector2 p_position) { + target_position = p_position; target_position_submitted = true; _request_repath(); } -Vector2 NavigationAgent2D::get_target_location() const { - return target_location; +Vector2 NavigationAgent2D::get_target_position() const { + return target_position; } -Vector2 NavigationAgent2D::get_next_location() { +Vector2 NavigationAgent2D::get_next_path_position() { update_navigation(); const Vector<Vector2> &navigation_path = navigation_result->get_path(); @@ -352,7 +352,7 @@ Vector2 NavigationAgent2D::get_next_location() { real_t NavigationAgent2D::distance_to_target() const { ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent."); - return agent_parent->get_global_position().distance_to(target_location); + return agent_parent->get_global_position().distance_to(target_position); } bool NavigationAgent2D::is_target_reached() const { @@ -360,7 +360,7 @@ bool NavigationAgent2D::is_target_reached() const { } bool NavigationAgent2D::is_target_reachable() { - return target_desired_distance >= get_final_location().distance_to(target_location); + return target_desired_distance >= get_final_position().distance_to(target_position); } bool NavigationAgent2D::is_navigation_finished() { @@ -368,7 +368,7 @@ bool NavigationAgent2D::is_navigation_finished() { return navigation_finished; } -Vector2 NavigationAgent2D::get_final_location() { +Vector2 NavigationAgent2D::get_final_position() { update_navigation(); const Vector<Vector2> &navigation_path = navigation_result->get_path(); @@ -450,7 +450,7 @@ void NavigationAgent2D::update_navigation() { if (reload_path) { navigation_query->set_start_position(origin); - navigation_query->set_target_position(target_location); + navigation_query->set_target_position(target_position); navigation_query->set_navigation_layers(navigation_layers); navigation_query->set_metadata_flags(path_metadata_flags); @@ -472,7 +472,7 @@ void NavigationAgent2D::update_navigation() { // Check if we can advance the navigation path if (navigation_finished == false) { - // Advances to the next far away location. + // Advances to the next far away position. const Vector<Vector2> &navigation_path = navigation_result->get_path(); const Vector<int32_t> &navigation_path_types = navigation_result->get_path_types(); const TypedArray<RID> &navigation_path_rids = navigation_result->get_path_rids(); @@ -482,7 +482,7 @@ void NavigationAgent2D::update_navigation() { Dictionary details; const Vector2 waypoint = navigation_path[navigation_path_index]; - details[SNAME("location")] = waypoint; + details[SNAME("position")] = waypoint; int waypoint_type = -1; if (path_metadata_flags.has_flag(NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_TYPES)) { diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 190a2fcbda..9787bb1bdb 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -60,7 +60,7 @@ class NavigationAgent2D : public Node { real_t path_max_distance = 100.0; - Vector2 target_location; + Vector2 target_position; bool target_position_submitted = false; Ref<NavigationPathQueryParameters2D> navigation_query; Ref<NavigationPathQueryResult2D> navigation_result; @@ -143,10 +143,10 @@ public: void set_path_max_distance(real_t p_pmd); real_t get_path_max_distance(); - void set_target_location(Vector2 p_location); - Vector2 get_target_location() const; + void set_target_position(Vector2 p_position); + Vector2 get_target_position() const; - Vector2 get_next_location(); + Vector2 get_next_path_position(); Ref<NavigationPathQueryResult2D> get_current_navigation_result() const { return navigation_result; @@ -162,7 +162,7 @@ public: bool is_target_reached() const; bool is_target_reachable(); bool is_navigation_finished(); - Vector2 get_final_location(); + Vector2 get_final_position(); void set_velocity(Vector2 p_velocity); void _avoidance_done(Vector3 p_new_velocity); diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation_link_2d.cpp index 9ef0ba617e..65bf178cc5 100644 --- a/scene/2d/navigation_link_2d.cpp +++ b/scene/2d/navigation_link_2d.cpp @@ -48,11 +48,11 @@ void NavigationLink2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationLink2D::set_navigation_layer_value); ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationLink2D::get_navigation_layer_value); - ClassDB::bind_method(D_METHOD("set_start_location", "location"), &NavigationLink2D::set_start_location); - ClassDB::bind_method(D_METHOD("get_start_location"), &NavigationLink2D::get_start_location); + ClassDB::bind_method(D_METHOD("set_start_position", "position"), &NavigationLink2D::set_start_position); + ClassDB::bind_method(D_METHOD("get_start_position"), &NavigationLink2D::get_start_position); - ClassDB::bind_method(D_METHOD("set_end_location", "location"), &NavigationLink2D::set_end_location); - ClassDB::bind_method(D_METHOD("get_end_location"), &NavigationLink2D::get_end_location); + ClassDB::bind_method(D_METHOD("set_end_position", "position"), &NavigationLink2D::set_end_position); + ClassDB::bind_method(D_METHOD("get_end_position"), &NavigationLink2D::get_end_position); ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink2D::set_enter_cost); ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink2D::get_enter_cost); @@ -63,12 +63,38 @@ void NavigationLink2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bidirectional"), "set_bidirectional", "is_bidirectional"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_location"), "set_start_location", "get_start_location"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "end_location"), "set_end_location", "get_end_location"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_position"), "set_start_position", "get_start_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "end_position"), "set_end_position", "get_end_position"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "enter_cost"), "set_enter_cost", "get_enter_cost"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "travel_cost"), "set_travel_cost", "get_travel_cost"); } +#ifndef DISABLE_DEPRECATED +bool NavigationLink2D::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "start_location") { + set_start_position(p_value); + return true; + } + if (p_name == "end_location") { + set_end_position(p_value); + return true; + } + return false; +} + +bool NavigationLink2D::_get(const StringName &p_name, Variant &r_ret) const { + if (p_name == "start_location") { + r_ret = get_start_position(); + return true; + } + if (p_name == "end_location") { + r_ret = get_end_position(); + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + void NavigationLink2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -77,15 +103,15 @@ void NavigationLink2D::_notification(int p_what) { // Update global positions for the link. Transform2D gt = get_global_transform(); - NavigationServer2D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); - NavigationServer2D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + NavigationServer2D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); + NavigationServer2D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); } } break; case NOTIFICATION_TRANSFORM_CHANGED: { // Update global positions for the link. Transform2D gt = get_global_transform(); - NavigationServer2D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); - NavigationServer2D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + NavigationServer2D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); + NavigationServer2D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); } break; case NOTIFICATION_EXIT_TREE: { NavigationServer2D::get_singleton()->link_set_map(link, RID()); @@ -102,9 +128,9 @@ void NavigationLink2D::_notification(int p_what) { real_t radius = NavigationServer2D::get_singleton()->map_get_link_connection_radius(get_world_2d()->get_navigation_map()); - draw_line(get_start_location(), get_end_location(), color); - draw_arc(get_start_location(), radius, 0, Math_TAU, 10, color); - draw_arc(get_end_location(), radius, 0, Math_TAU, 10, color); + draw_line(get_start_position(), get_end_position(), color); + draw_arc(get_start_position(), radius, 0, Math_TAU, 10, color); + draw_arc(get_end_position(), radius, 0, Math_TAU, 10, color); } #endif // DEBUG_ENABLED } break; @@ -119,14 +145,14 @@ Rect2 NavigationLink2D::_edit_get_rect() const { real_t radius = NavigationServer2D::get_singleton()->map_get_link_connection_radius(get_world_2d()->get_navigation_map()); - Rect2 rect(get_start_location(), Size2()); - rect.expand_to(get_end_location()); + Rect2 rect(get_start_position(), Size2()); + rect.expand_to(get_end_position()); rect.grow_by(radius); return rect; } bool NavigationLink2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - Point2 segment[2] = { get_start_location(), get_end_location() }; + Point2 segment[2] = { get_start_position(), get_end_position() }; Vector2 closest_point = Geometry2D::get_closest_point_to_segment(p_point, segment); return p_point.distance_to(closest_point) < p_tolerance; @@ -199,19 +225,19 @@ bool NavigationLink2D::get_navigation_layer_value(int p_layer_number) const { return get_navigation_layers() & (1 << (p_layer_number - 1)); } -void NavigationLink2D::set_start_location(Vector2 p_location) { - if (start_location.is_equal_approx(p_location)) { +void NavigationLink2D::set_start_position(Vector2 p_position) { + if (start_position.is_equal_approx(p_position)) { return; } - start_location = p_location; + start_position = p_position; if (!is_inside_tree()) { return; } Transform2D gt = get_global_transform(); - NavigationServer2D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); + NavigationServer2D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); update_configuration_warnings(); @@ -222,19 +248,19 @@ void NavigationLink2D::set_start_location(Vector2 p_location) { #endif // DEBUG_ENABLED } -void NavigationLink2D::set_end_location(Vector2 p_location) { - if (end_location.is_equal_approx(p_location)) { +void NavigationLink2D::set_end_position(Vector2 p_position) { + if (end_position.is_equal_approx(p_position)) { return; } - end_location = p_location; + end_position = p_position; if (!is_inside_tree()) { return; } Transform2D gt = get_global_transform(); - NavigationServer2D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + NavigationServer2D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); update_configuration_warnings(); @@ -270,8 +296,8 @@ void NavigationLink2D::set_travel_cost(real_t p_travel_cost) { PackedStringArray NavigationLink2D::get_configuration_warnings() const { PackedStringArray warnings = Node::get_configuration_warnings(); - if (start_location.is_equal_approx(end_location)) { - warnings.push_back(RTR("NavigationLink2D start location should be different than the end location to be useful.")); + if (start_position.is_equal_approx(end_position)) { + warnings.push_back(RTR("NavigationLink2D start position should be different than the end position to be useful.")); } return warnings; diff --git a/scene/2d/navigation_link_2d.h b/scene/2d/navigation_link_2d.h index e14ee5adb9..5bf2a72358 100644 --- a/scene/2d/navigation_link_2d.h +++ b/scene/2d/navigation_link_2d.h @@ -40,8 +40,8 @@ class NavigationLink2D : public Node2D { RID link; bool bidirectional = true; uint32_t navigation_layers = 1; - Vector2 end_location; - Vector2 start_location; + Vector2 end_position; + Vector2 start_position; real_t enter_cost = 0.0; real_t travel_cost = 1.0; @@ -49,6 +49,11 @@ protected: static void _bind_methods(); void _notification(int p_what); +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; +#endif // DISABLE_DEPRECATED + public: #ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const override; @@ -67,11 +72,11 @@ public: void set_navigation_layer_value(int p_layer_number, bool p_value); bool get_navigation_layer_value(int p_layer_number) const; - void set_start_location(Vector2 p_location); - Vector2 get_start_location() const { return start_location; } + void set_start_position(Vector2 p_position); + Vector2 get_start_position() const { return start_position; } - void set_end_location(Vector2 p_location); - Vector2 get_end_location() const { return end_location; } + void set_end_position(Vector2 p_position); + Vector2 get_end_position() const { return end_position; } void set_enter_cost(real_t p_enter_cost); real_t get_enter_cost() const { return enter_cost; } diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 02388a7681..83cfffc333 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -562,7 +562,7 @@ void Skeleton2D::_get_property_list(List<PropertyInfo> *p_list) const { PropertyInfo(Variant::OBJECT, PNAME("modification_stack"), PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModificationStack2D", - PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); + PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE | PROPERTY_USAGE_ALWAYS_DUPLICATE)); } void Skeleton2D::_make_bone_setup_dirty() { diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index e91948c6e1..47eb1eaa40 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -554,7 +554,7 @@ void Camera3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal,Frustum"), "set_projection", "get_projection"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1,degrees"), "set_fov", "get_fov"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.001,16384,0.001,suffix:m"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.001,16384,0.001,or_greater,suffix:m"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_frustum_offset", "get_frustum_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater,exp,suffix:m"), "set_near", "get_near"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_RANGE, "0.01,4000,0.01,or_greater,exp,suffix:m"), "set_far", "get_far"); @@ -602,7 +602,7 @@ void Camera3D::set_fov(real_t p_fov) { } void Camera3D::set_size(real_t p_size) { - ERR_FAIL_COND(p_size < 0.001 || p_size > 16384); + ERR_FAIL_COND(p_size <= CMP_EPSILON); size = p_size; _update_camera_mode(); } diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 0034bf78b9..fe7ddcb06e 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -80,10 +80,10 @@ void NavigationAgent3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent3D::set_navigation_map); ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent3D::get_navigation_map); - ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent3D::set_target_location); - ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent3D::get_target_location); + ClassDB::bind_method(D_METHOD("set_target_position", "position"), &NavigationAgent3D::set_target_position); + ClassDB::bind_method(D_METHOD("get_target_position"), &NavigationAgent3D::get_target_position); - ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent3D::get_next_location); + ClassDB::bind_method(D_METHOD("get_next_path_position"), &NavigationAgent3D::get_next_path_position); ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent3D::distance_to_target); ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent3D::set_velocity); ClassDB::bind_method(D_METHOD("get_current_navigation_result"), &NavigationAgent3D::get_current_navigation_result); @@ -92,12 +92,12 @@ void NavigationAgent3D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent3D::is_target_reached); ClassDB::bind_method(D_METHOD("is_target_reachable"), &NavigationAgent3D::is_target_reachable); ClassDB::bind_method(D_METHOD("is_navigation_finished"), &NavigationAgent3D::is_navigation_finished); - ClassDB::bind_method(D_METHOD("get_final_location"), &NavigationAgent3D::get_final_location); + ClassDB::bind_method(D_METHOD("get_final_position"), &NavigationAgent3D::get_final_position); ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent3D::_avoidance_done); ADD_GROUP("Pathfinding", ""); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_location", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_location", "get_target_location"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_position", "get_target_position"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_path_desired_distance", "get_path_desired_distance"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_target_desired_distance", "get_target_desired_distance"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01,suffix:m"), "set_agent_height_offset", "get_agent_height_offset"); @@ -344,17 +344,17 @@ real_t NavigationAgent3D::get_path_max_distance() { return path_max_distance; } -void NavigationAgent3D::set_target_location(Vector3 p_location) { - target_location = p_location; +void NavigationAgent3D::set_target_position(Vector3 p_position) { + target_position = p_position; target_position_submitted = true; _request_repath(); } -Vector3 NavigationAgent3D::get_target_location() const { - return target_location; +Vector3 NavigationAgent3D::get_target_position() const { + return target_position; } -Vector3 NavigationAgent3D::get_next_location() { +Vector3 NavigationAgent3D::get_next_path_position() { update_navigation(); const Vector<Vector3> &navigation_path = navigation_result->get_path(); @@ -368,7 +368,7 @@ Vector3 NavigationAgent3D::get_next_location() { real_t NavigationAgent3D::distance_to_target() const { ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent."); - return agent_parent->get_global_transform().origin.distance_to(target_location); + return agent_parent->get_global_transform().origin.distance_to(target_position); } bool NavigationAgent3D::is_target_reached() const { @@ -376,7 +376,7 @@ bool NavigationAgent3D::is_target_reached() const { } bool NavigationAgent3D::is_target_reachable() { - return target_desired_distance >= get_final_location().distance_to(target_location); + return target_desired_distance >= get_final_position().distance_to(target_position); } bool NavigationAgent3D::is_navigation_finished() { @@ -384,7 +384,7 @@ bool NavigationAgent3D::is_navigation_finished() { return navigation_finished; } -Vector3 NavigationAgent3D::get_final_location() { +Vector3 NavigationAgent3D::get_final_position() { update_navigation(); const Vector<Vector3> &navigation_path = navigation_result->get_path(); @@ -467,7 +467,7 @@ void NavigationAgent3D::update_navigation() { if (reload_path) { navigation_query->set_start_position(origin); - navigation_query->set_target_position(target_location); + navigation_query->set_target_position(target_position); navigation_query->set_navigation_layers(navigation_layers); navigation_query->set_metadata_flags(path_metadata_flags); @@ -489,7 +489,7 @@ void NavigationAgent3D::update_navigation() { // Check if we can advance the navigation path if (navigation_finished == false) { - // Advances to the next far away location. + // Advances to the next far away position. const Vector<Vector3> &navigation_path = navigation_result->get_path(); const Vector<int32_t> &navigation_path_types = navigation_result->get_path_types(); const TypedArray<RID> &navigation_path_rids = navigation_result->get_path_rids(); @@ -499,7 +499,7 @@ void NavigationAgent3D::update_navigation() { Dictionary details; const Vector3 waypoint = navigation_path[navigation_path_index]; - details[SNAME("location")] = waypoint; + details[SNAME("position")] = waypoint; int waypoint_type = -1; if (path_metadata_flags.has_flag(NavigationPathQueryParameters3D::PathMetadataFlags::PATH_METADATA_INCLUDE_TYPES)) { diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index 91be068392..12f83ce6a8 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -62,7 +62,7 @@ class NavigationAgent3D : public Node { real_t path_max_distance = 3.0; - Vector3 target_location; + Vector3 target_position; bool target_position_submitted = false; Ref<NavigationPathQueryParameters3D> navigation_query; Ref<NavigationPathQueryResult3D> navigation_result; @@ -155,10 +155,10 @@ public: void set_path_max_distance(real_t p_pmd); real_t get_path_max_distance(); - void set_target_location(Vector3 p_location); - Vector3 get_target_location() const; + void set_target_position(Vector3 p_position); + Vector3 get_target_position() const; - Vector3 get_next_location(); + Vector3 get_next_path_position(); Ref<NavigationPathQueryResult3D> get_current_navigation_result() const { return navigation_result; @@ -174,7 +174,7 @@ public: bool is_target_reached() const; bool is_target_reachable(); bool is_navigation_finished(); - Vector3 get_final_location(); + Vector3 get_final_position(); void set_velocity(Vector3 p_velocity); void _avoidance_done(Vector3 p_new_velocity); diff --git a/scene/3d/navigation_link_3d.cpp b/scene/3d/navigation_link_3d.cpp index e058ef62d0..f47fcfaf51 100644 --- a/scene/3d/navigation_link_3d.cpp +++ b/scene/3d/navigation_link_3d.cpp @@ -70,10 +70,10 @@ void NavigationLink3D::_update_debug_mesh() { Vector<Vector3> lines; // Draw line between the points. - lines.push_back(start_location); - lines.push_back(end_location); + lines.push_back(start_position); + lines.push_back(end_position); - // Draw start location search radius + // Draw start position search radius for (int i = 0; i < 30; i++) { // Create a circle const float ra = Math::deg_to_rad((float)(i * 12)); @@ -84,21 +84,21 @@ void NavigationLink3D::_update_debug_mesh() { // Draw axis-aligned circle switch (up_axis) { case Vector3::AXIS_X: - lines.append(start_location + Vector3(0, a.x, a.y)); - lines.append(start_location + Vector3(0, b.x, b.y)); + lines.append(start_position + Vector3(0, a.x, a.y)); + lines.append(start_position + Vector3(0, b.x, b.y)); break; case Vector3::AXIS_Y: - lines.append(start_location + Vector3(a.x, 0, a.y)); - lines.append(start_location + Vector3(b.x, 0, b.y)); + lines.append(start_position + Vector3(a.x, 0, a.y)); + lines.append(start_position + Vector3(b.x, 0, b.y)); break; case Vector3::AXIS_Z: - lines.append(start_location + Vector3(a.x, a.y, 0)); - lines.append(start_location + Vector3(b.x, b.y, 0)); + lines.append(start_position + Vector3(a.x, a.y, 0)); + lines.append(start_position + Vector3(b.x, b.y, 0)); break; } } - // Draw end location search radius + // Draw end position search radius for (int i = 0; i < 30; i++) { // Create a circle const float ra = Math::deg_to_rad((float)(i * 12)); @@ -109,16 +109,16 @@ void NavigationLink3D::_update_debug_mesh() { // Draw axis-aligned circle switch (up_axis) { case Vector3::AXIS_X: - lines.append(end_location + Vector3(0, a.x, a.y)); - lines.append(end_location + Vector3(0, b.x, b.y)); + lines.append(end_position + Vector3(0, a.x, a.y)); + lines.append(end_position + Vector3(0, b.x, b.y)); break; case Vector3::AXIS_Y: - lines.append(end_location + Vector3(a.x, 0, a.y)); - lines.append(end_location + Vector3(b.x, 0, b.y)); + lines.append(end_position + Vector3(a.x, 0, a.y)); + lines.append(end_position + Vector3(b.x, 0, b.y)); break; case Vector3::AXIS_Z: - lines.append(end_location + Vector3(a.x, a.y, 0)); - lines.append(end_location + Vector3(b.x, b.y, 0)); + lines.append(end_position + Vector3(a.x, a.y, 0)); + lines.append(end_position + Vector3(b.x, b.y, 0)); break; } } @@ -157,11 +157,11 @@ void NavigationLink3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationLink3D::set_navigation_layer_value); ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationLink3D::get_navigation_layer_value); - ClassDB::bind_method(D_METHOD("set_start_location", "location"), &NavigationLink3D::set_start_location); - ClassDB::bind_method(D_METHOD("get_start_location"), &NavigationLink3D::get_start_location); + ClassDB::bind_method(D_METHOD("set_start_position", "position"), &NavigationLink3D::set_start_position); + ClassDB::bind_method(D_METHOD("get_start_position"), &NavigationLink3D::get_start_position); - ClassDB::bind_method(D_METHOD("set_end_location", "location"), &NavigationLink3D::set_end_location); - ClassDB::bind_method(D_METHOD("get_end_location"), &NavigationLink3D::get_end_location); + ClassDB::bind_method(D_METHOD("set_end_position", "position"), &NavigationLink3D::set_end_position); + ClassDB::bind_method(D_METHOD("get_end_position"), &NavigationLink3D::get_end_position); ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink3D::set_enter_cost); ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink3D::get_enter_cost); @@ -172,12 +172,38 @@ void NavigationLink3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bidirectional"), "set_bidirectional", "is_bidirectional"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_location"), "set_start_location", "get_start_location"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "end_location"), "set_end_location", "get_end_location"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_position"), "set_start_position", "get_start_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "end_position"), "set_end_position", "get_end_position"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "enter_cost"), "set_enter_cost", "get_enter_cost"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "travel_cost"), "set_travel_cost", "get_travel_cost"); } +#ifndef DISABLE_DEPRECATED +bool NavigationLink3D::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "start_location") { + set_start_position(p_value); + return true; + } + if (p_name == "end_location") { + set_end_position(p_value); + return true; + } + return false; +} + +bool NavigationLink3D::_get(const StringName &p_name, Variant &r_ret) const { + if (p_name == "start_location") { + r_ret = get_start_position(); + return true; + } + if (p_name == "end_location") { + r_ret = get_end_position(); + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + void NavigationLink3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -186,8 +212,8 @@ void NavigationLink3D::_notification(int p_what) { // Update global positions for the link. Transform3D gt = get_global_transform(); - NavigationServer3D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); - NavigationServer3D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + NavigationServer3D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); + NavigationServer3D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); } #ifdef DEBUG_ENABLED @@ -197,8 +223,8 @@ void NavigationLink3D::_notification(int p_what) { case NOTIFICATION_TRANSFORM_CHANGED: { // Update global positions for the link. Transform3D gt = get_global_transform(); - NavigationServer3D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); - NavigationServer3D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + NavigationServer3D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); + NavigationServer3D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); #ifdef DEBUG_ENABLED if (is_inside_tree() && debug_instance.is_valid()) { @@ -316,19 +342,19 @@ bool NavigationLink3D::get_navigation_layer_value(int p_layer_number) const { return get_navigation_layers() & (1 << (p_layer_number - 1)); } -void NavigationLink3D::set_start_location(Vector3 p_location) { - if (start_location.is_equal_approx(p_location)) { +void NavigationLink3D::set_start_position(Vector3 p_position) { + if (start_position.is_equal_approx(p_position)) { return; } - start_location = p_location; + start_position = p_position; if (!is_inside_tree()) { return; } Transform3D gt = get_global_transform(); - NavigationServer3D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); + NavigationServer3D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); #ifdef DEBUG_ENABLED _update_debug_mesh(); @@ -338,19 +364,19 @@ void NavigationLink3D::set_start_location(Vector3 p_location) { update_configuration_warnings(); } -void NavigationLink3D::set_end_location(Vector3 p_location) { - if (end_location.is_equal_approx(p_location)) { +void NavigationLink3D::set_end_position(Vector3 p_position) { + if (end_position.is_equal_approx(p_position)) { return; } - end_location = p_location; + end_position = p_position; if (!is_inside_tree()) { return; } Transform3D gt = get_global_transform(); - NavigationServer3D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + NavigationServer3D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); #ifdef DEBUG_ENABLED _update_debug_mesh(); @@ -385,8 +411,8 @@ void NavigationLink3D::set_travel_cost(real_t p_travel_cost) { PackedStringArray NavigationLink3D::get_configuration_warnings() const { PackedStringArray warnings = Node::get_configuration_warnings(); - if (start_location.is_equal_approx(end_location)) { - warnings.push_back(RTR("NavigationLink3D start location should be different than the end location to be useful.")); + if (start_position.is_equal_approx(end_position)) { + warnings.push_back(RTR("NavigationLink3D start position should be different than the end position to be useful.")); } return warnings; diff --git a/scene/3d/navigation_link_3d.h b/scene/3d/navigation_link_3d.h index 175c5cdd5d..5c9ec36189 100644 --- a/scene/3d/navigation_link_3d.h +++ b/scene/3d/navigation_link_3d.h @@ -40,8 +40,8 @@ class NavigationLink3D : public Node3D { RID link; bool bidirectional = true; uint32_t navigation_layers = 1; - Vector3 end_location; - Vector3 start_location; + Vector3 end_position; + Vector3 start_position; real_t enter_cost = 0.0; real_t travel_cost = 1.0; @@ -56,6 +56,11 @@ protected: static void _bind_methods(); void _notification(int p_what); +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; +#endif // DISABLE_DEPRECATED + public: NavigationLink3D(); ~NavigationLink3D(); @@ -72,11 +77,11 @@ public: void set_navigation_layer_value(int p_layer_number, bool p_value); bool get_navigation_layer_value(int p_layer_number) const; - void set_start_location(Vector3 p_location); - Vector3 get_start_location() const { return start_location; } + void set_start_position(Vector3 p_position); + Vector3 get_start_position() const { return start_position; } - void set_end_location(Vector3 p_location); - Vector3 get_end_location() const { return end_location; } + void set_end_position(Vector3 p_position); + Vector3 get_end_position() const { return end_position; } void set_enter_cost(real_t p_enter_cost); real_t get_enter_cost() const { return enter_cost; } diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp index 4325152a7b..41dc27352f 100644 --- a/scene/3d/voxel_gi.cpp +++ b/scene/3d/voxel_gi.cpp @@ -502,7 +502,7 @@ void VoxelGI::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "subdiv", PROPERTY_HINT_ENUM, "64,128,256,512"), "set_subdiv", "get_subdiv"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_NONE, "suffix:m"), "set_extents", "get_extents"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_attributes", PROPERTY_HINT_RESOURCE_TYPE, "CameraAttributesPractical,CameraAttributesPhysical"), "set_camera_attributes", "get_camera_attributes"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "data", PROPERTY_HINT_RESOURCE_TYPE, "VoxelGIData", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_probe_data", "get_probe_data"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "data", PROPERTY_HINT_RESOURCE_TYPE, "VoxelGIData", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ALWAYS_DUPLICATE), "set_probe_data", "get_probe_data"); BIND_ENUM_CONSTANT(SUBDIV_64); BIND_ENUM_CONSTANT(SUBDIV_128); diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 02f1e9f9a6..7fb831b3b2 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -228,6 +228,22 @@ float AnimationNodeStateMachinePlayback::get_current_length() const { return len_current; } +float AnimationNodeStateMachinePlayback::get_fade_from_play_pos() const { + return pos_fade_from; +} + +float AnimationNodeStateMachinePlayback::get_fade_from_length() const { + return len_fade_from; +} + +float AnimationNodeStateMachinePlayback::get_fading_time() const { + return fading_time; +} + +float AnimationNodeStateMachinePlayback::get_fading_pos() const { + return fading_pos; +} + bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel) { ERR_FAIL_COND_V(!playing, false); ERR_FAIL_COND_V(!p_state_machine->states.has(p_travel), false); @@ -466,7 +482,17 @@ double AnimationNodeStateMachinePlayback::_process(AnimationNodeStateMachine *p_ if (fading_from != StringName()) { double fade_blend_inv = 1.0 - fade_blend; - p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, p_is_external_seeking, Math::is_zero_approx(fade_blend_inv) ? CMP_EPSILON : fade_blend_inv, AnimationNode::FILTER_IGNORE, true); // Blend values must be more than CMP_EPSILON to process discrete keys in edge. + float fading_from_rem = 0.0; + fading_from_rem = p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, p_is_external_seeking, Math::is_zero_approx(fade_blend_inv) ? CMP_EPSILON : fade_blend_inv, AnimationNode::FILTER_IGNORE, true); // Blend values must be more than CMP_EPSILON to process discrete keys in edge. + //guess playback position + if (fading_from_rem > len_fade_from) { // weird but ok + len_fade_from = fading_from_rem; + } + + { //advance and loop check + float next_pos = len_fade_from - fading_from_rem; + pos_fade_from = next_pos; //looped + } if (fade_blend >= 1.0) { fading_from = StringName(); } @@ -633,6 +659,8 @@ double AnimationNodeStateMachinePlayback::_process(AnimationNodeStateMachine *p_ } current = next; + pos_fade_from = pos_current; + len_fade_from = len_current; if (reset_request) { len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_is_external_seeking, CMP_EPSILON, AnimationNode::FILTER_IGNORE, true); // Process next node's first key in here. @@ -716,7 +744,7 @@ AnimationNodeStateMachinePlayback::AnimationNodeStateMachinePlayback() { /////////////////////////////////////////////////////// void AnimationNodeStateMachine::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::OBJECT, playback, PROPERTY_HINT_RESOURCE_TYPE, "AnimationNodeStateMachinePlayback", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); + r_list->push_back(PropertyInfo(Variant::OBJECT, playback, PROPERTY_HINT_RESOURCE_TYPE, "AnimationNodeStateMachinePlayback", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ALWAYS_DUPLICATE)); List<StringName> advance_conditions; for (int i = 0; i < transitions.size(); i++) { StringName ac = transitions[i].transition->get_advance_condition_name(); diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index 1b4e010a06..cf4d850aa6 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -118,6 +118,9 @@ class AnimationNodeStateMachinePlayback : public Resource { StringName next; }; + double len_fade_from = 0.0; + double pos_fade_from = 0.0; + double len_current = 0.0; double pos_current = 0.0; bool end_loop = false; @@ -164,6 +167,12 @@ public: float get_current_play_pos() const; float get_current_length() const; + float get_fade_from_play_pos() const; + float get_fade_from_length() const; + + float get_fading_time() const; + float get_fading_pos() const; + AnimationNodeStateMachinePlayback(); }; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 047997ca09..77d82990d1 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -451,6 +451,15 @@ static void _call_object(Object *p_object, const StringName &p_method, const Vec } } +Variant AnimationPlayer::post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) { + Variant res; + if (GDVIRTUAL_CALL(_post_process_key_value, p_anim, p_track, p_value, const_cast<Object *>(p_object), p_object_idx, res)) { + return res; + } + + return _post_process_key_value(p_anim, p_track, p_value, p_object, p_object_idx); +} + Variant AnimationPlayer::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) { switch (p_anim->track_get_type(p_track)) { #ifndef _3D_DISABLED @@ -473,7 +482,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count()); Animation *a = p_anim->animation.operator->(); +#ifdef TOOLS_ENABLED bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint(); +#endif // TOOLS_ENABLED bool backward = signbit(p_delta); for (int i = 0; i < a->get_track_count(); i++) { @@ -512,7 +523,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } - loc = _post_process_key_value(a, i, loc, nc->node_3d, nc->bone_idx); + loc = post_process_key_value(a, i, loc, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -540,7 +551,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } - rot = _post_process_key_value(a, i, rot, nc->node_3d, nc->bone_idx); + rot = post_process_key_value(a, i, rot, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -568,7 +579,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } - scale = _post_process_key_value(a, i, scale, nc->node_3d, nc->bone_idx); + scale = post_process_key_value(a, i, scale, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -596,7 +607,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } - blend = _post_process_key_value(a, i, blend, nc->node_blend_shape, nc->blend_shape_idx); + blend = post_process_key_value(a, i, blend, nc->node_blend_shape, nc->blend_shape_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -649,7 +660,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (p_time < first_key_time) { double c = Math::ease(p_time / first_key_time, transition); Variant first_value = a->track_get_key_value(i, first_key); - first_value = _post_process_key_value(a, i, first_value, nc->node); + first_value = post_process_key_value(a, i, first_value, nc->node); Variant interp_value = Animation::interpolate_variant(pa->capture, first_value, c); if (pa->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX); @@ -670,7 +681,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (value == Variant()) { continue; } - value = _post_process_key_value(a, i, value, nc->node); + value = post_process_key_value(a, i, value, nc->node); if (pa->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX); @@ -701,7 +712,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double for (int &F : indices) { Variant value = a->track_get_key_value(i, F); - value = _post_process_key_value(a, i, value, nc->node); + value = post_process_key_value(a, i, value, nc->node); switch (pa->special) { case SP_NONE: { bool valid; @@ -745,11 +756,13 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double } break; case Animation::TYPE_METHOD: { - if (!nc->node || is_stopping) { +#ifdef TOOLS_ENABLED + if (!can_call) { continue; } - if (!p_is_current) { - break; +#endif // TOOLS_ENABLED + if (!p_is_current || !nc->node || is_stopping) { + continue; } List<int> indices; @@ -772,16 +785,12 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double for (int &E : indices) { StringName method = a->method_track_get_name(i, E); Vector<Variant> params = a->method_track_get_params(i, E); - #ifdef DEBUG_ENABLED if (!nc->node->has_method(method)) { ERR_PRINT("Invalid method call '" + method + "'. '" + a->get_name() + "' at node '" + get_path() + "'."); } #endif - - if (can_call) { - _call_object(nc->node, method, params, method_call_mode == ANIMATION_METHOD_CALL_DEFERRED); - } + _call_object(nc->node, method, params, method_call_mode == ANIMATION_METHOD_CALL_DEFERRED); } } break; @@ -796,7 +805,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double TrackNodeCache::BezierAnim *ba = &E->value; real_t bezier = a->bezier_track_interpolate(i, p_time); - bezier = _post_process_key_value(a, i, bezier, nc->node); + bezier = post_process_key_value(a, i, bezier, nc->node); if (ba->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_bezier_size >= NODE_CACHE_UPDATE_MAX); cache_update_bezier[cache_update_bezier_size++] = ba; @@ -813,7 +822,11 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double } if (p_seeked) { - //find whatever should be playing +#ifdef TOOLS_ENABLED + if (!can_call) { + continue; // To avoid spamming the preview in editor. + } +#endif // TOOLS_ENABLED int idx = a->track_find_key(i, p_time); if (idx < 0) { continue; @@ -2190,6 +2203,8 @@ void AnimationPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("seek", "seconds", "update"), &AnimationPlayer::seek, DEFVAL(false)); ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationPlayer::advance); + GDVIRTUAL_BIND(_post_process_key_value, "animation", "track", "value", "object", "object_idx"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_node"), "set_root", "get_root"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "current_animation", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_EDITOR), "set_current_animation", "get_current_animation"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "assigned_animation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_assigned_animation", "get_assigned_animation"); diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 7e7d12f982..2901c43dcf 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -317,6 +317,8 @@ protected: static void _bind_methods(); + GDVIRTUAL5RC(Variant, _post_process_key_value, Ref<Animation>, int, Variant, Object *, int); + Variant post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1); virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1); public: diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 077a5696bb..a2a1a0aaef 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -1015,8 +1015,9 @@ void AnimationTree::_process_graph(double p_delta) { // Apply value/transform/blend/bezier blends to track caches and execute method/audio/animation tracks. { +#ifdef TOOLS_ENABLED bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint(); - +#endif // TOOLS_ENABLED for (const AnimationNode::AnimationState &as : state.animation_states) { Ref<Animation> a = as.animation; double time = as.time; @@ -1104,9 +1105,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); + loc[0] = post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, (double)a->get_length(), &loc[1]); - loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); + loc[1] = post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = 0; } @@ -1116,9 +1117,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); + loc[0] = post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, 0, &loc[1]); - loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); + loc[1] = post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = (double)a->get_length(); } @@ -1128,10 +1129,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); + loc[0] = post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, time, &loc[1]); - loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); + loc[1] = post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = !backward ? 0 : (double)a->get_length(); @@ -1142,7 +1143,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - loc = _post_process_key_value(a, i, loc, t->object, t->bone_idx); + loc = post_process_key_value(a, i, loc, t->object, t->bone_idx); t->loc += (loc - t->init_loc) * blend; } @@ -1195,9 +1196,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); + rot[0] = post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, (double)a->get_length(), &rot[1]); - rot[1] = _post_process_key_value(a, i, rot[1], t->object, t->bone_idx); + rot[1] = post_process_key_value(a, i, rot[1], t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = 0; } @@ -1207,7 +1208,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); + rot[0] = post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, 0, &rot[1]); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = (double)a->get_length(); @@ -1218,10 +1219,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); + rot[0] = post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, time, &rot[1]); - rot[1] = _post_process_key_value(a, i, rot[1], t->object, t->bone_idx); + rot[1] = post_process_key_value(a, i, rot[1], t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = !backward ? 0 : (double)a->get_length(); @@ -1232,7 +1233,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - rot = _post_process_key_value(a, i, rot, t->object, t->bone_idx); + rot = post_process_key_value(a, i, rot, t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(t->init_rot.inverse() * rot, blend)).normalized(); } @@ -1285,10 +1286,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); + scale[0] = post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, (double)a->get_length(), &scale[1]); t->scale += (scale[1] - scale[0]) * blend; - scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); + scale[1] = post_process_key_value(a, i, scale[1], t->object, t->bone_idx); prev_time = 0; } } else { @@ -1297,9 +1298,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); + scale[0] = post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, 0, &scale[1]); - scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); + scale[1] = post_process_key_value(a, i, scale[1], t->object, t->bone_idx); t->scale += (scale[1] - scale[0]) * blend; prev_time = (double)a->get_length(); } @@ -1309,10 +1310,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); + scale[0] = post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, time, &scale[1]); - scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); + scale[1] = post_process_key_value(a, i, scale[1], t->object, t->bone_idx); t->scale += (scale[1] - scale[0]) * blend; prev_time = !backward ? 0 : (double)a->get_length(); @@ -1323,7 +1324,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - scale = _post_process_key_value(a, i, scale, t->object, t->bone_idx); + scale = post_process_key_value(a, i, scale, t->object, t->bone_idx); t->scale += (scale - t->init_scale) * blend; } @@ -1341,7 +1342,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } - value = _post_process_key_value(a, i, value, t->object, t->shape_index); + value = post_process_key_value(a, i, value, t->object, t->shape_index); t->value += (value - t->init_value) * blend; #endif // _3D_DISABLED @@ -1353,7 +1354,7 @@ void AnimationTree::_process_graph(double p_delta) { if (update_mode == Animation::UPDATE_CONTINUOUS || update_mode == Animation::UPDATE_CAPTURE) { Variant value = a->value_track_interpolate(i, time); - value = _post_process_key_value(a, i, value, t->object); + value = post_process_key_value(a, i, value, t->object); if (value == Variant()) { continue; @@ -1393,14 +1394,14 @@ void AnimationTree::_process_graph(double p_delta) { continue; } Variant value = a->track_get_key_value(i, idx); - value = _post_process_key_value(a, i, value, t->object); + value = post_process_key_value(a, i, value, t->object); t->object->set_indexed(t->subpath, value); } else { List<int> indices; a->track_get_key_indices_in_range(i, time, delta, &indices, looped_flag); for (int &F : indices) { Variant value = a->track_get_key_value(i, F); - value = _post_process_key_value(a, i, value, t->object); + value = post_process_key_value(a, i, value, t->object); t->object->set_indexed(t->subpath, value); } } @@ -1408,6 +1409,11 @@ void AnimationTree::_process_graph(double p_delta) { } break; case Animation::TYPE_METHOD: { +#ifdef TOOLS_ENABLED + if (!can_call) { + return; + } +#endif // TOOLS_ENABLED TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track); if (seeked) { @@ -1417,18 +1423,14 @@ void AnimationTree::_process_graph(double p_delta) { } StringName method = a->method_track_get_name(i, idx); Vector<Variant> params = a->method_track_get_params(i, idx); - if (can_call) { - _call_object(t->object, method, params, false); - } + _call_object(t->object, method, params, false); } else { List<int> indices; a->track_get_key_indices_in_range(i, time, delta, &indices, looped_flag); for (int &F : indices) { StringName method = a->method_track_get_name(i, F); Vector<Variant> params = a->method_track_get_params(i, F); - if (can_call) { - _call_object(t->object, method, params, true); - } + _call_object(t->object, method, params, true); } } } break; @@ -1436,7 +1438,7 @@ void AnimationTree::_process_graph(double p_delta) { TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track); real_t bezier = a->bezier_track_interpolate(i, time); - bezier = _post_process_key_value(a, i, bezier, t->object); + bezier = post_process_key_value(a, i, bezier, t->object); t->value += (bezier - t->init_value) * blend; } break; @@ -1444,7 +1446,6 @@ void AnimationTree::_process_graph(double p_delta) { TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track); if (seeked) { - //find whatever should be playing int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT); if (idx < 0) { continue; @@ -1700,6 +1701,15 @@ void AnimationTree::_process_graph(double p_delta) { } } +Variant AnimationTree::post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) { + Variant res; + if (GDVIRTUAL_CALL(_post_process_key_value, p_anim, p_track, p_value, const_cast<Object *>(p_object), p_object_idx, res)) { + return res; + } + + return _post_process_key_value(p_anim, p_track, p_value, p_object, p_object_idx); +} + Variant AnimationTree::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) { switch (p_anim->track_get_type(p_track)) { #ifndef _3D_DISABLED @@ -2034,6 +2044,8 @@ void AnimationTree::_bind_methods() { ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTree::advance); + GDVIRTUAL_BIND(_post_process_key_value, "animation", "track", "value", "object", "object_idx"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "advance_expression_base_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node"), "set_advance_expression_base_node", "get_advance_expression_base_node"); diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 52d3e1bd41..ab538feb58 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -328,6 +328,8 @@ protected: void _notification(int p_what); static void _bind_methods(); + GDVIRTUAL5RC(Variant, _post_process_key_value, Ref<Animation>, int, Variant, Object *, int); + Variant post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1); virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1); public: diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 472299b135..c26a00221a 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -479,14 +479,16 @@ void BaseButton::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toggle_mode"), "set_toggle_mode", "is_toggle_mode"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_in_tooltip"), "set_shortcut_in_tooltip", "is_shortcut_in_tooltip_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "button_pressed"), "set_pressed", "is_pressed"); ADD_PROPERTY(PropertyInfo(Variant::INT, "action_mode", PROPERTY_HINT_ENUM, "Button Press,Button Release"), "set_action_mode", "get_action_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask", PROPERTY_HINT_FLAGS, "Mouse Left, Mouse Right, Mouse Middle"), "set_button_mask", "get_button_mask"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_pressed_outside"), "set_keep_pressed_outside", "is_keep_pressed_outside"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "button_group", PROPERTY_HINT_RESOURCE_TYPE, "ButtonGroup"), "set_button_group", "get_button_group"); + + ADD_GROUP("Shortcut", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "Shortcut"), "set_shortcut", "get_shortcut"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_feedback"), "set_shortcut_feedback", "is_shortcut_feedback"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "button_group", PROPERTY_HINT_RESOURCE_TYPE, "ButtonGroup"), "set_button_group", "get_button_group"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_in_tooltip"), "set_shortcut_in_tooltip", "is_shortcut_in_tooltip_enabled"); BIND_ENUM_CONSTANT(DRAW_NORMAL); BIND_ENUM_CONSTANT(DRAW_PRESSED); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 1e07a53642..2a8b1cd8c4 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -575,9 +575,13 @@ void Button::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_button_icon", "get_button_icon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text"); + + ADD_GROUP("Text Behavior", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_alignment", "get_text_alignment"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text"); + + ADD_GROUP("Icon Behavior", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_icon_alignment", "get_icon_alignment"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand_icon"), "set_expand_icon", "is_expand_icon"); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index fead0878fb..f7c056316d 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1387,13 +1387,7 @@ Point2 Control::get_global_position() const { Point2 Control::get_screen_position() const { ERR_FAIL_COND_V(!is_inside_tree(), Point2()); - Point2 global_pos = get_global_transform_with_canvas().get_origin(); - Window *w = Object::cast_to<Window>(get_viewport()); - if (w && !w->is_embedding_subwindows()) { - global_pos += w->get_position(); - } - - return global_pos; + return get_screen_transform().get_origin(); } void Control::_set_size(const Size2 &p_size) { @@ -1444,24 +1438,20 @@ void Control::set_rect(const Rect2 &p_rect) { } Rect2 Control::get_rect() const { - return Rect2(get_position(), get_size()); + Transform2D xform = get_transform(); + return Rect2(xform.get_origin(), xform.get_scale() * get_size()); } Rect2 Control::get_global_rect() const { - return Rect2(get_global_position(), get_size()); + Transform2D xform = get_global_transform(); + return Rect2(xform.get_origin(), xform.get_scale() * get_size()); } Rect2 Control::get_screen_rect() const { ERR_FAIL_COND_V(!is_inside_tree(), Rect2()); - Rect2 r(get_global_position(), get_size()); - - Window *w = Object::cast_to<Window>(get_viewport()); - if (w && !w->is_embedding_subwindows()) { - r.position += w->get_position(); - } - - return r; + Transform2D xform = get_screen_transform(); + return Rect2(xform.get_origin(), xform.get_scale() * get_size()); } Rect2 Control::get_anchorable_rect() const { diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 6c495ab2c9..af52f6664a 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1380,34 +1380,15 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { accept_event(); } } - - Ref<InputEventMagnifyGesture> magnify_gesture = p_ev; - if (magnify_gesture.is_valid()) { - set_zoom_custom(zoom * magnify_gesture->get_factor(), magnify_gesture->get_position()); - } - - Ref<InputEventPanGesture> pan_gesture = p_ev; - if (pan_gesture.is_valid()) { - h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * pan_gesture->get_delta().x / 8); - v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * pan_gesture->get_delta().y / 8); - } -} - -void GraphEdit::_scroll_callback(Vector2 p_scroll_vec, bool p_alt) { - if (p_scroll_vec.x != 0) { - h_scroll->set_value(h_scroll->get_value() + (h_scroll->get_page() * Math::abs(p_scroll_vec.x) / 8) * SIGN(p_scroll_vec.x)); - } else { - v_scroll->set_value(v_scroll->get_value() + (v_scroll->get_page() * Math::abs(p_scroll_vec.y) / 8) * SIGN(p_scroll_vec.y)); - } } -void GraphEdit::_pan_callback(Vector2 p_scroll_vec) { +void GraphEdit::_pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event) { h_scroll->set_value(h_scroll->get_value() - p_scroll_vec.x); v_scroll->set_value(v_scroll->get_value() - p_scroll_vec.y); } -void GraphEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { - set_zoom_custom(p_scroll_vec.y < 0 ? zoom * zoom_step : zoom / zoom_step, p_origin); +void GraphEdit::_zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event) { + set_zoom_custom(zoom * p_zoom_factor, p_origin); } void GraphEdit::set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity) { @@ -1502,6 +1483,7 @@ void GraphEdit::set_zoom_step(float p_zoom_step) { } zoom_step = p_zoom_step; + panner->set_scroll_zoom_factor(zoom_step); } float GraphEdit::get_zoom_step() const { @@ -2421,7 +2403,7 @@ GraphEdit::GraphEdit() { zoom_max = (1 * Math::pow(zoom_step, 4)); panner.instantiate(); - panner->set_callbacks(callable_mp(this, &GraphEdit::_scroll_callback), callable_mp(this, &GraphEdit::_pan_callback), callable_mp(this, &GraphEdit::_zoom_callback)); + panner->set_callbacks(callable_mp(this, &GraphEdit::_pan_callback), callable_mp(this, &GraphEdit::_zoom_callback)); top_layer = memnew(GraphEditFilter(this)); add_child(top_layer, false, INTERNAL_MODE_BACK); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 030f40e370..dfe6b94906 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -129,9 +129,8 @@ private: Ref<ViewPanner> panner; bool warped_panning = true; - void _scroll_callback(Vector2 p_scroll_vec, bool p_alt); - void _pan_callback(Vector2 p_scroll_vec); - void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt); + void _pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event); + void _zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event); bool arrange_nodes_button_hidden = false; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index e2a5b0c8a3..5aa777b40c 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -1724,6 +1724,10 @@ void LineEdit::insert_text_at_caret(String p_text) { input_direction = (TextDirection)dir; } set_caret_column(caret_column + p_text.length()); + + if (!ime_text.is_empty()) { + _shape(); + } } void LineEdit::clear_internal() { diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index a7e50a765e..9baf7c9180 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -2778,7 +2778,7 @@ bool RichTextLabel::_validate_line_caches() { main->first_resized_line.store(main->lines.size()); - if (fit_content_height) { + if (fit_content) { update_minimum_size(); } return true; @@ -2862,7 +2862,7 @@ void RichTextLabel::_process_line_caches() { main->first_resized_line.store(main->lines.size()); main->first_invalid_font_line.store(main->lines.size()); - if (fit_content_height) { + if (fit_content) { update_minimum_size(); } emit_signal(SNAME("finished")); @@ -2963,7 +2963,7 @@ void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline) _invalidate_current_line(current_frame); - if (fixed_width != -1) { + if (fit_content) { update_minimum_size(); } queue_redraw(); @@ -3435,6 +3435,8 @@ void RichTextLabel::push_customfx(Ref<RichTextEffect> p_custom_effect, Dictionar item->custom_effect = p_custom_effect; item->char_fx_transform->environment = p_environment; _add_item(item, true); + + set_process_internal(true); } void RichTextLabel::set_table_column_expand(int p_column, bool p_expand, int p_ratio) { @@ -3551,7 +3553,7 @@ void RichTextLabel::clear() { scroll_following = true; } - if (fixed_width != -1) { + if (fit_content) { update_minimum_size(); } } @@ -3572,15 +3574,17 @@ int RichTextLabel::get_tab_size() const { return tab_size; } -void RichTextLabel::set_fit_content_height(bool p_enabled) { - if (p_enabled != fit_content_height) { - fit_content_height = p_enabled; - update_minimum_size(); +void RichTextLabel::set_fit_content(bool p_enabled) { + if (p_enabled == fit_content) { + return; } + + fit_content = p_enabled; + update_minimum_size(); } -bool RichTextLabel::is_fit_content_height_enabled() const { - return fit_content_height; +bool RichTextLabel::is_fit_content_enabled() const { + return fit_content; } void RichTextLabel::set_meta_underline(bool p_underline) { @@ -4550,7 +4554,6 @@ void RichTextLabel::append_text(const String &p_bbcode) { push_customfx(effect, properties); pos = brk_end + 1; tag_stack.push_front(identifier); - set_process_internal(true); } else { add_text("["); //ignore pos = brk_pos + 1; @@ -5344,6 +5347,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("push_cell"), &RichTextLabel::push_cell); ClassDB::bind_method(D_METHOD("push_fgcolor", "fgcolor"), &RichTextLabel::push_fgcolor); ClassDB::bind_method(D_METHOD("push_bgcolor", "bgcolor"), &RichTextLabel::push_bgcolor); + ClassDB::bind_method(D_METHOD("push_customfx", "effect", "env"), &RichTextLabel::push_customfx); ClassDB::bind_method(D_METHOD("pop"), &RichTextLabel::pop); ClassDB::bind_method(D_METHOD("clear"), &RichTextLabel::clear); @@ -5381,8 +5385,8 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tab_size", "spaces"), &RichTextLabel::set_tab_size); ClassDB::bind_method(D_METHOD("get_tab_size"), &RichTextLabel::get_tab_size); - ClassDB::bind_method(D_METHOD("set_fit_content_height", "enabled"), &RichTextLabel::set_fit_content_height); - ClassDB::bind_method(D_METHOD("is_fit_content_height_enabled"), &RichTextLabel::is_fit_content_height_enabled); + ClassDB::bind_method(D_METHOD("set_fit_content", "enabled"), &RichTextLabel::set_fit_content); + ClassDB::bind_method(D_METHOD("is_fit_content_enabled"), &RichTextLabel::is_fit_content_enabled); ClassDB::bind_method(D_METHOD("set_selection_enabled", "enabled"), &RichTextLabel::set_selection_enabled); ClassDB::bind_method(D_METHOD("is_selection_enabled"), &RichTextLabel::is_selection_enabled); @@ -5457,7 +5461,7 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bbcode_enabled"), "set_use_bbcode", "is_using_bbcode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fit_content_height"), "set_fit_content_height", "is_fit_content_height_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fit_content"), "set_fit_content", "is_fit_content_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_active"), "set_scroll_active", "is_scroll_active"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_following"), "set_scroll_follow", "is_scroll_following"); ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode"); @@ -5644,27 +5648,17 @@ int RichTextLabel::get_total_glyph_count() const { return tg; } -void RichTextLabel::set_fixed_size_to_width(int p_width) { - if (fixed_width == p_width) { - return; - } - - fixed_width = p_width; - update_minimum_size(); -} - Size2 RichTextLabel::get_minimum_size() const { - Size2 size = theme_cache.normal_style->get_minimum_size(); - - if (fixed_width != -1) { - size.x += fixed_width; - } + Size2 sb_min_size = theme_cache.normal_style->get_minimum_size(); + Size2 min_size; - if (fit_content_height) { - size.y += get_content_height(); + if (fit_content) { + min_size.x = get_content_width(); + min_size.y = get_content_height(); } - return size; + return sb_min_size + + ((autowrap_mode != TextServer::AUTOWRAP_OFF) ? Size2(1, min_size.height) : min_size); } // Context menu. diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 8ac77d5b47..58b82d4672 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -524,9 +524,7 @@ private: bool use_bbcode = false; String text; - int fixed_width = -1; - - bool fit_content_height = false; + bool fit_content = false; struct ThemeCache { Ref<StyleBox> normal_style; @@ -640,8 +638,8 @@ public: void set_shortcut_keys_enabled(bool p_enabled); bool is_shortcut_keys_enabled() const; - void set_fit_content_height(bool p_enabled); - bool is_fit_content_height_enabled() const; + void set_fit_content(bool p_enabled); + bool is_fit_content_enabled() const; bool search(const String &p_string, bool p_from_selection = false, bool p_search_previous = false); @@ -731,7 +729,6 @@ public: void install_effect(const Variant effect); - void set_fixed_size_to_width(int p_width); virtual Size2 get_minimum_size() const override; RichTextLabel(const String &p_text = String()); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 56bd5c872a..723f3fe7af 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -3544,6 +3544,19 @@ void TextEdit::insert_text_at_caret(const String &p_text, int p_caret) { adjust_carets_after_edit(i, new_line, new_column, from_line, from_col); } + + if (!ime_text.is_empty()) { + for (int i = 0; i < carets.size(); i++) { + String t; + if (get_caret_column(i) >= 0) { + t = text[get_caret_line(i)].substr(0, get_caret_column(i)) + ime_text + text[get_caret_line(i)].substr(get_caret_column(i), text[get_caret_line(i)].length()); + } else { + t = ime_text; + } + text.invalidate_cache(get_caret_line(i), get_caret_column(i), true, t, structured_text_parser(st_parser, st_args, t)); + } + } + end_complex_operation(); queue_redraw(); } @@ -6374,7 +6387,7 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_tabs"), "set_draw_tabs", "is_drawing_tabs"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_spaces"), "set_draw_spaces", "is_drawing_spaces"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "syntax_highlighter", PROPERTY_HINT_RESOURCE_TYPE, "SyntaxHighlighter", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_syntax_highlighter", "get_syntax_highlighter"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "syntax_highlighter", PROPERTY_HINT_RESOURCE_TYPE, "SyntaxHighlighter", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ALWAYS_DUPLICATE), "set_syntax_highlighter", "get_syntax_highlighter"); ADD_GROUP("Scroll", "scroll_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_smooth"), "set_smooth_scroll_enabled", "is_smooth_scroll_enabled"); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 2d985c2324..d9e6157489 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -3554,7 +3554,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { icon_size_x = icon_region.size.width; } } - // Icon is treated as if it is outside of the rect so that double clicking on it will emit the item_double_clicked signal. + // Icon is treated as if it is outside of the rect so that double clicking on it will emit the item_icon_double_clicked signal. if (rtl) { mpos.x = get_size().width - (mpos.x + icon_size_x); } else { @@ -3562,10 +3562,10 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { } if (rect.has_point(mpos)) { if (!edit_selected()) { - emit_signal(SNAME("item_double_clicked")); + emit_signal(SNAME("item_icon_double_clicked")); } } else { - emit_signal(SNAME("item_double_clicked")); + emit_signal(SNAME("item_icon_double_clicked")); } } pressing_for_editor = false; @@ -5257,7 +5257,7 @@ void Tree::_bind_methods() { ADD_SIGNAL(MethodInfo("item_edited")); ADD_SIGNAL(MethodInfo("custom_item_clicked", PropertyInfo(Variant::INT, "mouse_button_index"))); ADD_SIGNAL(MethodInfo("item_custom_button_pressed")); - ADD_SIGNAL(MethodInfo("item_double_clicked")); + ADD_SIGNAL(MethodInfo("item_icon_double_clicked")); ADD_SIGNAL(MethodInfo("item_collapsed", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "TreeItem"))); ADD_SIGNAL(MethodInfo("check_propagated_to_item", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "TreeItem"), PropertyInfo(Variant::INT, "column"))); ADD_SIGNAL(MethodInfo("button_clicked", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "TreeItem"), PropertyInfo(Variant::INT, "column"), PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::INT, "mouse_button_index"))); diff --git a/scene/gui/view_panner.cpp b/scene/gui/view_panner.cpp index e8d54e6937..145497fa61 100644 --- a/scene/gui/view_panner.cpp +++ b/scene/gui/view_panner.cpp @@ -43,36 +43,42 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect) if (scroll_vec != Vector2() && mb->is_pressed()) { if (control_scheme == SCROLL_PANS) { if (mb->is_ctrl_pressed()) { - scroll_vec.y *= mb->get_factor(); - callback_helper(zoom_callback, varray(scroll_vec, mb->get_position(), mb->is_alt_pressed())); + // Compute the zoom factor. + float zoom_factor = mb->get_factor() <= 0 ? 1.0 : mb->get_factor(); + zoom_factor = ((scroll_zoom_factor - 1.0) * zoom_factor) + 1.0; + float zoom = (scroll_vec.x + scroll_vec.y) > 0 ? 1.0 / scroll_zoom_factor : scroll_zoom_factor; + callback_helper(zoom_callback, varray(zoom, mb->get_position(), p_event)); return true; } else { - Vector2 panning; - if (mb->is_shift_pressed()) { - panning.x += mb->get_factor() * scroll_vec.y; - panning.y += mb->get_factor() * scroll_vec.x; - } else { - panning.y += mb->get_factor() * scroll_vec.y; - panning.x += mb->get_factor() * scroll_vec.x; + Vector2 panning = scroll_vec * mb->get_factor(); + if (pan_axis == PAN_AXIS_HORIZONTAL) { + panning = Vector2(panning.x + panning.y, 0); + } else if (pan_axis == PAN_AXIS_VERTICAL) { + panning = Vector2(0, panning.x + panning.y); + } else if (mb->is_shift_pressed()) { + panning = Vector2(panning.y, panning.x); } - callback_helper(scroll_callback, varray(panning, mb->is_alt_pressed())); + callback_helper(pan_callback, varray(-panning * scroll_speed, p_event)); return true; } } else { if (mb->is_ctrl_pressed()) { - Vector2 panning; - if (mb->is_shift_pressed()) { - panning.x += mb->get_factor() * scroll_vec.y; - panning.y += mb->get_factor() * scroll_vec.x; - } else { - panning.y += mb->get_factor() * scroll_vec.y; - panning.x += mb->get_factor() * scroll_vec.x; + Vector2 panning = scroll_vec * mb->get_factor(); + if (pan_axis == PAN_AXIS_HORIZONTAL) { + panning = Vector2(panning.x + panning.y, 0); + } else if (pan_axis == PAN_AXIS_VERTICAL) { + panning = Vector2(0, panning.x + panning.y); + } else if (mb->is_shift_pressed()) { + panning = Vector2(panning.y, panning.x); } - callback_helper(scroll_callback, varray(panning, mb->is_alt_pressed())); + callback_helper(pan_callback, varray(-panning * scroll_speed, p_event)); return true; } else if (!mb->is_shift_pressed()) { - scroll_vec.y *= mb->get_factor(); - callback_helper(zoom_callback, varray(scroll_vec, mb->get_position(), mb->is_alt_pressed())); + // Compute the zoom factor. + float zoom_factor = mb->get_factor() <= 0 ? 1.0 : mb->get_factor(); + zoom_factor = ((scroll_zoom_factor - 1.0) * zoom_factor) + 1.0; + float zoom = (scroll_vec.x + scroll_vec.y) > 0 ? 1.0 / scroll_zoom_factor : scroll_zoom_factor; + callback_helper(zoom_callback, varray(zoom, mb->get_position(), p_event)); return true; } } @@ -102,14 +108,31 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect) if (mm.is_valid()) { if (is_dragging) { if (p_canvas_rect != Rect2()) { - callback_helper(pan_callback, varray(Input::get_singleton()->warp_mouse_motion(mm, p_canvas_rect))); + callback_helper(pan_callback, varray(Input::get_singleton()->warp_mouse_motion(mm, p_canvas_rect), p_event)); } else { - callback_helper(pan_callback, varray(mm->get_relative())); + callback_helper(pan_callback, varray(mm->get_relative(), p_event)); } return true; } } + Ref<InputEventMagnifyGesture> magnify_gesture = p_event; + if (magnify_gesture.is_valid()) { + // Zoom gesture + callback_helper(zoom_callback, varray(magnify_gesture->get_factor(), magnify_gesture->get_position(), p_event)); + return true; + } + + Ref<InputEventPanGesture> pan_gesture = p_event; + if (pan_gesture.is_valid()) { + callback_helper(pan_callback, varray(-pan_gesture->get_delta(), p_event)); + } + + Ref<InputEventScreenDrag> screen_drag = p_event; + if (screen_drag.is_valid()) { + callback_helper(pan_callback, varray(screen_drag->get_relative(), p_event)); + } + Ref<InputEventKey> k = p_event; if (k.is_valid()) { if (pan_view_shortcut.is_valid() && pan_view_shortcut->matches_event(k)) { @@ -140,8 +163,7 @@ void ViewPanner::callback_helper(Callable p_callback, Vector<Variant> p_args) { p_callback.callp(argptr, p_args.size(), result, ce); } -void ViewPanner::set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback) { - scroll_callback = p_scroll_callback; +void ViewPanner::set_callbacks(Callable p_pan_callback, Callable p_zoom_callback) { pan_callback = p_pan_callback; zoom_callback = p_zoom_callback; } @@ -163,6 +185,20 @@ void ViewPanner::set_simple_panning_enabled(bool p_enabled) { simple_panning_enabled = p_enabled; } +void ViewPanner::set_scroll_speed(int p_scroll_speed) { + ERR_FAIL_COND(p_scroll_speed <= 0); + scroll_speed = p_scroll_speed; +} + +void ViewPanner::set_scroll_zoom_factor(float p_scroll_zoom_factor) { + ERR_FAIL_COND(p_scroll_zoom_factor <= 1.0); + scroll_zoom_factor = p_scroll_zoom_factor; +} + +void ViewPanner::set_pan_axis(PanAxis p_pan_axis) { + pan_axis = p_pan_axis; +} + void ViewPanner::setup(ControlScheme p_scheme, Ref<Shortcut> p_shortcut, bool p_simple_panning) { set_control_scheme(p_scheme); set_pan_shortcut(p_shortcut); diff --git a/scene/gui/view_panner.h b/scene/gui/view_panner.h index 861574a80c..60d36ca04c 100644 --- a/scene/gui/view_panner.h +++ b/scene/gui/view_panner.h @@ -45,7 +45,17 @@ public: SCROLL_PANS, }; + enum PanAxis { + PAN_AXIS_BOTH, + PAN_AXIS_HORIZONTAL, + PAN_AXIS_VERTICAL, + }; + private: + int scroll_speed = 32; + float scroll_zoom_factor = 1.1; + PanAxis pan_axis = PAN_AXIS_BOTH; + bool is_dragging = false; bool pan_key_pressed = false; bool force_drag = false; @@ -55,7 +65,6 @@ private: Ref<Shortcut> pan_view_shortcut; - Callable scroll_callback; Callable pan_callback; Callable zoom_callback; @@ -63,11 +72,14 @@ private: ControlScheme control_scheme = SCROLL_ZOOMS; public: - void set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback); + void set_callbacks(Callable p_pan_callback, Callable p_zoom_callback); void set_control_scheme(ControlScheme p_scheme); void set_enable_rmb(bool p_enable); void set_pan_shortcut(Ref<Shortcut> p_shortcut); void set_simple_panning_enabled(bool p_enabled); + void set_scroll_speed(int p_scroll_speed); + void set_scroll_zoom_factor(float p_scroll_zoom_factor); + void set_pan_axis(PanAxis p_pan_axis); void setup(ControlScheme p_scheme, Ref<Shortcut> p_shortcut, bool p_simple_panning); diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 7b0554442c..3323c0f848 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -154,17 +154,7 @@ Transform2D CanvasItem::get_global_transform_with_canvas() const { Transform2D CanvasItem::get_screen_transform() const { ERR_FAIL_COND_V(!is_inside_tree(), Transform2D()); - Transform2D xform = get_global_transform_with_canvas(); - - Window *w = Object::cast_to<Window>(get_viewport()); - if (w && !w->is_embedding_subwindows()) { - Transform2D s; - s.set_origin(w->get_position()); - - xform = s * xform; - } - - return xform; + return get_viewport()->get_popup_base_transform() * get_global_transform_with_canvas(); } Transform2D CanvasItem::get_global_transform() const { diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 0b1f8f101c..de486094fe 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -946,7 +946,7 @@ String Node::validate_child_name(Node *p_child) { #endif String Node::adjust_name_casing(const String &p_name) { - switch (GLOBAL_GET("editor/node_naming/name_casing").operator int()) { + switch (GLOBAL_GET("editor/naming/node_name_casing").operator int()) { case NAME_CASING_PASCAL_CASE: return p_name.to_pascal_case(); case NAME_CASING_CAMEL_CASE: @@ -2213,7 +2213,7 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c Variant value = N->get()->get(name).duplicate(true); - if (E.usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) { + if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) { Resource *res = Object::cast_to<Resource>(value); if (res) { // Duplicate only if it's a resource current_node->set(name, res->duplicate()); @@ -2799,8 +2799,8 @@ void Node::unhandled_key_input(const Ref<InputEvent> &p_key_event) { } void Node::_bind_methods() { - GLOBAL_DEF(PropertyInfo(Variant::INT, "editor/node_naming/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"), 0); - GLOBAL_DEF(PropertyInfo(Variant::INT, "editor/node_naming/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case"), NAME_CASING_PASCAL_CASE); + GLOBAL_DEF(PropertyInfo(Variant::INT, "editor/naming/node_name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"), 0); + GLOBAL_DEF(PropertyInfo(Variant::INT, "editor/naming/node_name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case"), NAME_CASING_PASCAL_CASE); ClassDB::bind_static_method("Node", D_METHOD("print_orphan_nodes"), &Node::print_orphan_nodes); ClassDB::bind_method(D_METHOD("add_sibling", "sibling", "force_readable_name"), &Node::add_sibling, DEFVAL(false)); @@ -3022,7 +3022,7 @@ void Node::_bind_methods() { } String Node::_get_name_num_separator() { - switch (GLOBAL_GET("editor/node_naming/name_num_separator").operator int()) { + switch (GLOBAL_GET("editor/naming/node_name_num_separator").operator int()) { case 0: return ""; case 1: diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 07bcf45899..48cff5aa8e 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -704,25 +704,15 @@ void Viewport::_process_picking() { } #ifndef _3D_DISABLED - bool captured = false; - + CollisionObject3D *capture_object = nullptr; if (physics_object_capture.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture)); - if (co && camera_3d) { - _collision_object_3d_input_event(co, camera_3d, ev, Vector3(), Vector3(), 0); - captured = true; - if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) { - physics_object_capture = ObjectID(); - } - - } else { + capture_object = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture)); + if (!capture_object || !camera_3d || (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed())) { physics_object_capture = ObjectID(); } } - if (captured) { - // None. - } else if (pos == last_pos) { + if (pos == last_pos) { if (last_id.is_valid()) { if (ObjectDB::get_instance(last_id) && last_object) { // Good, exists. @@ -748,13 +738,12 @@ void Viewport::_process_picking() { bool col = space->intersect_ray(ray_params, result); ObjectID new_collider; - if (col) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider); - if (co && co->can_process()) { - _collision_object_3d_input_event(co, camera_3d, ev, result.position, result.normal, result.shape); + CollisionObject3D *co = col ? Object::cast_to<CollisionObject3D>(result.collider) : nullptr; + if (co && co->can_process()) { + new_collider = result.collider_id; + if (!capture_object) { last_object = co; last_id = result.collider_id; - new_collider = last_id; if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { physics_object_capture = last_id; } @@ -763,21 +752,24 @@ void Viewport::_process_picking() { if (is_mouse && new_collider != physics_object_over) { if (physics_object_over.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); - if (co) { - co->_mouse_exit(); + CollisionObject3D *previous_co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); + if (previous_co) { + previous_co->_mouse_exit(); } } if (new_collider.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(new_collider)); - if (co) { - co->_mouse_enter(); - } + DEV_ASSERT(co); + co->_mouse_enter(); } physics_object_over = new_collider; } + if (capture_object) { + _collision_object_3d_input_event(capture_object, camera_3d, ev, result.position, result.normal, result.shape); + } else if (new_collider.is_valid()) { + _collision_object_3d_input_event(co, camera_3d, ev, result.position, result.normal, result.shape); + } } last_pos = pos; @@ -1050,7 +1042,7 @@ Camera2D *Viewport::get_camera_2d() const { } Transform2D Viewport::get_final_transform() const { - return stretch_transform * global_canvas_transform; + return _get_input_pre_xform().affine_inverse() * stretch_transform * global_canvas_transform; } void Viewport::_update_canvas_items(Node *p_node) { @@ -1133,7 +1125,7 @@ Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) { return ev; // No transformation defined for null event } - Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform(); + Transform2D ai = get_final_transform().affine_inverse(); return ev->xformed_by(ai); } @@ -1795,9 +1787,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (w->is_embedded()) { embedder = w->_get_embedder(); - Transform2D ai = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse(); - - viewport_pos = ai.xform(mpos) + w->get_position(); // To parent coords. + viewport_pos = get_final_transform().xform(mpos) + w->get_position(); // To parent coords. } } } @@ -1847,7 +1837,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (viewport_under) { if (viewport_under != this) { - Transform2D ai = (viewport_under->get_final_transform().affine_inverse() * viewport_under->_get_input_pre_xform()); + Transform2D ai = viewport_under->get_final_transform().affine_inverse(); viewport_pos = ai.xform(viewport_pos); } // Find control under at position. @@ -2853,7 +2843,7 @@ bool Viewport::get_physics_object_picking() { } Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const { - Transform2D xf = get_final_transform(); + Transform2D xf = stretch_transform * global_canvas_transform; return xf.xform(p_viewport_coords); } @@ -3245,7 +3235,7 @@ Viewport::SDFScale Viewport::get_sdf_scale() const { } Transform2D Viewport::get_screen_transform() const { - return _get_input_pre_xform().affine_inverse() * get_final_transform(); + return get_final_transform(); } void Viewport::set_canvas_cull_mask(uint32_t p_canvas_cull_mask) { @@ -4188,6 +4178,21 @@ Transform2D SubViewport::get_screen_transform() const { return container_transform * Viewport::get_screen_transform(); } +Transform2D SubViewport::get_popup_base_transform() const { + if (is_embedding_subwindows()) { + return Transform2D(); + } + SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent()); + if (!c) { + return Viewport::get_screen_transform(); + } + Transform2D container_transform; + if (c->is_stretch_enabled()) { + container_transform.scale(Vector2(c->get_stretch_shrink(), c->get_stretch_shrink())); + } + return c->get_screen_transform() * container_transform * Viewport::get_screen_transform(); +} + void SubViewport::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 603e92b071..d5d5201e9a 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -649,6 +649,7 @@ public: bool get_canvas_cull_mask_bit(uint32_t p_layer) const; virtual Transform2D get_screen_transform() const; + virtual Transform2D get_popup_base_transform() const { return Transform2D(); } #ifndef _3D_DISABLED bool use_xr = false; @@ -775,6 +776,7 @@ public: ClearMode get_clear_mode() const; virtual Transform2D get_screen_transform() const override; + virtual Transform2D get_popup_base_transform() const override; SubViewport(); ~SubViewport(); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 2c6599d849..3ceb27b3e6 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -2104,6 +2104,19 @@ Transform2D Window::get_screen_transform() const { return embedder_transform * Viewport::get_screen_transform(); } +Transform2D Window::get_popup_base_transform() const { + if (is_embedding_subwindows()) { + return Transform2D(); + } + Transform2D window_transform; + window_transform.set_origin(get_position()); + window_transform *= Viewport::get_screen_transform(); + if (_get_embedder()) { + return _get_embedder()->get_popup_base_transform() * window_transform; + } + return window_transform; +} + void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title); ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title); diff --git a/scene/main/window.h b/scene/main/window.h index e9c217f973..18841a4f1a 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -373,6 +373,7 @@ public: // virtual Transform2D get_screen_transform() const override; + virtual Transform2D get_popup_base_transform() const override; Rect2i get_parent_rect() const; virtual DisplayServer::WindowID get_window_id() const override; diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index deee187e8e..e5a1adff20 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -2868,6 +2868,12 @@ void SystemFont::_bind_methods() { ClassDB::bind_method(D_METHOD("set_multichannel_signed_distance_field", "msdf"), &SystemFont::set_multichannel_signed_distance_field); ClassDB::bind_method(D_METHOD("is_multichannel_signed_distance_field"), &SystemFont::is_multichannel_signed_distance_field); + ClassDB::bind_method(D_METHOD("set_msdf_pixel_range", "msdf_pixel_range"), &SystemFont::set_msdf_pixel_range); + ClassDB::bind_method(D_METHOD("get_msdf_pixel_range"), &SystemFont::get_msdf_pixel_range); + + ClassDB::bind_method(D_METHOD("set_msdf_size", "msdf_size"), &SystemFont::set_msdf_size); + ClassDB::bind_method(D_METHOD("get_msdf_size"), &SystemFont::get_msdf_size); + ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &SystemFont::set_oversampling); ClassDB::bind_method(D_METHOD("get_oversampling"), &SystemFont::get_oversampling); @@ -2890,6 +2896,8 @@ void SystemFont::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel"), "set_subpixel_positioning", "get_subpixel_positioning"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field"), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range"), "set_msdf_pixel_range", "get_msdf_pixel_range"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size"), "set_msdf_size", "get_msdf_size"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), "set_oversampling", "get_oversampling"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("Font")), "set_fallbacks", "get_fallbacks"); } @@ -2987,6 +2995,8 @@ void SystemFont::_update_base_font() { file->set_hinting(hinting); file->set_subpixel_positioning(subpixel_positioning); file->set_multichannel_signed_distance_field(msdf); + file->set_msdf_pixel_range(msdf_pixel_range); + file->set_msdf_size(msdf_size); file->set_oversampling(oversampling); base_font = file; @@ -3186,6 +3196,34 @@ bool SystemFont::is_multichannel_signed_distance_field() const { return msdf; } +void SystemFont::set_msdf_pixel_range(int p_msdf_pixel_range) { + if (msdf_pixel_range != p_msdf_pixel_range) { + msdf_pixel_range = p_msdf_pixel_range; + if (base_font.is_valid()) { + base_font->set_msdf_pixel_range(msdf_pixel_range); + } + emit_changed(); + } +} + +int SystemFont::get_msdf_pixel_range() const { + return msdf_pixel_range; +} + +void SystemFont::set_msdf_size(int p_msdf_size) { + if (msdf_size != p_msdf_size) { + msdf_size = p_msdf_size; + if (base_font.is_valid()) { + base_font->set_msdf_size(msdf_size); + } + emit_changed(); + } +} + +int SystemFont::get_msdf_size() const { + return msdf_size; +} + void SystemFont::set_oversampling(real_t p_oversampling) { if (oversampling != p_oversampling) { oversampling = p_oversampling; diff --git a/scene/resources/font.h b/scene/resources/font.h index 4d468a8841..ef79f8bd02 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -452,6 +452,8 @@ class SystemFont : public Font { TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; real_t oversampling = 0.f; bool msdf = false; + int msdf_pixel_range = 16; + int msdf_size = 48; protected: static void _bind_methods(); @@ -488,6 +490,12 @@ public: virtual void set_multichannel_signed_distance_field(bool p_msdf); virtual bool is_multichannel_signed_distance_field() const; + virtual void set_msdf_pixel_range(int p_msdf_pixel_range); + virtual int get_msdf_pixel_range() const; + + virtual void set_msdf_size(int p_msdf_size); + virtual int get_msdf_size() const; + virtual void set_font_names(const PackedStringArray &p_names); virtual PackedStringArray get_font_names() const; diff --git a/scene/resources/skeleton_modification_2d_stackholder.cpp b/scene/resources/skeleton_modification_2d_stackholder.cpp index 121108965b..34d31bac8a 100644 --- a/scene/resources/skeleton_modification_2d_stackholder.cpp +++ b/scene/resources/skeleton_modification_2d_stackholder.cpp @@ -64,7 +64,7 @@ bool SkeletonModification2DStackHolder::_get(const StringName &p_path, Variant & } void SkeletonModification2DStackHolder::_get_property_list(List<PropertyInfo> *p_list) const { - p_list->push_back(PropertyInfo(Variant::OBJECT, "held_modification_stack", PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModificationStack2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "held_modification_stack", PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModificationStack2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ALWAYS_DUPLICATE)); #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { diff --git a/scene/resources/skeleton_modification_stack_2d.cpp b/scene/resources/skeleton_modification_stack_2d.cpp index 4fa287e7b6..71ddbc0898 100644 --- a/scene/resources/skeleton_modification_stack_2d.cpp +++ b/scene/resources/skeleton_modification_stack_2d.cpp @@ -37,7 +37,7 @@ void SkeletonModificationStack2D::_get_property_list(List<PropertyInfo> *p_list) PropertyInfo(Variant::OBJECT, "modifications/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModification2D", - PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); + PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE | PROPERTY_USAGE_ALWAYS_DUPLICATE)); } } diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 4f16986392..0beb62185d 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -231,22 +231,6 @@ bool StyleBoxTexture::is_draw_center_enabled() const { return draw_center; } -Size2 StyleBoxTexture::get_minimum_size() const { - Size2 min_size = StyleBox::get_minimum_size(); - - // Make sure that the min size is no smaller than the used texture region. - if (texture.is_valid()) { - if (min_size.x < region_rect.size.x) { - min_size.x = region_rect.size.x; - } - if (min_size.y < region_rect.size.y) { - min_size.y = region_rect.size.y; - } - } - - return min_size; -} - void StyleBoxTexture::set_expand_margin(Side p_side, float p_size) { ERR_FAIL_INDEX((int)p_side, 4); expand_margin[p_side] = p_size; diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 91033617ab..17acfd773e 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -107,8 +107,6 @@ protected: static void _bind_methods(); public: - virtual Size2 get_minimum_size() const override; - void set_expand_margin(Side p_expand_side, float p_size); void set_expand_margin_all(float p_expand_margin_size); void set_expand_margin_individual(float p_left, float p_top, float p_right, float p_bottom); diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 17e92ddfca..5a2b917b9a 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -146,6 +146,25 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) { return h; } +bool SurfaceTool::SmoothGroupVertex::operator==(const SmoothGroupVertex &p_vertex) const { + if (vertex != p_vertex.vertex) { + return false; + } + + if (smooth_group != p_vertex.smooth_group) { + return false; + } + + return true; +} + +uint32_t SurfaceTool::SmoothGroupVertexHasher::hash(const SmoothGroupVertex &p_vtx) { + uint32_t h = hash_djb2_buffer((const uint8_t *)&p_vtx.vertex, sizeof(real_t) * 3); + h = hash_murmur3_one_32(p_vtx.smooth_group, h); + h = hash_fmix32(h); + return h; +} + uint32_t SurfaceTool::TriangleHasher::hash(const int *p_triangle) { int t0 = p_triangle[0]; int t1 = p_triangle[1]; @@ -1152,7 +1171,7 @@ void SurfaceTool::generate_normals(bool p_flip) { ERR_FAIL_COND((vertex_array.size() % 3) != 0); - HashMap<Vertex, Vector3, VertexHasher> vertex_hash; + HashMap<SmoothGroupVertex, Vector3, SmoothGroupVertexHasher> smooth_hash; for (uint32_t vi = 0; vi < vertex_array.size(); vi += 3) { Vertex *v = &vertex_array[vi]; @@ -1165,21 +1184,28 @@ void SurfaceTool::generate_normals(bool p_flip) { } for (int i = 0; i < 3; i++) { - Vector3 *lv = vertex_hash.getptr(v[i]); - if (!lv) { - vertex_hash.insert(v[i], normal); + // Add face normal to smooth vertex influence if vertex is member of a smoothing group + if (v[i].smooth_group != UINT32_MAX) { + Vector3 *lv = smooth_hash.getptr(v[i]); + if (!lv) { + smooth_hash.insert(v[i], normal); + } else { + (*lv) += normal; + } } else { - (*lv) += normal; + v[i].normal = normal; } } } for (Vertex &vertex : vertex_array) { - Vector3 *lv = vertex_hash.getptr(vertex); - if (!lv) { - vertex.normal = Vector3(); - } else { - vertex.normal = lv->normalized(); + if (vertex.smooth_group != UINT32_MAX) { + Vector3 *lv = smooth_hash.getptr(vertex); + if (!lv) { + vertex.normal = Vector3(); + } else { + vertex.normal = lv->normalized(); + } } } diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 25e078d2ff..00438c4a53 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -97,6 +97,21 @@ private: static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx); }; + struct SmoothGroupVertex { + Vector3 vertex; + uint32_t smooth_group = 0; + bool operator==(const SmoothGroupVertex &p_vertex) const; + + SmoothGroupVertex(const Vertex &p_vertex) { + vertex = p_vertex.vertex; + smooth_group = p_vertex.smooth_group; + }; + }; + + struct SmoothGroupVertexHasher { + static _FORCE_INLINE_ uint32_t hash(const SmoothGroupVertex &p_vtx); + }; + struct TriangleHasher { static _FORCE_INLINE_ uint32_t hash(const int *p_triangle); static _FORCE_INLINE_ bool compare(const int *p_lhs, const int *p_rhs); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 1cbeaae428..bfcf5cb137 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -1561,7 +1561,7 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { prop_name += "/" + itos(E.key); if (E.key != NODE_ID_OUTPUT) { - p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); + p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_ALWAYS_DUPLICATE)); } p_list->push_back(PropertyInfo(Variant::VECTOR2, prop_name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index e78d9b924d..12be0f46a6 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -3690,16 +3690,47 @@ String VisualShaderNodeDerivativeFunc::get_output_port_name(int p_port) const { String VisualShaderNodeDerivativeFunc::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 { static const char *functions[FUNC_MAX] = { - "fwidth($)", - "dFdx($)", - "dFdy($)" + "fwidth$($)", + "dFdx$($)", + "dFdy$($)" + }; + + static const char *precisions[PRECISION_MAX] = { + "", + "Coarse", + "Fine" }; String code; - code += " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n"; + if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") { + code += " " + p_output_vars[0] + " = " + String(functions[func]).replace_first("$", "").replace_first("$", p_input_vars[0]) + ";\n"; + return code; + } + + code += " " + p_output_vars[0] + " = " + String(functions[func]).replace_first("$", String(precisions[precision])).replace_first("$", p_input_vars[0]) + ";\n"; return code; } +String VisualShaderNodeDerivativeFunc::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { + if (precision != PRECISION_NONE && OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") { + String precision_str; + switch (precision) { + case PRECISION_COARSE: { + precision_str = "Coarse"; + } break; + case PRECISION_FINE: { + precision_str = "Fine"; + } break; + default: { + } break; + } + + return vformat(RTR("`%s` precision mode is not available for `gl_compatibility` profile.\nReverted to `None` precision."), precision_str); + } + + return String(); +} + void VisualShaderNodeDerivativeFunc::set_op_type(OpType p_op_type) { ERR_FAIL_INDEX((int)p_op_type, int(OP_TYPE_MAX)); if (op_type == p_op_type) { @@ -3742,10 +3773,24 @@ VisualShaderNodeDerivativeFunc::Function VisualShaderNodeDerivativeFunc::get_fun return func; } +void VisualShaderNodeDerivativeFunc::set_precision(Precision p_precision) { + ERR_FAIL_INDEX(int(p_precision), int(PRECISION_MAX)); + if (precision == p_precision) { + return; + } + precision = p_precision; + emit_changed(); +} + +VisualShaderNodeDerivativeFunc::Precision VisualShaderNodeDerivativeFunc::get_precision() const { + return precision; +} + Vector<StringName> VisualShaderNodeDerivativeFunc::get_editable_properties() const { Vector<StringName> props; props.push_back("op_type"); props.push_back("function"); + props.push_back("precision"); return props; } @@ -3756,8 +3801,12 @@ void VisualShaderNodeDerivativeFunc::_bind_methods() { ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeDerivativeFunc::set_function); ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeDerivativeFunc::get_function); + ClassDB::bind_method(D_METHOD("set_precision", "precision"), &VisualShaderNodeDerivativeFunc::set_precision); + ClassDB::bind_method(D_METHOD("get_precision"), &VisualShaderNodeDerivativeFunc::get_precision); + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3,Vector4"), "set_op_type", "get_op_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sum,X,Y"), "set_function", "get_function"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "precision", PROPERTY_HINT_ENUM, "None,Coarse,Fine"), "set_precision", "get_precision"); BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D); @@ -3769,6 +3818,11 @@ void VisualShaderNodeDerivativeFunc::_bind_methods() { BIND_ENUM_CONSTANT(FUNC_X); BIND_ENUM_CONSTANT(FUNC_Y); BIND_ENUM_CONSTANT(FUNC_MAX); + + BIND_ENUM_CONSTANT(PRECISION_NONE); + BIND_ENUM_CONSTANT(PRECISION_COARSE); + BIND_ENUM_CONSTANT(PRECISION_FINE); + BIND_ENUM_CONSTANT(PRECISION_MAX); } VisualShaderNodeDerivativeFunc::VisualShaderNodeDerivativeFunc() { diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index e3b101cf84..fa6b134526 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -1536,9 +1536,17 @@ public: FUNC_MAX, }; + enum Precision { + PRECISION_NONE, + PRECISION_COARSE, + PRECISION_FINE, + PRECISION_MAX, + }; + protected: OpType op_type = OP_TYPE_SCALAR; Function func = FUNC_SUM; + Precision precision = PRECISION_NONE; protected: static void _bind_methods(); @@ -1555,6 +1563,7 @@ public: virtual String get_output_port_name(int p_port) const override; 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 override; + virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override; void set_op_type(OpType p_op_type); OpType get_op_type() const; @@ -1562,6 +1571,9 @@ public: void set_function(Function p_func); Function get_function() const; + void set_precision(Precision p_precision); + Precision get_precision() const; + virtual Vector<StringName> get_editable_properties() const override; VisualShaderNodeDerivativeFunc(); @@ -1569,6 +1581,7 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::OpType) VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::Function) +VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::Precision) /////////////////////////////////////// /// FACEFORWARD |