diff options
Diffstat (limited to 'scene')
70 files changed, 1621 insertions, 387 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 2dcf7c3a11..a37fabf21f 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -51,13 +51,13 @@ bool Area2D::is_gravity_a_point() const { return gravity_is_point; } -void Area2D::set_gravity_point_distance_scale(real_t p_scale) { - gravity_distance_scale = p_scale; - PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale); +void Area2D::set_gravity_point_unit_distance(real_t p_scale) { + gravity_point_unit_distance = p_scale; + PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_UNIT_DISTANCE, p_scale); } -real_t Area2D::get_gravity_point_distance_scale() const { - return gravity_distance_scale; +real_t Area2D::get_gravity_point_unit_distance() const { + return gravity_point_unit_distance; } void Area2D::set_gravity_point_center(const Vector2 &p_center) { @@ -557,8 +557,8 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gravity_is_point", "enable"), &Area2D::set_gravity_is_point); ClassDB::bind_method(D_METHOD("is_gravity_a_point"), &Area2D::is_gravity_a_point); - ClassDB::bind_method(D_METHOD("set_gravity_point_distance_scale", "distance_scale"), &Area2D::set_gravity_point_distance_scale); - ClassDB::bind_method(D_METHOD("get_gravity_point_distance_scale"), &Area2D::get_gravity_point_distance_scale); + ClassDB::bind_method(D_METHOD("set_gravity_point_unit_distance", "distance_scale"), &Area2D::set_gravity_point_unit_distance); + ClassDB::bind_method(D_METHOD("get_gravity_point_unit_distance"), &Area2D::get_gravity_point_unit_distance); ClassDB::bind_method(D_METHOD("set_gravity_point_center", "center"), &Area2D::set_gravity_point_center); ClassDB::bind_method(D_METHOD("get_gravity_point_center"), &Area2D::get_gravity_point_center); @@ -622,7 +622,7 @@ void Area2D::_bind_methods() { ADD_GROUP("Gravity", "gravity_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "gravity_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_gravity_space_override_mode", "get_gravity_space_override_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_gravity_is_point", "is_gravity_a_point"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp"), "set_gravity_point_distance_scale", "get_gravity_point_distance_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_unit_distance", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp,suffix:px"), "set_gravity_point_unit_distance", "get_gravity_point_unit_distance"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_point_center", PROPERTY_HINT_NONE, "suffix:px"), "set_gravity_point_center", "get_gravity_point_center"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_direction"), "set_gravity_direction", "get_gravity_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-4096,4096,0.001,or_less,or_greater,suffix:px/s\u00B2"), "set_gravity", "get_gravity"); diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index aaf7ea28f8..8f4bbe3219 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -51,7 +51,7 @@ private: Vector2 gravity_vec; real_t gravity = 0.0; bool gravity_is_point = false; - real_t gravity_distance_scale = 0.0; + real_t gravity_point_unit_distance = 0.0; SpaceOverride linear_damp_space_override = SPACE_OVERRIDE_DISABLED; SpaceOverride angular_damp_space_override = SPACE_OVERRIDE_DISABLED; @@ -144,8 +144,8 @@ public: void set_gravity_is_point(bool p_enabled); bool is_gravity_a_point() const; - void set_gravity_point_distance_scale(real_t p_scale); - real_t get_gravity_point_distance_scale() const; + void set_gravity_point_unit_distance(real_t p_scale); + real_t get_gravity_point_unit_distance() const; void set_gravity_point_center(const Vector2 &p_center); const Vector2 &get_gravity_point_center() const; diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 71b8fdb539..49c5501e77 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -50,7 +50,7 @@ void Camera2D::_update_scroll() { return; } - if (current) { + if (is_current()) { ERR_FAIL_COND(custom_viewport && !ObjectDB::get_instance(custom_viewport_id)); Transform2D xform = get_camera_transform(); @@ -241,10 +241,6 @@ void Camera2D::_notification(int p_what) { viewport = get_viewport(); } - if (is_current()) { - viewport->_camera_2d_set(this); - } - canvas = get_canvas(); RID vp = viewport->get_viewport_rid(); @@ -254,6 +250,10 @@ void Camera2D::_notification(int p_what) { add_to_group(group_name); add_to_group(canvas_group_name); + if (enabled && !viewport->get_camera_2d()) { + make_current(); + } + _update_process_callback(); first = true; _update_scroll(); @@ -261,11 +261,7 @@ void Camera2D::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { if (is_current()) { - if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { - viewport->set_canvas_transform(Transform2D()); - clear_current(); - current = true; - } + clear_current(); } remove_from_group(group_name); remove_from_group(canvas_group_name); @@ -397,19 +393,31 @@ void Camera2D::set_process_callback(Camera2DProcessCallback p_mode) { _update_process_callback(); } +void Camera2D::set_enabled(bool p_enabled) { + enabled = p_enabled; + + if (enabled && is_inside_tree() && !viewport->get_camera_2d()) { + make_current(); + } else if (!enabled && is_current()) { + clear_current(); + } +} + +bool Camera2D::is_enabled() const { + return enabled; +} + Camera2D::Camera2DProcessCallback Camera2D::get_process_callback() const { return process_callback; } void Camera2D::_make_current(Object *p_which) { if (p_which == this) { - current = true; if (is_inside_tree()) { get_viewport()->_camera_2d_set(this); queue_redraw(); } } else { - current = false; if (is_inside_tree()) { if (get_viewport()->get_camera_2d() == this) { get_viewport()->_camera_2d_set(nullptr); @@ -419,43 +427,32 @@ void Camera2D::_make_current(Object *p_which) { } } -void Camera2D::set_current(bool p_current) { - if (p_current) { - make_current(); - } else { - if (current) { - clear_current(); - } - } -} - void Camera2D::_update_process_internal_for_smoothing() { bool is_not_in_scene_or_editor = !(is_inside_tree() && Engine::get_singleton()->is_editor_hint()); bool is_any_smoothing_valid = position_smoothing_speed > 0 || rotation_smoothing_speed > 0; - bool enabled = is_any_smoothing_valid && is_not_in_scene_or_editor; - set_process_internal(enabled); -} - -bool Camera2D::is_current() const { - return current; + bool enable = is_any_smoothing_valid && is_not_in_scene_or_editor; + set_process_internal(enable); } void Camera2D::make_current() { - if (is_inside_tree()) { - get_tree()->call_group(group_name, "_make_current", this); - } else { - current = true; - } + ERR_FAIL_COND(!enabled || !is_inside_tree()); + get_tree()->call_group(group_name, "_make_current", this); _update_scroll(); } void Camera2D::clear_current() { - if (is_inside_tree()) { - get_tree()->call_group(group_name, "_make_current", (Object *)nullptr); - } else { - current = false; + ERR_FAIL_COND(!is_current()); + if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { + viewport->assign_next_enabled_camera_2d(group_name); + } +} + +bool Camera2D::is_current() const { + if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { + return viewport->get_camera_2d() == this; } + return false; } void Camera2D::set_limit(Side p_side, int p_limit) { @@ -715,7 +712,10 @@ void Camera2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &Camera2D::set_process_callback); ClassDB::bind_method(D_METHOD("get_process_callback"), &Camera2D::get_process_callback); - ClassDB::bind_method(D_METHOD("set_current", "current"), &Camera2D::set_current); + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Camera2D::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &Camera2D::is_enabled); + + ClassDB::bind_method(D_METHOD("make_current"), &Camera2D::make_current); ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current); ClassDB::bind_method(D_METHOD("_make_current"), &Camera2D::_make_current); @@ -779,7 +779,7 @@ void Camera2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset", PROPERTY_HINT_NONE, "suffix:px"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_mode", PROPERTY_HINT_ENUM, "Fixed TopLeft,Drag Center"), "set_anchor_mode", "get_anchor_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_rotation"), "set_ignore_rotation", "is_ignoring_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom", PROPERTY_HINT_LINK), "set_zoom", "get_zoom"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", PROPERTY_USAGE_NONE), "set_custom_viewport", "get_custom_viewport"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback"); diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 304b4ceaa6..7a77266db8 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -64,7 +64,7 @@ protected: Vector2 zoom_scale = Vector2(1, 1); AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER; bool ignore_rotation = true; - bool current = false; + bool enabled = true; real_t position_smoothing_speed = 5.0; bool follow_smoothing_enabled = false; @@ -88,7 +88,6 @@ protected: void _update_scroll(); void _make_current(Object *p_which); - void set_current(bool p_current); void _set_old_smoothing(real_t p_enable); @@ -155,6 +154,9 @@ public: void set_process_callback(Camera2DProcessCallback p_mode); Camera2DProcessCallback get_process_callback() const; + void set_enabled(bool p_enabled); + bool is_enabled() const; + void make_current(); void clear_current(); bool is_current() const; diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index e73b6e7e23..380a684c9b 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -108,6 +108,26 @@ void NavigationAgent2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10,0.01,suffix:s"), "set_time_horizon", "get_time_horizon"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:px/s"), "set_max_speed", "get_max_speed"); +#ifdef DEBUG_ENABLED + ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationAgent2D::set_debug_enabled); + ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationAgent2D::get_debug_enabled); + ClassDB::bind_method(D_METHOD("set_debug_use_custom", "enabled"), &NavigationAgent2D::set_debug_use_custom); + ClassDB::bind_method(D_METHOD("get_debug_use_custom"), &NavigationAgent2D::get_debug_use_custom); + ClassDB::bind_method(D_METHOD("set_debug_path_custom_color", "color"), &NavigationAgent2D::set_debug_path_custom_color); + ClassDB::bind_method(D_METHOD("get_debug_path_custom_color"), &NavigationAgent2D::get_debug_path_custom_color); + ClassDB::bind_method(D_METHOD("set_debug_path_custom_point_size", "point_size"), &NavigationAgent2D::set_debug_path_custom_point_size); + ClassDB::bind_method(D_METHOD("get_debug_path_custom_point_size"), &NavigationAgent2D::get_debug_path_custom_point_size); + ClassDB::bind_method(D_METHOD("set_debug_path_custom_line_width", "line_width"), &NavigationAgent2D::set_debug_path_custom_line_width); + ClassDB::bind_method(D_METHOD("get_debug_path_custom_line_width"), &NavigationAgent2D::get_debug_path_custom_line_width); + + ADD_GROUP("Debug", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_enabled"), "set_debug_enabled", "get_debug_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_use_custom"), "set_debug_use_custom", "get_debug_use_custom"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_path_custom_color"), "set_debug_path_custom_color", "get_debug_path_custom_color"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_point_size", PROPERTY_HINT_RANGE, "1,50,1,suffix:px"), "set_debug_path_custom_point_size", "get_debug_path_custom_point_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_line_width", PROPERTY_HINT_RANGE, "1,50,1,suffix:px"), "set_debug_path_custom_line_width", "get_debug_path_custom_line_width"); +#endif // DEBUG_ENABLED + ADD_SIGNAL(MethodInfo("path_changed")); ADD_SIGNAL(MethodInfo("target_reached")); ADD_SIGNAL(MethodInfo("waypoint_reached", PropertyInfo(Variant::DICTIONARY, "details"))); @@ -123,6 +143,12 @@ void NavigationAgent2D::_notification(int p_what) { // cannot use READY as ready does not get called if Node is readded to SceneTree set_agent_parent(get_parent()); set_physics_process_internal(true); + +#ifdef DEBUG_ENABLED + if (NavigationServer2D::get_singleton()->get_debug_enabled()) { + debug_path_dirty = true; + } +#endif // DEBUG_ENABLED } break; case NOTIFICATION_PARENTED: { @@ -165,6 +191,12 @@ void NavigationAgent2D::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { agent_parent = nullptr; set_physics_process_internal(false); + +#ifdef DEBUG_ENABLED + if (debug_path_instance.is_valid()) { + RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, false); + } +#endif // DEBUG_ENABLED } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { @@ -176,6 +208,12 @@ void NavigationAgent2D::_notification(int p_what) { } _check_distance_to_target(); } + +#ifdef DEBUG_ENABLED + if (debug_path_dirty) { + _update_debug_path(); + } +#endif // DEBUG_ENABLED } break; } } @@ -194,12 +232,25 @@ NavigationAgent2D::NavigationAgent2D() { navigation_result = Ref<NavigationPathQueryResult2D>(); navigation_result.instantiate(); + +#ifdef DEBUG_ENABLED + NavigationServer2D::get_singleton()->connect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent2D::_navigation_debug_changed)); +#endif // DEBUG_ENABLED } NavigationAgent2D::~NavigationAgent2D() { ERR_FAIL_NULL(NavigationServer2D::get_singleton()); NavigationServer2D::get_singleton()->free(agent); agent = RID(); // Pointless + +#ifdef DEBUG_ENABLED + NavigationServer2D::get_singleton()->disconnect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent2D::_navigation_debug_changed)); + + ERR_FAIL_NULL(RenderingServer::get_singleton()); + if (debug_path_instance.is_valid()) { + RenderingServer::get_singleton()->free(debug_path_instance); + } +#endif // DEBUG_ENABLED } void NavigationAgent2D::set_avoidance_enabled(bool p_enabled) { @@ -463,6 +514,9 @@ void NavigationAgent2D::update_navigation() { } NavigationServer2D::get_singleton()->query_path(navigation_query, navigation_result); +#ifdef DEBUG_ENABLED + debug_path_dirty = true; +#endif // DEBUG_ENABLED navigation_finished = false; navigation_path_index = 0; emit_signal(SNAME("path_changed")); @@ -549,3 +603,111 @@ void NavigationAgent2D::_check_distance_to_target() { } } } + +////////DEBUG//////////////////////////////////////////////////////////// + +#ifdef DEBUG_ENABLED +void NavigationAgent2D::set_debug_enabled(bool p_enabled) { + debug_enabled = p_enabled; + debug_path_dirty = true; +} + +bool NavigationAgent2D::get_debug_enabled() const { + return debug_enabled; +} + +void NavigationAgent2D::set_debug_use_custom(bool p_enabled) { + debug_use_custom = p_enabled; + debug_path_dirty = true; +} + +bool NavigationAgent2D::get_debug_use_custom() const { + return debug_use_custom; +} + +void NavigationAgent2D::set_debug_path_custom_color(Color p_color) { + debug_path_custom_color = p_color; + debug_path_dirty = true; +} + +Color NavigationAgent2D::get_debug_path_custom_color() const { + return debug_path_custom_color; +} + +void NavigationAgent2D::set_debug_path_custom_point_size(float p_point_size) { + debug_path_custom_point_size = MAX(0.1, p_point_size); + debug_path_dirty = true; +} + +float NavigationAgent2D::get_debug_path_custom_point_size() const { + return debug_path_custom_point_size; +} + +void NavigationAgent2D::set_debug_path_custom_line_width(float p_line_width) { + debug_path_custom_line_width = p_line_width; + debug_path_dirty = true; +} + +float NavigationAgent2D::get_debug_path_custom_line_width() const { + return debug_path_custom_line_width; +} + +void NavigationAgent2D::_navigation_debug_changed() { + debug_path_dirty = true; +} + +void NavigationAgent2D::_update_debug_path() { + if (!debug_path_dirty) { + return; + } + debug_path_dirty = false; + + if (!debug_path_instance.is_valid()) { + debug_path_instance = RenderingServer::get_singleton()->canvas_item_create(); + } + + RenderingServer::get_singleton()->canvas_item_clear(debug_path_instance); + + if (!(debug_enabled && NavigationServer2D::get_singleton()->get_debug_navigation_enable_agent_paths())) { + return; + } + + if (!(agent_parent && agent_parent->is_inside_tree())) { + return; + } + + RenderingServer::get_singleton()->canvas_item_set_parent(debug_path_instance, agent_parent->get_canvas()); + RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, agent_parent->is_visible_in_tree()); + + const Vector<Vector2> &navigation_path = navigation_result->get_path(); + + if (navigation_path.size() <= 1) { + return; + } + + Color debug_path_color = NavigationServer2D::get_singleton()->get_debug_navigation_agent_path_color(); + if (debug_use_custom) { + debug_path_color = debug_path_custom_color; + } + + Vector<Color> debug_path_colors; + debug_path_colors.resize(navigation_path.size()); + debug_path_colors.fill(debug_path_color); + + RenderingServer::get_singleton()->canvas_item_add_polyline(debug_path_instance, navigation_path, debug_path_colors, debug_path_custom_line_width, false); + + float point_size = NavigationServer2D::get_singleton()->get_debug_navigation_agent_path_point_size(); + float half_point_size = point_size * 0.5; + + if (debug_use_custom) { + point_size = debug_path_custom_point_size; + half_point_size = debug_path_custom_point_size * 0.5; + } + + for (int i = 0; i < navigation_path.size(); i++) { + const Vector2 &vert = navigation_path[i]; + Rect2 path_point_rect = Rect2(vert.x - half_point_size, vert.y - half_point_size, point_size, point_size); + RenderingServer::get_singleton()->canvas_item_add_rect(debug_path_instance, path_point_rect, debug_path_color); + } +} +#endif // DEBUG_ENABLED diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 9787bb1bdb..8f4a373327 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -74,6 +74,20 @@ class NavigationAgent2D : public Node { // No initialized on purpose uint32_t update_frame_id = 0; +#ifdef DEBUG_ENABLED + bool debug_enabled = false; + bool debug_path_dirty = true; + RID debug_path_instance; + float debug_path_custom_point_size = 4.0; + float debug_path_custom_line_width = 1.0; + bool debug_use_custom = false; + Color debug_path_custom_color = Color(1.0, 1.0, 1.0, 1.0); + +private: + void _navigation_debug_changed(); + void _update_debug_path(); +#endif // DEBUG_ENABLED + protected: static void _bind_methods(); void _notification(int p_what); @@ -169,6 +183,23 @@ public: PackedStringArray get_configuration_warnings() const override; +#ifdef DEBUG_ENABLED + void set_debug_enabled(bool p_enabled); + bool get_debug_enabled() const; + + void set_debug_use_custom(bool p_enabled); + bool get_debug_use_custom() const; + + void set_debug_path_custom_color(Color p_color); + Color get_debug_path_custom_color() const; + + void set_debug_path_custom_point_size(float p_point_size); + float get_debug_path_custom_point_size() const; + + void set_debug_path_custom_line_width(float p_line_width); + float get_debug_path_custom_line_width() const; +#endif // DEBUG_ENABLED + private: void update_navigation(); void _request_repath(); diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 72f186c676..5901e38bb4 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -51,13 +51,13 @@ bool Area3D::is_gravity_a_point() const { return gravity_is_point; } -void Area3D::set_gravity_point_distance_scale(real_t p_scale) { - gravity_distance_scale = p_scale; - PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale); +void Area3D::set_gravity_point_unit_distance(real_t p_scale) { + gravity_point_unit_distance = p_scale; + PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_UNIT_DISTANCE, p_scale); } -real_t Area3D::get_gravity_point_distance_scale() const { - return gravity_distance_scale; +real_t Area3D::get_gravity_point_unit_distance() const { + return gravity_point_unit_distance; } void Area3D::set_gravity_point_center(const Vector3 &p_center) { @@ -655,8 +655,8 @@ void Area3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gravity_is_point", "enable"), &Area3D::set_gravity_is_point); ClassDB::bind_method(D_METHOD("is_gravity_a_point"), &Area3D::is_gravity_a_point); - ClassDB::bind_method(D_METHOD("set_gravity_point_distance_scale", "distance_scale"), &Area3D::set_gravity_point_distance_scale); - ClassDB::bind_method(D_METHOD("get_gravity_point_distance_scale"), &Area3D::get_gravity_point_distance_scale); + ClassDB::bind_method(D_METHOD("set_gravity_point_unit_distance", "distance_scale"), &Area3D::set_gravity_point_unit_distance); + ClassDB::bind_method(D_METHOD("get_gravity_point_unit_distance"), &Area3D::get_gravity_point_unit_distance); ClassDB::bind_method(D_METHOD("set_gravity_point_center", "center"), &Area3D::set_gravity_point_center); ClassDB::bind_method(D_METHOD("get_gravity_point_center"), &Area3D::get_gravity_point_center); @@ -741,7 +741,7 @@ void Area3D::_bind_methods() { ADD_GROUP("Gravity", "gravity_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "gravity_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_gravity_space_override_mode", "get_gravity_space_override_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_gravity_is_point", "is_gravity_a_point"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp"), "set_gravity_point_distance_scale", "get_gravity_point_distance_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_unit_distance", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp,suffix:m"), "set_gravity_point_unit_distance", "get_gravity_point_unit_distance"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_point_center", PROPERTY_HINT_NONE, "suffix:m"), "set_gravity_point_center", "get_gravity_point_center"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_direction"), "set_gravity_direction", "get_gravity_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-32,32,0.001,or_less,or_greater,suffix:m/s\u00B2"), "set_gravity", "get_gravity"); diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index 91b91f741a..607e0d2af8 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -51,7 +51,7 @@ private: Vector3 gravity_vec; real_t gravity = 0.0; bool gravity_is_point = false; - real_t gravity_distance_scale = 0.0; + real_t gravity_point_unit_distance = 0.0; SpaceOverride linear_damp_space_override = SPACE_OVERRIDE_DISABLED; SpaceOverride angular_damp_space_override = SPACE_OVERRIDE_DISABLED; @@ -155,8 +155,8 @@ public: void set_gravity_is_point(bool p_enabled); bool is_gravity_a_point() const; - void set_gravity_point_distance_scale(real_t p_scale); - real_t get_gravity_point_distance_scale() const; + void set_gravity_point_unit_distance(real_t p_scale); + real_t get_gravity_point_unit_distance() const; void set_gravity_point_center(const Vector3 &p_center); const Vector3 &get_gravity_point_center() const; diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp index fe7f6837f0..ba5ff02862 100644 --- a/scene/3d/bone_attachment_3d.cpp +++ b/scene/3d/bone_attachment_3d.cpp @@ -81,11 +81,6 @@ bool BoneAttachment3D::_get(const StringName &p_path, Variant &r_ret) const { } void BoneAttachment3D::_get_property_list(List<PropertyInfo> *p_list) const { - p_list->push_back(PropertyInfo(Variant::BOOL, "override_pose", PROPERTY_HINT_NONE, "")); - if (override_pose) { - p_list->push_back(PropertyInfo(Variant::INT, "override_mode", PROPERTY_HINT_ENUM, "Global Pose Override,Local Pose Override,Custom Pose")); - } - p_list->push_back(PropertyInfo(Variant::BOOL, "use_external_skeleton", PROPERTY_HINT_NONE, "")); if (use_external_skeleton) { p_list->push_back(PropertyInfo(Variant::NODE_PATH, "external_skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton3D")); diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index fbcb1c8f2c..e122adcc8c 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -30,14 +30,14 @@ #include "decal.h" -void Decal::set_extents(const Vector3 &p_extents) { - extents = p_extents; - RS::get_singleton()->decal_set_extents(decal, p_extents); +void Decal::set_size(const Vector3 &p_size) { + size = p_size; + RS::get_singleton()->decal_set_size(decal, p_size); update_gizmos(); } -Vector3 Decal::get_extents() const { - return extents; +Vector3 Decal::get_size() const { + return size; } void Decal::set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture) { @@ -147,8 +147,8 @@ uint32_t Decal::get_cull_mask() const { AABB Decal::get_aabb() const { AABB aabb; - aabb.position = -extents; - aabb.size = extents * 2.0; + aabb.position = -size / 2; + aabb.size = size; return aabb; } @@ -181,8 +181,8 @@ PackedStringArray Decal::get_configuration_warnings() const { } void Decal::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &Decal::get_extents); + ClassDB::bind_method(D_METHOD("set_size", "size"), &Decal::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &Decal::get_size); ClassDB::bind_method(D_METHOD("set_texture", "type", "texture"), &Decal::set_texture); ClassDB::bind_method(D_METHOD("get_texture", "type"), &Decal::get_texture); @@ -217,7 +217,7 @@ void Decal::_bind_methods() { ClassDB::bind_method(D_METHOD("set_cull_mask", "mask"), &Decal::set_cull_mask); ClassDB::bind_method(D_METHOD("get_cull_mask"), &Decal::get_cull_mask); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,suffix:m"), "set_extents", "get_extents"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,suffix:m"), "set_size", "get_size"); ADD_GROUP("Textures", "texture_"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO); @@ -252,6 +252,24 @@ void Decal::_bind_methods() { BIND_ENUM_CONSTANT(TEXTURE_MAX); } +#ifndef DISABLE_DEPRECATED +bool Decal::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "extents") { // Compatibility with Godot 3.x. + set_size((Vector3)p_value * 2); + return true; + } + return false; +} + +bool Decal::_get(const StringName &p_name, Variant &r_property) const { + if (p_name == "extents") { // Compatibility with Godot 3.x. + r_property = size / 2; + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + Decal::Decal() { decal = RenderingServer::get_singleton()->decal_create(); RS::get_singleton()->instance_set_base(get_instance(), decal); diff --git a/scene/3d/decal.h b/scene/3d/decal.h index 5797a2f645..171b52815a 100644 --- a/scene/3d/decal.h +++ b/scene/3d/decal.h @@ -47,7 +47,7 @@ public: private: RID decal; - Vector3 extents = Vector3(1, 1, 1); + Vector3 size = Vector3(2, 2, 2); Ref<Texture2D> textures[TEXTURE_MAX]; real_t emission_energy = 1.0; real_t albedo_mix = 1.0; @@ -63,12 +63,16 @@ private: protected: static void _bind_methods(); void _validate_property(PropertyInfo &p_property) const; +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_property) const; +#endif // DISABLE_DEPRECATED public: virtual PackedStringArray get_configuration_warnings() const override; - void set_extents(const Vector3 &p_extents); - Vector3 get_extents() const; + void set_size(const Vector3 &p_size); + Vector3 get_size() const; void set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture); Ref<Texture2D> get_texture(DecalTexture p_type) const; diff --git a/scene/3d/fog_volume.cpp b/scene/3d/fog_volume.cpp index 30dfb45836..9b0a7bb302 100644 --- a/scene/3d/fog_volume.cpp +++ b/scene/3d/fog_volume.cpp @@ -34,36 +34,54 @@ /////////////////////////// void FogVolume::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &FogVolume::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &FogVolume::get_extents); + ClassDB::bind_method(D_METHOD("set_size", "size"), &FogVolume::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &FogVolume::get_size); ClassDB::bind_method(D_METHOD("set_shape", "shape"), &FogVolume::set_shape); ClassDB::bind_method(D_METHOD("get_shape"), &FogVolume::get_shape); ClassDB::bind_method(D_METHOD("set_material", "material"), &FogVolume::set_material); ClassDB::bind_method(D_METHOD("get_material"), &FogVolume::get_material); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shape", PROPERTY_HINT_ENUM, "Ellipsoid (Local),Cone (Local),Cylinder (Local),Box (Local),World (Global)"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "FogMaterial,ShaderMaterial"), "set_material", "get_material"); } void FogVolume::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "extents" && shape == RS::FOG_VOLUME_SHAPE_WORLD) { + if (p_property.name == "size" && shape == RS::FOG_VOLUME_SHAPE_WORLD) { p_property.usage = PROPERTY_USAGE_NONE; return; } } -void FogVolume::set_extents(const Vector3 &p_extents) { - extents = p_extents; - extents.x = MAX(0.0, extents.x); - extents.y = MAX(0.0, extents.y); - extents.z = MAX(0.0, extents.z); - RS::get_singleton()->fog_volume_set_extents(_get_volume(), extents); +#ifndef DISABLE_DEPRECATED +bool FogVolume::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "extents") { // Compatibility with Godot 3.x. + set_size((Vector3)p_value * 2); + return true; + } + return false; +} + +bool FogVolume::_get(const StringName &p_name, Variant &r_property) const { + if (p_name == "extents") { // Compatibility with Godot 3.x. + r_property = size / 2; + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + +void FogVolume::set_size(const Vector3 &p_size) { + size = p_size; + size.x = MAX(0.0, size.x); + size.y = MAX(0.0, size.y); + size.z = MAX(0.0, size.z); + RS::get_singleton()->fog_volume_set_size(_get_volume(), size); update_gizmos(); } -Vector3 FogVolume::get_extents() const { - return extents; +Vector3 FogVolume::get_size() const { + return size; } void FogVolume::set_shape(RS::FogVolumeShape p_type) { @@ -94,7 +112,7 @@ Ref<Material> FogVolume::get_material() const { AABB FogVolume::get_aabb() const { if (shape != RS::FOG_VOLUME_SHAPE_WORLD) { - return AABB(-extents, extents * 2); + return AABB(-size / 2, size); } return AABB(); } diff --git a/scene/3d/fog_volume.h b/scene/3d/fog_volume.h index fa02834762..f7e861e3d0 100644 --- a/scene/3d/fog_volume.h +++ b/scene/3d/fog_volume.h @@ -40,7 +40,7 @@ class FogVolume : public VisualInstance3D { GDCLASS(FogVolume, VisualInstance3D); - Vector3 extents = Vector3(1, 1, 1); + Vector3 size = Vector3(2, 2, 2); Ref<Material> material; RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX; @@ -50,10 +50,14 @@ protected: _FORCE_INLINE_ RID _get_volume() { return volume; } static void _bind_methods(); void _validate_property(PropertyInfo &p_property) const; +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_property) const; +#endif // DISABLE_DEPRECATED public: - void set_extents(const Vector3 &p_extents); - Vector3 get_extents() const; + void set_size(const Vector3 &p_size); + Vector3 get_size() const; void set_shape(RS::FogVolumeShape p_type); RS::FogVolumeShape get_shape() const; diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index d1f2dfb25f..137d578291 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -95,24 +95,42 @@ GPUParticlesCollisionSphere3D::~GPUParticlesCollisionSphere3D() { /////////////////////////// void GPUParticlesCollisionBox3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionBox3D::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionBox3D::get_extents); + ClassDB::bind_method(D_METHOD("set_size", "size"), &GPUParticlesCollisionBox3D::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &GPUParticlesCollisionBox3D::get_size); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size"); } -void GPUParticlesCollisionBox3D::set_extents(const Vector3 &p_extents) { - extents = p_extents; - RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); +#ifndef DISABLE_DEPRECATED +bool GPUParticlesCollisionBox3D::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "extents") { // Compatibility with Godot 3.x. + set_size((Vector3)p_value * 2); + return true; + } + return false; +} + +bool GPUParticlesCollisionBox3D::_get(const StringName &p_name, Variant &r_property) const { + if (p_name == "extents") { // Compatibility with Godot 3.x. + r_property = size / 2; + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + +void GPUParticlesCollisionBox3D::set_size(const Vector3 &p_size) { + size = p_size; + RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), size / 2); update_gizmos(); } -Vector3 GPUParticlesCollisionBox3D::get_extents() const { - return extents; +Vector3 GPUParticlesCollisionBox3D::get_size() const { + return size; } AABB GPUParticlesCollisionBox3D::get_aabb() const { - return AABB(-extents, extents * 2); + return AABB(-size / 2, size); } GPUParticlesCollisionBox3D::GPUParticlesCollisionBox3D() : @@ -359,7 +377,7 @@ Vector3i GPUParticlesCollisionSDF3D::get_estimated_cell_size() const { static const int subdivs[RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 }; int subdiv = subdivs[get_resolution()]; - AABB aabb(-extents, extents * 2); + AABB aabb(-size / 2, size); float cell_size = aabb.get_longest_axis_size() / float(subdiv); @@ -374,7 +392,7 @@ Ref<Image> GPUParticlesCollisionSDF3D::bake() { static const int subdivs[RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 }; int subdiv = subdivs[get_resolution()]; - AABB aabb(-extents, extents * 2); + AABB aabb(-size / 2, size); float cell_size = aabb.get_longest_axis_size() / float(subdiv); @@ -515,8 +533,8 @@ PackedStringArray GPUParticlesCollisionSDF3D::get_configuration_warnings() const } void GPUParticlesCollisionSDF3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionSDF3D::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionSDF3D::get_extents); + ClassDB::bind_method(D_METHOD("set_size", "size"), &GPUParticlesCollisionSDF3D::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &GPUParticlesCollisionSDF3D::get_size); ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionSDF3D::set_resolution); ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionSDF3D::get_resolution); @@ -532,7 +550,7 @@ void GPUParticlesCollisionSDF3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bake_mask_value", "layer_number", "value"), &GPUParticlesCollisionSDF3D::set_bake_mask_value); ClassDB::bind_method(D_METHOD("get_bake_mask_value", "layer_number"), &GPUParticlesCollisionSDF3D::get_bake_mask_value); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "16,32,64,128,256,512"), "set_resolution", "get_resolution"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "thickness", PROPERTY_HINT_RANGE, "0.0,2.0,0.01,suffix:m"), "set_thickness", "get_thickness"); ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_bake_mask", "get_bake_mask"); @@ -547,6 +565,24 @@ void GPUParticlesCollisionSDF3D::_bind_methods() { BIND_ENUM_CONSTANT(RESOLUTION_MAX); } +#ifndef DISABLE_DEPRECATED +bool GPUParticlesCollisionSDF3D::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "extents") { // Compatibility with Godot 3.x. + set_size((Vector3)p_value * 2); + return true; + } + return false; +} + +bool GPUParticlesCollisionSDF3D::_get(const StringName &p_name, Variant &r_property) const { + if (p_name == "extents") { // Compatibility with Godot 3.x. + r_property = size / 2; + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + void GPUParticlesCollisionSDF3D::set_thickness(float p_thickness) { thickness = p_thickness; } @@ -555,14 +591,14 @@ float GPUParticlesCollisionSDF3D::get_thickness() const { return thickness; } -void GPUParticlesCollisionSDF3D::set_extents(const Vector3 &p_extents) { - extents = p_extents; - RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); +void GPUParticlesCollisionSDF3D::set_size(const Vector3 &p_size) { + size = p_size; + RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), size / 2); update_gizmos(); } -Vector3 GPUParticlesCollisionSDF3D::get_extents() const { - return extents; +Vector3 GPUParticlesCollisionSDF3D::get_size() const { + return size; } void GPUParticlesCollisionSDF3D::set_resolution(Resolution p_resolution) { @@ -610,7 +646,7 @@ Ref<Texture3D> GPUParticlesCollisionSDF3D::get_texture() const { } AABB GPUParticlesCollisionSDF3D::get_aabb() const { - return AABB(-extents, extents * 2); + return AABB(-size / 2, size); } GPUParticlesCollisionSDF3D::BakeBeginFunc GPUParticlesCollisionSDF3D::bake_begin_function = nullptr; @@ -675,8 +711,8 @@ void GPUParticlesCollisionHeightField3D::_notification(int p_what) { } void GPUParticlesCollisionHeightField3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionHeightField3D::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionHeightField3D::get_extents); + ClassDB::bind_method(D_METHOD("set_size", "size"), &GPUParticlesCollisionHeightField3D::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &GPUParticlesCollisionHeightField3D::get_size); ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionHeightField3D::set_resolution); ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionHeightField3D::get_resolution); @@ -687,7 +723,7 @@ void GPUParticlesCollisionHeightField3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_follow_camera_enabled", "enabled"), &GPUParticlesCollisionHeightField3D::set_follow_camera_enabled); ClassDB::bind_method(D_METHOD("is_follow_camera_enabled"), &GPUParticlesCollisionHeightField3D::is_follow_camera_enabled); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "256 (Fastest),512 (Fast),1024 (Average),2048 (Slow),4096 (Slower),8192 (Slowest)"), "set_resolution", "get_resolution"); ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "When Moved (Fast),Always (Slow)"), "set_update_mode", "get_update_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_camera_enabled"), "set_follow_camera_enabled", "is_follow_camera_enabled"); @@ -704,15 +740,33 @@ void GPUParticlesCollisionHeightField3D::_bind_methods() { BIND_ENUM_CONSTANT(UPDATE_MODE_ALWAYS); } -void GPUParticlesCollisionHeightField3D::set_extents(const Vector3 &p_extents) { - extents = p_extents; - RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); +#ifndef DISABLE_DEPRECATED +bool GPUParticlesCollisionHeightField3D::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "extents") { // Compatibility with Godot 3.x. + set_size((Vector3)p_value * 2); + return true; + } + return false; +} + +bool GPUParticlesCollisionHeightField3D::_get(const StringName &p_name, Variant &r_property) const { + if (p_name == "extents") { // Compatibility with Godot 3.x. + r_property = size / 2; + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + +void GPUParticlesCollisionHeightField3D::set_size(const Vector3 &p_size) { + size = p_size; + RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), size / 2); update_gizmos(); RS::get_singleton()->particles_collision_height_field_update(_get_collision()); } -Vector3 GPUParticlesCollisionHeightField3D::get_extents() const { - return extents; +Vector3 GPUParticlesCollisionHeightField3D::get_size() const { + return size; } void GPUParticlesCollisionHeightField3D::set_resolution(Resolution p_resolution) { @@ -745,7 +799,7 @@ bool GPUParticlesCollisionHeightField3D::is_follow_camera_enabled() const { } AABB GPUParticlesCollisionHeightField3D::get_aabb() const { - return AABB(-extents, extents * 2); + return AABB(-size / 2, size); } GPUParticlesCollisionHeightField3D::GPUParticlesCollisionHeightField3D() : @@ -857,24 +911,42 @@ GPUParticlesAttractorSphere3D::~GPUParticlesAttractorSphere3D() { /////////////////////////// void GPUParticlesAttractorBox3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorBox3D::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorBox3D::get_extents); + ClassDB::bind_method(D_METHOD("set_size", "size"), &GPUParticlesAttractorBox3D::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &GPUParticlesAttractorBox3D::get_size); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size"); +} - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents"); +#ifndef DISABLE_DEPRECATED +bool GPUParticlesAttractorBox3D::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "extents") { // Compatibility with Godot 3.x. + set_size((Vector3)p_value * 2); + return true; + } + return false; } -void GPUParticlesAttractorBox3D::set_extents(const Vector3 &p_extents) { - extents = p_extents; - RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); +bool GPUParticlesAttractorBox3D::_get(const StringName &p_name, Variant &r_property) const { + if (p_name == "extents") { // Compatibility with Godot 3.x. + r_property = size / 2; + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + +void GPUParticlesAttractorBox3D::set_size(const Vector3 &p_size) { + size = p_size; + RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), size / 2); update_gizmos(); } -Vector3 GPUParticlesAttractorBox3D::get_extents() const { - return extents; +Vector3 GPUParticlesAttractorBox3D::get_size() const { + return size; } AABB GPUParticlesAttractorBox3D::get_aabb() const { - return AABB(-extents, extents * 2); + return AABB(-size / 2, size); } GPUParticlesAttractorBox3D::GPUParticlesAttractorBox3D() : @@ -887,24 +959,42 @@ GPUParticlesAttractorBox3D::~GPUParticlesAttractorBox3D() { /////////////////////////// void GPUParticlesAttractorVectorField3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorVectorField3D::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorVectorField3D::get_extents); + ClassDB::bind_method(D_METHOD("set_size", "size"), &GPUParticlesAttractorVectorField3D::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &GPUParticlesAttractorVectorField3D::get_size); ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesAttractorVectorField3D::set_texture); ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesAttractorVectorField3D::get_texture); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture"); } -void GPUParticlesAttractorVectorField3D::set_extents(const Vector3 &p_extents) { - extents = p_extents; - RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); +#ifndef DISABLE_DEPRECATED +bool GPUParticlesAttractorVectorField3D::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "extents") { // Compatibility with Godot 3.x. + set_size((Vector3)p_value * 2); + return true; + } + return false; +} + +bool GPUParticlesAttractorVectorField3D::_get(const StringName &p_name, Variant &r_property) const { + if (p_name == "extents") { // Compatibility with Godot 3.x. + r_property = size / 2; + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + +void GPUParticlesAttractorVectorField3D::set_size(const Vector3 &p_size) { + size = p_size; + RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), size / 2); update_gizmos(); } -Vector3 GPUParticlesAttractorVectorField3D::get_extents() const { - return extents; +Vector3 GPUParticlesAttractorVectorField3D::get_size() const { + return size; } void GPUParticlesAttractorVectorField3D::set_texture(const Ref<Texture3D> &p_texture) { @@ -918,7 +1008,7 @@ Ref<Texture3D> GPUParticlesAttractorVectorField3D::get_texture() const { } AABB GPUParticlesAttractorVectorField3D::get_aabb() const { - return AABB(-extents, extents * 2); + return AABB(-size / 2, size); } GPUParticlesAttractorVectorField3D::GPUParticlesAttractorVectorField3D() : diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index 3c569ac73d..1649320069 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -74,14 +74,18 @@ public: class GPUParticlesCollisionBox3D : public GPUParticlesCollision3D { GDCLASS(GPUParticlesCollisionBox3D, GPUParticlesCollision3D); - Vector3 extents = Vector3(1, 1, 1); + Vector3 size = Vector3(2, 2, 2); protected: static void _bind_methods(); +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_property) const; +#endif // DISABLE_DEPRECATED public: - void set_extents(const Vector3 &p_extents); - Vector3 get_extents() const; + void set_size(const Vector3 &p_size); + Vector3 get_size() const; virtual AABB get_aabb() const override; @@ -108,7 +112,7 @@ public: typedef void (*BakeEndFunc)(); private: - Vector3 extents = Vector3(1, 1, 1); + Vector3 size = Vector3(2, 2, 2); Resolution resolution = RESOLUTION_64; uint32_t bake_mask = 0xFFFFFFFF; Ref<Texture3D> texture; @@ -160,6 +164,10 @@ private: protected: static void _bind_methods(); +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_property) const; +#endif // DISABLE_DEPRECATED public: virtual PackedStringArray get_configuration_warnings() const override; @@ -167,8 +175,8 @@ public: void set_thickness(float p_thickness); float get_thickness() const; - void set_extents(const Vector3 &p_extents); - Vector3 get_extents() const; + void set_size(const Vector3 &p_size); + Vector3 get_size() const; void set_resolution(Resolution p_resolution); Resolution get_resolution() const; @@ -217,7 +225,7 @@ public: }; private: - Vector3 extents = Vector3(1, 1, 1); + Vector3 size = Vector3(2, 2, 2); Resolution resolution = RESOLUTION_1024; bool follow_camera_mode = false; @@ -226,10 +234,14 @@ private: protected: void _notification(int p_what); static void _bind_methods(); +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_property) const; +#endif // DISABLE_DEPRECATED public: - void set_extents(const Vector3 &p_extents); - Vector3 get_extents() const; + void set_size(const Vector3 &p_size); + Vector3 get_size() const; void set_resolution(Resolution p_resolution); Resolution get_resolution() const; @@ -301,14 +313,18 @@ public: class GPUParticlesAttractorBox3D : public GPUParticlesAttractor3D { GDCLASS(GPUParticlesAttractorBox3D, GPUParticlesAttractor3D); - Vector3 extents = Vector3(1, 1, 1); + Vector3 size = Vector3(2, 2, 2); protected: static void _bind_methods(); +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_property) const; +#endif // DISABLE_DEPRECATED public: - void set_extents(const Vector3 &p_extents); - Vector3 get_extents() const; + void set_size(const Vector3 &p_size); + Vector3 get_size() const; virtual AABB get_aabb() const override; @@ -319,15 +335,19 @@ public: class GPUParticlesAttractorVectorField3D : public GPUParticlesAttractor3D { GDCLASS(GPUParticlesAttractorVectorField3D, GPUParticlesAttractor3D); - Vector3 extents = Vector3(1, 1, 1); + Vector3 size = Vector3(2, 2, 2); Ref<Texture3D> texture; protected: static void _bind_methods(); +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_property) const; +#endif // DISABLE_DEPRECATED public: - void set_extents(const Vector3 &p_extents); - Vector3 get_extents() const; + void set_size(const Vector3 &p_size); + Vector3 get_size() const; void set_texture(const Ref<Texture3D> &p_texture); Ref<Texture3D> get_texture() const; diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index 6a9b8c9ac4..b39ca43d2e 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -112,6 +112,12 @@ void Label3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_alpha_hash_scale", "threshold"), &Label3D::set_alpha_hash_scale); ClassDB::bind_method(D_METHOD("get_alpha_hash_scale"), &Label3D::get_alpha_hash_scale); + ClassDB::bind_method(D_METHOD("set_alpha_antialiasing", "alpha_aa"), &Label3D::set_alpha_antialiasing); + ClassDB::bind_method(D_METHOD("get_alpha_antialiasing"), &Label3D::get_alpha_antialiasing); + + ClassDB::bind_method(D_METHOD("set_alpha_antialiasing_edge", "edge"), &Label3D::set_alpha_antialiasing_edge); + ClassDB::bind_method(D_METHOD("get_alpha_antialiasing_edge"), &Label3D::get_alpha_antialiasing_edge); + ClassDB::bind_method(D_METHOD("set_texture_filter", "mode"), &Label3D::set_texture_filter); ClassDB::bind_method(D_METHOD("get_texture_filter"), &Label3D::get_texture_filter); @@ -133,6 +139,8 @@ void Label3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass,Alpha Hash"), "set_alpha_cut_mode", "get_alpha_cut_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode", PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip"), "set_alpha_antialiasing", "get_alpha_antialiasing"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_antialiasing_edge", "get_alpha_antialiasing_edge"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_outline_render_priority", "get_outline_render_priority"); @@ -356,6 +364,7 @@ void Label3D::_generate_glyph_surfaces(const Glyph &p_glyph, Vector2 &r_offset, RS::get_singleton()->material_set_param(surf.material, "uv2_scale", Vector3(1, 1, 1)); RS::get_singleton()->material_set_param(surf.material, "alpha_scissor_threshold", alpha_scissor_threshold); RS::get_singleton()->material_set_param(surf.material, "alpha_hash_scale", alpha_hash_scale); + RS::get_singleton()->material_set_param(surf.material, "alpha_antialiasing_edge", alpha_antialiasing_edge); if (msdf) { RS::get_singleton()->material_set_param(surf.material, "msdf_pixel_range", TS->font_get_msdf_pixel_range(p_glyph.font_rid)); RS::get_singleton()->material_set_param(surf.material, "msdf_outline_size", p_outline_size); @@ -371,7 +380,7 @@ void Label3D::_generate_glyph_surfaces(const Glyph &p_glyph, Vector2 &r_offset, } RID shader_rid; - StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), mat_transparency, get_draw_flag(FLAG_DOUBLE_SIDED), get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, msdf, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), texture_filter, &shader_rid); + StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), mat_transparency, get_draw_flag(FLAG_DOUBLE_SIDED), get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, msdf, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), texture_filter, alpha_antialiasing_mode, &shader_rid); RS::get_singleton()->material_set_shader(surf.material, shader_rid); RS::get_singleton()->material_set_param(surf.material, "texture_albedo", tex); @@ -966,6 +975,28 @@ float Label3D::get_alpha_scissor_threshold() const { return alpha_scissor_threshold; } +void Label3D::set_alpha_antialiasing(BaseMaterial3D::AlphaAntiAliasing p_alpha_aa) { + if (alpha_antialiasing_mode != p_alpha_aa) { + alpha_antialiasing_mode = p_alpha_aa; + _queue_update(); + } +} + +BaseMaterial3D::AlphaAntiAliasing Label3D::get_alpha_antialiasing() const { + return alpha_antialiasing_mode; +} + +void Label3D::set_alpha_antialiasing_edge(float p_edge) { + if (alpha_antialiasing_edge != p_edge) { + alpha_antialiasing_edge = p_edge; + _queue_update(); + } +} + +float Label3D::get_alpha_antialiasing_edge() const { + return alpha_antialiasing_edge; +} + Label3D::Label3D() { for (int i = 0; i < FLAG_MAX; i++) { flags[i] = (i == FLAG_DOUBLE_SIDED); diff --git a/scene/3d/label_3d.h b/scene/3d/label_3d.h index 576735840a..912f485354 100644 --- a/scene/3d/label_3d.h +++ b/scene/3d/label_3d.h @@ -62,6 +62,8 @@ private: AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED; float alpha_scissor_threshold = 0.5; float alpha_hash_scale = 1.0; + StandardMaterial3D::AlphaAntiAliasing alpha_antialiasing_mode = StandardMaterial3D::ALPHA_ANTIALIASING_OFF; + float alpha_antialiasing_edge = 0.0f; AABB aabb; @@ -234,6 +236,12 @@ public: void set_alpha_hash_scale(float p_hash_scale); float get_alpha_hash_scale() const; + void set_alpha_antialiasing(BaseMaterial3D::AlphaAntiAliasing p_alpha_aa); + BaseMaterial3D::AlphaAntiAliasing get_alpha_antialiasing() const; + + void set_alpha_antialiasing_edge(float p_edge); + float get_alpha_antialiasing_edge() const; + void set_billboard_mode(StandardMaterial3D::BillboardMode p_mode); StandardMaterial3D::BillboardMode get_billboard_mode() const; diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 4aa6e61ec5..5db8611d72 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -120,6 +120,23 @@ void NavigationAgent3D::_bind_methods() { ADD_SIGNAL(MethodInfo("link_reached", PropertyInfo(Variant::DICTIONARY, "details"))); ADD_SIGNAL(MethodInfo("navigation_finished")); ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR3, "safe_velocity"))); + +#ifdef DEBUG_ENABLED + ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationAgent3D::set_debug_enabled); + ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationAgent3D::get_debug_enabled); + ClassDB::bind_method(D_METHOD("set_debug_use_custom", "enabled"), &NavigationAgent3D::set_debug_use_custom); + ClassDB::bind_method(D_METHOD("get_debug_use_custom"), &NavigationAgent3D::get_debug_use_custom); + ClassDB::bind_method(D_METHOD("set_debug_path_custom_color", "color"), &NavigationAgent3D::set_debug_path_custom_color); + ClassDB::bind_method(D_METHOD("get_debug_path_custom_color"), &NavigationAgent3D::get_debug_path_custom_color); + ClassDB::bind_method(D_METHOD("set_debug_path_custom_point_size", "point_size"), &NavigationAgent3D::set_debug_path_custom_point_size); + ClassDB::bind_method(D_METHOD("get_debug_path_custom_point_size"), &NavigationAgent3D::get_debug_path_custom_point_size); + + ADD_GROUP("Debug", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_enabled"), "set_debug_enabled", "get_debug_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_use_custom"), "set_debug_use_custom", "get_debug_use_custom"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_path_custom_color"), "set_debug_path_custom_color", "get_debug_path_custom_color"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_point_size", PROPERTY_HINT_RANGE, "1,50,1,suffix:px"), "set_debug_path_custom_point_size", "get_debug_path_custom_point_size"); +#endif // DEBUG_ENABLED } void NavigationAgent3D::_notification(int p_what) { @@ -129,6 +146,12 @@ void NavigationAgent3D::_notification(int p_what) { // cannot use READY as ready does not get called if Node is readded to SceneTree set_agent_parent(get_parent()); set_physics_process_internal(true); + +#ifdef DEBUG_ENABLED + if (NavigationServer3D::get_singleton()->get_debug_enabled()) { + debug_path_dirty = true; + } +#endif // DEBUG_ENABLED } break; case NOTIFICATION_PARENTED: { @@ -151,6 +174,12 @@ void NavigationAgent3D::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { set_agent_parent(nullptr); set_physics_process_internal(false); + +#ifdef DEBUG_ENABLED + if (debug_path_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_path_instance, false); + } +#endif // DEBUG_ENABLED } break; case NOTIFICATION_PAUSED: { @@ -182,6 +211,11 @@ void NavigationAgent3D::_notification(int p_what) { } _check_distance_to_target(); } +#ifdef DEBUG_ENABLED + if (debug_path_dirty) { + _update_debug_path(); + } +#endif // DEBUG_ENABLED } break; } } @@ -201,12 +235,28 @@ NavigationAgent3D::NavigationAgent3D() { navigation_result = Ref<NavigationPathQueryResult3D>(); navigation_result.instantiate(); + +#ifdef DEBUG_ENABLED + NavigationServer3D::get_singleton()->connect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent3D::_navigation_debug_changed)); +#endif // DEBUG_ENABLED } NavigationAgent3D::~NavigationAgent3D() { ERR_FAIL_NULL(NavigationServer3D::get_singleton()); NavigationServer3D::get_singleton()->free(agent); agent = RID(); // Pointless + +#ifdef DEBUG_ENABLED + NavigationServer3D::get_singleton()->disconnect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent3D::_navigation_debug_changed)); + + ERR_FAIL_NULL(RenderingServer::get_singleton()); + if (debug_path_instance.is_valid()) { + RenderingServer::get_singleton()->free(debug_path_instance); + } + if (debug_path_mesh.is_valid()) { + RenderingServer::get_singleton()->free(debug_path_mesh->get_rid()); + } +#endif // DEBUG_ENABLED } void NavigationAgent3D::set_avoidance_enabled(bool p_enabled) { @@ -480,6 +530,9 @@ void NavigationAgent3D::update_navigation() { } NavigationServer3D::get_singleton()->query_path(navigation_query, navigation_result); +#ifdef DEBUG_ENABLED + debug_path_dirty = true; +#endif // DEBUG_ENABLED navigation_finished = false; navigation_path_index = 0; emit_signal(SNAME("path_changed")); @@ -566,3 +619,130 @@ void NavigationAgent3D::_check_distance_to_target() { } } } + +////////DEBUG//////////////////////////////////////////////////////////// + +#ifdef DEBUG_ENABLED +void NavigationAgent3D::set_debug_enabled(bool p_enabled) { + debug_enabled = p_enabled; + debug_path_dirty = true; +} + +bool NavigationAgent3D::get_debug_enabled() const { + return debug_enabled; +} + +void NavigationAgent3D::set_debug_use_custom(bool p_enabled) { + debug_use_custom = p_enabled; + debug_path_dirty = true; +} + +bool NavigationAgent3D::get_debug_use_custom() const { + return debug_use_custom; +} + +void NavigationAgent3D::set_debug_path_custom_color(Color p_color) { + debug_path_custom_color = p_color; + debug_path_dirty = true; +} + +Color NavigationAgent3D::get_debug_path_custom_color() const { + return debug_path_custom_color; +} + +void NavigationAgent3D::set_debug_path_custom_point_size(float p_point_size) { + debug_path_custom_point_size = p_point_size; + debug_path_dirty = true; +} + +float NavigationAgent3D::get_debug_path_custom_point_size() const { + return debug_path_custom_point_size; +} + +void NavigationAgent3D::_navigation_debug_changed() { + debug_path_dirty = true; +} + +void NavigationAgent3D::_update_debug_path() { + if (!debug_path_dirty) { + return; + } + debug_path_dirty = false; + + if (!debug_path_instance.is_valid()) { + debug_path_instance = RenderingServer::get_singleton()->instance_create(); + } + + if (!debug_path_mesh.is_valid()) { + debug_path_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + } + + debug_path_mesh->clear_surfaces(); + + if (!(debug_enabled && NavigationServer3D::get_singleton()->get_debug_navigation_enable_agent_paths())) { + return; + } + + if (!(agent_parent && agent_parent->is_inside_tree())) { + return; + } + + const Vector<Vector3> &navigation_path = navigation_result->get_path(); + + if (navigation_path.size() <= 1) { + return; + } + + Vector<Vector3> debug_path_lines_vertex_array; + + for (int i = 0; i < navigation_path.size() - 1; i++) { + debug_path_lines_vertex_array.push_back(navigation_path[i]); + debug_path_lines_vertex_array.push_back(navigation_path[i + 1]); + } + + Array debug_path_lines_mesh_array; + debug_path_lines_mesh_array.resize(Mesh::ARRAY_MAX); + debug_path_lines_mesh_array[Mesh::ARRAY_VERTEX] = debug_path_lines_vertex_array; + + debug_path_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, debug_path_lines_mesh_array); + + Ref<StandardMaterial3D> debug_agent_path_line_material = NavigationServer3D::get_singleton()->get_debug_navigation_agent_path_line_material(); + if (debug_use_custom) { + if (!debug_agent_path_line_custom_material.is_valid()) { + debug_agent_path_line_custom_material = debug_agent_path_line_material->duplicate(); + } + debug_agent_path_line_custom_material->set_albedo(debug_path_custom_color); + debug_path_mesh->surface_set_material(0, debug_agent_path_line_custom_material); + } else { + debug_path_mesh->surface_set_material(0, debug_agent_path_line_material); + } + + Vector<Vector3> debug_path_points_vertex_array; + + for (int i = 0; i < navigation_path.size(); i++) { + debug_path_points_vertex_array.push_back(navigation_path[i]); + } + + Array debug_path_points_mesh_array; + debug_path_points_mesh_array.resize(Mesh::ARRAY_MAX); + debug_path_points_mesh_array[Mesh::ARRAY_VERTEX] = debug_path_lines_vertex_array; + + debug_path_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, debug_path_points_mesh_array); + + Ref<StandardMaterial3D> debug_agent_path_point_material = NavigationServer3D::get_singleton()->get_debug_navigation_agent_path_point_material(); + if (debug_use_custom) { + if (!debug_agent_path_point_custom_material.is_valid()) { + debug_agent_path_point_custom_material = debug_agent_path_point_material->duplicate(); + } + debug_agent_path_point_custom_material->set_albedo(debug_path_custom_color); + debug_agent_path_point_custom_material->set_point_size(debug_path_custom_point_size); + debug_path_mesh->surface_set_material(1, debug_agent_path_point_custom_material); + } else { + debug_path_mesh->surface_set_material(1, debug_agent_path_point_material); + } + + RS::get_singleton()->instance_set_base(debug_path_instance, debug_path_mesh->get_rid()); + RS::get_singleton()->instance_set_scenario(debug_path_instance, agent_parent->get_world_3d()->get_scenario()); + RS::get_singleton()->instance_set_visible(debug_path_instance, agent_parent->is_visible_in_tree()); +} +#endif // DEBUG_ENABLED diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index 12f83ce6a8..98bf395d7c 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -76,6 +76,22 @@ class NavigationAgent3D : public Node { // No initialized on purpose uint32_t update_frame_id = 0; +#ifdef DEBUG_ENABLED + bool debug_enabled = false; + bool debug_path_dirty = true; + RID debug_path_instance; + Ref<ArrayMesh> debug_path_mesh; + float debug_path_custom_point_size = 4.0; + bool debug_use_custom = false; + Color debug_path_custom_color = Color(1.0, 1.0, 1.0, 1.0); + Ref<StandardMaterial3D> debug_agent_path_line_custom_material; + Ref<StandardMaterial3D> debug_agent_path_point_custom_material; + +private: + void _navigation_debug_changed(); + void _update_debug_path(); +#endif // DEBUG_ENABLED + protected: static void _bind_methods(); void _notification(int p_what); @@ -181,6 +197,20 @@ public: PackedStringArray get_configuration_warnings() const override; +#ifdef DEBUG_ENABLED + void set_debug_enabled(bool p_enabled); + bool get_debug_enabled() const; + + void set_debug_use_custom(bool p_enabled); + bool get_debug_use_custom() const; + + void set_debug_path_custom_color(Color p_color); + Color get_debug_path_custom_color() const; + + void set_debug_path_custom_point_size(float p_point_size); + float get_debug_path_custom_point_size() const; +#endif // DEBUG_ENABLED + private: void update_navigation(); void _request_repath(); diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp index 632b27953f..594580a205 100644 --- a/scene/3d/occluder_instance_3d.cpp +++ b/scene/3d/occluder_instance_3d.cpp @@ -542,13 +542,14 @@ void OccluderInstance3D::_bake_surface(const Transform3D &p_transform, Array p_s float error = -1.0f; int target_index_count = MIN(indices.size(), 36); + const int simplify_options = SurfaceTool::SIMPLIFY_LOCK_BORDER; + uint32_t index_count = SurfaceTool::simplify_func( (unsigned int *)indices.ptrw(), (unsigned int *)indices.ptr(), indices.size(), vertices_f32.ptr(), vertices.size(), sizeof(float) * 3, - target_index_count, target_error, &error); - + target_index_count, target_error, simplify_options, &error); indices.resize(index_count); } diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index f4ab09cd9b..c8cfcf7d7a 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -333,6 +333,11 @@ void AnimatableBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) { } void AnimatableBody3D::_notification(int p_what) { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif switch (p_what) { case NOTIFICATION_ENTER_TREE: { last_valid_transform = get_global_transform(); diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index 606f6140cb..62202c0b1b 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -85,38 +85,40 @@ float ReflectionProbe::get_mesh_lod_threshold() const { return mesh_lod_threshold; } -void ReflectionProbe::set_extents(const Vector3 &p_extents) { - extents = p_extents; +void ReflectionProbe::set_size(const Vector3 &p_size) { + size = p_size; for (int i = 0; i < 3; i++) { - if (extents[i] < 0.01) { - extents[i] = 0.01; + float half_size = size[i] / 2; + if (half_size < 0.01) { + half_size = 0.01; } - if (extents[i] - 0.01 < ABS(origin_offset[i])) { - origin_offset[i] = SIGN(origin_offset[i]) * (extents[i] - 0.01); + if (half_size - 0.01 < ABS(origin_offset[i])) { + origin_offset[i] = SIGN(origin_offset[i]) * (half_size - 0.01); } } - RS::get_singleton()->reflection_probe_set_extents(probe, extents); + RS::get_singleton()->reflection_probe_set_size(probe, size); RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset); update_gizmos(); } -Vector3 ReflectionProbe::get_extents() const { - return extents; +Vector3 ReflectionProbe::get_size() const { + return size; } -void ReflectionProbe::set_origin_offset(const Vector3 &p_extents) { - origin_offset = p_extents; +void ReflectionProbe::set_origin_offset(const Vector3 &p_offset) { + origin_offset = p_offset; for (int i = 0; i < 3; i++) { - if (extents[i] - 0.01 < ABS(origin_offset[i])) { - origin_offset[i] = SIGN(origin_offset[i]) * (extents[i] - 0.01); + float half_size = size[i] / 2; + if (half_size - 0.01 < ABS(origin_offset[i])) { + origin_offset[i] = SIGN(origin_offset[i]) * (half_size - 0.01); } } - RS::get_singleton()->reflection_probe_set_extents(probe, extents); + RS::get_singleton()->reflection_probe_set_size(probe, size); RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset); update_gizmos(); @@ -174,7 +176,7 @@ ReflectionProbe::UpdateMode ReflectionProbe::get_update_mode() const { AABB ReflectionProbe::get_aabb() const { AABB aabb; aabb.position = -origin_offset; - aabb.size = origin_offset + extents; + aabb.size = origin_offset + size / 2; return aabb; } @@ -205,8 +207,8 @@ void ReflectionProbe::_bind_methods() { ClassDB::bind_method(D_METHOD("set_mesh_lod_threshold", "ratio"), &ReflectionProbe::set_mesh_lod_threshold); ClassDB::bind_method(D_METHOD("get_mesh_lod_threshold"), &ReflectionProbe::get_mesh_lod_threshold); - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &ReflectionProbe::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &ReflectionProbe::get_extents); + ClassDB::bind_method(D_METHOD("set_size", "size"), &ReflectionProbe::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &ReflectionProbe::get_size); ClassDB::bind_method(D_METHOD("set_origin_offset", "origin_offset"), &ReflectionProbe::set_origin_offset); ClassDB::bind_method(D_METHOD("get_origin_offset"), &ReflectionProbe::get_origin_offset); @@ -229,7 +231,7 @@ void ReflectionProbe::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Once (Fast),Always (Slow)"), "set_update_mode", "get_update_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "intensity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_intensity", "get_intensity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,16384,0.1,or_greater,exp,suffix:m"), "set_max_distance", "get_max_distance"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_NONE, "suffix:m"), "set_extents", "get_extents"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_NONE, "suffix:m"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "origin_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_origin_offset", "get_origin_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "box_projection"), "set_enable_box_projection", "is_box_projection_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_as_interior", "is_set_as_interior"); @@ -250,6 +252,24 @@ void ReflectionProbe::_bind_methods() { BIND_ENUM_CONSTANT(AMBIENT_COLOR); } +#ifndef DISABLE_DEPRECATED +bool ReflectionProbe::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "extents") { // Compatibility with Godot 3.x. + set_size((Vector3)p_value * 2); + return true; + } + return false; +} + +bool ReflectionProbe::_get(const StringName &p_name, Variant &r_property) const { + if (p_name == "extents") { // Compatibility with Godot 3.x. + r_property = size / 2; + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + ReflectionProbe::ReflectionProbe() { probe = RenderingServer::get_singleton()->reflection_probe_create(); RS::get_singleton()->instance_set_base(get_instance(), probe); diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index cb417c3eea..738277ad39 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -52,7 +52,7 @@ private: RID probe; float intensity = 1.0; float max_distance = 0.0; - Vector3 extents = Vector3(10, 10, 10); + Vector3 size = Vector3(20, 20, 20); Vector3 origin_offset = Vector3(0, 0, 0); bool box_projection = false; bool enable_shadows = false; @@ -68,6 +68,10 @@ private: protected: static void _bind_methods(); void _validate_property(PropertyInfo &p_property) const; +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_property) const; +#endif // DISABLE_DEPRECATED public: void set_intensity(float p_intensity); @@ -91,10 +95,10 @@ public: void set_mesh_lod_threshold(float p_pixels); float get_mesh_lod_threshold() const; - void set_extents(const Vector3 &p_extents); - Vector3 get_extents() const; + void set_size(const Vector3 &p_size); + Vector3 get_size() const; - void set_origin_offset(const Vector3 &p_extents); + void set_origin_offset(const Vector3 &p_offset); Vector3 get_origin_offset() const; void set_as_interior(bool p_enable); diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 041ca7707b..59e4a0b718 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -247,6 +247,7 @@ void SpriteBase3D::draw_texture_rect(Ref<Texture2D> p_texture, Rect2 p_dst_rect, RS::get_singleton()->material_set_param(get_material(), "alpha_scissor_threshold", alpha_scissor_threshold); RS::get_singleton()->material_set_param(get_material(), "alpha_hash_scale", alpha_hash_scale); + RS::get_singleton()->material_set_param(get_material(), "alpha_antialiasing_edge", alpha_antialiasing_edge); BaseMaterial3D::Transparency mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_DISABLED; if (get_draw_flag(FLAG_TRANSPARENT)) { @@ -262,7 +263,7 @@ void SpriteBase3D::draw_texture_rect(Ref<Texture2D> p_texture, Rect2 p_dst_rect, } RID shader_rid; - StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), mat_transparency, get_draw_flag(FLAG_DOUBLE_SIDED), get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, false, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), get_texture_filter(), &shader_rid); + StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), mat_transparency, get_draw_flag(FLAG_DOUBLE_SIDED), get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, false, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), get_texture_filter(), alpha_antialiasing_mode, &shader_rid); if (last_shader != shader_rid) { RS::get_singleton()->material_set_shader(get_material(), shader_rid); @@ -481,6 +482,28 @@ float SpriteBase3D::get_alpha_scissor_threshold() const { return alpha_scissor_threshold; } +void SpriteBase3D::set_alpha_antialiasing(BaseMaterial3D::AlphaAntiAliasing p_alpha_aa) { + if (alpha_antialiasing_mode != p_alpha_aa) { + alpha_antialiasing_mode = p_alpha_aa; + _queue_redraw(); + } +} + +BaseMaterial3D::AlphaAntiAliasing SpriteBase3D::get_alpha_antialiasing() const { + return alpha_antialiasing_mode; +} + +void SpriteBase3D::set_alpha_antialiasing_edge(float p_edge) { + if (alpha_antialiasing_edge != p_edge) { + alpha_antialiasing_edge = p_edge; + _queue_redraw(); + } +} + +float SpriteBase3D::get_alpha_antialiasing_edge() const { + return alpha_antialiasing_edge; +} + void SpriteBase3D::set_billboard_mode(StandardMaterial3D::BillboardMode p_mode) { ERR_FAIL_INDEX(p_mode, 3); // Cannot use BILLBOARD_PARTICLES. billboard_mode = p_mode; @@ -539,6 +562,12 @@ void SpriteBase3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_alpha_hash_scale", "threshold"), &SpriteBase3D::set_alpha_hash_scale); ClassDB::bind_method(D_METHOD("get_alpha_hash_scale"), &SpriteBase3D::get_alpha_hash_scale); + ClassDB::bind_method(D_METHOD("set_alpha_antialiasing", "alpha_aa"), &SpriteBase3D::set_alpha_antialiasing); + ClassDB::bind_method(D_METHOD("get_alpha_antialiasing"), &SpriteBase3D::get_alpha_antialiasing); + + ClassDB::bind_method(D_METHOD("set_alpha_antialiasing_edge", "edge"), &SpriteBase3D::set_alpha_antialiasing_edge); + ClassDB::bind_method(D_METHOD("get_alpha_antialiasing_edge"), &SpriteBase3D::get_alpha_antialiasing_edge); + ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &SpriteBase3D::set_billboard_mode); ClassDB::bind_method(D_METHOD("get_billboard_mode"), &SpriteBase3D::get_billboard_mode); @@ -567,6 +596,8 @@ void SpriteBase3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass,Alpha Hash"), "set_alpha_cut_mode", "get_alpha_cut_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode", PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip"), "set_alpha_antialiasing", "get_alpha_antialiasing"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_antialiasing_edge", "get_alpha_antialiasing_edge"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 873c321878..1eb1211951 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -89,6 +89,8 @@ private: AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED; float alpha_scissor_threshold = 0.5; float alpha_hash_scale = 1.0; + StandardMaterial3D::AlphaAntiAliasing alpha_antialiasing_mode = StandardMaterial3D::ALPHA_ANTIALIASING_OFF; + float alpha_antialiasing_edge = 0.0f; StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED; StandardMaterial3D::TextureFilter texture_filter = StandardMaterial3D::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; bool pending_update = false; @@ -153,6 +155,12 @@ public: void set_alpha_hash_scale(float p_hash_scale); float get_alpha_hash_scale() const; + void set_alpha_antialiasing(BaseMaterial3D::AlphaAntiAliasing p_alpha_aa); + BaseMaterial3D::AlphaAntiAliasing get_alpha_antialiasing() const; + + void set_alpha_antialiasing_edge(float p_edge); + float get_alpha_antialiasing_edge() const; + void set_billboard_mode(StandardMaterial3D::BillboardMode p_mode); StandardMaterial3D::BillboardMode get_billboard_mode() const; diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp index 41dc27352f..36a877246e 100644 --- a/scene/3d/voxel_gi.cpp +++ b/scene/3d/voxel_gi.cpp @@ -237,6 +237,24 @@ void VoxelGIData::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior"); } +#ifndef DISABLE_DEPRECATED +bool VoxelGI::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "extents") { // Compatibility with Godot 3.x. + set_size((Vector3)p_value * 2); + return true; + } + return false; +} + +bool VoxelGI::_get(const StringName &p_name, Variant &r_property) const { + if (p_name == "extents") { // Compatibility with Godot 3.x. + r_property = size / 2; + return true; + } + return false; +} +#endif // DISABLE_DEPRECATED + VoxelGIData::VoxelGIData() { probe = RS::get_singleton()->voxel_gi_create(); } @@ -273,14 +291,14 @@ VoxelGI::Subdiv VoxelGI::get_subdiv() const { return subdiv; } -void VoxelGI::set_extents(const Vector3 &p_extents) { - // Prevent very small extents as these break baking if other extents are set very high. - extents = Vector3(MAX(1.0, p_extents.x), MAX(1.0, p_extents.y), MAX(1.0, p_extents.z)); +void VoxelGI::set_size(const Vector3 &p_size) { + // Prevent very small size dimensions as these breaks baking if other size dimensions are set very high. + size = Vector3(MAX(1.0, p_size.x), MAX(1.0, p_size.y), MAX(1.0, p_size.z)); update_gizmos(); } -Vector3 VoxelGI::get_extents() const { - return extents; +Vector3 VoxelGI::get_size() const { + return size; } void VoxelGI::set_camera_attributes(const Ref<CameraAttributes> &p_camera_attributes) { @@ -300,7 +318,7 @@ void VoxelGI::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { Transform3D xf = get_global_transform().affine_inverse() * mi->get_global_transform(); - if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) { + if (AABB(-size / 2, size).intersects(xf.xform(aabb))) { PlotMesh pm; pm.local_xform = xf; pm.mesh = mesh; @@ -328,7 +346,7 @@ void VoxelGI::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { Transform3D xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); - if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) { + if (AABB(-size / 2, size).intersects(xf.xform(aabb))) { PlotMesh pm; pm.local_xform = xf; pm.mesh = mesh; @@ -352,7 +370,7 @@ Vector3i VoxelGI::get_estimated_cell_size() const { static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 }; int cell_subdiv = subdiv_value[subdiv]; int axis_cell_size[3]; - AABB bounds = AABB(-extents, extents * 2.0); + AABB bounds = AABB(-size / 2, size); int longest_axis = bounds.get_longest_axis_index(); axis_cell_size[longest_axis] = 1 << cell_subdiv; @@ -390,7 +408,7 @@ void VoxelGI::bake(Node *p_from_node, bool p_create_visual_debug) { Voxelizer baker; - baker.begin_bake(subdiv_value[subdiv], AABB(-extents, extents * 2.0), exposure_normalization); + baker.begin_bake(subdiv_value[subdiv], AABB(-size / 2, size), exposure_normalization); List<PlotMesh> mesh_list; @@ -448,7 +466,7 @@ void VoxelGI::bake(Node *p_from_node, bool p_create_visual_debug) { RS::get_singleton()->voxel_gi_set_baked_exposure_normalization(probe_data_new->get_rid(), exposure_normalization); - probe_data_new->allocate(baker.get_to_cell_space_xform(), AABB(-extents, extents * 2.0), baker.get_voxel_gi_octree_size(), baker.get_voxel_gi_octree_cells(), baker.get_voxel_gi_data_cells(), df, baker.get_voxel_gi_level_cell_count()); + probe_data_new->allocate(baker.get_to_cell_space_xform(), AABB(-size / 2, size), baker.get_voxel_gi_octree_size(), baker.get_voxel_gi_octree_cells(), baker.get_voxel_gi_data_cells(), df, baker.get_voxel_gi_level_cell_count()); set_probe_data(probe_data_new); #ifdef TOOLS_ENABLED @@ -468,7 +486,7 @@ void VoxelGI::_debug_bake() { } AABB VoxelGI::get_aabb() const { - return AABB(-extents, extents * 2); + return AABB(-size / 2, size); } PackedStringArray VoxelGI::get_configuration_warnings() const { @@ -489,8 +507,8 @@ void VoxelGI::_bind_methods() { ClassDB::bind_method(D_METHOD("set_subdiv", "subdiv"), &VoxelGI::set_subdiv); ClassDB::bind_method(D_METHOD("get_subdiv"), &VoxelGI::get_subdiv); - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &VoxelGI::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &VoxelGI::get_extents); + ClassDB::bind_method(D_METHOD("set_size", "size"), &VoxelGI::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &VoxelGI::get_size); ClassDB::bind_method(D_METHOD("set_camera_attributes", "camera_attributes"), &VoxelGI::set_camera_attributes); ClassDB::bind_method(D_METHOD("get_camera_attributes"), &VoxelGI::get_camera_attributes); @@ -500,7 +518,7 @@ void VoxelGI::_bind_methods() { ClassDB::set_method_flags(get_class_static(), _scs_create("debug_bake"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); 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::VECTOR3, "size", PROPERTY_HINT_NONE, "suffix:m"), "set_size", "get_size"); 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_ALWAYS_DUPLICATE), "set_probe_data", "get_probe_data"); diff --git a/scene/3d/voxel_gi.h b/scene/3d/voxel_gi.h index ae348daf9e..d276186dd1 100644 --- a/scene/3d/voxel_gi.h +++ b/scene/3d/voxel_gi.h @@ -118,7 +118,7 @@ private: RID voxel_gi; Subdiv subdiv = SUBDIV_128; - Vector3 extents = Vector3(10, 10, 10); + Vector3 size = Vector3(20, 20, 20); Ref<CameraAttributes> camera_attributes; struct PlotMesh { @@ -133,6 +133,10 @@ private: protected: static void _bind_methods(); +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_property) const; +#endif // DISABLE_DEPRECATED public: static BakeBeginFunc bake_begin_function; @@ -145,8 +149,8 @@ public: void set_subdiv(Subdiv p_subdiv); Subdiv get_subdiv() const; - void set_extents(const Vector3 &p_extents); - Vector3 get_extents() const; + void set_size(const Vector3 &p_size); + Vector3 get_size() const; void set_camera_attributes(const Ref<CameraAttributes> &p_camera_attributes); Ref<CameraAttributes> get_camera_attributes() const; diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index a2028b8de8..d28a6fcc04 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -30,12 +30,20 @@ #include "animation_blend_space_1d.h" +#include "animation_blend_tree.h" + void AnimationNodeBlendSpace1D::get_parameter_list(List<PropertyInfo> *r_list) const { r_list->push_back(PropertyInfo(Variant::FLOAT, blend_position)); + r_list->push_back(PropertyInfo(Variant::INT, closest, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE)); + r_list->push_back(PropertyInfo(Variant::FLOAT, length_internal, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE)); } Variant AnimationNodeBlendSpace1D::get_parameter_default_value(const StringName &p_parameter) const { - return 0; + if (p_parameter == closest) { + return -1; + } else { + return 0; + } } Ref<AnimationNode> AnimationNodeBlendSpace1D::get_child_by_name(const StringName &p_name) { @@ -77,6 +85,9 @@ void AnimationNodeBlendSpace1D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_value_label", "text"), &AnimationNodeBlendSpace1D::set_value_label); ClassDB::bind_method(D_METHOD("get_value_label"), &AnimationNodeBlendSpace1D::get_value_label); + ClassDB::bind_method(D_METHOD("set_blend_mode", "mode"), &AnimationNodeBlendSpace1D::set_blend_mode); + ClassDB::bind_method(D_METHOD("get_blend_mode"), &AnimationNodeBlendSpace1D::get_blend_mode); + ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlendSpace1D::set_use_sync); ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlendSpace1D::is_using_sync); @@ -91,7 +102,12 @@ void AnimationNodeBlendSpace1D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_max_space", "get_max_space"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_snap", "get_snap"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "value_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_value_label", "get_value_label"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Interpolated,Discrete,Carry", PROPERTY_USAGE_NO_EDITOR), "set_blend_mode", "get_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_use_sync", "is_using_sync"); + + BIND_ENUM_CONSTANT(BLEND_MODE_INTERPOLATED); + BIND_ENUM_CONSTANT(BLEND_MODE_DISCRETE); + BIND_ENUM_CONSTANT(BLEND_MODE_DISCRETE_CARRY); } void AnimationNodeBlendSpace1D::get_child_nodes(List<ChildNode> *r_child_nodes) { @@ -214,6 +230,14 @@ String AnimationNodeBlendSpace1D::get_value_label() const { return value_label; } +void AnimationNodeBlendSpace1D::set_blend_mode(BlendMode p_blend_mode) { + blend_mode = p_blend_mode; +} + +AnimationNodeBlendSpace1D::BlendMode AnimationNodeBlendSpace1D::get_blend_mode() const { + return blend_mode; +} + void AnimationNodeBlendSpace1D::set_use_sync(bool p_sync) { sync = p_sync; } @@ -241,79 +265,125 @@ double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_is_ } double blend_pos = get_parameter(blend_position); + int cur_closest = get_parameter(closest); + double cur_length_internal = get_parameter(length_internal); + double max_time_remaining = 0.0; - float weights[MAX_BLEND_POINTS] = {}; + if (blend_mode == BLEND_MODE_INTERPOLATED) { + float weights[MAX_BLEND_POINTS] = {}; + + int point_lower = -1; + float pos_lower = 0.0; + int point_higher = -1; + float pos_higher = 0.0; + + // find the closest two points to blend between + for (int i = 0; i < blend_points_used; i++) { + float pos = blend_points[i].position; + + if (pos <= blend_pos) { + if (point_lower == -1) { + point_lower = i; + pos_lower = pos; + } else if ((blend_pos - pos) < (blend_pos - pos_lower)) { + point_lower = i; + pos_lower = pos; + } + } else { + if (point_higher == -1) { + point_higher = i; + pos_higher = pos; + } else if ((pos - blend_pos) < (pos_higher - blend_pos)) { + point_higher = i; + pos_higher = pos; + } + } + } - int point_lower = -1; - float pos_lower = 0.0; - int point_higher = -1; - float pos_higher = 0.0; + // fill in weights - // find the closest two points to blend between - for (int i = 0; i < blend_points_used; i++) { - float pos = blend_points[i].position; - - if (pos <= blend_pos) { - if (point_lower == -1) { - point_lower = i; - pos_lower = pos; - } else if ((blend_pos - pos) < (blend_pos - pos_lower)) { - point_lower = i; - pos_lower = pos; - } + if (point_lower == -1 && point_higher != -1) { + // we are on the left side, no other point to the left + // we just play the next point. + + weights[point_higher] = 1.0; + } else if (point_higher == -1) { + // we are on the right side, no other point to the right + // we just play the previous point + + weights[point_lower] = 1.0; } else { - if (point_higher == -1) { - point_higher = i; - pos_higher = pos; - } else if ((pos - blend_pos) < (pos_higher - blend_pos)) { - point_higher = i; - pos_higher = pos; - } - } - } + // we are between two points. + // figure out weights, then blend the animations - // fill in weights + float distance_between_points = pos_higher - pos_lower; - if (point_lower == -1 && point_higher != -1) { - // we are on the left side, no other point to the left - // we just play the next point. + float current_pos_inbetween = blend_pos - pos_lower; - weights[point_higher] = 1.0; - } else if (point_higher == -1) { - // we are on the right side, no other point to the right - // we just play the previous point + float blend_percentage = current_pos_inbetween / distance_between_points; - weights[point_lower] = 1.0; - } else { - // we are between two points. - // figure out weights, then blend the animations + float blend_lower = 1.0 - blend_percentage; + float blend_higher = blend_percentage; - float distance_between_points = pos_higher - pos_lower; + weights[point_lower] = blend_lower; + weights[point_higher] = blend_higher; + } - float current_pos_inbetween = blend_pos - pos_lower; + // actually blend the animations now - float blend_percentage = current_pos_inbetween / distance_between_points; + for (int i = 0; i < blend_points_used; i++) { + if (i == point_lower || i == point_higher) { + double remaining = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, weights[i], FILTER_IGNORE, true); + max_time_remaining = MAX(max_time_remaining, remaining); + } else if (sync) { + blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true); + } + } + } else { + int new_closest = -1; + double new_closest_dist = 1e20; + + for (int i = 0; i < blend_points_used; i++) { + double d = abs(blend_points[i].position - blend_pos); + if (d < new_closest_dist) { + new_closest = i; + new_closest_dist = d; + } + } - float blend_lower = 1.0 - blend_percentage; - float blend_higher = blend_percentage; + if (new_closest != cur_closest && new_closest != -1) { + double from = 0.0; + if (blend_mode == BLEND_MODE_DISCRETE_CARRY && cur_closest != -1) { + //for ping-pong loop + Ref<AnimationNodeAnimation> na_c = static_cast<Ref<AnimationNodeAnimation>>(blend_points[cur_closest].node); + Ref<AnimationNodeAnimation> na_n = static_cast<Ref<AnimationNodeAnimation>>(blend_points[new_closest].node); + if (!na_c.is_null() && !na_n.is_null()) { + na_n->set_backward(na_c->is_backward()); + } + //see how much animation remains + from = cur_length_internal - blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, false, p_is_external_seeking, 0.0, FILTER_IGNORE, true); + } - weights[point_lower] = blend_lower; - weights[point_higher] = blend_higher; - } + max_time_remaining = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true); + cur_length_internal = from + max_time_remaining; - // actually blend the animations now + cur_closest = new_closest; - double max_time_remaining = 0.0; + } else { + max_time_remaining = blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true); + } - for (int i = 0; i < blend_points_used; i++) { - if (i == point_lower || i == point_higher) { - double remaining = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, weights[i], FILTER_IGNORE, true); - max_time_remaining = MAX(max_time_remaining, remaining); - } else if (sync) { - blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true); + if (sync) { + for (int i = 0; i < blend_points_used; i++) { + if (i != cur_closest) { + blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true); + } + } } } + set_parameter(this->closest, cur_closest); + set_parameter(this->length_internal, cur_length_internal); return max_time_remaining; } diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h index af93783c0d..a1e9a7a764 100644 --- a/scene/animation/animation_blend_space_1d.h +++ b/scene/animation/animation_blend_space_1d.h @@ -36,6 +36,14 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode { GDCLASS(AnimationNodeBlendSpace1D, AnimationRootNode); +public: + enum BlendMode { + BLEND_MODE_INTERPOLATED, + BLEND_MODE_DISCRETE, + BLEND_MODE_DISCRETE_CARRY, + }; + +protected: enum { MAX_BLEND_POINTS = 64 }; @@ -61,6 +69,10 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode { void _tree_changed(); StringName blend_position = "blend_position"; + StringName closest = "closest"; + StringName length_internal = "length_internal"; + + BlendMode blend_mode = BLEND_MODE_INTERPOLATED; protected: bool sync = false; @@ -95,6 +107,9 @@ public: void set_value_label(const String &p_label); String get_value_label() const; + void set_blend_mode(BlendMode p_blend_mode); + BlendMode get_blend_mode() const; + void set_use_sync(bool p_sync); bool is_using_sync() const; @@ -107,4 +122,6 @@ public: ~AnimationNodeBlendSpace1D(); }; +VARIANT_ENUM_CAST(AnimationNodeBlendSpace1D::BlendMode) + #endif // ANIMATION_BLEND_SPACE_1D_H diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 45f4f690b9..797999625b 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -800,6 +800,14 @@ Ref<Curve> AnimationNodeTransition::get_xfade_curve() const { return xfade_curve; } +void AnimationNodeTransition::set_allow_transition_to_self(bool p_enable) { + allow_transition_to_self = p_enable; +} + +bool AnimationNodeTransition::is_allow_transition_to_self() const { + return allow_transition_to_self; +} + double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_external_seeking) { String cur_transition_request = get_parameter(transition_request); int cur_current_index = get_parameter(current_index); @@ -815,20 +823,22 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex int new_idx = find_input(cur_transition_request); if (new_idx >= 0) { if (cur_current_index == new_idx) { - // Transition to same state. - restart = input_data[cur_current_index].reset; - cur_prev_xfading = 0; - set_parameter(prev_xfading, 0); - cur_prev_index = -1; - set_parameter(prev_index, -1); + if (allow_transition_to_self) { + // Transition to same state. + restart = input_data[cur_current_index].reset; + cur_prev_xfading = 0; + set_parameter(prev_xfading, 0); + cur_prev_index = -1; + set_parameter(prev_index, -1); + } } else { switched = true; cur_prev_index = cur_current_index; set_parameter(prev_index, cur_current_index); + cur_current_index = new_idx; + set_parameter(current_index, cur_current_index); + set_parameter(current_state, cur_transition_request); } - cur_current_index = new_idx; - set_parameter(current_index, cur_current_index); - set_parameter(current_state, cur_transition_request); } else { ERR_PRINT("No such input: '" + cur_transition_request + "'"); } @@ -932,8 +942,12 @@ void AnimationNodeTransition::_bind_methods() { ClassDB::bind_method(D_METHOD("set_xfade_curve", "curve"), &AnimationNodeTransition::set_xfade_curve); ClassDB::bind_method(D_METHOD("get_xfade_curve"), &AnimationNodeTransition::get_xfade_curve); + ClassDB::bind_method(D_METHOD("set_allow_transition_to_self", "enable"), &AnimationNodeTransition::set_allow_transition_to_self); + ClassDB::bind_method(D_METHOD("is_allow_transition_to_self"), &AnimationNodeTransition::is_allow_transition_to_self); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,120,0.01,suffix:s"), "set_xfade_time", "get_xfade_time"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "xfade_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_xfade_curve", "get_xfade_curve"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_transition_to_self"), "set_allow_transition_to_self", "is_allow_transition_to_self"); ADD_PROPERTY(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED, "Inputs,input_"), "set_input_count", "get_input_count"); } diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index 3c27edbf70..20f8e9b190 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -294,6 +294,7 @@ class AnimationNodeTransition : public AnimationNodeSync { double xfade_time = 0.0; Ref<Curve> xfade_curve; + bool allow_transition_to_self = false; protected: bool _get(const StringName &p_path, Variant &r_ret) const; @@ -325,6 +326,9 @@ public: void set_xfade_curve(const Ref<Curve> &p_curve); Ref<Curve> get_xfade_curve() const; + void set_allow_transition_to_self(bool p_enable); + bool is_allow_transition_to_self() const; + double process(double p_time, bool p_seek, bool p_is_external_seeking) override; AnimationNodeTransition(); diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 7fb831b3b2..ec28a5cca1 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -252,7 +252,7 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta path.clear(); //a new one will be needed if (current == p_travel) { - return false; // Will teleport oneself (restart). + return !p_state_machine->is_allow_transition_to_self(); } Vector2 current_pos = p_state_machine->states[current].position; @@ -813,6 +813,14 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), CONNECT_REFERENCE_COUNTED); } +void AnimationNodeStateMachine::set_allow_transition_to_self(bool p_enable) { + allow_transition_to_self = p_enable; +} + +bool AnimationNodeStateMachine::is_allow_transition_to_self() const { + return allow_transition_to_self; +} + bool AnimationNodeStateMachine::can_edit_node(const StringName &p_name) const { if (states.has(p_name)) { return !(states[p_name].node->is_class("AnimationNodeStartState") || states[p_name].node->is_class("AnimationNodeEndState")); @@ -1383,6 +1391,11 @@ void AnimationNodeStateMachine::_bind_methods() { ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &AnimationNodeStateMachine::set_graph_offset); ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeStateMachine::get_graph_offset); + + ClassDB::bind_method(D_METHOD("set_allow_transition_to_self", "enable"), &AnimationNodeStateMachine::set_allow_transition_to_self); + ClassDB::bind_method(D_METHOD("is_allow_transition_to_self"), &AnimationNodeStateMachine::is_allow_transition_to_self); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_transition_to_self"), "set_allow_transition_to_self", "is_allow_transition_to_self"); } AnimationNodeStateMachine::AnimationNodeStateMachine() { diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index cf4d850aa6..5c2a4d6264 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -188,6 +188,7 @@ private: }; HashMap<StringName, State> states; + bool allow_transition_to_self = false; struct Transition { StringName from; @@ -254,6 +255,9 @@ public: void remove_transition_by_index(const int p_transition); void remove_transition(const StringName &p_from, const StringName &p_to); + void set_allow_transition_to_self(bool p_enable); + bool is_allow_transition_to_self() const; + bool can_edit_node(const StringName &p_name) const; AnimationNodeStateMachine *get_prev_state_machine() const; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 1c1f94c986..fa72bbc593 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -1861,6 +1861,8 @@ void AnimationTree::_setup_animation_player() { return; } + cache_valid = false; + AnimationPlayer *new_player = nullptr; if (!animation_player.is_empty()) { new_player = Object::cast_to<AnimationPlayer>(get_node_or_null(animation_player)); diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 39d1793368..abc7814877 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -594,7 +594,7 @@ PropertyTweener::PropertyTweener(Object *p_target, NodePath p_property, Variant } PropertyTweener::PropertyTweener() { - ERR_FAIL_MSG("Can't create empty PropertyTweener. Use get_tree().tween_property() or tween_property() instead."); + ERR_FAIL_MSG("PropertyTweener can't be created directly. Use the tween_property() method in Tween."); } void IntervalTweener::start() { @@ -625,7 +625,7 @@ IntervalTweener::IntervalTweener(double p_time) { } IntervalTweener::IntervalTweener() { - ERR_FAIL_MSG("Can't create empty IntervalTweener. Use get_tree().tween_interval() instead."); + ERR_FAIL_MSG("IntervalTweener can't be created directly. Use the tween_interval() method in Tween."); } Ref<CallbackTweener> CallbackTweener::set_delay(double p_delay) { @@ -676,7 +676,7 @@ CallbackTweener::CallbackTweener(Callable p_callback) { } CallbackTweener::CallbackTweener() { - ERR_FAIL_MSG("Can't create empty CallbackTweener. Use get_tree().tween_callback() instead."); + ERR_FAIL_MSG("CallbackTweener can't be created directly. Use the tween_callback() method in Tween."); } Ref<MethodTweener> MethodTweener::set_delay(double p_delay) { @@ -769,5 +769,5 @@ MethodTweener::MethodTweener(Callable p_callback, Variant p_from, Variant p_to, } MethodTweener::MethodTweener() { - ERR_FAIL_MSG("Can't create empty MethodTweener. Use get_tree().tween_method() instead."); + ERR_FAIL_MSG("MethodTweener can't be created directly. Use the tween_method() method in Tween."); } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index f7c056316d..6f5e2cf058 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -692,6 +692,12 @@ Transform2D Control::get_transform() const { return xform; } +void Control::_toplevel_changed_on_parent() { + // Update root control status. + _notification(NOTIFICATION_EXIT_CANVAS); + _notification(NOTIFICATION_ENTER_CANVAS); +} + /// Anchors and offsets. void Control::_set_anchor(Side p_side, real_t p_anchor) { diff --git a/scene/gui/control.h b/scene/gui/control.h index a93a88e5b4..5977f4dbea 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -292,6 +292,9 @@ private: void _update_minimum_size(); void _size_changed(); + void _toplevel_changed() override{}; // Controls don't need to do anything, only other CanvasItems. + void _toplevel_changed_on_parent() override; + void _clear_size_warning(); // Input events. diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index dc23bcb14a..fe2eed6755 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -264,10 +264,6 @@ void GraphEdit::_scroll_moved(double) { top_layer->queue_redraw(); minimap->queue_redraw(); queue_redraw(); - - if (!setting_scroll_ofs) { //in godot, signals on change value are avoided as a convention - emit_signal(SNAME("scroll_offset_changed"), get_scroll_ofs()); - } } void GraphEdit::_update_scroll_offset() { @@ -290,6 +286,10 @@ void GraphEdit::_update_scroll_offset() { connections_layer->set_position(-Point2(h_scroll->get_value(), v_scroll->get_value())); set_block_minimum_size_adjust(false); awaiting_scroll_offset_update = false; + + if (!setting_scroll_ofs) { //in godot, signals on change value are avoided as a convention + emit_signal(SNAME("scroll_offset_changed"), get_scroll_ofs()); + } } void GraphEdit::_update_scroll() { diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 71ee3c8d0d..3051502dd0 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1797,7 +1797,9 @@ void RichTextLabel::_notification(int p_what) { } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - queue_redraw(); + if (is_visible_in_tree()) { + queue_redraw(); + } } break; case NOTIFICATION_DRAW: { @@ -2665,19 +2667,26 @@ bool RichTextLabel::_find_layout_subitem(Item *from, Item *to) { return false; } -void RichTextLabel::_thread_function(void *self) { - RichTextLabel *rtl = reinterpret_cast<RichTextLabel *>(self); - rtl->set_physics_process_internal(true); - rtl->_process_line_caches(); - rtl->set_physics_process_internal(false); - rtl->updating.store(false); - rtl->call_deferred(SNAME("queue_redraw")); +void RichTextLabel::_thread_function(void *p_userdata) { + _process_line_caches(); + updating.store(false); + call_deferred(SNAME("thread_end")); +} + +void RichTextLabel::_thread_end() { + set_physics_process_internal(false); + if (is_visible_in_tree()) { + queue_redraw(); + } } void RichTextLabel::_stop_thread() { if (threaded) { stop_thread.store(true); - thread.wait_to_finish(); + if (task != WorkerThreadPool::INVALID_TASK_ID) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(task); + task = WorkerThreadPool::INVALID_TASK_ID; + } } } @@ -2787,7 +2796,8 @@ bool RichTextLabel::_validate_line_caches() { if (threaded) { updating.store(true); loaded.store(true); - thread.start(RichTextLabel::_thread_function, reinterpret_cast<void *>(this)); + task = WorkerThreadPool::get_singleton()->add_template_task(this, &RichTextLabel::_thread_function, nullptr, true, vformat("RichTextLabelShape:%x", (int64_t)get_instance_id())); + set_physics_process_internal(true); loading_started = OS::get_singleton()->get_ticks_msec(); return false; } else { @@ -5457,6 +5467,8 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("get_menu"), &RichTextLabel::get_menu); ClassDB::bind_method(D_METHOD("is_menu_visible"), &RichTextLabel::is_menu_visible); + ClassDB::bind_method(D_METHOD("_thread_end"), &RichTextLabel::_thread_end); + // Note: set "bbcode_enabled" first, to avoid unnecessary "text" resets. 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"); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 58b82d4672..fcbb91f67e 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -31,6 +31,7 @@ #ifndef RICH_TEXT_LABEL_H #define RICH_TEXT_LABEL_H +#include "core/object/worker_thread_pool.h" #include "rich_text_effect.h" #include "scene/gui/popup_menu.h" #include "scene/gui/scroll_bar.h" @@ -369,7 +370,7 @@ private: Item *current = nullptr; ItemFrame *current_frame = nullptr; - Thread thread; + WorkerThreadPool::TaskID task = WorkerThreadPool::INVALID_TASK_ID; Mutex data_mutex; bool threaded = false; std::atomic<bool> stop_thread; @@ -409,7 +410,8 @@ private: void _invalidate_current_line(ItemFrame *p_frame); - static void _thread_function(void *self); + void _thread_function(void *p_userdata); + void _thread_end(); void _stop_thread(); bool _validate_line_caches(); void _process_line_caches(); diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp index 7c1d2f95a9..f10e1c2cd1 100644 --- a/scene/gui/subviewport_container.cpp +++ b/scene/gui/subviewport_container.cpp @@ -85,7 +85,7 @@ void SubViewportContainer::set_stretch_shrink(int p_shrink) { continue; } - c->set_size(get_size() / shrink); + c->set_size_force(get_size() / shrink); } queue_redraw(); @@ -116,7 +116,7 @@ void SubViewportContainer::_notification(int p_what) { continue; } - c->set_size(get_size() / shrink); + c->set_size_force(get_size() / shrink); } } break; diff --git a/scene/gui/video_stream_player.cpp b/scene/gui/video_stream_player.cpp index 6eb25bf852..1f3bbff779 100644 --- a/scene/gui/video_stream_player.cpp +++ b/scene/gui/video_stream_player.cpp @@ -236,7 +236,6 @@ void VideoStreamPlayer::set_stream(const Ref<VideoStream> &p_stream) { AudioServer::get_singleton()->unlock(); if (!playback.is_null()) { - playback->set_loop(loops); playback->set_paused(paused); texture = playback->get_texture(); @@ -344,6 +343,12 @@ int VideoStreamPlayer::get_buffering_msec() const { void VideoStreamPlayer::set_audio_track(int p_track) { audio_track = p_track; + if (stream.is_valid()) { + stream->set_audio_track(audio_track); + } + if (playback.is_valid()) { + playback->set_audio_track(audio_track); + } } int VideoStreamPlayer::get_audio_track() const { diff --git a/scene/gui/video_stream_player.h b/scene/gui/video_stream_player.h index 09ef272a9a..1fd599a9e1 100644 --- a/scene/gui/video_stream_player.h +++ b/scene/gui/video_stream_player.h @@ -65,7 +65,6 @@ class VideoStreamPlayer : public Control { float volume = 1.0; double last_audio_time = 0.0; bool expand = false; - bool loops = false; int buffering_ms = 500; int audio_track = 0; int bus_index = 0; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 35176f0edd..cde3503bdf 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -400,11 +400,28 @@ void CanvasItem::set_as_top_level(bool p_top_level) { _exit_canvas(); top_level = p_top_level; + _toplevel_changed(); _enter_canvas(); _notify_transform(); } +void CanvasItem::_toplevel_changed() { + // Inform children that toplevel status has changed on a parent. + int childs = get_child_count(); + for (int i = 0; i < childs; i++) { + CanvasItem *child = Object::cast_to<CanvasItem>(get_child(i)); + if (child) { + child->_toplevel_changed_on_parent(); + } + } +} + +void CanvasItem::_toplevel_changed_on_parent() { + // Inform children that toplevel status has changed on a parent. + _toplevel_changed(); +} + bool CanvasItem::is_set_as_top_level() const { return top_level; } diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 1c84ea338a..1ddfaa288c 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -125,6 +125,9 @@ private: void _propagate_visibility_changed(bool p_parent_visible_in_tree); void _handle_visibility_change(bool p_visible); + virtual void _toplevel_changed(); + virtual void _toplevel_changed_on_parent(); + void _redraw_callback(); void _enter_canvas(); diff --git a/scene/main/multiplayer_api.cpp b/scene/main/multiplayer_api.cpp index c54e61580f..950eb2809c 100644 --- a/scene/main/multiplayer_api.cpp +++ b/scene/main/multiplayer_api.cpp @@ -329,9 +329,9 @@ void MultiplayerAPI::_bind_methods() { /// MultiplayerAPIExtension Error MultiplayerAPIExtension::poll() { - int err = OK; + Error err = OK; GDVIRTUAL_CALL(_poll, err); - return (Error)err; + return err; } void MultiplayerAPIExtension::set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) { @@ -364,9 +364,9 @@ Error MultiplayerAPIExtension::rpcp(Object *p_obj, int p_peer_id, const StringNa for (int i = 0; i < p_argcount; i++) { args.push_back(*p_arg[i]); } - int ret = FAILED; + Error ret = FAILED; GDVIRTUAL_CALL(_rpc, p_peer_id, p_obj, p_method, args, ret); - return (Error)ret; + return ret; } int MultiplayerAPIExtension::get_remote_sender_id() { @@ -376,15 +376,15 @@ int MultiplayerAPIExtension::get_remote_sender_id() { } Error MultiplayerAPIExtension::object_configuration_add(Object *p_object, Variant p_config) { - int err = ERR_UNAVAILABLE; + Error err = ERR_UNAVAILABLE; GDVIRTUAL_CALL(_object_configuration_add, p_object, p_config, err); - return (Error)err; + return err; } Error MultiplayerAPIExtension::object_configuration_remove(Object *p_object, Variant p_config) { - int err = ERR_UNAVAILABLE; + Error err = ERR_UNAVAILABLE; GDVIRTUAL_CALL(_object_configuration_remove, p_object, p_config, err); - return (Error)err; + return err; } void MultiplayerAPIExtension::_bind_methods() { diff --git a/scene/main/multiplayer_api.h b/scene/main/multiplayer_api.h index 0b107ee50b..a578e6f2f1 100644 --- a/scene/main/multiplayer_api.h +++ b/scene/main/multiplayer_api.h @@ -101,15 +101,15 @@ public: virtual Error object_configuration_remove(Object *p_object, Variant p_config) override; // Extensions - GDVIRTUAL0R(int, _poll); + GDVIRTUAL0R(Error, _poll); GDVIRTUAL1(_set_multiplayer_peer, Ref<MultiplayerPeer>); GDVIRTUAL0R(Ref<MultiplayerPeer>, _get_multiplayer_peer); GDVIRTUAL0RC(int, _get_unique_id); GDVIRTUAL0RC(PackedInt32Array, _get_peer_ids); - GDVIRTUAL4R(int, _rpc, int, Object *, StringName, Array); + GDVIRTUAL4R(Error, _rpc, int, Object *, StringName, Array); GDVIRTUAL0RC(int, _get_remote_sender_id); - GDVIRTUAL2R(int, _object_configuration_add, Object *, Variant); - GDVIRTUAL2R(int, _object_configuration_remove, Object *, Variant); + GDVIRTUAL2R(Error, _object_configuration_add, Object *, Variant); + GDVIRTUAL2R(Error, _object_configuration_remove, Object *, Variant); }; #endif // MULTIPLAYER_API_H diff --git a/scene/main/multiplayer_peer.cpp b/scene/main/multiplayer_peer.cpp index 83555966d7..f3e56a1455 100644 --- a/scene/main/multiplayer_peer.cpp +++ b/scene/main/multiplayer_peer.cpp @@ -163,7 +163,7 @@ Error MultiplayerPeerExtension::put_packet(const uint8_t *p_buffer, int p_buffer if (!GDVIRTUAL_CALL(_put_packet_script, a, err)) { return FAILED; } - return (Error)err; + return err; } WARN_PRINT_ONCE("MultiplayerPeerExtension::_put_packet_native is unimplemented!"); return FAILED; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 48cff5aa8e..fe82fed2f7 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1045,6 +1045,25 @@ Transform2D Viewport::get_final_transform() const { return _get_input_pre_xform().affine_inverse() * stretch_transform * global_canvas_transform; } +void Viewport::assign_next_enabled_camera_2d(const StringName &p_camera_group) { + List<Node *> camera_list; + get_tree()->get_nodes_in_group(p_camera_group, &camera_list); + + Camera2D *new_camera = nullptr; + for (const Node *E : camera_list) { + const Camera2D *cam = Object::cast_to<Camera2D>(E); + if (cam->is_enabled()) { + new_camera = const_cast<Camera2D *>(cam); + break; + } + } + + _camera_2d_set(new_camera); + if (!camera_2d) { + set_canvas_transform(Transform2D()); + } +} + void Viewport::_update_canvas_items(Node *p_node) { if (p_node != this) { Window *w = Object::cast_to<Window>(p_node); @@ -1110,14 +1129,11 @@ Viewport::PositionalShadowAtlasQuadrantSubdiv Viewport::get_positional_shadow_at } Transform2D Viewport::_get_input_pre_xform() const { - Transform2D pre_xf; - - if (to_screen_rect.size.x != 0 && to_screen_rect.size.y != 0) { - pre_xf.columns[2] = -to_screen_rect.position; - pre_xf.scale(Vector2(size) / to_screen_rect.size); + const Window *this_window = Object::cast_to<Window>(this); + if (this_window) { + return this_window->window_transform.affine_inverse(); } - - return pre_xf; + return Transform2D(); } Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) { @@ -4098,9 +4114,26 @@ Viewport::~Viewport() { ///////////////////////////////// void SubViewport::set_size(const Size2i &p_size) { - _set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true); + _internal_set_size(p_size); +} + +void SubViewport::set_size_force(const Size2i &p_size) { + // Use only for setting the size from the parent SubViewportContainer with enabled stretch mode. + // Don't expose function to scripting. + _internal_set_size(p_size, true); +} +void SubViewport::_internal_set_size(const Size2i &p_size, bool p_force) { SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent()); + if (!p_force && c && c->is_stretch_enabled()) { +#ifdef DEBUG_ENABLED + WARN_PRINT("Can't change the size of a `SubViewport` with a `SubViewportContainer` parent that has `stretch` enabled. Set `SubViewportContainer.stretch` to `false` to allow changing the size manually."); +#endif // DEBUG_ENABLED + return; + } + + _set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true); + if (c) { c->update_minimum_size(); } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index d5d5201e9a..2a4ddc422f 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -511,6 +511,7 @@ public: Transform2D get_global_canvas_transform() const; Transform2D get_final_transform() const; + void assign_next_enabled_camera_2d(const StringName &p_camera_group); void gui_set_root_order_dirty(); @@ -753,6 +754,8 @@ private: ClearMode clear_mode = CLEAR_MODE_ALWAYS; bool size_2d_override_stretch = false; + void _internal_set_size(const Size2i &p_size, bool p_force = false); + protected: static void _bind_methods(); virtual DisplayServer::WindowID get_window_id() const override; @@ -762,6 +765,7 @@ protected: public: void set_size(const Size2i &p_size); Size2i get_size() const; + void set_size_force(const Size2i &p_size); void set_size_2d_override(const Size2i &p_size); Size2i get_size_2d_override() const; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 869d12b4df..b1f2bc65dc 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -907,6 +907,7 @@ void Window::_update_viewport_size() { Rect2i attach_to_screen_rect(Point2i(), size); Transform2D stretch_transform_new; float font_oversampling = 1.0; + window_transform = Transform2D(); if (content_scale_mode == CONTENT_SCALE_MODE_DISABLED || content_scale_size.x == 0 || content_scale_size.y == 0) { font_oversampling = content_scale_factor; @@ -993,11 +994,18 @@ void Window::_update_viewport_size() { Size2 scale = Vector2(screen_size) / Vector2(final_size_override); stretch_transform_new.scale(scale); + window_transform.translate_local(margin); } break; case CONTENT_SCALE_MODE_VIEWPORT: { final_size = (viewport_size / content_scale_factor).floor(); attach_to_screen_rect = Rect2(margin, screen_size); + window_transform.translate_local(margin); + if (final_size.x != 0 && final_size.y != 0) { + Transform2D scale_transform; + scale_transform.scale(Vector2(attach_to_screen_rect.size) / Vector2(final_size)); + window_transform *= scale_transform; + } } break; } } @@ -2127,13 +2135,13 @@ 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(); + Transform2D popup_base_transform; + popup_base_transform.set_origin(get_position()); + popup_base_transform *= Viewport::get_screen_transform(); if (_get_embedder()) { - return _get_embedder()->get_popup_base_transform() * window_transform; + return _get_embedder()->get_popup_base_transform() * popup_base_transform; } - return window_transform; + return popup_base_transform; } void Window::_bind_methods() { diff --git a/scene/main/window.h b/scene/main/window.h index 182caf5f0c..1730de0b33 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -173,6 +173,8 @@ private: Viewport *embedder = nullptr; + Transform2D window_transform; + friend class Viewport; //friend back, can call the methods below void _window_input(const Ref<InputEvent> &p_ev); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 7bebf1cfd3..39fc03f9f1 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -393,6 +393,8 @@ void register_scene_types() { GDREGISTER_CLASS(LineEdit); GDREGISTER_CLASS(VideoStreamPlayer); + GDREGISTER_VIRTUAL_CLASS(VideoStreamPlayback); + GDREGISTER_VIRTUAL_CLASS(VideoStream); #ifndef ADVANCED_GUI_DISABLED GDREGISTER_CLASS(FileDialog); @@ -906,7 +908,6 @@ void register_scene_types() { #ifndef _3D_DISABLED GDREGISTER_CLASS(AudioStreamPlayer3D); #endif - GDREGISTER_ABSTRACT_CLASS(VideoStream); GDREGISTER_CLASS(AudioStreamWAV); GDREGISTER_CLASS(AudioStreamPolyphonic); GDREGISTER_ABSTRACT_CLASS(AudioStreamPlaybackPolyphonic); diff --git a/scene/resources/fog_material.cpp b/scene/resources/fog_material.cpp index 4e51bbaa73..aabaa54505 100644 --- a/scene/resources/fog_material.cpp +++ b/scene/resources/fog_material.cpp @@ -159,7 +159,7 @@ uniform sampler3D density_texture: hint_default_white; void fog() { DENSITY = density * clamp(exp2(-height_falloff * (WORLD_POSITION.y - OBJECT_POSITION.y)), 0.0, 1.0); DENSITY *= texture(density_texture, UVW).r; - DENSITY *= pow(clamp(-SDF / min(min(EXTENTS.x, EXTENTS.y), EXTENTS.z), 0.0, 1.0), edge_fade); + DENSITY *= pow(clamp(-2.0 * SDF / min(min(SIZE.x, SIZE.y), SIZE.z), 0.0, 1.0), edge_fade); ALBEDO = albedo.rgb; EMISSION = emission.rgb; } diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index 55b633a40c..672581bbe2 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -452,6 +452,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli new_indices.resize(index_count); Vector<float> merged_normals_f32 = vector3_to_float32_array(merged_normals.ptr(), merged_normals.size()); + const int simplify_options = SurfaceTool::SIMPLIFY_LOCK_BORDER; size_t new_index_count = SurfaceTool::simplify_with_attrib_func( (unsigned int *)new_indices.ptrw(), @@ -460,6 +461,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli sizeof(float) * 3, // Vertex stride index_target, max_mesh_error, + simplify_options, &mesh_error, merged_normals_f32.ptr(), normal_weights.ptr(), 3); @@ -1058,6 +1060,8 @@ struct EditorSceneFormatImporterMeshLightmapSurface { String name; }; +static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT }; + Error ImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache) { ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED); ERR_FAIL_COND_V_MSG(blend_shapes.size() != 0, ERR_UNAVAILABLE, "Can't unwrap mesh with blend shapes."); @@ -1178,9 +1182,6 @@ Error ImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, return ERR_CANT_CREATE; } - //remove surfaces - clear(); - //create surfacetools for each surface.. LocalVector<Ref<SurfaceTool>> surfaces_tools; @@ -1190,9 +1191,16 @@ Error ImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, st->begin(Mesh::PRIMITIVE_TRIANGLES); st->set_material(lightmap_surfaces[i].material); st->set_meta("name", lightmap_surfaces[i].name); + + for (int custom_i = 0; custom_i < RS::ARRAY_CUSTOM_COUNT; custom_i++) { + st->set_custom_format(custom_i, (SurfaceTool::CustomFormat)((lightmap_surfaces[i].format >> custom_shift[custom_i]) & RS::ARRAY_FORMAT_CUSTOM_MASK)); + } surfaces_tools.push_back(st); //stay there } + //remove surfaces + clear(); + print_verbose("Mesh: Gen indices: " + itos(gen_index_count)); //go through all indices @@ -1229,6 +1237,11 @@ Error ImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, if (lightmap_surfaces[surface].format & Mesh::ARRAY_FORMAT_WEIGHTS) { surfaces_tools[surface]->set_weights(v.weights); } + for (int custom_i = 0; custom_i < RS::ARRAY_CUSTOM_COUNT; custom_i++) { + if ((lightmap_surfaces[surface].format >> custom_shift[custom_i]) & RS::ARRAY_FORMAT_CUSTOM_MASK) { + surfaces_tools[surface]->set_custom(custom_i, v.custom[custom_i]); + } + } Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]); surfaces_tools[surface]->set_uv2(uv2); @@ -1238,10 +1251,11 @@ Error ImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, } //generate surfaces - for (Ref<SurfaceTool> &tool : surfaces_tools) { + for (int i = 0; i < lightmap_surfaces.size(); i++) { + Ref<SurfaceTool> &tool = surfaces_tools[i]; tool->index(); Array arrays = tool->commit_to_arrays(); - add_surface(tool->get_primitive_type(), arrays, Array(), Dictionary(), tool->get_material(), tool->get_meta("name")); + add_surface(tool->get_primitive_type(), arrays, Array(), Dictionary(), tool->get_material(), tool->get_meta("name"), lightmap_surfaces[i].format); } set_lightmap_size_hint(Size2(size_x, size_y)); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index d6393966b1..7e84814ab3 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -2316,7 +2316,7 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel() return refraction_texture_channel; } -Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard, bool p_billboard_y, bool p_msdf, bool p_no_depth, bool p_fixed_size, TextureFilter p_filter, RID *r_shader_rid) { +Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard, bool p_billboard_y, bool p_msdf, bool p_no_depth, bool p_fixed_size, TextureFilter p_filter, AlphaAntiAliasing p_alpha_antialiasing_mode, RID *r_shader_rid) { uint64_t key = 0; key |= ((int8_t)p_shaded & 0x01) << 0; key |= ((int8_t)p_transparency & 0x07) << 1; // Bits 1-3. @@ -2326,7 +2326,8 @@ Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, Transparency p_ key |= ((int8_t)p_msdf & 0x01) << 7; key |= ((int8_t)p_no_depth & 0x01) << 8; key |= ((int8_t)p_fixed_size & 0x01) << 9; - key |= ((int8_t)p_filter & 0x07) << 10; // Bits 10-13. + key |= ((int8_t)p_filter & 0x07) << 10; // Bits 10-12. + key |= ((int8_t)p_alpha_antialiasing_mode & 0x07) << 13; // Bits 13-15. if (materials_for_2d.has(key)) { if (r_shader_rid) { @@ -2346,6 +2347,7 @@ Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, Transparency p_ material->set_flag(FLAG_ALBEDO_TEXTURE_MSDF, p_msdf); material->set_flag(FLAG_DISABLE_DEPTH_TEST, p_no_depth); material->set_flag(FLAG_FIXED_SIZE, p_fixed_size); + material->set_alpha_antialiasing(p_alpha_antialiasing_mode); material->set_texture_filter(p_filter); if (p_billboard || p_billboard_y) { material->set_flag(FLAG_BILLBOARD_KEEP_SCALE, true); diff --git a/scene/resources/material.h b/scene/resources/material.h index 23f3a8824d..5ea9a807d4 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -760,7 +760,7 @@ public: static void finish_shaders(); static void flush_changes(); - static Ref<Material> get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard = false, bool p_billboard_y = false, bool p_msdf = false, bool p_no_depth = false, bool p_fixed_size = false, TextureFilter p_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RID *r_shader_rid = nullptr); + static Ref<Material> get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard = false, bool p_billboard_y = false, bool p_msdf = false, bool p_no_depth = false, bool p_fixed_size = false, TextureFilter p_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, AlphaAntiAliasing p_alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF, RID *r_shader_rid = nullptr); virtual RID get_shader_rid() const override; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index e497a628aa..1e9038139e 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -43,7 +43,7 @@ #include "scene/main/missing_node.h" #include "scene/property_utils.h" -#define PACKED_SCENE_VERSION 2 +#define PACKED_SCENE_VERSION 3 #define META_POINTER_PROPERTY_BASE "metadata/_editor_prop_ptr_" bool SceneState::can_instantiate() const { return nodes.size() > 0; @@ -314,7 +314,19 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { //must make a copy, because this res is local to scene } } - } else if (p_edit_state == GEN_EDIT_STATE_INSTANCE) { + } + if (value.get_type() == Variant::ARRAY) { + Array set_array = value; + bool is_get_valid = false; + Variant get_value = node->get(snames[nprops[j].name], &is_get_valid); + if (is_get_valid && get_value.get_type() == Variant::ARRAY) { + Array get_array = get_value; + if (!set_array.is_same_typed(get_array)) { + value = Array(set_array, get_array.get_typed_builtin(), get_array.get_typed_class_name(), get_array.get_typed_script()); + } + } + } + if (p_edit_state == GEN_EDIT_STATE_INSTANCE && value.get_type() != Variant::OBJECT) { value = value.duplicate(true); // Duplicate arrays and dictionaries for the editor } @@ -1282,6 +1294,9 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) { for (int j = 0; j < cd.binds.size(); j++) { cd.binds.write[j] = r[idx++]; } + if (version >= 3) { + cd.unbinds = r[idx++]; + } } } @@ -1368,6 +1383,7 @@ Dictionary SceneState::get_bundled_scene() const { for (int j = 0; j < cd.binds.size(); j++) { rconns.push_back(cd.binds[j]); } + rconns.push_back(cd.unbinds); } d["conns"] = rconns; diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 0ba177f882..608d15019e 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -636,6 +636,18 @@ Error ResourceLoaderText::load() { } } + if (value.get_type() == Variant::ARRAY) { + Array set_array = value; + bool is_get_valid = false; + Variant get_value = res->get(assign, &is_get_valid); + if (is_get_valid && get_value.get_type() == Variant::ARRAY) { + Array get_array = get_value; + if (!set_array.is_same_typed(get_array)) { + value = Array(set_array, get_array.get_typed_builtin(), get_array.get_typed_class_name(), get_array.get_typed_script()); + } + } + } + if (set_valid) { res->set(assign, value); } @@ -746,6 +758,18 @@ Error ResourceLoaderText::load() { } } + if (value.get_type() == Variant::ARRAY) { + Array set_array = value; + bool is_get_valid = false; + Variant get_value = resource->get(assign, &is_get_valid); + if (is_get_valid && get_value.get_type() == Variant::ARRAY) { + Array get_array = get_value; + if (!set_array.is_same_typed(get_array)) { + value = Array(set_array, get_array.get_typed_builtin(), get_array.get_typed_class_name(), get_array.get_typed_script()); + } + } + } + if (set_valid) { resource->set(assign, value); } diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 5a2b917b9a..16cc1c3370 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -1307,7 +1307,8 @@ Vector<int> SurfaceTool::generate_lod(float p_threshold, int p_target_index_coun } float error; - uint32_t index_count = simplify_func((unsigned int *)lod.ptrw(), (unsigned int *)index_array.ptr(), index_array.size(), vertices.ptr(), vertex_array.size(), sizeof(float) * 3, p_target_index_count, p_threshold, &error); + const int simplify_options = SIMPLIFY_LOCK_BORDER; + uint32_t index_count = simplify_func((unsigned int *)lod.ptrw(), (unsigned int *)index_array.ptr(), index_array.size(), vertices.ptr(), vertex_array.size(), sizeof(float) * 3, p_target_index_count, p_threshold, simplify_options, &error); ERR_FAIL_COND_V(index_count == 0, lod); lod.resize(index_count); diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 00438c4a53..77318bb061 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -74,11 +74,16 @@ public: SKIN_8_WEIGHTS }; + enum { + /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */ + SIMPLIFY_LOCK_BORDER = 1 << 0, // From meshopt_SimplifyLockBorder + }; + typedef void (*OptimizeVertexCacheFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, size_t vertex_count); static OptimizeVertexCacheFunc optimize_vertex_cache_func; - typedef size_t (*SimplifyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *r_error); + typedef size_t (*SimplifyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float *r_error); static SimplifyFunc simplify_func; - typedef size_t (*SimplifyWithAttribFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float *result_error, const float *attributes, const float *attribute_weights, size_t attribute_count); + typedef size_t (*SimplifyWithAttribFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, unsigned int options, float *result_error, const float *attributes, const float *attribute_weights, size_t attribute_count); static SimplifyWithAttribFunc simplify_with_attrib_func; typedef float (*SimplifyScaleFunc)(const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride); static SimplifyScaleFunc simplify_scale_func; diff --git a/scene/resources/video_stream.cpp b/scene/resources/video_stream.cpp new file mode 100644 index 0000000000..ee1a47c338 --- /dev/null +++ b/scene/resources/video_stream.cpp @@ -0,0 +1,198 @@ +/**************************************************************************/ +/* video_stream.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "video_stream.h" + +#include "core/config/project_settings.h" +#include "servers/audio_server.h" + +// VideoStreamPlayback starts here. + +void VideoStreamPlayback::_bind_methods() { + ClassDB::bind_method(D_METHOD("mix_audio", "num_frames", "buffer", "offset"), &VideoStreamPlayback::mix_audio, DEFVAL(PackedFloat32Array()), DEFVAL(0)); + GDVIRTUAL_BIND(_stop); + GDVIRTUAL_BIND(_play); + GDVIRTUAL_BIND(_is_playing); + GDVIRTUAL_BIND(_set_paused, "paused"); + GDVIRTUAL_BIND(_is_paused); + GDVIRTUAL_BIND(_get_length); + GDVIRTUAL_BIND(_get_playback_position); + GDVIRTUAL_BIND(_seek, "time"); + GDVIRTUAL_BIND(_set_audio_track, "idx"); + GDVIRTUAL_BIND(_get_texture); + GDVIRTUAL_BIND(_update, "delta"); + GDVIRTUAL_BIND(_get_channels); + GDVIRTUAL_BIND(_get_mix_rate); +} + +VideoStreamPlayback::VideoStreamPlayback() { +} + +VideoStreamPlayback::~VideoStreamPlayback() { +} + +void VideoStreamPlayback::stop() { + GDVIRTUAL_CALL(_stop); +} + +void VideoStreamPlayback::play() { + GDVIRTUAL_CALL(_play); +} + +bool VideoStreamPlayback::is_playing() const { + bool ret; + if (GDVIRTUAL_CALL(_is_playing, ret)) { + return ret; + } + return false; +} + +void VideoStreamPlayback::set_paused(bool p_paused) { + GDVIRTUAL_CALL(_is_playing, p_paused); +} + +bool VideoStreamPlayback::is_paused() const { + bool ret; + if (GDVIRTUAL_CALL(_is_paused, ret)) { + return ret; + } + return false; +} + +double VideoStreamPlayback::get_length() const { + double ret; + if (GDVIRTUAL_CALL(_get_length, ret)) { + return ret; + } + return 0; +} + +double VideoStreamPlayback::get_playback_position() const { + double ret; + if (GDVIRTUAL_CALL(_get_playback_position, ret)) { + return ret; + } + return 0; +} + +void VideoStreamPlayback::seek(double p_time) { + GDVIRTUAL_CALL(_seek, p_time); +} + +void VideoStreamPlayback::set_audio_track(int p_idx) { + GDVIRTUAL_CALL(_set_audio_track, p_idx); +} + +Ref<Texture2D> VideoStreamPlayback::get_texture() const { + Ref<Texture2D> ret; + if (GDVIRTUAL_CALL(_get_texture, ret)) { + return ret; + } + return nullptr; +} + +void VideoStreamPlayback::update(double p_delta) { + if (!GDVIRTUAL_CALL(_update, p_delta)) { + ERR_FAIL_MSG("VideoStreamPlayback::update unimplemented"); + } +} + +void VideoStreamPlayback::set_mix_callback(AudioMixCallback p_callback, void *p_userdata) { + mix_callback = p_callback; + mix_udata = p_userdata; +} + +int VideoStreamPlayback::get_channels() const { + int ret; + if (GDVIRTUAL_CALL(_get_channels, ret)) { + _channel_count = ret; + return ret; + } + return 0; +} + +int VideoStreamPlayback::get_mix_rate() const { + int ret; + if (GDVIRTUAL_CALL(_get_mix_rate, ret)) { + return ret; + } + return 0; +} + +int VideoStreamPlayback::mix_audio(int num_frames, PackedFloat32Array buffer, int offset) { + if (num_frames <= 0) { + return 0; + } + if (!mix_callback) { + return -1; + } + ERR_FAIL_INDEX_V(offset, buffer.size(), -1); + ERR_FAIL_INDEX_V((_channel_count < 1 ? 1 : _channel_count) * num_frames - 1, buffer.size() - offset, -1); + return mix_callback(mix_udata, buffer.ptr() + offset, num_frames); +} + +/* --- NOTE VideoStream starts here. ----- */ + +Ref<VideoStreamPlayback> VideoStream::instantiate_playback() { + Ref<VideoStreamPlayback> ret; + if (GDVIRTUAL_CALL(_instantiate_playback, ret)) { + ERR_FAIL_COND_V_MSG(ret.is_null(), nullptr, "Plugin returned null playback"); + ret->set_audio_track(audio_track); + return ret; + } + return nullptr; +} + +void VideoStream::set_file(const String &p_file) { + file = p_file; +} + +String VideoStream::get_file() { + return file; +} + +void VideoStream::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStream::set_file); + ClassDB::bind_method(D_METHOD("get_file"), &VideoStream::get_file); + + ADD_PROPERTY(PropertyInfo(Variant::STRING, "file"), "set_file", "get_file"); + + GDVIRTUAL_BIND(_instantiate_playback); +} + +VideoStream::VideoStream() { +} + +VideoStream::~VideoStream() { +} + +void VideoStream::set_audio_track(int p_track) { + audio_track = p_track; +} diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h index f83c621d0a..b91a7acf35 100644 --- a/scene/resources/video_stream.h +++ b/scene/resources/video_stream.h @@ -31,6 +31,7 @@ #ifndef VIDEO_STREAM_H #define VIDEO_STREAM_H +#include "core/io/file_access.h" #include "scene/resources/texture.h" class VideoStreamPlayback : public Resource { @@ -39,40 +40,77 @@ class VideoStreamPlayback : public Resource { public: typedef int (*AudioMixCallback)(void *p_udata, const float *p_data, int p_frames); - virtual void stop() = 0; - virtual void play() = 0; +protected: + AudioMixCallback mix_callback = nullptr; + void *mix_udata = nullptr; + mutable int _channel_count = 0; // Used only to assist with bounds checking in mix_audio. + + static void _bind_methods(); + GDVIRTUAL0(_stop); + GDVIRTUAL0(_play); + GDVIRTUAL0RC(bool, _is_playing); + GDVIRTUAL1(_set_paused, bool); + GDVIRTUAL0RC(bool, _is_paused); + GDVIRTUAL0RC(double, _get_length); + GDVIRTUAL0RC(double, _get_playback_position); + GDVIRTUAL1(_seek, double); + GDVIRTUAL1(_set_audio_track, int); + GDVIRTUAL0RC(Ref<Texture2D>, _get_texture); + GDVIRTUAL1(_update, double); + GDVIRTUAL0RC(int, _get_channels); + GDVIRTUAL0RC(int, _get_mix_rate); + + int mix_audio(int num_frames, PackedFloat32Array buffer = {}, int offset = 0); - virtual bool is_playing() const = 0; +public: + VideoStreamPlayback(); + virtual ~VideoStreamPlayback(); - virtual void set_paused(bool p_paused) = 0; - virtual bool is_paused() const = 0; + virtual void stop(); + virtual void play(); - virtual void set_loop(bool p_enable) = 0; - virtual bool has_loop() const = 0; + virtual bool is_playing() const; - virtual double get_length() const = 0; + virtual void set_paused(bool p_paused); + virtual bool is_paused() const; - virtual double get_playback_position() const = 0; - virtual void seek(double p_time) = 0; + virtual double get_length() const; - virtual void set_audio_track(int p_idx) = 0; + virtual double get_playback_position() const; + virtual void seek(double p_time); - virtual Ref<Texture2D> get_texture() const = 0; + virtual void set_audio_track(int p_idx); - virtual void update(double p_delta) = 0; + virtual Ref<Texture2D> get_texture() const; + virtual void update(double p_delta); - virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata) = 0; - virtual int get_channels() const = 0; - virtual int get_mix_rate() const = 0; + virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata); + virtual int get_channels() const; + virtual int get_mix_rate() const; }; class VideoStream : public Resource { GDCLASS(VideoStream, Resource); - OBJ_SAVE_TYPE(VideoStream); // Saves derived classes with common type so they can be interchanged. + OBJ_SAVE_TYPE(VideoStream); + +protected: + static void + _bind_methods(); + + GDVIRTUAL0R(Ref<VideoStreamPlayback>, _instantiate_playback); + + String file; + int audio_track = 0; public: - virtual void set_audio_track(int p_track) = 0; - virtual Ref<VideoStreamPlayback> instantiate_playback() = 0; + void set_file(const String &p_file); + String get_file(); + + virtual void set_audio_track(int p_track); + virtual Ref<VideoStreamPlayback> instantiate_playback(); + + VideoStream(); + ~VideoStream(); }; #endif // VIDEO_STREAM_H diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index bfcf5cb137..4132972cb3 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -427,7 +427,10 @@ void VisualShaderNodeCustom::update_ports() { if (!GDVIRTUAL_CALL(_get_input_port_name, i, port.name)) { port.name = "in" + itos(i); } - if (!GDVIRTUAL_CALL(_get_input_port_type, i, port.type)) { + PortType port_type; + if (GDVIRTUAL_CALL(_get_input_port_type, i, port_type)) { + port.type = (int)port_type; + } else { port.type = (int)PortType::PORT_TYPE_SCALAR; } @@ -445,7 +448,10 @@ void VisualShaderNodeCustom::update_ports() { if (!GDVIRTUAL_CALL(_get_output_port_name, i, port.name)) { port.name = "out" + itos(i); } - if (!GDVIRTUAL_CALL(_get_output_port_type, i, port.type)) { + PortType port_type; + if (GDVIRTUAL_CALL(_get_output_port_type, i, port_type)) { + port.type = (int)port_type; + } else { port.type = (int)PortType::PORT_TYPE_SCALAR; } @@ -2702,6 +2708,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "eye_offset", "EYE_OFFSET" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_world", "NODE_POSITION_WORLD" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_position_world", "CAMERA_POSITION_WORLD" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_direction_world", "CAMERA_DIRECTION_WORLD" }, @@ -2736,6 +2743,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "eye_offset", "EYE_OFFSET" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_world", "NODE_POSITION_WORLD" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_position_world", "CAMERA_POSITION_WORLD" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_direction_world", "CAMERA_DIRECTION_WORLD" }, @@ -2936,7 +2944,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_FOG, VisualShader::TYPE_FOG, VisualShaderNode::PORT_TYPE_VECTOR_3D, "world_position", "WORLD_POSITION" }, { Shader::MODE_FOG, VisualShader::TYPE_FOG, VisualShaderNode::PORT_TYPE_VECTOR_3D, "object_position", "OBJECT_POSITION" }, { Shader::MODE_FOG, VisualShader::TYPE_FOG, VisualShaderNode::PORT_TYPE_VECTOR_3D, "uvw", "UVW" }, - { Shader::MODE_FOG, VisualShader::TYPE_FOG, VisualShaderNode::PORT_TYPE_VECTOR_3D, "extents", "EXTENTS" }, + { Shader::MODE_FOG, VisualShader::TYPE_FOG, VisualShaderNode::PORT_TYPE_VECTOR_3D, "size", "SIZE" }, { Shader::MODE_FOG, VisualShader::TYPE_FOG, VisualShaderNode::PORT_TYPE_SCALAR, "sdf", "SDF" }, { Shader::MODE_FOG, VisualShader::TYPE_FOG, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 0d53589fa5..fc5e48410b 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -369,12 +369,12 @@ protected: GDVIRTUAL0RC(String, _get_name) GDVIRTUAL0RC(String, _get_description) GDVIRTUAL0RC(String, _get_category) - GDVIRTUAL0RC(int, _get_return_icon_type) + GDVIRTUAL0RC(PortType, _get_return_icon_type) GDVIRTUAL0RC(int, _get_input_port_count) - GDVIRTUAL1RC(int, _get_input_port_type, int) + GDVIRTUAL1RC(PortType, _get_input_port_type, int) GDVIRTUAL1RC(String, _get_input_port_name, int) GDVIRTUAL0RC(int, _get_output_port_count) - GDVIRTUAL1RC(int, _get_output_port_type, int) + GDVIRTUAL1RC(PortType, _get_output_port_type, int) GDVIRTUAL1RC(String, _get_output_port_name, int) GDVIRTUAL4RC(String, _get_code, TypedArray<String>, TypedArray<String>, Shader::Mode, VisualShader::Type) GDVIRTUAL2RC(String, _get_func_code, Shader::Mode, VisualShader::Type) diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 12be0f46a6..0695492e7f 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -6923,15 +6923,34 @@ void VisualShaderNodeSwitch::_bind_methods() { // static } String VisualShaderNodeSwitch::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 { + bool use_mix = false; + switch (op_type) { + case OP_TYPE_FLOAT: { + use_mix = true; + } break; + case OP_TYPE_VECTOR_2D: { + use_mix = true; + } break; + case OP_TYPE_VECTOR_3D: { + use_mix = true; + } break; + case OP_TYPE_VECTOR_4D: { + use_mix = true; + } break; + default: { + } break; + } + String code; - code += " if(" + p_input_vars[0] + ")\n"; - code += " {\n"; - code += " " + p_output_vars[0] + " = " + p_input_vars[1] + ";\n"; - code += " }\n"; - code += " else\n"; - code += " {\n"; - code += " " + p_output_vars[0] + " = " + p_input_vars[2] + ";\n"; - code += " }\n"; + if (use_mix) { + code += " " + p_output_vars[0] + " = mix(" + p_input_vars[2] + ", " + p_input_vars[1] + ", float(" + p_input_vars[0] + "));\n"; + } else { + code += " if (" + p_input_vars[0] + ") {\n"; + code += " " + p_output_vars[0] + " = " + p_input_vars[1] + ";\n"; + code += " } else {\n"; + code += " " + p_output_vars[0] + " = " + p_input_vars[2] + ";\n"; + code += " }\n"; + } return code; } diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 2a70139bcb..c7304da358 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -43,6 +43,14 @@ RID World2D::get_canvas() const { } RID World2D::get_space() const { + if (space.is_null()) { + space = PhysicsServer2D::get_singleton()->space_create(); + PhysicsServer2D::get_singleton()->space_set_active(space, true); + PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_GET("physics/2d/default_gravity")); + PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_GET("physics/2d/default_gravity_vector")); + PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_LINEAR_DAMP, GLOBAL_GET("physics/2d/default_linear_damp")); + PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_GET("physics/2d/default_angular_damp")); + } return space; } @@ -71,19 +79,11 @@ void World2D::_bind_methods() { } PhysicsDirectSpaceState2D *World2D::get_direct_space_state() { - return PhysicsServer2D::get_singleton()->space_get_direct_state(space); + return PhysicsServer2D::get_singleton()->space_get_direct_state(get_space()); } World2D::World2D() { canvas = RenderingServer::get_singleton()->canvas_create(); - - // Create and configure space2D to be more friendly with pixels than meters - space = PhysicsServer2D::get_singleton()->space_create(); - PhysicsServer2D::get_singleton()->space_set_active(space, true); - PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_DEF_BASIC("physics/2d/default_gravity", 980.0)); - PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF_BASIC("physics/2d/default_gravity_vector", Vector2(0, 1))); - PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), 0.1)); - PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), 1.0)); } World2D::~World2D() { @@ -91,7 +91,9 @@ World2D::~World2D() { ERR_FAIL_NULL(PhysicsServer2D::get_singleton()); ERR_FAIL_NULL(NavigationServer2D::get_singleton()); RenderingServer::get_singleton()->free(canvas); - PhysicsServer2D::get_singleton()->free(space); + if (space.is_valid()) { + PhysicsServer2D::get_singleton()->free(space); + } if (navigation_map.is_valid()) { NavigationServer2D::get_singleton()->free(navigation_map); } diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index f02dddd2fe..0b3b9df7dc 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -43,7 +43,7 @@ class World2D : public Resource { GDCLASS(World2D, Resource); RID canvas; - RID space; + mutable RID space; mutable RID navigation_map; HashSet<Viewport *> viewports; diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp index cc4d261c0d..82c056d5ee 100644 --- a/scene/resources/world_3d.cpp +++ b/scene/resources/world_3d.cpp @@ -51,6 +51,14 @@ void World3D::_remove_camera(Camera3D *p_camera) { } RID World3D::get_space() const { + if (space.is_null()) { + space = PhysicsServer3D::get_singleton()->space_create(); + PhysicsServer3D::get_singleton()->space_set_active(space, true); + PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_GRAVITY, GLOBAL_GET("physics/3d/default_gravity")); + PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_GET("physics/3d/default_gravity_vector")); + PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_LINEAR_DAMP, GLOBAL_GET("physics/3d/default_linear_damp")); + PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_GET("physics/3d/default_angular_damp")); + } return space; } @@ -121,7 +129,7 @@ Ref<CameraAttributes> World3D::get_camera_attributes() const { } PhysicsDirectSpaceState3D *World3D::get_direct_space_state() { - return PhysicsServer3D::get_singleton()->space_get_direct_state(space); + return PhysicsServer3D::get_singleton()->space_get_direct_state(get_space()); } void World3D::_bind_methods() { @@ -145,22 +153,18 @@ void World3D::_bind_methods() { } World3D::World3D() { - space = PhysicsServer3D::get_singleton()->space_create(); scenario = RenderingServer::get_singleton()->scenario_create(); - - PhysicsServer3D::get_singleton()->space_set_active(space, true); - PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_GRAVITY, GLOBAL_DEF_BASIC("physics/3d/default_gravity", 9.8)); - PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF_BASIC("physics/3d/default_gravity_vector", Vector3(0, -1, 0))); - PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/default_linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), 0.1)); - PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), 0.1)); } World3D::~World3D() { - ERR_FAIL_NULL(PhysicsServer3D::get_singleton()); ERR_FAIL_NULL(RenderingServer::get_singleton()); + ERR_FAIL_NULL(PhysicsServer3D::get_singleton()); ERR_FAIL_NULL(NavigationServer3D::get_singleton()); - PhysicsServer3D::get_singleton()->free(space); + RenderingServer::get_singleton()->free(scenario); + if (space.is_valid()) { + PhysicsServer3D::get_singleton()->free(space); + } if (navigation_map.is_valid()) { NavigationServer3D::get_singleton()->free(navigation_map); } diff --git a/scene/resources/world_3d.h b/scene/resources/world_3d.h index ad17daf466..518fff64e2 100644 --- a/scene/resources/world_3d.h +++ b/scene/resources/world_3d.h @@ -45,8 +45,8 @@ class World3D : public Resource { GDCLASS(World3D, Resource); private: - RID space; RID scenario; + mutable RID space; mutable RID navigation_map; Ref<Environment> environment; |