diff options
Diffstat (limited to 'scene')
78 files changed, 1381 insertions, 349 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index c46b6eeb5c..8ba334bc67 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -435,10 +435,10 @@ bool Area2D::is_monitorable() const { return monitorable; } -Array Area2D::get_overlapping_bodies() const { +TypedArray<Node2D> Area2D::get_overlapping_bodies() const { ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); - Array ret; + TypedArray<Node2D> ret; ret.resize(body_map.size()); int idx = 0; for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) { @@ -453,10 +453,10 @@ Array Area2D::get_overlapping_bodies() const { return ret; } -Array Area2D::get_overlapping_areas() const { +TypedArray<Area2D> Area2D::get_overlapping_areas() const { ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); - Array ret; + TypedArray<Area2D> ret; ret.resize(area_map.size()); int idx = 0; for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) { diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index c5e6635412..0e2c0ac672 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -178,8 +178,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; //function for script - Array get_overlapping_areas() const; //function for script + TypedArray<Node2D> get_overlapping_bodies() const; //function for script + TypedArray<Area2D> get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index c45eab70df..43c54ffd17 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -43,7 +43,7 @@ Line2D::Line2D() { _begin_cap_mode = LINE_CAP_NONE; _end_cap_mode = LINE_CAP_NONE; _width = 10; - _default_color = Color(0.4, 0.5, 1); + _default_color = Color(1, 1, 1); _texture_mode = LINE_TEXTURE_NONE; _sharp_limit = 2.f; _round_precision = 8; diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index d77fd5b097..19484442b1 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -95,7 +95,7 @@ Vector<Vector2> NavigationPolygon::get_vertices() const { return vertices; } -void NavigationPolygon::_set_polygons(const Array &p_array) { +void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array) { { MutexLock lock(navmesh_generation); @@ -118,7 +118,7 @@ Array NavigationPolygon::_get_polygons() const { return ret; } -void NavigationPolygon::_set_outlines(const Array &p_array) { +void NavigationPolygon::_set_outlines(const TypedArray<Vector<int32_t>> &p_array) { outlines.resize(p_array.size()); for (int i = 0; i < p_array.size(); i++) { diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index 73e056a353..cbfe4299fb 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -55,10 +55,10 @@ class NavigationPolygon : public Resource { protected: static void _bind_methods(); - void _set_polygons(const Array &p_array); + void _set_polygons(const TypedArray<Vector<int32_t>> &p_array); Array _get_polygons() const; - void _set_outlines(const Array &p_array); + void _set_outlines(const TypedArray<Vector<int32_t>> &p_array); Array _get_outlines() const; public: diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index d55b21bc24..149d5c6b0d 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -102,7 +102,7 @@ void Path2D::_notification(int p_what) { #else const float line_width = 2; #endif - const Color color = Color(1.0, 1.0, 1.0, 1.0); + const Color color = Color(0.5, 0.6, 1.0, 0.7); for (int i = 0; i < curve->get_point_count(); i++) { @@ -162,7 +162,6 @@ void Path2D::_bind_methods() { Path2D::Path2D() { set_curve(Ref<Curve2D>(memnew(Curve2D))); //create one by default - set_self_modulate(Color(0.5, 0.6, 1.0, 0.7)); } ///////////////////////////////////////////////////////////////////////////////// @@ -321,16 +320,14 @@ void PathFollow2D::set_offset(float p_offset) { offset = p_offset; if (path) { - if (path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { + if (path->get_curve().is_valid()) { float path_length = path->get_curve()->get_baked_length(); if (loop) { - while (offset > path_length) - offset -= path_length; - - while (offset < 0) - offset += path_length; - + offset = Math::fposmod(offset, path_length); + if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) { + offset = path_length; + } } else { offset = CLAMP(offset, 0, path_length); } diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 21dc9537ec..de15f0efc2 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -139,7 +139,7 @@ PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) : set_pickable(false); } -Array PhysicsBody2D::get_collision_exceptions() { +TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; @@ -739,11 +739,11 @@ RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() cons return ccd_mode; } -Array RigidBody2D::get_colliding_bodies() const { +TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const { ERR_FAIL_COND_V(!contact_monitor, Array()); - Array ret; + TypedArray<Node2D> ret; ret.resize(contact_monitor->body_map.size()); int idx = 0; for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 0d92a820e3..75f4f778bf 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -67,7 +67,7 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray<PhysicsBody2D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -256,7 +256,7 @@ public: void add_force(const Vector2 &p_offset, const Vector2 &p_force); void add_torque(float p_torque); - Array get_colliding_bodies() const; //function for script + TypedArray<Node2D> get_colliding_bodies() const; //function for script virtual String get_configuration_warning() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 1cf12e4421..9628c01718 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1691,27 +1691,27 @@ bool TileMap::is_centered_textures_enabled() const { return centered_textures; } -Array TileMap::get_used_cells() const { +TypedArray<Vector2i> TileMap::get_used_cells() const { - Array a; + TypedArray<Vector2i> a; a.resize(tile_map.size()); int i = 0; for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a[i++] = p; } return a; } -Array TileMap::get_used_cells_by_id(int p_id) const { +TypedArray<Vector2i> TileMap::get_used_cells_by_id(int p_id) const { - Array a; + TypedArray<Vector2i> a; for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { if (E->value().id == p_id) { - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a.push_back(p); } } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index d9490aae13..cc1537f583 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -328,8 +328,8 @@ public: void set_centered_textures(bool p_enable); bool is_centered_textures_enabled() const; - Array get_used_cells() const; - Array get_used_cells_by_id(int p_id) const; + TypedArray<Vector2i> get_used_cells() const; + TypedArray<Vector2i> get_used_cells_by_id(int p_id) const; Rect2 get_used_rect(); // Not const because of cache void set_occluder_light_mask(int p_mask); diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 2cb979a0e0..85fd05ac15 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -30,7 +30,7 @@ #include "touch_screen_button.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/input/input_map.h" #include "core/os/os.h" #include "scene/main/window.h" @@ -290,7 +290,7 @@ void TouchScreenButton::_press(int p_finger_pressed) { if (action != StringName()) { - InputFilter::get_singleton()->action_press(action); + Input::get_singleton()->action_press(action); Ref<InputEventAction> iea; iea.instance(); iea->set_action(action); @@ -308,7 +308,7 @@ void TouchScreenButton::_release(bool p_exiting_tree) { if (action != StringName()) { - InputFilter::get_singleton()->action_release(action); + Input::get_singleton()->action_release(action); if (!p_exiting_tree) { Ref<InputEventAction> iea; diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 17ae553e5e..b72483d71b 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -416,7 +416,7 @@ bool Area3D::is_monitoring() const { return monitoring; } -Array Area3D::get_overlapping_bodies() const { +TypedArray<Node3D> Area3D::get_overlapping_bodies() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; @@ -451,7 +451,7 @@ bool Area3D::is_monitorable() const { return monitorable; } -Array Area3D::get_overlapping_areas() const { +TypedArray<Area3D> Area3D::get_overlapping_areas() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index ff6c0b6b08..f6503c6d2d 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -184,8 +184,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; - Array get_overlapping_areas() const; //function for script + TypedArray<Node3D> get_overlapping_bodies() const; + TypedArray<Area3D> get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 097368853e..28a8b01437 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -556,7 +556,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { for (int i = 0; i < vol_index_max; i++) { - output.reverb_vol[i] = output.reverb_vol[i].linear_interpolate(center_frame, attenuation); + output.reverb_vol[i] = output.reverb_vol[i].lerp(center_frame, attenuation); } } else { for (int i = 0; i < vol_index_max; i++) { @@ -567,7 +567,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { for (int i = 0; i < vol_index_max; i++) { - output.reverb_vol[i] = output.vol[i].linear_interpolate(output.reverb_vol[i] * attenuation, uniformity); + output.reverb_vol[i] = output.vol[i].lerp(output.reverb_vol[i] * attenuation, uniformity); output.reverb_vol[i] *= area_send; } diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 12c105b0f4..4c25f55f0b 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -69,6 +69,7 @@ void CPUParticles3D::set_amount(int p_amount) { for (int i = 0; i < p_amount; i++) { w[i].active = false; + w[i].custom[3] = 0.0; // Make sure w component isn't garbage data } } diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp new file mode 100644 index 0000000000..4c824aedc4 --- /dev/null +++ b/scene/3d/decal.cpp @@ -0,0 +1,235 @@ +/*************************************************************************/ +/* decal.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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 "decal.h" + +void Decal::set_extents(const Vector3 &p_extents) { + extents = p_extents; + RS::get_singleton()->decal_set_extents(decal, p_extents); + update_gizmo(); + _change_notify("extents"); +} + +Vector3 Decal::get_extents() const { + return extents; +} + +void Decal::set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture) { + ERR_FAIL_INDEX(p_type, TEXTURE_MAX); + textures[p_type] = p_texture; + RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + RS::get_singleton()->decal_set_texture(decal, RS::DecalTexture(p_type), texture_rid); +} +Ref<Texture2D> Decal::get_texture(DecalTexture p_type) const { + ERR_FAIL_INDEX_V(p_type, TEXTURE_MAX, Ref<Texture2D>()); + return textures[p_type]; +} + +void Decal::set_emission_energy(float p_energy) { + emission_energy = p_energy; + RS::get_singleton()->decal_set_emission_energy(decal, emission_energy); +} +float Decal::get_emission_energy() const { + return emission_energy; +} + +void Decal::set_albedo_mix(float p_mix) { + albedo_mix = p_mix; + RS::get_singleton()->decal_set_albedo_mix(decal, albedo_mix); +} +float Decal::get_albedo_mix() const { + return albedo_mix; +} + +void Decal::set_upper_fade(float p_fade) { + upper_fade = p_fade; + RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade); +} +float Decal::get_upper_fade() const { + return upper_fade; +} + +void Decal::set_lower_fade(float p_fade) { + lower_fade = p_fade; + RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade); +} +float Decal::get_lower_fade() const { + return lower_fade; +} + +void Decal::set_normal_fade(float p_fade) { + normal_fade = p_fade; + RS::get_singleton()->decal_set_normal_fade(decal, normal_fade); +} +float Decal::get_normal_fade() const { + return normal_fade; +} + +void Decal::set_modulate(Color p_modulate) { + modulate = p_modulate; + RS::get_singleton()->decal_set_modulate(decal, p_modulate); +} + +Color Decal::get_modulate() const { + return modulate; +} + +void Decal::set_enable_distance_fade(bool p_enable) { + distance_fade_enabled = p_enable; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +bool Decal::is_distance_fade_enabled() const { + return distance_fade_enabled; +} + +void Decal::set_distance_fade_begin(float p_distance) { + distance_fade_begin = p_distance; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +float Decal::get_distance_fade_begin() const { + return distance_fade_begin; +} + +void Decal::set_distance_fade_length(float p_length) { + distance_fade_length = p_length; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +float Decal::get_distance_fade_length() const { + return distance_fade_length; +} + +void Decal::set_cull_mask(uint32_t p_layers) { + cull_mask = p_layers; + RS::get_singleton()->decal_set_cull_mask(decal, cull_mask); +} +uint32_t Decal::get_cull_mask() const { + return cull_mask; +} + +AABB Decal::get_aabb() const { + + AABB aabb; + aabb.position = -extents; + aabb.size = extents * 2.0; + return aabb; +} +Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const { + + return Vector<Face3>(); +} + +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_texture", "type", "texture"), &Decal::set_texture); + ClassDB::bind_method(D_METHOD("get_texture", "type"), &Decal::get_texture); + + ClassDB::bind_method(D_METHOD("set_emission_energy", "energy"), &Decal::set_emission_energy); + ClassDB::bind_method(D_METHOD("get_emission_energy"), &Decal::get_emission_energy); + + ClassDB::bind_method(D_METHOD("set_albedo_mix", "energy"), &Decal::set_albedo_mix); + ClassDB::bind_method(D_METHOD("get_albedo_mix"), &Decal::get_albedo_mix); + + ClassDB::bind_method(D_METHOD("set_modulate", "color"), &Decal::set_modulate); + ClassDB::bind_method(D_METHOD("get_modulate"), &Decal::get_modulate); + + ClassDB::bind_method(D_METHOD("set_upper_fade", "fade"), &Decal::set_upper_fade); + ClassDB::bind_method(D_METHOD("get_upper_fade"), &Decal::get_upper_fade); + + ClassDB::bind_method(D_METHOD("set_lower_fade", "fade"), &Decal::set_lower_fade); + ClassDB::bind_method(D_METHOD("get_lower_fade"), &Decal::get_lower_fade); + + ClassDB::bind_method(D_METHOD("set_normal_fade", "fade"), &Decal::set_normal_fade); + ClassDB::bind_method(D_METHOD("get_normal_fade"), &Decal::get_normal_fade); + + ClassDB::bind_method(D_METHOD("set_enable_distance_fade", "enable"), &Decal::set_enable_distance_fade); + ClassDB::bind_method(D_METHOD("is_distance_fade_enabled"), &Decal::is_distance_fade_enabled); + + ClassDB::bind_method(D_METHOD("set_distance_fade_begin", "distance"), &Decal::set_distance_fade_begin); + ClassDB::bind_method(D_METHOD("get_distance_fade_begin"), &Decal::get_distance_fade_begin); + + ClassDB::bind_method(D_METHOD("set_distance_fade_length", "distance"), &Decal::set_distance_fade_length); + ClassDB::bind_method(D_METHOD("get_distance_fade_length"), &Decal::get_distance_fade_length); + + 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"), "set_extents", "get_extents"); + ADD_GROUP("Textures", "texture_"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_orm", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ORM); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_emission", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION); + ADD_GROUP("Parameters", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_emission_energy", "get_emission_energy"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "albedo_mix", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_albedo_mix", "get_albedo_mix"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_fade", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_normal_fade", "get_normal_fade"); + ADD_GROUP("Vertical Fade", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "upper_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_upper_fade", "get_upper_fade"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lower_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_lower_fade", "get_lower_fade"); + ADD_GROUP("Distance Fade", "distance_fade_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin"), "set_distance_fade_begin", "get_distance_fade_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length"), "set_distance_fade_length", "get_distance_fade_length"); + ADD_GROUP("Cull Mask", ""); + ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); + + BIND_ENUM_CONSTANT(TEXTURE_ALBEDO); + BIND_ENUM_CONSTANT(TEXTURE_NORMAL); + BIND_ENUM_CONSTANT(TEXTURE_ORM); + BIND_ENUM_CONSTANT(TEXTURE_EMISSION); + BIND_ENUM_CONSTANT(TEXTURE_MAX); +} + +Decal::Decal() { + + extents = Vector3(1, 1, 1); + emission_energy = 1.0; + modulate = Color(1, 1, 1, 1); + albedo_mix = 1.0; + cull_mask = (1 << 20) - 1; + upper_fade = 0.3; + lower_fade = 0.3; + normal_fade = 0; + distance_fade_enabled = false; + distance_fade_begin = 10; + distance_fade_length = 1; + + decal = RenderingServer::get_singleton()->decal_create(); + RS::get_singleton()->instance_set_base(get_instance(), decal); +} + +Decal::~Decal() { + + RS::get_singleton()->free(decal); +} diff --git a/scene/3d/decal.h b/scene/3d/decal.h new file mode 100644 index 0000000000..665444829d --- /dev/null +++ b/scene/3d/decal.h @@ -0,0 +1,114 @@ +/*************************************************************************/ +/* decal.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef DECAL_H +#define DECAL_H + +#include "scene/3d/visual_instance_3d.h" +#include "scene/resources/texture.h" +#include "servers/rendering_server.h" + +class Decal : public VisualInstance3D { + GDCLASS(Decal, VisualInstance3D); + +public: + enum DecalTexture { + TEXTURE_ALBEDO, + TEXTURE_NORMAL, + TEXTURE_ORM, + TEXTURE_EMISSION, + TEXTURE_MAX + }; + +private: + RID decal; + Vector3 extents; + Ref<Texture2D> textures[TEXTURE_MAX]; + float emission_energy; + float albedo_mix; + Color modulate; + uint32_t cull_mask; + float normal_fade; + float upper_fade; + float lower_fade; + bool distance_fade_enabled; + float distance_fade_begin; + float distance_fade_length; + +protected: + static void _bind_methods(); + +public: + void set_extents(const Vector3 &p_extents); + Vector3 get_extents() const; + + void set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture(DecalTexture p_type) const; + + void set_emission_energy(float p_energy); + float get_emission_energy() const; + + void set_albedo_mix(float p_mix); + float get_albedo_mix() const; + + void set_modulate(Color p_modulate); + Color get_modulate() const; + + void set_upper_fade(float p_energy); + float get_upper_fade() const; + + void set_lower_fade(float p_fade); + float get_lower_fade() const; + + void set_normal_fade(float p_fade); + float get_normal_fade() const; + + void set_enable_distance_fade(bool p_enable); + bool is_distance_fade_enabled() const; + + void set_distance_fade_begin(float p_distance); + float get_distance_fade_begin() const; + + void set_distance_fade_length(float p_length); + float get_distance_fade_length() const; + + void set_cull_mask(uint32_t p_layers); + uint32_t get_cull_mask() const; + + virtual AABB get_aabb() const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; + + Decal(); + ~Decal(); +}; + +VARIANT_ENUM_CAST(Decal::DecalTexture); + +#endif // DECAL_H diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index c822b70a4b..c048f60ebd 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -70,7 +70,7 @@ void Light3D::set_shadow(bool p_enable) { shadow = p_enable; RS::get_singleton()->light_set_shadow(light, p_enable); - if (type == RenderingServer::LIGHT_SPOT) { + if (type == RenderingServer::LIGHT_SPOT || type == RenderingServer::LIGHT_OMNI) { update_configuration_warning(); } } @@ -166,6 +166,18 @@ Light3D::BakeMode Light3D::get_bake_mode() const { return bake_mode; } +void Light3D::set_projector(const Ref<Texture2D> &p_texture) { + + projector = p_texture; + RID tex_id = projector.is_valid() ? projector->get_rid() : RID(); + RS::get_singleton()->light_set_projector(light, tex_id); + update_configuration_warning(); +} + +Ref<Texture2D> Light3D::get_projector() const { + return projector; +} + void Light3D::_update_visibility() { if (!is_inside_tree()) @@ -216,6 +228,18 @@ bool Light3D::is_editor_only() const { } void Light3D::_validate_property(PropertyInfo &property) const { + + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_size") { + property.usage = 0; + } + + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_projector") { + property.usage = 0; + } + + if (get_light_type() != RS::LIGHT_DIRECTIONAL && property.name == "light_angular_distance") { + property.usage = 0; + } } void Light3D::_bind_methods() { @@ -247,10 +271,16 @@ void Light3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bake_mode", "bake_mode"), &Light3D::set_bake_mode); ClassDB::bind_method(D_METHOD("get_bake_mode"), &Light3D::get_bake_mode); + ClassDB::bind_method(D_METHOD("set_projector", "projector"), &Light3D::set_projector); + ClassDB::bind_method(D_METHOD("get_projector"), &Light3D::get_projector); + ADD_GROUP("Light", "light_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_color", "get_color"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_ENERGY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_projector", "get_projector"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,64,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_angular_distance", PROPERTY_HINT_RANGE, "0,90,0.01"), "set_param", "get_param", PARAM_SIZE); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_bake_mode", PROPERTY_HINT_ENUM, "Disable,Indirect,All"), "set_bake_mode", "get_bake_mode"); @@ -262,6 +292,7 @@ void Light3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_normal_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0.1,8,0.01"), "set_param", "get_param", PARAM_SHADOW_BLUR); ADD_GROUP("Editor", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); ADD_GROUP("", ""); @@ -270,6 +301,7 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_INDIRECT_ENERGY); BIND_ENUM_CONSTANT(PARAM_SPECULAR); BIND_ENUM_CONSTANT(PARAM_RANGE); + BIND_ENUM_CONSTANT(PARAM_SIZE); BIND_ENUM_CONSTANT(PARAM_ATTENUATION); BIND_ENUM_CONSTANT(PARAM_SPOT_ANGLE); BIND_ENUM_CONSTANT(PARAM_SPOT_ATTENUATION); @@ -281,6 +313,7 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_SHADOW_NORMAL_BIAS); BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS); BIND_ENUM_CONSTANT(PARAM_SHADOW_PANCAKE_SIZE); + BIND_ENUM_CONSTANT(PARAM_SHADOW_BLUR); BIND_ENUM_CONSTANT(PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(PARAM_MAX); @@ -315,6 +348,7 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_INDIRECT_ENERGY, 1); set_param(PARAM_SPECULAR, 0.5); set_param(PARAM_RANGE, 5); + set_param(PARAM_SIZE, 0); set_param(PARAM_ATTENUATION, 1); set_param(PARAM_SPOT_ANGLE, 45); set_param(PARAM_SPOT_ATTENUATION, 1); @@ -324,6 +358,7 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5); set_param(PARAM_SHADOW_FADE_START, 0.8); set_param(PARAM_SHADOW_PANCAKE_SIZE, 20.0); + set_param(PARAM_SHADOW_BLUR, 1.0); set_param(PARAM_SHADOW_BIAS, 0.02); set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); set_param(PARAM_TRANSMITTANCE_BIAS, 0.05); @@ -430,6 +465,19 @@ OmniLight3D::ShadowMode OmniLight3D::get_shadow_mode() const { return shadow_mode; } +String OmniLight3D::get_configuration_warning() const { + String warning = Light3D::get_configuration_warning(); + + if (!has_shadow() && get_projector().is_valid()) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Projector texture only works with shadows active."); + } + + return warning; +} + void OmniLight3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight3D::set_shadow_mode); @@ -461,6 +509,13 @@ String SpotLight3D::get_configuration_warning() const { warning += TTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows."); } + if (!has_shadow() && get_projector().is_valid()) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Projector texture only works with shadows active."); + } + return warning; } diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index ad2a1d5a84..6e78217342 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -46,6 +46,7 @@ public: PARAM_INDIRECT_ENERGY = RS::LIGHT_PARAM_INDIRECT_ENERGY, PARAM_SPECULAR = RS::LIGHT_PARAM_SPECULAR, PARAM_RANGE = RS::LIGHT_PARAM_RANGE, + PARAM_SIZE = RS::LIGHT_PARAM_SIZE, PARAM_ATTENUATION = RS::LIGHT_PARAM_ATTENUATION, PARAM_SPOT_ANGLE = RS::LIGHT_PARAM_SPOT_ANGLE, PARAM_SPOT_ATTENUATION = RS::LIGHT_PARAM_SPOT_ATTENUATION, @@ -57,6 +58,7 @@ public: PARAM_SHADOW_NORMAL_BIAS = RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS, PARAM_SHADOW_BIAS = RS::LIGHT_PARAM_SHADOW_BIAS, PARAM_SHADOW_PANCAKE_SIZE = RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE, + PARAM_SHADOW_BLUR = RS::LIGHT_PARAM_SHADOW_BLUR, PARAM_TRANSMITTANCE_BIAS = RS::LIGHT_PARAM_TRANSMITTANCE_BIAS, PARAM_MAX = RS::LIGHT_PARAM_MAX }; @@ -79,6 +81,7 @@ private: bool editor_only; void _update_visibility(); BakeMode bake_mode; + Ref<Texture2D> projector; // bind helpers @@ -123,6 +126,9 @@ public: void set_bake_mode(BakeMode p_mode); BakeMode get_bake_mode() const; + void set_projector(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_projector() const; + virtual AABB get_aabb() const; virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; @@ -194,6 +200,8 @@ public: void set_shadow_mode(ShadowMode p_mode); ShadowMode get_shadow_mode() const; + virtual String get_configuration_warning() const; + OmniLight3D(); }; diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index d56a095a5b..cdc8db8aea 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -307,19 +307,22 @@ Ref<Material> MeshInstance3D::get_surface_material(int p_surface) const { Ref<Material> MeshInstance3D::get_active_material(int p_surface) const { - if (get_material_override() != Ref<Material>()) { - return get_material_override(); - } else if (p_surface < materials.size()) { - return materials[p_surface]; - } else { - Ref<Mesh> mesh = get_mesh(); + Ref<Material> material_override = get_material_override(); + if (material_override.is_valid()) { + return material_override; + } - if (mesh.is_null() || p_surface >= mesh->get_surface_count()) { - return Ref<Material>(); - } + Ref<Material> surface_material = get_surface_material(p_surface); + if (surface_material.is_valid()) { + return surface_material; + } + Ref<Mesh> mesh = get_mesh(); + if (mesh.is_valid()) { return mesh->surface_get_material(p_surface); } + + return Ref<Material>(); } void MeshInstance3D::_mesh_changed() { diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index f06135f53d..4a425d1e0e 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -316,16 +316,14 @@ void PathFollow3D::set_offset(float p_offset) { offset = p_offset; if (path) { - if (path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { + if (path->get_curve().is_valid()) { float path_length = path->get_curve()->get_baked_length(); if (loop) { - while (offset > path_length) - offset -= path_length; - - while (offset < 0) - offset += path_length; - + offset = Math::fposmod(offset, path_length); + if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) { + offset = path_length; + } } else { offset = CLAMP(offset, 0, path_length); } diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 2b6eb8ac8a..3991efc7c0 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -110,7 +110,7 @@ bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const { return get_collision_layer() & (1 << p_bit); } -Array PhysicsBody3D::get_collision_exceptions() { +TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; @@ -2134,6 +2134,10 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_joint_offset", "offset"), &PhysicalBone3D::set_joint_offset); ClassDB::bind_method(D_METHOD("get_joint_offset"), &PhysicalBone3D::get_joint_offset); + ClassDB::bind_method(D_METHOD("set_joint_rotation", "euler"), &PhysicalBone3D::set_joint_rotation); + ClassDB::bind_method(D_METHOD("get_joint_rotation"), &PhysicalBone3D::get_joint_rotation); + ClassDB::bind_method(D_METHOD("set_joint_rotation_degrees", "euler_degrees"), &PhysicalBone3D::set_joint_rotation_degrees); + ClassDB::bind_method(D_METHOD("get_joint_rotation_degrees"), &PhysicalBone3D::get_joint_rotation_degrees); ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone3D::set_body_offset); ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone3D::get_body_offset); @@ -2159,9 +2163,23 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &PhysicalBone3D::set_gravity_scale); ClassDB::bind_method(D_METHOD("get_gravity_scale"), &PhysicalBone3D::get_gravity_scale); + ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &PhysicalBone3D::set_linear_damp); + ClassDB::bind_method(D_METHOD("get_linear_damp"), &PhysicalBone3D::get_linear_damp); + + ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &PhysicalBone3D::set_angular_damp); + ClassDB::bind_method(D_METHOD("get_angular_damp"), &PhysicalBone3D::get_angular_damp); + + ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &PhysicalBone3D::set_can_sleep); + ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &PhysicalBone3D::is_able_to_sleep); + + ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicalBone3D::set_axis_lock); + ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicalBone3D::get_axis_lock); + ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "joint_offset"), "set_joint_offset", "get_joint_offset"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_joint_rotation_degrees", "get_joint_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_NONE, "", 0), "set_joint_rotation", "get_joint_rotation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "body_offset"), "set_body_offset", "get_body_offset"); @@ -2170,6 +2188,17 @@ void PhysicalBone3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); + + ADD_GROUP("Axis Lock", "axis_lock_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); BIND_ENUM_CONSTANT(JOINT_TYPE_NONE); BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); @@ -2187,6 +2216,19 @@ Skeleton3D *PhysicalBone3D::find_skeleton_parent(Node *p_parent) { return s ? s : find_skeleton_parent(p_parent->get_parent()); } +void PhysicalBone3D::_update_joint_offset() { + _fix_joint_offset(); + + set_ignore_transform_notification(true); + reset_to_rest_position(); + set_ignore_transform_notification(false); + +#ifdef TOOLS_ENABLED + if (get_gizmo().is_valid()) + get_gizmo()->redraw(); +#endif +} + void PhysicalBone3D::_fix_joint_offset() { // Clamp joint origin to bone origin if (parent_skeleton) { @@ -2370,16 +2412,31 @@ PhysicalBone3D::JointType PhysicalBone3D::get_joint_type() const { void PhysicalBone3D::set_joint_offset(const Transform &p_offset) { joint_offset = p_offset; - _fix_joint_offset(); + _update_joint_offset(); + _change_notify("joint_rotation_degrees"); +} - set_ignore_transform_notification(true); - reset_to_rest_position(); - set_ignore_transform_notification(false); +const Transform &PhysicalBone3D::get_joint_offset() const { + return joint_offset; +} -#ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) - get_gizmo()->redraw(); -#endif +void PhysicalBone3D::set_joint_rotation(const Vector3 &p_euler_rad) { + joint_offset.basis.set_euler_scale(p_euler_rad, joint_offset.basis.get_scale()); + + _update_joint_offset(); + _change_notify("joint_offset"); +} + +Vector3 PhysicalBone3D::get_joint_rotation() const { + return joint_offset.basis.get_rotation(); +} + +void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) { + set_joint_rotation(p_euler_deg * Math_PI / 180.0); +} + +Vector3 PhysicalBone3D::get_joint_rotation_degrees() const { + return get_joint_rotation() * 180.0 / Math_PI; } const Transform &PhysicalBone3D::get_body_offset() const { @@ -2390,20 +2447,7 @@ void PhysicalBone3D::set_body_offset(const Transform &p_offset) { body_offset = p_offset; body_offset_inverse = body_offset.affine_inverse(); - _fix_joint_offset(); - - set_ignore_transform_notification(true); - reset_to_rest_position(); - set_ignore_transform_notification(false); - -#ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) - get_gizmo()->redraw(); -#endif -} - -const Transform &PhysicalBone3D::get_joint_offset() const { - return joint_offset; + _update_joint_offset(); } void PhysicalBone3D::set_simulate_physics(bool p_simulate) { @@ -2496,6 +2540,43 @@ real_t PhysicalBone3D::get_gravity_scale() const { return gravity_scale; } +void PhysicalBone3D::set_linear_damp(real_t p_linear_damp) { + ERR_FAIL_COND(p_linear_damp < -1); + linear_damp = p_linear_damp; + PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp); +} + +real_t PhysicalBone3D::get_linear_damp() const { + return linear_damp; +} + +void PhysicalBone3D::set_angular_damp(real_t p_angular_damp) { + ERR_FAIL_COND(p_angular_damp < -1); + angular_damp = p_angular_damp; + PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp); +} + +real_t PhysicalBone3D::get_angular_damp() const { + return angular_damp; +} + +void PhysicalBone3D::set_can_sleep(bool p_active) { + can_sleep = p_active; + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_CAN_SLEEP, p_active); +} + +bool PhysicalBone3D::is_able_to_sleep() const { + return can_sleep; +} + +void PhysicalBone3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { + PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +} + +bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { + return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); +} + PhysicalBone3D::PhysicalBone3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC), #ifdef TOOLS_ENABLED @@ -2510,7 +2591,10 @@ PhysicalBone3D::PhysicalBone3D() : bounce(0), mass(1), friction(1), - gravity_scale(1) { + gravity_scale(1), + linear_damp(-1), + angular_damp(-1), + can_sleep(true) { reset_physics_simulation_state(); } diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index bf7854b68d..0e719f5108 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -68,7 +68,7 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray<PhysicsBody3D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -562,6 +562,9 @@ private: real_t mass; real_t friction; real_t gravity_scale; + real_t linear_damp; + real_t angular_damp; + bool can_sleep; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -575,6 +578,7 @@ protected: private: static Skeleton3D *find_skeleton_parent(Node *p_parent); + void _update_joint_offset(); void _fix_joint_offset(); void _reload_joint(); @@ -599,6 +603,12 @@ public: void set_joint_offset(const Transform &p_offset); const Transform &get_joint_offset() const; + void set_joint_rotation(const Vector3 &p_euler_rad); + Vector3 get_joint_rotation() const; + + void set_joint_rotation_degrees(const Vector3 &p_euler_deg); + Vector3 get_joint_rotation_degrees() const; + void set_body_offset(const Transform &p_offset); const Transform &get_body_offset() const; @@ -624,6 +634,18 @@ public: void set_gravity_scale(real_t p_gravity_scale); real_t get_gravity_scale() const; + void set_linear_damp(real_t p_linear_damp); + real_t get_linear_damp() const; + + void set_angular_damp(real_t p_angular_damp); + real_t get_angular_damp() const; + + void set_can_sleep(bool p_active); + bool is_able_to_sleep() const; + + void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); + bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; + void apply_central_impulse(const Vector3 &p_impulse); void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse); diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp index 591c17a91e..140d887d9a 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -807,6 +807,9 @@ void Generic6DOFJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_LINEAR_DAMPING); BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTOR_TARGET_VELOCITY); BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTOR_FORCE_LIMIT); + BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_STIFFNESS); + BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_DAMPING); + BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); BIND_ENUM_CONSTANT(PARAM_ANGULAR_LOWER_LIMIT); BIND_ENUM_CONSTANT(PARAM_ANGULAR_UPPER_LIMIT); BIND_ENUM_CONSTANT(PARAM_ANGULAR_LIMIT_SOFTNESS); @@ -816,6 +819,9 @@ void Generic6DOFJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_ANGULAR_ERP); BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_STIFFNESS); + BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_DAMPING); + BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); BIND_ENUM_CONSTANT(PARAM_MAX); BIND_ENUM_CONSTANT(FLAG_ENABLE_LINEAR_LIMIT); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 59a6e23005..973822653a 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -33,6 +33,7 @@ #include "core/engine.h" #include "core/message_queue.h" #include "core/project_settings.h" +#include "core/type_info.h" #include "scene/3d/physics_body_3d.h" #include "scene/resources/surface_tool.h" @@ -770,7 +771,7 @@ void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vect } } -void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { +void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones) { set_physics_process_internal(false); Vector<int> sim_bones; @@ -780,12 +781,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { sim_bones.resize(p_bones.size()); int c = 0; for (int i = sim_bones.size() - 1; 0 <= i; --i) { - Variant::Type type = p_bones.get(i).get_type(); - if (Variant::STRING == type || Variant::STRING_NAME == type) { - int bone_id = find_bone(p_bones.get(i)); - if (bone_id != -1) - sim_bones.write[c++] = bone_id; - } + int bone_id = find_bone(p_bones[i]); + if (bone_id != -1) + sim_bones.write[c++] = bone_id; } sim_bones.resize(c); } diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 08b8691658..0bccd3f8fc 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -222,7 +222,7 @@ private: public: void physical_bones_stop_simulation(); - void physical_bones_start_simulation_on(const Array &p_bones); + void physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones); void physical_bones_add_collision_exception(RID p_exception); void physical_bones_remove_collision_exception(RID p_exception); #endif // _3D_DISABLED diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index 7366290ed3..10bdd71d73 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -287,14 +287,22 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove return; // Skip solving } - p_task->skeleton->clear_bones_global_pose_override(); + p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform(), 0.0, true); + + if (p_task->chain.middle_chain_item) { + p_task->skeleton->set_bone_global_pose_override(p_task->chain.middle_chain_item->bone, Transform(), 0.0, true); + } + + for (int i = 0; i < p_task->chain.tips.size(); i += 1) { + p_task->skeleton->set_bone_global_pose_override(p_task->chain.tips[i].chain_item->bone, Transform(), 0.0, true); + } make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse().scaled(p_task->skeleton->get_global_transform().get_basis().get_scale()), blending_delta); update_chain(p_task->skeleton, &p_task->chain.chain_root); if (p_use_magnet && p_task->chain.middle_chain_item) { - p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.linear_interpolate(p_magnet_position, blending_delta); + p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.lerp(p_magnet_position, blending_delta); solve_simple(p_task, true); } solve_simple(p_task, false); diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 281be3f7d3..0ffde7aa8f 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -45,15 +45,15 @@ void SpringArm3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: if (!Engine::get_singleton()->is_editor_hint()) { - set_process_internal(true); + set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: if (!Engine::get_singleton()->is_editor_hint()) { - set_process_internal(false); + set_physics_process_internal(false); } break; - case NOTIFICATION_INTERNAL_PROCESS: + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: process_spring(); break; } diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 775a9b76e2..604bc53422 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -217,6 +217,62 @@ float GeometryInstance3D::get_lod_max_hysteresis() const { void GeometryInstance3D::_notification(int p_what) { } +const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringName p_name) const { + StringName *r = instance_uniform_property_remap.getptr(p_name); + if (!r) { + String s = p_name; + if (s.begins_with("shader_params/")) { + StringName name = s.replace("shader_params/", ""); + instance_uniform_property_remap[p_name] = name; + return instance_uniform_property_remap.getptr(p_name); + } + + return nullptr; + } + + return r; +} + +bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) { + const StringName *r = _instance_uniform_get_remap(p_name); + if (r) { + set_shader_instance_uniform(*r, p_value); + return true; + } + + return false; +} + +bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { + const StringName *r = _instance_uniform_get_remap(p_name); + if (r) { + r_ret = get_shader_instance_uniform(*r); + return true; + } + + return false; +} +void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { + List<PropertyInfo> pinfo; + RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo); + for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + PropertyInfo pi = E->get(); + bool has_def_value = false; + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), pi.name); + if (def_value.get_type() != Variant::NIL) { + has_def_value = true; + } + if (instance_uniforms.has(pi.name)) { + pi.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE | (has_def_value ? (PROPERTY_USAGE_CHECKABLE | PROPERTY_USAGE_CHECKED) : 0); + } else { + pi.usage = PROPERTY_USAGE_EDITOR | (has_def_value ? PROPERTY_USAGE_CHECKABLE : 0); //do not save if not changed + } + + pi.name = "shader_params/" + pi.name; + p_list->push_back(pi); + } +} + void GeometryInstance3D::set_flag(Flags p_flag, bool p_value) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); @@ -258,6 +314,22 @@ float GeometryInstance3D::get_extra_cull_margin() const { return extra_cull_margin; } +void GeometryInstance3D::set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value) { + + if (p_value.get_type() == Variant::NIL) { + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_uniform); + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, def_value); + instance_uniforms.erase(p_value); + } else { + instance_uniforms[p_uniform] = p_value; + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, p_value); + } +} + +Variant GeometryInstance3D::get_shader_instance_uniform(const StringName &p_uniform) const { + + return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_uniform); +} void GeometryInstance3D::set_custom_aabb(AABB aabb) { RS::get_singleton()->instance_set_custom_aabb(get_instance(), aabb); @@ -280,6 +352,9 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lod_max_distance", "mode"), &GeometryInstance3D::set_lod_max_distance); ClassDB::bind_method(D_METHOD("get_lod_max_distance"), &GeometryInstance3D::get_lod_max_distance); + ClassDB::bind_method(D_METHOD("set_shader_instance_uniform", "uniform", "value"), &GeometryInstance3D::set_shader_instance_uniform); + ClassDB::bind_method(D_METHOD("get_shader_instance_uniform", "uniform"), &GeometryInstance3D::get_shader_instance_uniform); + ClassDB::bind_method(D_METHOD("set_lod_min_hysteresis", "mode"), &GeometryInstance3D::set_lod_min_hysteresis); ClassDB::bind_method(D_METHOD("get_lod_min_hysteresis"), &GeometryInstance3D::get_lod_min_hysteresis); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index 9476c28848..cc5f92066f 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -108,9 +108,18 @@ private: float lod_min_hysteresis; float lod_max_hysteresis; + mutable HashMap<StringName, Variant> instance_uniforms; + mutable HashMap<StringName, StringName> instance_uniform_property_remap; + float extra_cull_margin; + const StringName *_instance_uniform_get_remap(const StringName p_name) const; + protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + void _notification(int p_what); static void _bind_methods(); @@ -139,6 +148,9 @@ public: void set_extra_cull_margin(float p_margin); float get_extra_cull_margin() const; + void set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value); + Variant get_shader_instance_uniform(const StringName &p_uniform) const; + void set_custom_aabb(AABB aabb); GeometryInstance3D(); diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 203c3cd812..f30c58be55 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -592,22 +592,16 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; const Vector3 *vr = vertices.ptr(); Vector<Vector2> uv = a[Mesh::ARRAY_TEX_UV]; - const Vector2 *uvr; + const Vector2 *uvr = nullptr; Vector<Vector3> normals = a[Mesh::ARRAY_NORMAL]; - const Vector3 *nr; + const Vector3 *nr = nullptr; Vector<int> index = a[Mesh::ARRAY_INDEX]; - bool read_uv = false; - bool read_normals = false; - if (uv.size()) { - uvr = uv.ptr(); - read_uv = true; } if (normals.size()) { - read_normals = true; nr = normals.ptr(); } @@ -626,13 +620,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]); } - if (read_uv) { + if (uvr) { for (int k = 0; k < 3; k++) { uvs[k] = uvr[ir[j * 3 + k]]; } } - if (read_normals) { + if (nr) { for (int k = 0; k < 3; k++) { normal[k] = nr[ir[j * 3 + k]]; } @@ -659,13 +653,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec vtxs[k] = p_xform.xform(vr[j * 3 + k]); } - if (read_uv) { + if (uvr) { for (int k = 0; k < 3; k++) { uvs[k] = uvr[j * 3 + k]; } } - if (read_normals) { + if (nr) { for (int k = 0; k < 3; k++) { normal[k] = nr[j * 3 + k]; } diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index 0373114e7d..6f41629bac 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "xr_nodes.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "servers/xr/xr_interface.h" #include "servers/xr_server.h" @@ -206,7 +206,7 @@ void XRController3D::_notification(int p_what) { // check button states for (int i = 0; i < 16; i++) { bool was_pressed = (button_states & mask) == mask; - bool is_pressed = InputFilter::get_singleton()->is_joy_button_pressed(joy_id, i); + bool is_pressed = Input::get_singleton()->is_joy_button_pressed(joy_id, i); if (!was_pressed && is_pressed) { emit_signal("button_pressed", i); @@ -306,7 +306,7 @@ bool XRController3D::is_button_pressed(int p_button) const { return false; }; - return InputFilter::get_singleton()->is_joy_button_pressed(joy_id, p_button); + return Input::get_singleton()->is_joy_button_pressed(joy_id, p_button); }; float XRController3D::get_joystick_axis(int p_axis) const { @@ -315,7 +315,7 @@ float XRController3D::get_joystick_axis(int p_axis) const { return 0.0; }; - return InputFilter::get_singleton()->get_joy_axis(joy_id, p_axis); + return Input::get_singleton()->get_joy_axis(joy_id, p_axis); }; real_t XRController3D::get_rumble() const { diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index b657833a3b..9ef6b9864a 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -395,9 +395,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float } else { - nc->loc_accum = nc->loc_accum.linear_interpolate(loc, p_interp); + nc->loc_accum = nc->loc_accum.lerp(loc, p_interp); nc->rot_accum = nc->rot_accum.slerp(rot, p_interp); - nc->scale_accum = nc->scale_accum.linear_interpolate(scale, p_interp); + nc->scale_accum = nc->scale_accum.lerp(scale, p_interp); } } break; @@ -950,13 +950,13 @@ void AnimationPlayer::_animation_process(float p_delta) { play(queued.front()->get()); String new_name = playback.assigned; queued.pop_front(); - if (end_notify) + if (end_notify || playback.seeked) emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name); } else { //stop(); playing = false; _set_process(false); - if (end_notify) + if (end_notify || playback.seeked) emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned); } end_reached = false; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index f8b3ca291b..56e224819f 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -958,7 +958,7 @@ void AnimationTree::_process_graph(float p_delta) { if (err != OK) continue; - t->loc = t->loc.linear_interpolate(loc, blend); + t->loc = t->loc.lerp(loc, blend); if (t->rot_blend_accum == 0) { t->rot = rot; t->rot_blend_accum = blend; @@ -967,7 +967,7 @@ void AnimationTree::_process_graph(float p_delta) { t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized(); t->rot_blend_accum = rot_total; } - t->scale = t->scale.linear_interpolate(scale, blend); + t->scale = t->scale.lerp(scale, blend); } } break; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 5e0f4c91e8..63878a0b26 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -30,7 +30,7 @@ #include "color_picker.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "core/os/os.h" diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index 88107f754c..a6ed3d8de9 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -207,7 +207,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) { prev = points[pos]; } - newPoint.color = prev.color.linear_interpolate(next.color, (newPoint.offset - prev.offset) / (next.offset - prev.offset)); + newPoint.color = prev.color.lerp(next.color, (newPoint.offset - prev.offset) / (next.offset - prev.offset)); points.push_back(newPoint); points.sort(); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index e37e93e2a9..0bf67df9b4 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -30,7 +30,7 @@ #include "graph_edit.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "scene/gui/box_container.h" @@ -653,7 +653,7 @@ void GraphEdit::_bake_segment2d(Vector<Vector2> &points, Vector<Color> &colors, if (p_depth >= p_min_depth && (dp < p_tol || p_depth >= p_max_depth)) { points.push_back((beg + end) * 0.5); - colors.push_back(p_color.linear_interpolate(p_to_color, mp)); + colors.push_back(p_color.lerp(p_to_color, mp)); lines++; } else { _bake_segment2d(points, colors, p_begin, mp, p_a, p_out, p_b, p_in, p_depth + 1, p_min_depth, p_max_depth, p_tol, p_color, p_to_color, lines); @@ -737,8 +737,8 @@ void GraphEdit::_connections_layer_draw() { Color tocolor = gto->get_connection_input_color(E->get().to_port); if (E->get().activity > 0) { - color = color.linear_interpolate(activity_color, E->get().activity); - tocolor = tocolor.linear_interpolate(activity_color, E->get().activity); + color = color.lerp(activity_color, E->get().activity); + tocolor = tocolor.lerp(activity_color, E->get().activity); } _draw_cos_line(connections_layer, frompos, topos, color, tocolor); } @@ -804,7 +804,7 @@ void GraphEdit::set_selected(Node *p_child) { void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { Ref<InputEventMouseMotion> mm = p_ev; - if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)))) { + if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); } @@ -823,7 +823,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { // Snapping can be toggled temporarily by holding down Ctrl. // This is done here as to not toggle the grid when holding down Ctrl. - if (is_using_snap() ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (is_using_snap() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { const int snap = get_snap(); pos = pos.snapped(Vector2(snap, snap)); } @@ -852,7 +852,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { bool in_box = r.intersects(box_selecting_rect); if (in_box) - gn->set_selected(box_selection_mode_aditive); + gn->set_selected(box_selection_mode_additive); else gn->set_selected(previus_selected.find(gn) != nullptr); } @@ -886,7 +886,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { } if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && dragging) { - if (!just_selected && drag_accum == Vector2() && InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { //deselect current node for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); @@ -948,11 +948,19 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { drag_accum = Vector2(); drag_origin = get_local_mouse_position(); just_selected = !gn->is_selected(); - if (!gn->is_selected() && !InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); - if (o_gn) - o_gn->set_selected(o_gn == gn); + if (o_gn) { + if (o_gn == gn) { + o_gn->set_selected(true); + } else { + if (o_gn->is_selected()) { + emit_signal("node_unselected", o_gn); + } + o_gn->set_selected(false); + } + } } } @@ -968,13 +976,13 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { } else { if (_filter_input(b->get_position())) return; - if (InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)) + if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) return; box_selecting = true; box_selecting_from = get_local_mouse_position(); if (b->get_control()) { - box_selection_mode_aditive = true; + box_selection_mode_additive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { @@ -985,7 +993,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { previus_selected.push_back(gn2); } } else if (b->get_shift()) { - box_selection_mode_aditive = false; + box_selection_mode_additive = false; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { @@ -996,14 +1004,16 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { previus_selected.push_back(gn2); } } else { - box_selection_mode_aditive = true; + box_selection_mode_additive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2) continue; - + if (gn2->is_selected()) { + emit_signal("node_unselected", gn2); + } gn2->set_selected(false); } } @@ -1025,16 +1035,16 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { //too difficult to get right //set_zoom(zoom/ZOOM_SCALE); } - if (b->get_button_index() == BUTTON_WHEEL_UP && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (b->get_button_index() == BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8); } - if (b->get_button_index() == BUTTON_WHEEL_DOWN && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8); } - if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT))) { + if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8); } - if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT))) { + if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8); } } @@ -1311,6 +1321,7 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("copy_nodes_request")); ADD_SIGNAL(MethodInfo("paste_nodes_request")); ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); + ADD_SIGNAL(MethodInfo("node_unselected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); ADD_SIGNAL(MethodInfo("delete_nodes_request")); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 7f1d2699ba..f675f8c7f3 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -104,7 +104,7 @@ private: float zoom; bool box_selecting; - bool box_selection_mode_aditive; + bool box_selection_mode_additive; Point2 box_selecting_from; Point2 box_selecting_to; Rect2 box_selecting_rect; diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 30ecd651b1..a03d6d0cdc 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -340,8 +340,8 @@ void OptionButton::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items"); // "selected" property must come after "items", otherwise GH-10213 occurs. ADD_PROPERTY(PropertyInfo(Variant::INT, "selected"), "_select_int", "get_selected"); - ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "id"))); - ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "index"))); + ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "index"))); } OptionButton::OptionButton() { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 1e933c9aa1..a247863298 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -30,7 +30,7 @@ #include "popup_menu.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/print_string.h" @@ -594,7 +594,7 @@ void PopupMenu::_notification(int p_what) { } break; case NOTIFICATION_POST_POPUP: { - initial_button_mask = InputFilter::get_singleton()->get_mouse_button_mask(); + initial_button_mask = Input::get_singleton()->get_mouse_button_mask(); during_grabbed_click = (bool)initial_button_mask; } break; case NOTIFICATION_WM_SIZE_CHANGED: { diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 0b314d57c5..5c293cdf3c 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -407,7 +407,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & cw = tab_size * font->get_char_size(' ').width; } - if (end > 0 && w + cw + begin > p_width) { + if (end > 0 && fw + cw + begin > p_width) { break; //don't allow lines longer than assigned width } @@ -416,7 +416,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & end++; } CHECK_HEIGHT(fh); - ENSURE_WIDTH(w); + ENSURE_WIDTH(fw); line_ascent = MAX(line_ascent, ascent); line_descent = MAX(line_descent, descent); @@ -2093,6 +2093,8 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { } String tag = p_bbcode.substr(brk_pos + 1, brk_end - brk_pos - 1); + Vector<String> split_tag_block = tag.split(" ", false); + String bbcode = !split_tag_block.empty() ? split_tag_block[0] : ""; if (tag.begins_with("/") && tag_stack.size()) { bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length()); @@ -2325,15 +2327,14 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { pos = brk_end + 1; tag_stack.push_front("font"); - } else if (tag.begins_with("fade")) { - Vector<String> tags = tag.split(" ", false); + } else if (bbcode == "fade") { int startIndex = 0; int length = 10; - if (tags.size() > 1) { - tags.remove(0); - for (int i = 0; i < tags.size(); i++) { - String expr = tags[i]; + if (split_tag_block.size() > 1) { + split_tag_block.remove(0); + for (int i = 0; i < split_tag_block.size(); i++) { + String expr = split_tag_block[i]; if (expr.begins_with("start=")) { String start_str = expr.substr(6, expr.length()); startIndex = start_str.to_int(); @@ -2347,15 +2348,14 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { push_fade(startIndex, length); pos = brk_end + 1; tag_stack.push_front("fade"); - } else if (tag.begins_with("shake")) { - Vector<String> tags = tag.split(" ", false); + } else if (bbcode == "shake") { int strength = 5; float rate = 20.0f; - if (tags.size() > 1) { - tags.remove(0); - for (int i = 0; i < tags.size(); i++) { - String expr = tags[i]; + if (split_tag_block.size() > 1) { + split_tag_block.remove(0); + for (int i = 0; i < split_tag_block.size(); i++) { + String expr = split_tag_block[i]; if (expr.begins_with("level=")) { String str_str = expr.substr(6, expr.length()); strength = str_str.to_int(); @@ -2370,15 +2370,14 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { pos = brk_end + 1; tag_stack.push_front("shake"); set_process_internal(true); - } else if (tag.begins_with("wave")) { - Vector<String> tags = tag.split(" ", false); + } else if (bbcode == "wave") { float amplitude = 20.0f; float period = 5.0f; - if (tags.size() > 1) { - tags.remove(0); - for (int i = 0; i < tags.size(); i++) { - String expr = tags[i]; + if (split_tag_block.size() > 1) { + split_tag_block.remove(0); + for (int i = 0; i < split_tag_block.size(); i++) { + String expr = split_tag_block[i]; if (expr.begins_with("amp=")) { String amp_str = expr.substr(4, expr.length()); amplitude = amp_str.to_float(); @@ -2393,15 +2392,14 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { pos = brk_end + 1; tag_stack.push_front("wave"); set_process_internal(true); - } else if (tag.begins_with("tornado")) { - Vector<String> tags = tag.split(" ", false); + } else if (bbcode == "tornado") { float radius = 10.0f; float frequency = 1.0f; - if (tags.size() > 1) { - tags.remove(0); - for (int i = 0; i < tags.size(); i++) { - String expr = tags[i]; + if (split_tag_block.size() > 1) { + split_tag_block.remove(0); + for (int i = 0; i < split_tag_block.size(); i++) { + String expr = split_tag_block[i]; if (expr.begins_with("radius=")) { String amp_str = expr.substr(7, expr.length()); radius = amp_str.to_float(); @@ -2416,16 +2414,15 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { pos = brk_end + 1; tag_stack.push_front("tornado"); set_process_internal(true); - } else if (tag.begins_with("rainbow")) { - Vector<String> tags = tag.split(" ", false); + } else if (bbcode == "rainbow") { float saturation = 0.8f; float value = 0.8f; float frequency = 1.0f; - if (tags.size() > 1) { - tags.remove(0); - for (int i = 0; i < tags.size(); i++) { - String expr = tags[i]; + if (split_tag_block.size() > 1) { + split_tag_block.remove(0); + for (int i = 0; i < split_tag_block.size(); i++) { + String expr = split_tag_block[i]; if (expr.begins_with("sat=")) { String sat_str = expr.substr(4, expr.length()); saturation = sat_str.to_float(); @@ -2444,7 +2441,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { tag_stack.push_front("rainbow"); set_process_internal(true); } else { - Vector<String> expr = tag.split(" ", false); + Vector<String> &expr = split_tag_block; if (expr.size() < 1) { add_text("["); pos = brk_pos + 1; diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index e47e2b869d..1f135163d4 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -166,8 +166,9 @@ void Slider::_notification(int p_what) { RID ci = get_canvas_item(); Size2i size = get_size(); Ref<StyleBox> style = get_theme_stylebox("slider"); - Ref<StyleBox> grabber_area = get_theme_stylebox("grabber_area"); - Ref<Texture2D> grabber = get_theme_icon(editable ? ((mouse_inside || has_focus()) ? "grabber_highlight" : "grabber") : "grabber_disabled"); + bool highlighted = mouse_inside || has_focus(); + Ref<StyleBox> grabber_area = get_theme_stylebox(highlighted ? "grabber_area_highlight" : "grabber_area"); + Ref<Texture2D> grabber = get_theme_icon(editable ? (highlighted ? "grabber_highlight" : "grabber") : "grabber_disabled"); Ref<Texture2D> tick = get_theme_icon("tick"); double ratio = Math::is_nan(get_as_ratio()) ? 0 : get_as_ratio(); diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 8572d570fb..94628f7cea 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -30,7 +30,7 @@ #include "spin_box.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/math/expression.h" Size2 SpinBox::get_minimum_size() const { @@ -77,7 +77,7 @@ void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) { void SpinBox::_range_click_timeout() { - if (!drag.enabled && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { bool up = get_local_mouse_position().y < (get_size().height / 2); set_value(get_value() + (up ? get_step() : -get_step())); @@ -149,7 +149,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) { if (drag.enabled) { drag.enabled = false; - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); warp_mouse(drag.capture_pos); } drag.allowed = false; @@ -166,7 +166,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) { set_value(CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max())); } else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) { - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); drag.enabled = true; drag.base_val = get_value(); drag.diff_y = 0; diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index de80049862..3a128cf8e6 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -990,7 +990,7 @@ void TabContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_current_tab"), &TabContainer::get_current_tab); ClassDB::bind_method(D_METHOD("get_previous_tab"), &TabContainer::get_previous_tab); ClassDB::bind_method(D_METHOD("get_current_tab_control"), &TabContainer::get_current_tab_control); - ClassDB::bind_method(D_METHOD("get_tab_control", "idx"), &TabContainer::get_tab_control); + ClassDB::bind_method(D_METHOD("get_tab_control", "tab_idx"), &TabContainer::get_tab_control); ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &TabContainer::set_tab_align); ClassDB::bind_method(D_METHOD("get_tab_align"), &TabContainer::get_tab_align); ClassDB::bind_method(D_METHOD("set_tabs_visible", "visible"), &TabContainer::set_tabs_visible); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 36e35897d1..9ee7456d26 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -30,7 +30,7 @@ #include "text_edit.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/message_queue.h" #include "core/os/keyboard.h" #include "core/os/os.h" @@ -446,7 +446,7 @@ void TextEdit::_click_selection_held() { // Warning: is_mouse_button_pressed(BUTTON_LEFT) returns false for double+ clicks, so this doesn't work for MODE_WORD // and MODE_LINE. However, moving the mouse triggers _gui_input, which calls these functions too, so that's not a huge problem. // I'm unsure if there's an actual fix that doesn't have a ton of side effects. - if (InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) { + if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) { switch (selection.selecting_mode) { case Selection::MODE_POINTER: { _update_selection_mode_pointer(); @@ -1064,11 +1064,6 @@ void TextEdit::_notification(int p_what) { break; } - // re-adjust if we went backwards. - if (color != previous_color && !is_whitespace) { - characters++; - } - if (str[j] == '\t') { tabs += minimap_tab_size; } @@ -6220,6 +6215,10 @@ void TextEdit::_push_current_op() { current_op.type = TextOperation::TYPE_NONE; current_op.text = ""; current_op.chain_forward = false; + + if (undo_stack.size() > undo_stack_max_size) { + undo_stack.pop_front(); + } } void TextEdit::set_indent_using_spaces(const bool p_use_spaces) { @@ -7244,6 +7243,8 @@ void TextEdit::_bind_methods() { GLOBAL_DEF("gui/timers/text_edit_idle_detect_sec", 3); ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/text_edit_idle_detect_sec", PropertyInfo(Variant::FLOAT, "gui/timers/text_edit_idle_detect_sec", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); // No negative numbers. + GLOBAL_DEF("gui/common/text_edit_undo_stack_max_size", 1024); + ProjectSettings::get_singleton()->set_custom_property_info("gui/common/text_edit_undo_stack_max_size", PropertyInfo(Variant::INT, "gui/common/text_edit_undo_stack_max_size", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); // No negative numbers. } TextEdit::TextEdit() { @@ -7323,6 +7324,7 @@ TextEdit::TextEdit() { current_op.type = TextOperation::TYPE_NONE; undo_enabled = true; + undo_stack_max_size = GLOBAL_GET("gui/common/text_edit_undo_stack_max_size"); undo_stack_pos = nullptr; setting_text = false; last_dblclk = 0; diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index ef8c39d32f..ac8eb5da1d 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -306,6 +306,7 @@ private: List<TextOperation> undo_stack; List<TextOperation>::Element *undo_stack_pos; + int undo_stack_max_size; void _clear_redo(); void _do_text_op(const TextOperation &p_op, bool p_reverse); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index a7acaae8df..aad36ebf02 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -30,7 +30,7 @@ #include "tree.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/math/math_funcs.h" #include "core/os/keyboard.h" #include "core/os/os.h" @@ -1425,7 +1425,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (p_item->cells[i].custom_button) { if (cache.hover_item == p_item && cache.hover_cell == i) { - if (InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { draw_style_box(cache.custom_button_pressed, ir); } else { draw_style_box(cache.custom_button_hover, ir); @@ -1661,7 +1661,7 @@ Rect2 Tree::search_item_rect(TreeItem *p_from, TreeItem *p_item) { void Tree::_range_click_timeout() { - if (range_item_last && !range_drag_enabled && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + if (range_item_last && !range_drag_enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { Point2 pos = get_local_mouse_position() - cache.bg->get_offset(); if (show_column_titles) { @@ -2048,9 +2048,9 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool void Tree::_text_editor_modal_close() { - if (InputFilter::get_singleton()->is_key_pressed(KEY_ESCAPE) || - InputFilter::get_singleton()->is_key_pressed(KEY_KP_ENTER) || - InputFilter::get_singleton()->is_key_pressed(KEY_ENTER)) { + if (Input::get_singleton()->is_key_pressed(KEY_ESCAPE) || + Input::get_singleton()->is_key_pressed(KEY_KP_ENTER) || + Input::get_singleton()->is_key_pressed(KEY_ENTER)) { return; } @@ -2532,7 +2532,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { range_drag_enabled = true; range_drag_capture_pos = cpos; range_drag_base = popup_edited_item->get_range(popup_edited_item_col); - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); } } else { @@ -2594,7 +2594,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { if (range_drag_enabled) { range_drag_enabled = false; - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); warp_mouse(range_drag_capture_pos); } else { Rect2 rect = get_selected()->get_meta("__focus_rect"); @@ -3045,13 +3045,6 @@ void Tree::_notification(int p_what) { draw_item(Point2(), draw_ofs, draw_size, root); } - int ofs = 0; - - for (int i = 0; i < (columns.size() - 1 - 1); i++) { - - ofs += get_column_width(i); - } - if (show_column_titles) { //title buttons @@ -3245,7 +3238,7 @@ void Tree::clear() { if (pressing_for_editor) { if (range_drag_enabled) { range_drag_enabled = false; - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); warp_mouse(range_drag_capture_pos); } pressing_for_editor = false; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 2eacad68c3..b5d54b2199 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -30,7 +30,7 @@ #include "canvas_item.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/message_queue.h" #include "core/method_bind_ext.gen.inc" #include "scene/main/canvas_layer.h" diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 50f3bf834f..4c02a15531 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2693,9 +2693,9 @@ void Node::queue_delete() { } } -Array Node::_get_children() const { +TypedArray<Node> Node::_get_children() const { - Array arr; + TypedArray<Node> arr; int cc = get_child_count(); arr.resize(cc); for (int i = 0; i < cc; i++) diff --git a/scene/main/node.h b/scene/main/node.h index 5de07d506e..1c1b7bbd7a 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -37,6 +37,7 @@ #include "core/object.h" #include "core/project_settings.h" #include "core/script_language.h" +#include "core/typed_array.h" #include "scene/main/scene_tree.h" class Viewport; @@ -182,7 +183,7 @@ private: void _duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const; Node *_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap = nullptr) const; - Array _get_children() const; + TypedArray<Node> _get_children() const; Array _get_groups() const; Variant _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 41f31617d2..22cd1c98ab 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -31,7 +31,7 @@ #include "scene_tree.h" #include "core/debugger/engine_debugger.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/marshalls.h" #include "core/io/resource_loader.h" #include "core/message_queue.h" @@ -576,7 +576,7 @@ void SceneTree::_main_window_go_back() { } void SceneTree::_main_window_focus_in() { - InputFilter *id = InputFilter::get_singleton(); + Input *id = Input::get_singleton(); if (id) { id->ensure_touch_mouse_raised(); } @@ -1421,10 +1421,14 @@ SceneTree::SceneTree() { root->set_as_audio_listener_2d(true); current_scene = nullptr; - int msaa_mode = GLOBAL_DEF("rendering/quality/filters/msaa", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x")); + int msaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/msaa", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x")); root->set_msaa(Viewport::MSAA(msaa_mode)); + int ssaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/screen_space_aa", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_aa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA")); + root->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); + { //load default fallback environment //get possible extensions List<String> exts; diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp new file mode 100644 index 0000000000..13582cf655 --- /dev/null +++ b/scene/main/shader_globals_override.cpp @@ -0,0 +1,257 @@ +#include "shader_globals_override.h" + +#include "core/core_string_names.h" +#include "scene/main/window.h" +#include "scene/scene_string_names.h" + +StringName *ShaderGlobalsOverride::_remap(const StringName &p_name) const { + + StringName *r = param_remaps.getptr(p_name); + if (!r) { + //not cached, do caching + String p = p_name; + if (p.begins_with("params/")) { + String q = p.replace_first("params/", ""); + param_remaps[p] = q; + r = param_remaps.getptr(q); + } + } + + return r; +} +bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_value) { + + StringName *r = _remap(p_name); + + if (r) { + Override *o = overrides.getptr(*r); + if (!o) { + Override ov; + ov.in_use = false; + overrides[*r] = ov; + o = overrides.getptr(*r); + } + if (o) { + o->override = p_value; + if (active) { + RS::get_singleton()->global_variable_set_override(*r, p_value); + } + o->in_use = p_value.get_type() != Variant::NIL; + return true; + } + } + + return false; +} + +bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const { + + StringName *r = _remap(p_name); + + if (r) { + const Override *o = overrides.getptr(*r); + if (o) { + r_ret = o->override; + return true; + } + } + + return false; +} + +void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const { + + Vector<StringName> variables; + variables = RS::get_singleton()->global_variable_get_list(); + for (int i = 0; i < variables.size(); i++) { + PropertyInfo pinfo; + pinfo.name = "params/" + variables[i]; + pinfo.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; + + switch (RS::get_singleton()->global_variable_get_type(variables[i])) { + case RS::GLOBAL_VAR_TYPE_BOOL: { + pinfo.type = Variant::BOOL; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC2: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y"; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC3: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y,z"; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC4: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y,z,w"; + } break; + case RS::GLOBAL_VAR_TYPE_INT: { + pinfo.type = Variant::INT; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC2: { + pinfo.type = Variant::VECTOR2I; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC3: { + pinfo.type = Variant::VECTOR3I; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_RECT2I: { + pinfo.type = Variant::RECT2I; + } break; + case RS::GLOBAL_VAR_TYPE_UINT: { + pinfo.type = Variant::INT; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC2: { + pinfo.type = Variant::VECTOR2I; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC3: { + pinfo.type = Variant::VECTOR3I; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_FLOAT: { + pinfo.type = Variant::FLOAT; + } break; + case RS::GLOBAL_VAR_TYPE_VEC2: { + pinfo.type = Variant::VECTOR2; + } break; + case RS::GLOBAL_VAR_TYPE_VEC3: { + pinfo.type = Variant::VECTOR3; + } break; + case RS::GLOBAL_VAR_TYPE_VEC4: { + pinfo.type = Variant::PLANE; + } break; + case RS::GLOBAL_VAR_TYPE_RECT2: { + pinfo.type = Variant::RECT2; + } break; + case RS::GLOBAL_VAR_TYPE_COLOR: { + pinfo.type = Variant::COLOR; + } break; + case RS::GLOBAL_VAR_TYPE_MAT2: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_MAT3: { + pinfo.type = Variant::BASIS; + } break; + case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { + pinfo.type = Variant::TRANSFORM2D; + } break; + case RS::GLOBAL_VAR_TYPE_TRANSFORM: { + pinfo.type = Variant::TRANSFORM; + } break; + case RS::GLOBAL_VAR_TYPE_MAT4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture2D"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture2DArray"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER3D: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture3D"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Cubemap"; + } break; + default: { + + } break; + } + + if (!overrides.has(variables[i])) { + Override o; + o.in_use = false; + Callable::CallError ce; + o.override = Variant::construct(pinfo.type, NULL, 0, ce); + overrides[variables[i]] = o; + } + + Override *o = overrides.getptr(variables[i]); + if (o->in_use && o->override.get_type() != Variant::NIL) { + pinfo.usage |= PROPERTY_USAGE_CHECKED; + pinfo.usage |= PROPERTY_USAGE_STORAGE; + } + + p_list->push_back(pinfo); + } +} + +void ShaderGlobalsOverride::_activate() { + + List<Node *> nodes; + get_tree()->get_nodes_in_group(SceneStringNames::get_singleton()->shader_overrides_group_active, &nodes); + if (nodes.size() == 0) { + //good we are the only override, enable all + active = true; + add_to_group(SceneStringNames::get_singleton()->shader_overrides_group_active); + + const StringName *K = nullptr; + while ((K = overrides.next(K))) { + Override *o = overrides.getptr(*K); + if (o->in_use && o->override.get_type() != Variant::NIL) { + RS::get_singleton()->global_variable_set_override(*K, o->override); + } + } + + update_configuration_warning(); //may have activated + } +} + +void ShaderGlobalsOverride::_notification(int p_what) { + + if (p_what == Node3D::NOTIFICATION_ENTER_TREE) { + + add_to_group(SceneStringNames::get_singleton()->shader_overrides_group); + _activate(); + + } else if (p_what == Node3D::NOTIFICATION_EXIT_TREE) { + + if (active) { + //remove overrides + const StringName *K = nullptr; + while ((K = overrides.next(K))) { + Override *o = overrides.getptr(*K); + if (o->in_use) { + RS::get_singleton()->global_variable_set_override(*K, Variant()); + } + } + } + + remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group_active); + remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group); + get_tree()->call_group(SceneStringNames::get_singleton()->shader_overrides_group, "_activate"); //another may want to activate when this is removed + active = false; + } +} + +String ShaderGlobalsOverride::get_configuration_warning() const { + + if (!active) { + return TTR("ShaderGlobalsOverride is not active because another node of the same type is in the scene."); + } + + return String(); +} + +void ShaderGlobalsOverride::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_activate"), &ShaderGlobalsOverride::_activate); +} + +ShaderGlobalsOverride::ShaderGlobalsOverride() { + active = false; +} diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h new file mode 100644 index 0000000000..33d0dc948f --- /dev/null +++ b/scene/main/shader_globals_override.h @@ -0,0 +1,37 @@ +#ifndef SHADER_GLOBALS_OVERRIDE_H +#define SHADER_GLOBALS_OVERRIDE_H + +#include "scene/3d/node_3d.h" + +class ShaderGlobalsOverride : public Node { + + GDCLASS(ShaderGlobalsOverride, Node); + + struct Override { + bool in_use = false; + Variant override; + }; + + StringName *_remap(const StringName &p_name) const; + + bool active; + mutable HashMap<StringName, Override> overrides; + mutable HashMap<StringName, StringName> param_remaps; + + void _activate(); + +protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + + void _notification(int p_what); + static void _bind_methods(); + +public: + String get_configuration_warning() const; + + ShaderGlobalsOverride(); +}; + +#endif // SHADER_GLOBALS_OVERRIDE_H diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 1cfc3b0260..b0718eed79 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -32,7 +32,7 @@ #include "core/core_string_names.h" #include "core/debugger/engine_debugger.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" #include "core/project_settings.h" #include "scene/2d/collision_object_2d.h" @@ -582,7 +582,7 @@ void Viewport::_notification(int p_what) { RS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count); } - if (physics_object_picking && (to_screen_rect == Rect2i() || InputFilter::get_singleton()->get_mouse_mode() != InputFilter::MOUSE_MODE_CAPTURED)) { + if (physics_object_picking && (to_screen_rect == Rect2i() || Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED)) { #ifndef _3D_DISABLED Vector2 last_pos(1e20, 1e20); @@ -1517,7 +1517,7 @@ Vector2 Viewport::get_mouse_position() const { void Viewport::warp_mouse(const Vector2 &p_pos) { Vector2 gpos = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse().xform(p_pos); - InputFilter::get_singleton()->warp_mouse_position(gpos); + Input::get_singleton()->warp_mouse_position(gpos); } void Viewport::_gui_sort_roots() { @@ -2091,7 +2091,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gui.mouse_over = over; - DisplayServer::CursorShape ds_cursor_shape = (DisplayServer::CursorShape)InputFilter::get_singleton()->get_default_cursor_shape(); + DisplayServer::CursorShape ds_cursor_shape = (DisplayServer::CursorShape)Input::get_singleton()->get_default_cursor_shape(); if (over) { @@ -2411,7 +2411,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (from && p_event->is_pressed()) { Control *next = nullptr; - InputFilter *input = InputFilter::get_singleton(); + Input *input = Input::get_singleton(); if (p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) { @@ -3064,7 +3064,7 @@ void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coor if (physics_object_picking && !is_input_handled()) { - if (InputFilter::get_singleton()->get_mouse_mode() != InputFilter::MOUSE_MODE_CAPTURED && + if (Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED && (Object::cast_to<InputEventMouseButton>(*ev) || Object::cast_to<InputEventMouseMotion>(*ev) || Object::cast_to<InputEventScreenDrag>(*ev) || @@ -3173,7 +3173,7 @@ int Viewport::gui_get_canvas_sort_index() { void Viewport::set_msaa(MSAA p_msaa) { - ERR_FAIL_INDEX(p_msaa, 7); + ERR_FAIL_INDEX(p_msaa, MSAA_MAX); if (msaa == p_msaa) return; msaa = p_msaa; @@ -3185,6 +3185,19 @@ Viewport::MSAA Viewport::get_msaa() const { return msaa; } +void Viewport::set_screen_space_aa(ScreenSpaceAA p_screen_space_aa) { + + ERR_FAIL_INDEX(p_screen_space_aa, SCREEN_SPACE_AA_MAX); + if (screen_space_aa == p_screen_space_aa) + return; + screen_space_aa = p_screen_space_aa; + RS::get_singleton()->viewport_set_screen_space_aa(viewport, RS::ViewportScreenSpaceAA(p_screen_space_aa)); +} + +Viewport::ScreenSpaceAA Viewport::get_screen_space_aa() const { + + return screen_space_aa; +} void Viewport::set_debug_draw(DebugDraw p_debug_draw) { debug_draw = p_debug_draw; @@ -3371,6 +3384,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_msaa", "msaa"), &Viewport::set_msaa); ClassDB::bind_method(D_METHOD("get_msaa"), &Viewport::get_msaa); + ClassDB::bind_method(D_METHOD("set_screen_space_aa", "screen_space_aa"), &Viewport::set_screen_space_aa); + ClassDB::bind_method(D_METHOD("get_screen_space_aa"), &Viewport::get_screen_space_aa); + ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw); ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw); @@ -3444,6 +3460,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally"); ADD_GROUP("Rendering", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"), "set_screen_space_aa", "get_screen_space_aa"); ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw"); ADD_GROUP("Canvas Items", "canvas_item_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapLinear,MipmapNearest"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter"); @@ -3478,6 +3495,17 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024); BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX); + BIND_ENUM_CONSTANT(MSAA_DISABLED); + BIND_ENUM_CONSTANT(MSAA_2X); + BIND_ENUM_CONSTANT(MSAA_4X); + BIND_ENUM_CONSTANT(MSAA_8X); + BIND_ENUM_CONSTANT(MSAA_16X); + BIND_ENUM_CONSTANT(MSAA_MAX); + + BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_DISABLED); + BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_FXAA); + BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_MAX); + BIND_ENUM_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME); BIND_ENUM_CONSTANT(RENDER_INFO_VERTICES_IN_FRAME); BIND_ENUM_CONSTANT(RENDER_INFO_MATERIAL_CHANGES_IN_FRAME); @@ -3488,9 +3516,10 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLED); BIND_ENUM_CONSTANT(DEBUG_DRAW_UNSHADED); + BIND_ENUM_CONSTANT(DEBUG_DRAW_LIGHTING); BIND_ENUM_CONSTANT(DEBUG_DRAW_OVERDRAW); BIND_ENUM_CONSTANT(DEBUG_DRAW_WIREFRAME); - + BIND_ENUM_CONSTANT(DEBUG_DRAW_NORMAL_BUFFER); BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_ALBEDO); BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_LIGHTING); BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_EMISSION); @@ -3500,19 +3529,14 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEBUG_DRAW_SSAO); BIND_ENUM_CONSTANT(DEBUG_DRAW_ROUGHNESS_LIMITER); BIND_ENUM_CONSTANT(DEBUG_DRAW_PSSM_SPLITS); - - BIND_ENUM_CONSTANT(MSAA_DISABLED); - BIND_ENUM_CONSTANT(MSAA_2X); - BIND_ENUM_CONSTANT(MSAA_4X); - BIND_ENUM_CONSTANT(MSAA_8X); - BIND_ENUM_CONSTANT(MSAA_16X); + BIND_ENUM_CONSTANT(DEBUG_DRAW_DECAL_ATLAS); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS); - BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX); + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR); @@ -3586,7 +3610,7 @@ Viewport::Viewport() { gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED; msaa = MSAA_DISABLED; - + screen_space_aa = SCREEN_SPACE_AA_DISABLED; debug_draw = DEBUG_DRAW_DISABLED; snap_controls_to_pixels = true; @@ -3728,15 +3752,15 @@ void SubViewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode"); + BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS); + BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER); + BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME); + BIND_ENUM_CONSTANT(UPDATE_DISABLED); BIND_ENUM_CONSTANT(UPDATE_ONCE); BIND_ENUM_CONSTANT(UPDATE_WHEN_VISIBLE); BIND_ENUM_CONSTANT(UPDATE_WHEN_PARENT_VISIBLE); BIND_ENUM_CONSTANT(UPDATE_ALWAYS); - - BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS); - BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER); - BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME); } SubViewport::SubViewport() { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index ab3987d16d..7e2df9fe42 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -106,10 +106,16 @@ public: MSAA_4X, MSAA_8X, MSAA_16X, + MSAA_MAX }; - enum RenderInfo { + enum ScreenSpaceAA { + SCREEN_SPACE_AA_DISABLED, + SCREEN_SPACE_AA_FXAA, + SCREEN_SPACE_AA_MAX + }; + enum RenderInfo { RENDER_INFO_OBJECTS_IN_FRAME, RENDER_INFO_VERTICES_IN_FRAME, RENDER_INFO_MATERIAL_CHANGES_IN_FRAME, @@ -134,7 +140,8 @@ public: DEBUG_DRAW_SCENE_LUMINANCE, DEBUG_DRAW_SSAO, DEBUG_DRAW_ROUGHNESS_LIMITER, - DEBUG_DRAW_PSSM_SPLITS + DEBUG_DRAW_PSSM_SPLITS, + DEBUG_DRAW_DECAL_ATLAS }; enum DefaultCanvasItemTextureFilter { @@ -272,6 +279,7 @@ private: ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4]; MSAA msaa; + ScreenSpaceAA screen_space_aa; Ref<ViewportTexture> default_texture; Set<ViewportTexture *> viewport_textures; @@ -505,6 +513,9 @@ public: void set_msaa(MSAA p_msaa); MSAA get_msaa() const; + void set_screen_space_aa(ScreenSpaceAA p_screen_space_aa); + ScreenSpaceAA get_screen_space_aa() const; + Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const; Vector2 get_camera_rect_size() const; @@ -624,6 +635,7 @@ public: VARIANT_ENUM_CAST(SubViewport::UpdateMode); VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv); VARIANT_ENUM_CAST(Viewport::MSAA); +VARIANT_ENUM_CAST(Viewport::ScreenSpaceAA); VARIANT_ENUM_CAST(Viewport::DebugDraw); VARIANT_ENUM_CAST(SubViewport::ClearMode); VARIANT_ENUM_CAST(Viewport::RenderInfo); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 035d26b3e4..dc3ef5b508 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -177,6 +177,8 @@ #include "scene/3d/node_3d.h" #include "scene/3d/skeleton_3d.h" +#include "scene/main/shader_globals_override.h" + #ifndef _3D_DISABLED #include "scene/3d/area_3d.h" #include "scene/3d/audio_stream_player_3d.h" @@ -186,6 +188,7 @@ #include "scene/3d/collision_polygon_3d.h" #include "scene/3d/collision_shape_3d.h" #include "scene/3d/cpu_particles_3d.h" +#include "scene/3d/decal.h" #include "scene/3d/gi_probe.h" #include "scene/3d/gpu_particles_3d.h" #include "scene/3d/immediate_geometry_3d.h" @@ -402,6 +405,8 @@ void register_scene_types() { ClassDB::register_class<AnimationNodeTimeSeek>(); ClassDB::register_class<AnimationNodeTransition>(); + ClassDB::register_class<ShaderGlobalsOverride>(); //can be used in any shader + OS::get_singleton()->yield(); //may take time to init #ifndef _3D_DISABLED @@ -424,6 +429,7 @@ void register_scene_types() { ClassDB::register_class<OmniLight3D>(); ClassDB::register_class<SpotLight3D>(); ClassDB::register_class<ReflectionProbe>(); + ClassDB::register_class<Decal>(); ClassDB::register_class<GIProbe>(); ClassDB::register_class<GIProbeData>(); //ClassDB::register_class<BakedLightmap>(); @@ -751,8 +757,16 @@ void register_scene_types() { ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree"); // Renamed in 4.0. + // Keep alphabetical ordering to easily locate classes and avoid duplicates. ClassDB::add_compatibility_class("AnimatedSprite", "AnimatedSprite2D"); ClassDB::add_compatibility_class("Area", "Area3D"); + ClassDB::add_compatibility_class("ARVRCamera", "XRCamera3D"); + ClassDB::add_compatibility_class("ARVRController", "XRController3D"); + ClassDB::add_compatibility_class("ARVRAnchor", "XRAnchor3D"); + ClassDB::add_compatibility_class("ARVRInterface", "XRInterface"); + ClassDB::add_compatibility_class("ARVROrigin", "XROrigin3D"); + ClassDB::add_compatibility_class("ARVRPositionalTracker", "XRPositionalTracker"); + ClassDB::add_compatibility_class("ARVRServer", "XRServer"); ClassDB::add_compatibility_class("BoneAttachment", "BoneAttachment3D"); ClassDB::add_compatibility_class("BoxShape", "BoxShape3D"); ClassDB::add_compatibility_class("BulletPhysicsDirectBodyState", "BulletPhysicsDirectBodyState3D"); @@ -800,6 +814,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("Navigation2DServer", "NavigationServer2D"); ClassDB::add_compatibility_class("NavigationServer", "NavigationServer3D"); ClassDB::add_compatibility_class("OmniLight", "OmniLight3D"); + ClassDB::add_compatibility_class("PanoramaSky", "Sky"); ClassDB::add_compatibility_class("Particles", "GPUParticles3D"); ClassDB::add_compatibility_class("Particles2D", "GPUParticles2D"); ClassDB::add_compatibility_class("Path", "Path3D"); @@ -821,6 +836,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("PhysicsShapeQueryResult", "PhysicsShapeQueryResult3D"); ClassDB::add_compatibility_class("PinJoint", "PinJoint3D"); ClassDB::add_compatibility_class("PlaneShape", "WorldMarginShape3D"); + ClassDB::add_compatibility_class("ProceduralSky", "Sky"); ClassDB::add_compatibility_class("ProximityGroup", "ProximityGroup3D"); ClassDB::add_compatibility_class("RayCast", "RayCast3D"); ClassDB::add_compatibility_class("RayShape", "RayShape3D"); @@ -851,12 +867,6 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp"); ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); ClassDB::add_compatibility_class("World", "World3D"); - ClassDB::add_compatibility_class("ProceduralSky", "Sky"); - ClassDB::add_compatibility_class("PanoramaSky", "Sky"); - ClassDB::add_compatibility_class("ARVRCamera", "XRCamera3D"); - ClassDB::add_compatibility_class("ARVROrigin", "XROrigin3D"); - ClassDB::add_compatibility_class("ARVRController", "XRController3D"); - ClassDB::add_compatibility_class("ARVRAnchor", "XRAnchor3D"); #endif diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index aa4c9bf225..ea4338519e 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -1570,7 +1570,7 @@ Animation::TransformKey Animation::_interpolate(const Animation::TransformKey &p Vector3 Animation::_interpolate(const Vector3 &p_a, const Vector3 &p_b, float p_c) const { - return p_a.linear_interpolate(p_b, p_c); + return p_a.lerp(p_b, p_c); } Quat Animation::_interpolate(const Quat &p_a, const Quat &p_b, float p_c) const { @@ -2432,7 +2432,7 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const { Vector2 high_pos = _bezier_interp(high, start, start_out, end_in, end); float c = (t - low_pos.x) / (high_pos.x - low_pos.x); - return low_pos.linear_interpolate(high_pos, c).y; + return low_pos.lerp(high_pos, c).y; } int Animation::audio_track_insert_key(int p_track, float p_time, const RES &p_stream, float p_start_offset, float p_end_offset) { diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index d19eae0d4f..ae705a47e8 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -796,7 +796,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const { Vector2 post = (idx < (bpc - 2)) ? r[idx + 2] : r[idx + 1]; return r[idx].cubic_interpolate(r[idx + 1], pre, post, frac); } else { - return r[idx].linear_interpolate(r[idx + 1], frac); + return r[idx].lerp(r[idx + 1], frac); } } @@ -1354,7 +1354,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const { Vector3 post = (idx < (bpc - 2)) ? r[idx + 2] : r[idx + 1]; return r[idx].cubic_interpolate(r[idx + 1], pre, post, frac); } else { - return r[idx].linear_interpolate(r[idx + 1], frac); + return r[idx].lerp(r[idx + 1], frac); } } diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index e6f09eb034..a1e8bf51bd 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -497,6 +497,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("slider", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4)); theme->set_stylebox("grabber_area", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4)); + theme->set_stylebox("grabber_area_highlight", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4)); theme->set_icon("grabber", "HSlider", make_icon(hslider_grabber_png)); theme->set_icon("grabber_highlight", "HSlider", make_icon(hslider_grabber_hl_png)); @@ -507,6 +508,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("slider", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4)); theme->set_stylebox("grabber_area", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4)); + theme->set_stylebox("grabber_area_highlight", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4)); theme->set_icon("grabber", "VSlider", make_icon(vslider_grabber_png)); theme->set_icon("grabber_highlight", "VSlider", make_icon(vslider_grabber_hl_png)); diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index a613b01376..eea4d12d0e 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -1064,7 +1064,7 @@ void DynamicFont::update_oversampling() { ///////////////////////// -RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index 9e628fc35a..ef4b9dd9d0 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -302,7 +302,7 @@ VARIANT_ENUM_CAST(DynamicFont::SpacingType); class ResourceFormatLoaderDynamicFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 835fef81e1..02ea5b24b8 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1004,8 +1004,8 @@ void Environment::_bind_methods() { ADD_GROUP("SSAO", "ssao_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssao_radius", "get_ssao_radius"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity", "get_ssao_intensity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.01"), "set_ssao_radius", "get_ssao_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.01"), "set_ssao_intensity", "get_ssao_intensity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_bias", PROPERTY_HINT_RANGE, "0.001,8,0.001"), "set_ssao_bias", "get_ssao_bias"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_ao_channel_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_ao_channel_affect", "get_ssao_ao_channel_affect"); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 192eefbf6a..267816f267 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -646,7 +646,7 @@ BitmapFont::~BitmapFont() { //////////// -RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/font.h b/scene/resources/font.h index ce75f27e2a..c233344529 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -200,7 +200,7 @@ public: class ResourceFormatLoaderBMFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h index 2d98f799e2..573749ea7e 100644 --- a/scene/resources/gradient.h +++ b/scene/resources/gradient.h @@ -120,7 +120,7 @@ public: return points[0].color; const Point &pointFirst = points[first]; const Point &pointSecond = points[second]; - return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset)); + return pointFirst.color.lerp(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset)); } int get_points_count() const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 6bb5be15f3..401b689145 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1359,7 +1359,7 @@ void ArrayMesh::regen_normalmaps() { } //dirty hack -bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) = nullptr; +bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y, int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache); struct ArrayMeshLightmapSurface { @@ -1370,6 +1370,13 @@ struct ArrayMeshLightmapSurface { }; Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) { + int *cache_data = nullptr; + unsigned int cache_size = 0; + bool use_cache = false; // Don't use cache + return lightmap_unwrap_cached(cache_data, cache_size, use_cache, p_base_transform, p_texel_size); +} + +Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache, const Transform &p_base_transform, float p_texel_size) { 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."); @@ -1377,11 +1384,18 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe Vector<float> vertices; Vector<float> normals; Vector<int> indices; - Vector<int> face_materials; Vector<float> uv; - Vector<Pair<int, int>> uv_index; + Vector<Pair<int, int>> uv_indices; + + Vector<ArrayMeshLightmapSurface> lightmap_surfaces; + + // Keep only the scale + Transform transform = p_base_transform; + transform.origin = Vector3(); + transform.looking_at(Vector3(1, 0, 0), Vector3(0, 1, 0)); + + Basis normal_basis = transform.basis.inverse().transposed(); - Vector<ArrayMeshLightmapSurface> surfaces; for (int i = 0; i < get_surface_count(); i++) { ArrayMeshLightmapSurface s; s.primitive = surface_get_primitive_type(i); @@ -1405,12 +1419,12 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe vertices.resize((vertex_ofs + vc) * 3); normals.resize((vertex_ofs + vc) * 3); - uv_index.resize(vertex_ofs + vc); + uv_indices.resize(vertex_ofs + vc); for (int j = 0; j < vc; j++) { - Vector3 v = p_base_transform.xform(r[j]); - Vector3 n = p_base_transform.basis.xform(rn[j]).normalized(); + Vector3 v = transform.xform(r[j]); + Vector3 n = normal_basis.xform(rn[j]).normalized(); vertices.write[(j + vertex_ofs) * 3 + 0] = v.x; vertices.write[(j + vertex_ofs) * 3 + 1] = v.y; @@ -1418,7 +1432,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe normals.write[(j + vertex_ofs) * 3 + 0] = n.x; normals.write[(j + vertex_ofs) * 3 + 1] = n.y; normals.write[(j + vertex_ofs) * 3 + 2] = n.z; - uv_index.write[j + vertex_ofs] = Pair<int, int>(i, j); + uv_indices.write[j + vertex_ofs] = Pair<int, int>(i, j); } Vector<int> rindices = arrays[Mesh::ARRAY_INDEX]; @@ -1433,7 +1447,6 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe indices.push_back(vertex_ofs + j * 3 + 0); indices.push_back(vertex_ofs + j * 3 + 1); indices.push_back(vertex_ofs + j * 3 + 2); - face_materials.push_back(i); } } else { @@ -1445,11 +1458,10 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe indices.push_back(vertex_ofs + ri[j * 3 + 0]); indices.push_back(vertex_ofs + ri[j * 3 + 1]); indices.push_back(vertex_ofs + ri[j * 3 + 2]); - face_materials.push_back(i); } } - surfaces.push_back(s); + lightmap_surfaces.push_back(s); } //unwrap @@ -1462,7 +1474,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe int size_x; int size_y; - bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), face_materials.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y); + bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y, r_cache_data, r_cache_size, r_used_cache); if (!ok) { return ERR_CANT_CREATE; @@ -1474,11 +1486,11 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe //create surfacetools for each surface.. Vector<Ref<SurfaceTool>> surfaces_tools; - for (int i = 0; i < surfaces.size(); i++) { + for (int i = 0; i < lightmap_surfaces.size(); i++) { Ref<SurfaceTool> st; st.instance(); st->begin(Mesh::PRIMITIVE_TRIANGLES); - st->set_material(surfaces[i].material); + st->set_material(lightmap_surfaces[i].material); surfaces_tools.push_back(st); //stay there } @@ -1486,37 +1498,37 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe //go through all indices for (int i = 0; i < gen_index_count; i += 3) { - ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_index.size(), ERR_BUG); - ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_index.size(), ERR_BUG); - ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_index.size(), ERR_BUG); + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_indices.size(), ERR_BUG); + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_indices.size(), ERR_BUG); + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_indices.size(), ERR_BUG); - ERR_FAIL_COND_V(uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 1]]].first || uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG); + ERR_FAIL_COND_V(uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 1]]].first || uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG); - int surface = uv_index[gen_vertices[gen_indices[i + 0]]].first; + int surface = uv_indices[gen_vertices[gen_indices[i + 0]]].first; for (int j = 0; j < 3; j++) { - SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second]; + SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second]; - if (surfaces[surface].format & ARRAY_FORMAT_COLOR) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) { surfaces_tools.write[surface]->add_color(v.color); } - if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) { surfaces_tools.write[surface]->add_uv(v.uv); } - if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) { surfaces_tools.write[surface]->add_normal(v.normal); } - if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) { Plane t; t.normal = v.tangent; t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1; surfaces_tools.write[surface]->add_tangent(t); } - if (surfaces[surface].format & ARRAY_FORMAT_BONES) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) { surfaces_tools.write[surface]->add_bones(v.bones); } - if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) { surfaces_tools.write[surface]->add_weights(v.weights); } @@ -1527,20 +1539,22 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe } } - //free stuff - ::free(gen_vertices); - ::free(gen_indices); - ::free(gen_uvs); - //generate surfaces for (int i = 0; i < surfaces_tools.size(); i++) { surfaces_tools.write[i]->index(); - surfaces_tools.write[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format); + surfaces_tools.write[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), lightmap_surfaces[i].format); } set_lightmap_size_hint(Size2(size_x, size_y)); + if (!r_used_cache) { + //free stuff + ::free(gen_vertices); + ::free(gen_indices); + ::free(gen_uvs); + } + return OK; } diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 25a9722046..a65cf0a928 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -238,6 +238,7 @@ public: void regen_normalmaps(); Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05); + Error lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache, const Transform &p_base_transform = Transform(), float p_texel_size = 0.05); virtual void reload_from_file(); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 5068bb548f..41146036f6 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -120,18 +120,23 @@ Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, R int index = token.value; - String path = local_path + "::" + itos(index); + if (use_nocache) { + r_res = int_resources[index]; + } else { - if (!ignore_resource_parsing) { + String path = local_path + "::" + itos(index); - if (!ResourceCache::has(path)) { - r_err_str = "Can't load cached sub-resource: " + path; - return ERR_PARSE_ERROR; - } + if (!ignore_resource_parsing) { - r_res = RES(ResourceCache::get(path)); - } else { - r_res = RES(); + if (!ResourceCache::has(path)) { + r_err_str = "Can't load cached sub-resource: " + path; + return ERR_PARSE_ERROR; + } + + r_res = RES(ResourceCache::get(path)); + } else { + r_res = RES(); + } } VariantParser::get_token(p_stream, token, line, r_err_str); @@ -535,7 +540,7 @@ Error ResourceLoaderText::load() { Ref<Resource> res; - if (!ResourceCache::has(path)) { //only if it doesn't exist + if (use_nocache || !ResourceCache::has(path)) { //only if it doesn't exist Object *obj = ClassDB::instance(type); if (!obj) { @@ -556,8 +561,10 @@ Error ResourceLoaderText::load() { } res = Ref<Resource>(r); - resource_cache.push_back(res); - res->set_path(path); + int_resources[id] = res; + if (!use_nocache) { + res->set_path(path); + } } resource_current++; @@ -643,10 +650,12 @@ Error ResourceLoaderText::load() { _printerr(); } else { error = OK; - if (!ResourceCache::has(res_path)) { - resource->set_path(res_path); + if (!use_nocache) { + if (!ResourceCache::has(res_path)) { + resource->set_path(res_path); + } + resource->set_as_translation_remapped(translation_remapped); } - resource->set_as_translation_remapped(translation_remapped); } return error; } @@ -691,7 +700,7 @@ Error ResourceLoaderText::load() { error = OK; //get it here resource = packed_scene; - if (!ResourceCache::has(res_path)) { + if (!use_nocache && !ResourceCache::has(res_path)) { packed_scene->set_path(res_path); } @@ -725,6 +734,9 @@ void ResourceLoaderText::set_translation_remapped(bool p_remapped) { } ResourceLoaderText::ResourceLoaderText() { + + use_nocache = false; + resources_total = 0; resource_current = 0; use_sub_threads = false; @@ -1285,7 +1297,7 @@ String ResourceLoaderText::recognize(FileAccess *p_f) { ///////////////////// -RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; @@ -1298,6 +1310,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina ResourceLoaderText loader; String path = p_original_path != "" ? p_original_path : p_path; + loader.use_nocache = p_no_cache; loader.use_sub_threads = p_use_sub_threads; loader.local_path = ProjectSettings::get_singleton()->localize_path(path); loader.progress = r_progress; diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index fbbd2e3346..b9a6db5f36 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -62,6 +62,7 @@ class ResourceLoaderText { //Map<String,String> remaps; Map<int, ExtResource> ext_resources; + Map<int, RES> int_resources; int resources_total; int resource_current; @@ -69,6 +70,8 @@ class ResourceLoaderText { VariantParser::Tag next_tag; + bool use_nocache; + bool use_sub_threads; float *progress; @@ -106,7 +109,6 @@ class ResourceLoaderText { friend class ResourceFormatLoaderText; - List<RES> resource_cache; Error error; RES resource; @@ -134,7 +136,7 @@ public: class ResourceFormatLoaderText : public ResourceFormatLoader { public: static ResourceFormatLoaderText *singleton; - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index a62e7ded16..1ac2f7c3c9 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -176,7 +176,7 @@ Shader::~Shader() { } //////////// -RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/shader.h b/scene/resources/shader.h index cf0cec362c..75c38bd561 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -102,7 +102,7 @@ VARIANT_ENUM_CAST(Shader::Mode); class ResourceFormatLoaderShader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index 37b88cccea..a0b6ab1e30 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -111,16 +111,6 @@ float ProceduralSkyMaterial::get_ground_energy() const { return ground_energy; } -void ProceduralSkyMaterial::set_sun_angle_min(float p_angle) { - - sun_angle_min = p_angle; - RS::get_singleton()->material_set_param(_get_material(), "sun_angle_min", Math::deg2rad(sun_angle_min)); -} -float ProceduralSkyMaterial::get_sun_angle_min() const { - - return sun_angle_min; -} - void ProceduralSkyMaterial::set_sun_angle_max(float p_angle) { sun_angle_max = p_angle; @@ -181,9 +171,6 @@ void ProceduralSkyMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSkyMaterial::set_ground_energy); ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSkyMaterial::get_ground_energy); - ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSkyMaterial::set_sun_angle_min); - ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSkyMaterial::get_sun_angle_min); - ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSkyMaterial::set_sun_angle_max); ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSkyMaterial::get_sun_angle_max); @@ -203,7 +190,6 @@ void ProceduralSkyMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy"); ADD_GROUP("Sun", "sun_"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve"); } @@ -220,8 +206,7 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() { code += "uniform vec4 ground_horizon_color : hint_color = vec4(0.37, 0.33, 0.31, 1.0);\n"; code += "uniform float ground_curve : hint_range(0, 1) = 0.02;\n"; code += "uniform float ground_energy = 1.0;\n\n"; - code += "uniform float sun_angle_min = 0.01;\n"; - code += "uniform float sun_angle_max = 1.0;\n"; + code += "uniform float sun_angle_max = 1.74;\n"; code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n"; code += "const float PI = 3.1415926535897932384626433833;\n\n"; code += "void fragment() {\n"; @@ -231,37 +216,37 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() { code += "\tsky *= sky_energy;\n"; code += "\tif (LIGHT0_ENABLED) {\n"; code += "\t\tfloat sun_angle = acos(dot(LIGHT0_DIRECTION, EYEDIR));\n"; - code += "\t\tif (sun_angle < sun_angle_min) {\n"; + code += "\t\tif (sun_angle < LIGHT0_SIZE) {\n"; code += "\t\t\tsky = LIGHT0_COLOR * LIGHT0_ENERGY;\n"; code += "\t\t} else if (sun_angle < sun_angle_max) {\n"; - code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n"; + code += "\t\t\tfloat c2 = (sun_angle - LIGHT0_SIZE) / (sun_angle_max - LIGHT0_SIZE);\n"; code += "\t\t\tsky = mix(LIGHT0_COLOR * LIGHT0_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n"; code += "\t\t}\n"; code += "\t}\n"; code += "\tif (LIGHT1_ENABLED) {\n"; code += "\t\tfloat sun_angle = acos(dot(LIGHT1_DIRECTION, EYEDIR));\n"; - code += "\t\tif (sun_angle < sun_angle_min) {\n"; + code += "\t\tif (sun_angle < LIGHT1_SIZE) {\n"; code += "\t\t\tsky = LIGHT1_COLOR * LIGHT1_ENERGY;\n"; code += "\t\t} else if (sun_angle < sun_angle_max) {\n"; - code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n"; + code += "\t\t\tfloat c2 = (sun_angle - LIGHT1_SIZE) / (sun_angle_max - LIGHT1_SIZE);\n"; code += "\t\t\tsky = mix(LIGHT1_COLOR * LIGHT1_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n"; code += "\t\t}\n"; code += "\t}\n"; code += "\tif (LIGHT2_ENABLED) {\n"; code += "\t\tfloat sun_angle = acos(dot(LIGHT2_DIRECTION, EYEDIR));\n"; - code += "\t\tif (sun_angle < sun_angle_min) {\n"; + code += "\t\tif (sun_angle < LIGHT2_SIZE) {\n"; code += "\t\t\tsky = LIGHT2_COLOR * LIGHT2_ENERGY;\n"; code += "\t\t} else if (sun_angle < sun_angle_max) {\n"; - code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n"; + code += "\t\t\tfloat c2 = (sun_angle - LIGHT2_SIZE) / (sun_angle_max - LIGHT2_SIZE);\n"; code += "\t\t\tsky = mix(LIGHT2_COLOR * LIGHT2_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n"; code += "\t\t}\n"; code += "\t}\n"; code += "\tif (LIGHT3_ENABLED) {\n"; code += "\t\tfloat sun_angle = acos(dot(LIGHT3_DIRECTION, EYEDIR));\n"; - code += "\t\tif (sun_angle < sun_angle_min) {\n"; + code += "\t\tif (sun_angle < LIGHT3_SIZE) {\n"; code += "\t\t\tsky = LIGHT3_COLOR * LIGHT3_ENERGY;\n"; code += "\t\t} else if (sun_angle < sun_angle_max) {\n"; - code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n"; + code += "\t\t\tfloat c2 = (sun_angle - LIGHT3_SIZE) / (sun_angle_max - LIGHT3_SIZE);\n"; code += "\t\t\tsky = mix(LIGHT3_COLOR * LIGHT3_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n"; code += "\t\t}\n"; code += "\t}\n"; @@ -287,7 +272,6 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() { set_ground_curve(0.02); set_ground_energy(1.0); - set_sun_angle_min(1.0); set_sun_angle_max(100.0); set_sun_curve(0.05); } @@ -535,7 +519,6 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n"; code += "// Sun constants\n"; - code += "const float SOL_SIZE = 0.00872663806;\n"; code += "const float SUN_ENERGY = 1000.0;\n\n"; code += "// optical length at zenith for molecules\n"; @@ -591,8 +574,8 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { code += "\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n"; code += "\t// Solar disk and out-scattering\n"; - code += "\tfloat sunAngularDiameterCos = cos(SOL_SIZE * sun_disk_scale);\n"; - code += "\tfloat sunAngularDiameterCos2 = cos(SOL_SIZE * sun_disk_scale*0.5);\n"; + code += "\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n"; + code += "\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n"; code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n"; code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n"; code += "\t// Note: Add nightime here: L0 += night_sky * extinction\n\n"; diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index 515706b0c5..9bd9d7ec8b 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -49,7 +49,6 @@ private: float ground_curve; float ground_energy; - float sun_angle_min; float sun_angle_max; float sun_curve; @@ -84,9 +83,6 @@ public: void set_ground_energy(float p_energy); float get_ground_energy() const; - void set_sun_angle_min(float p_angle); - float get_sun_angle_min() const; - void set_sun_angle_max(float p_angle); float get_sun_angle_max() const; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 749dff24f2..d57af29599 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -796,7 +796,7 @@ StreamTexture::~StreamTexture() { } } -RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { Ref<StreamTexture> st; st.instance(); @@ -1692,15 +1692,20 @@ void AnimatedTexture::_update_proxy() { } int iter_max = frame_count; - while (iter_max) { + while (iter_max && !pause) { float frame_limit = limit + frames[current_frame].delay_sec; if (time > frame_limit) { current_frame++; if (current_frame >= frame_count) { - current_frame = 0; + if (oneshot) { + current_frame = frame_count - 1; + } else { + current_frame = 0; + } } time -= frame_limit; + _change_notify("current_frame"); } else { break; } @@ -1723,6 +1728,33 @@ int AnimatedTexture::get_frames() const { return frame_count; } +void AnimatedTexture::set_current_frame(int p_frame) { + ERR_FAIL_COND(p_frame < 0 || p_frame >= frame_count); + + RWLockWrite r(rw_lock); + + current_frame = p_frame; +} +int AnimatedTexture::get_current_frame() const { + return current_frame; +} + +void AnimatedTexture::set_pause(bool p_pause) { + RWLockWrite r(rw_lock); + pause = p_pause; +} +bool AnimatedTexture::get_pause() const { + return pause; +} + +void AnimatedTexture::set_oneshot(bool p_oneshot) { + RWLockWrite r(rw_lock); + oneshot = p_oneshot; +} +bool AnimatedTexture::get_oneshot() const { + return oneshot; +} + void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture) { ERR_FAIL_COND(p_texture == this); @@ -1833,6 +1865,15 @@ void AnimatedTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_frames", "frames"), &AnimatedTexture::set_frames); ClassDB::bind_method(D_METHOD("get_frames"), &AnimatedTexture::get_frames); + ClassDB::bind_method(D_METHOD("set_current_frame", "frame"), &AnimatedTexture::set_current_frame); + ClassDB::bind_method(D_METHOD("get_current_frame"), &AnimatedTexture::get_current_frame); + + ClassDB::bind_method(D_METHOD("set_pause", "pause"), &AnimatedTexture::set_pause); + ClassDB::bind_method(D_METHOD("get_pause"), &AnimatedTexture::get_pause); + + ClassDB::bind_method(D_METHOD("set_oneshot", "oneshot"), &AnimatedTexture::set_oneshot); + ClassDB::bind_method(D_METHOD("get_oneshot"), &AnimatedTexture::get_oneshot); + ClassDB::bind_method(D_METHOD("set_fps", "fps"), &AnimatedTexture::set_fps); ClassDB::bind_method(D_METHOD("get_fps"), &AnimatedTexture::get_fps); @@ -1843,6 +1884,9 @@ void AnimatedTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("get_frame_delay", "frame"), &AnimatedTexture::get_frame_delay); ADD_PROPERTY(PropertyInfo(Variant::INT, "frames", PROPERTY_HINT_RANGE, "1," + itos(MAX_FRAMES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_frames", "get_frames"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "current_frame", PROPERTY_HINT_NONE, "", 0), "set_current_frame", "get_current_frame"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pause"), "set_pause", "get_pause"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "oneshot"), "set_oneshot", "get_oneshot"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps"); for (int i = 0; i < MAX_FRAMES; i++) { @@ -1864,6 +1908,8 @@ AnimatedTexture::AnimatedTexture() { fps = 4; prev_ticks = 0; current_frame = 0; + pause = false; + oneshot = false; RenderingServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy)); #ifndef NO_THREADS @@ -2024,7 +2070,7 @@ TextureLayered::~TextureLayered() { } } -RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) { *r_error = ERR_CANT_OPEN; diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 18f70baa07..5d5f438eba 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -213,7 +213,7 @@ public: class ResourceFormatLoaderStreamTexture : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -421,7 +421,7 @@ public: COMPRESSION_UNCOMPRESSED }; - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -567,7 +567,8 @@ private: Frame frames[MAX_FRAMES]; int frame_count; int current_frame; - + bool pause; + bool oneshot; float fps; float time; @@ -584,6 +585,15 @@ public: void set_frames(int p_frames); int get_frames() const; + void set_current_frame(int p_frame); + int get_current_frame() const; + + void set_pause(bool p_pause); + bool get_pause() const; + + void set_oneshot(bool p_oneshot); + bool get_oneshot() const; + void set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture); Ref<Texture2D> get_frame_texture(int p_frame) const; diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 742ef106d9..f2f67d3814 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -314,7 +314,7 @@ struct SpatialIndexer2D { pass = 0; changed = false; - cell_size = 100; //should be configurable with GLOBAL_DEF("") i guess + cell_size = GLOBAL_DEF("world/2d/cell_size", 100); } }; diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index ad996e7d50..5e3f8b803b 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -202,4 +202,7 @@ SceneStringNames::SceneStringNames() { parameters_base_path = "parameters/"; tracks_changed = "tracks_changed"; + + shader_overrides_group = StaticCString::create("_shader_overrides_group_"); + shader_overrides_group_active = StaticCString::create("_shader_overrides_group_active_"); } diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 58e8c28454..c5de10a6f6 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -207,6 +207,8 @@ public: StringName window_input; StringName theme_changed; + StringName shader_overrides_group; + StringName shader_overrides_group_active; enum { MAX_MATERIALS = 32 |