diff options
Diffstat (limited to 'scene')
38 files changed, 885 insertions, 183 deletions
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/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/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/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_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/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/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/tree.cpp b/scene/gui/tree.cpp index d9e6157489..0f39715851 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -5256,7 +5256,6 @@ void Tree::_bind_methods() { ADD_SIGNAL(MethodInfo("empty_clicked", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::INT, "mouse_button_index"))); ADD_SIGNAL(MethodInfo("item_edited")); ADD_SIGNAL(MethodInfo("custom_item_clicked", PropertyInfo(Variant::INT, "mouse_button_index"))); - ADD_SIGNAL(MethodInfo("item_custom_button_pressed")); ADD_SIGNAL(MethodInfo("item_icon_double_clicked")); ADD_SIGNAL(MethodInfo("item_collapsed", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "TreeItem"))); ADD_SIGNAL(MethodInfo("check_propagated_to_item", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "TreeItem"), PropertyInfo(Variant::INT, "column"))); 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 b6bcbe04a3..fe82fed2f7 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -4114,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 e081013fde..2a4ddc422f 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -754,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; @@ -763,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 b1f2bc65dc..5fd39dfc68 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -2344,6 +2344,7 @@ void Window::_bind_methods() { ADD_SIGNAL(MethodInfo("visibility_changed")); ADD_SIGNAL(MethodInfo("about_to_popup")); ADD_SIGNAL(MethodInfo("theme_changed")); + ADD_SIGNAL(MethodInfo("dpi_changed")); ADD_SIGNAL(MethodInfo("titlebar_changed")); BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED); diff --git a/scene/resources/bone_map.cpp b/scene/resources/bone_map.cpp index c73f8ca0b0..759d189bfa 100644 --- a/scene/resources/bone_map.cpp +++ b/scene/resources/bone_map.cpp @@ -152,7 +152,6 @@ void BoneMap::_validate_bone_map() { } else { bone_map.clear(); } - emit_signal("retarget_option_updated"); } void BoneMap::_bind_methods() { 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 742ac2bbd9..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); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 7984ec735e..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; @@ -1294,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++]; + } } } @@ -1380,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/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/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; } |