summaryrefslogtreecommitdiffstats
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp2
-rw-r--r--scene/resources/2d/tile_set.cpp54
-rw-r--r--scene/resources/3d/world_3d.cpp1
-rw-r--r--scene/resources/animation.cpp1
-rw-r--r--scene/resources/animation_library.cpp4
-rw-r--r--scene/resources/atlas_texture.cpp2
-rw-r--r--scene/resources/audio_stream_wav.cpp5
-rw-r--r--scene/resources/canvas_item_material.cpp26
-rw-r--r--scene/resources/canvas_item_material.h3
-rw-r--r--scene/resources/curve_texture.cpp2
-rw-r--r--scene/resources/gradient_texture.cpp1
-rw-r--r--scene/resources/material.cpp35
-rw-r--r--scene/resources/material.h4
-rw-r--r--scene/resources/mesh.cpp2
-rw-r--r--scene/resources/packed_scene.cpp12
-rw-r--r--scene/resources/particle_process_material.cpp27
-rw-r--r--scene/resources/particle_process_material.h3
-rw-r--r--scene/resources/shader.cpp1
-rw-r--r--scene/resources/sprite_frames.cpp2
-rw-r--r--scene/resources/syntax_highlighter.cpp6
-rw-r--r--scene/resources/syntax_highlighter.h4
-rw-r--r--scene/resources/visual_shader.cpp152
-rw-r--r--scene/resources/visual_shader.h4
-rw-r--r--scene/resources/visual_shader_nodes.cpp79
-rw-r--r--scene/resources/visual_shader_nodes.h31
-rw-r--r--scene/resources/visual_shader_particle_nodes.cpp6
26 files changed, 328 insertions, 141 deletions
diff --git a/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp b/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp
index aa8d7d0b3b..001000fa17 100644
--- a/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp
+++ b/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp
@@ -194,7 +194,7 @@ void SkeletonModification2DPhysicalBones::fetch_physical_bones() {
node_queue.push_back(stack->skeleton);
while (node_queue.size() > 0) {
- Node *node_to_process = node_queue[0];
+ Node *node_to_process = node_queue.front()->get();
node_queue.pop_front();
if (node_to_process != nullptr) {
diff --git a/scene/resources/2d/tile_set.cpp b/scene/resources/2d/tile_set.cpp
index 6649cb9b82..0f73577768 100644
--- a/scene/resources/2d/tile_set.cpp
+++ b/scene/resources/2d/tile_set.cpp
@@ -74,7 +74,7 @@ void TileMapPattern::_set_tile_data(const Vector<int> &p_data) {
uint16_t alternative_tile = decode_uint16(&local[10]);
set_cell(Vector2i(x, y), source_id, Vector2i(atlas_coords_x, atlas_coords_y), alternative_tile);
}
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Vector<int> TileMapPattern::_get_tile_data() const {
@@ -4969,7 +4969,7 @@ void TileSetAtlasSource::create_tile(const Vector2i p_atlas_coords, const Vector
tad.alternatives[0] = memnew(TileData);
tad.alternatives[0]->set_tile_set(tile_set);
tad.alternatives[0]->set_allow_transform(false);
- tad.alternatives[0]->connect("changed", callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed));
+ tad.alternatives[0]->connect(CoreStringName(changed), callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed));
tad.alternatives[0]->notify_property_list_changed();
tad.alternatives_ids.push_back(0);
@@ -5353,7 +5353,7 @@ int TileSetAtlasSource::create_alternative_tile(const Vector2i p_atlas_coords, i
tiles[p_atlas_coords].alternatives[new_alternative_id] = memnew(TileData);
tiles[p_atlas_coords].alternatives[new_alternative_id]->set_tile_set(tile_set);
tiles[p_atlas_coords].alternatives[new_alternative_id]->set_allow_transform(true);
- tiles[p_atlas_coords].alternatives[new_alternative_id]->connect("changed", callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed));
+ tiles[p_atlas_coords].alternatives[new_alternative_id]->connect(CoreStringName(changed), callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed));
tiles[p_atlas_coords].alternatives[new_alternative_id]->notify_property_list_changed();
tiles[p_atlas_coords].alternatives_ids.push_back(new_alternative_id);
tiles[p_atlas_coords].alternatives_ids.sort();
@@ -5938,7 +5938,7 @@ void TileData::notify_tile_data_properties_should_change() {
}
notify_property_list_changed();
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
void TileData::add_occlusion_layer(int p_to_pos) {
@@ -6139,7 +6139,7 @@ TileData *TileData::duplicate() {
void TileData::set_flip_h(bool p_flip_h) {
ERR_FAIL_COND_MSG(!allow_transform && p_flip_h, "Transform is only allowed for alternative tiles (with its alternative_id != 0)");
flip_h = p_flip_h;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
bool TileData::get_flip_h() const {
return flip_h;
@@ -6148,7 +6148,7 @@ bool TileData::get_flip_h() const {
void TileData::set_flip_v(bool p_flip_v) {
ERR_FAIL_COND_MSG(!allow_transform && p_flip_v, "Transform is only allowed for alternative tiles (with its alternative_id != 0)");
flip_v = p_flip_v;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
bool TileData::get_flip_v() const {
@@ -6158,7 +6158,7 @@ bool TileData::get_flip_v() const {
void TileData::set_transpose(bool p_transpose) {
ERR_FAIL_COND_MSG(!allow_transform && p_transpose, "Transform is only allowed for alternative tiles (with its alternative_id != 0)");
transpose = p_transpose;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
bool TileData::get_transpose() const {
return transpose;
@@ -6166,7 +6166,7 @@ bool TileData::get_transpose() const {
void TileData::set_texture_origin(Vector2i p_texture_origin) {
texture_origin = p_texture_origin;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Vector2i TileData::get_texture_origin() const {
@@ -6175,7 +6175,7 @@ Vector2i TileData::get_texture_origin() const {
void TileData::set_material(Ref<Material> p_material) {
material = p_material;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Ref<Material> TileData::get_material() const {
return material;
@@ -6183,7 +6183,7 @@ Ref<Material> TileData::get_material() const {
void TileData::set_modulate(Color p_modulate) {
modulate = p_modulate;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Color TileData::get_modulate() const {
return modulate;
@@ -6191,7 +6191,7 @@ Color TileData::get_modulate() const {
void TileData::set_z_index(int p_z_index) {
z_index = p_z_index;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_z_index() const {
return z_index;
@@ -6199,7 +6199,7 @@ int TileData::get_z_index() const {
void TileData::set_y_sort_origin(int p_y_sort_origin) {
y_sort_origin = p_y_sort_origin;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_y_sort_origin() const {
return y_sort_origin;
@@ -6209,7 +6209,7 @@ void TileData::set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_po
ERR_FAIL_INDEX(p_layer_id, occluders.size());
occluders.write[p_layer_id].occluder = p_occluder_polygon;
occluders.write[p_layer_id].transformed_occluders.clear();
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id, bool p_flip_h, bool p_flip_v, bool p_transpose) const {
@@ -6242,7 +6242,7 @@ Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id, bool p_flip_h, boo
void TileData::set_constant_linear_velocity(int p_layer_id, const Vector2 &p_velocity) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
physics.write[p_layer_id].linear_velocity = p_velocity;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Vector2 TileData::get_constant_linear_velocity(int p_layer_id) const {
@@ -6253,7 +6253,7 @@ Vector2 TileData::get_constant_linear_velocity(int p_layer_id) const {
void TileData::set_constant_angular_velocity(int p_layer_id, real_t p_velocity) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
physics.write[p_layer_id].angular_velocity = p_velocity;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
real_t TileData::get_constant_angular_velocity(int p_layer_id) const {
@@ -6269,7 +6269,7 @@ void TileData::set_collision_polygons_count(int p_layer_id, int p_polygons_count
}
physics.write[p_layer_id].polygons.resize(p_polygons_count);
notify_property_list_changed();
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_collision_polygons_count(int p_layer_id) const {
@@ -6280,14 +6280,14 @@ int TileData::get_collision_polygons_count(int p_layer_id) const {
void TileData::add_collision_polygon(int p_layer_id) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
physics.write[p_layer_id].polygons.push_back(PhysicsLayerTileData::PolygonShapeTileData());
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
void TileData::remove_collision_polygon(int p_layer_id, int p_polygon_index) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
physics.write[p_layer_id].polygons.remove_at(p_polygon_index);
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
void TileData::set_collision_polygon_points(int p_layer_id, int p_polygon_index, Vector<Vector2> p_polygon) {
@@ -6314,7 +6314,7 @@ void TileData::set_collision_polygon_points(int p_layer_id, int p_polygon_index,
}
polygon_shape_tile_data.transformed_shapes.clear();
polygon_shape_tile_data.polygon = p_polygon;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Vector<Vector2> TileData::get_collision_polygon_points(int p_layer_id, int p_polygon_index) const {
@@ -6327,7 +6327,7 @@ void TileData::set_collision_polygon_one_way(int p_layer_id, int p_polygon_index
ERR_FAIL_INDEX(p_layer_id, physics.size());
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
physics.write[p_layer_id].polygons.write[p_polygon_index].one_way = p_one_way;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
bool TileData::is_collision_polygon_one_way(int p_layer_id, int p_polygon_index) const {
@@ -6340,7 +6340,7 @@ void TileData::set_collision_polygon_one_way_margin(int p_layer_id, int p_polygo
ERR_FAIL_INDEX(p_layer_id, physics.size());
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
physics.write[p_layer_id].polygons.write[p_polygon_index].one_way_margin = p_one_way_margin;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
float TileData::get_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index) const {
@@ -6402,7 +6402,7 @@ void TileData::set_terrain_set(int p_terrain_set) {
}
terrain_set = p_terrain_set;
notify_property_list_changed();
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_terrain_set() const {
@@ -6416,7 +6416,7 @@ void TileData::set_terrain(int p_terrain) {
ERR_FAIL_COND(p_terrain >= tile_set->get_terrains_count(terrain_set));
}
terrain = p_terrain;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_terrain() const {
@@ -6432,7 +6432,7 @@ void TileData::set_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit, int
ERR_FAIL_COND(!is_valid_terrain_peering_bit(p_peering_bit));
}
terrain_peering_bits[p_peering_bit] = p_terrain_index;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit) const {
@@ -6464,7 +6464,7 @@ void TileData::set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_n
ERR_FAIL_INDEX(p_layer_id, navigation.size());
navigation.write[p_layer_id].navigation_polygon = p_navigation_polygon;
navigation.write[p_layer_id].transformed_navigation_polygon.clear();
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_flip_h, bool p_flip_v, bool p_transpose) const {
@@ -6512,7 +6512,7 @@ Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_f
void TileData::set_probability(float p_probability) {
ERR_FAIL_COND(p_probability < 0.0);
probability = p_probability;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
float TileData::get_probability() const {
return probability;
@@ -6536,7 +6536,7 @@ Variant TileData::get_custom_data(String p_layer_name) const {
void TileData::set_custom_data_by_layer_id(int p_layer_id, Variant p_value) {
ERR_FAIL_INDEX(p_layer_id, custom_data.size());
custom_data.write[p_layer_id] = p_value;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Variant TileData::get_custom_data_by_layer_id(int p_layer_id) const {
diff --git a/scene/resources/3d/world_3d.cpp b/scene/resources/3d/world_3d.cpp
index 7948a8bfd5..b743b24262 100644
--- a/scene/resources/3d/world_3d.cpp
+++ b/scene/resources/3d/world_3d.cpp
@@ -35,7 +35,6 @@
#include "scene/3d/visible_on_screen_notifier_3d.h"
#include "scene/resources/camera_attributes.h"
#include "scene/resources/environment.h"
-#include "scene/scene_string_names.h"
#include "servers/navigation_server_3d.h"
void World3D::_register_camera(Camera3D *p_camera) {
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index d7b9528248..a3bfa987c6 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -33,7 +33,6 @@
#include "core/io/marshalls.h"
#include "core/math/geometry_3d.h"
-#include "scene/scene_string_names.h"
bool Animation::_set(const StringName &p_name, const Variant &p_value) {
String prop_name = p_name;
diff --git a/scene/resources/animation_library.cpp b/scene/resources/animation_library.cpp
index 79d06c4d66..22666876ae 100644
--- a/scene/resources/animation_library.cpp
+++ b/scene/resources/animation_library.cpp
@@ -30,6 +30,8 @@
#include "animation_library.h"
+#include "scene/scene_string_names.h"
+
bool AnimationLibrary::is_valid_animation_name(const String &p_name) {
return !(p_name.is_empty() || p_name.contains("/") || p_name.contains(":") || p_name.contains(",") || p_name.contains("["));
}
@@ -106,7 +108,7 @@ TypedArray<StringName> AnimationLibrary::_get_animation_list() const {
}
void AnimationLibrary::_animation_changed(const StringName &p_name) {
- emit_signal(SNAME("animation_changed"), p_name);
+ emit_signal(SceneStringName(animation_changed), p_name);
}
void AnimationLibrary::get_animation_list(List<StringName> *p_animations) const {
diff --git a/scene/resources/atlas_texture.cpp b/scene/resources/atlas_texture.cpp
index 6aed68849b..ef2f1eb135 100644
--- a/scene/resources/atlas_texture.cpp
+++ b/scene/resources/atlas_texture.cpp
@@ -30,8 +30,6 @@
#include "atlas_texture.h"
-#include "core/core_string_names.h"
-
int AtlasTexture::get_width() const {
if (region.size.width == 0) {
if (atlas.is_valid()) {
diff --git a/scene/resources/audio_stream_wav.cpp b/scene/resources/audio_stream_wav.cpp
index ba5dad088f..db2564af22 100644
--- a/scene/resources/audio_stream_wav.cpp
+++ b/scene/resources/audio_stream_wav.cpp
@@ -542,7 +542,7 @@ double AudioStreamWAV::get_length() const {
break;
case AudioStreamWAV::FORMAT_QOA:
qoa_desc desc = { 0, 0, 0, { { { 0 }, { 0 } } } };
- qoa_decode_header((uint8_t *)data + DATA_PAD, QOA_MIN_FILESIZE, &desc);
+ qoa_decode_header((uint8_t *)data + DATA_PAD, data_bytes, &desc);
len = desc.samples * desc.channels;
}
@@ -681,7 +681,8 @@ Ref<AudioStreamPlayback> AudioStreamWAV::instantiate_playback() {
if (format == AudioStreamWAV::FORMAT_QOA) {
sample->qoa.desc = (qoa_desc *)memalloc(sizeof(qoa_desc));
- qoa_decode_header((uint8_t *)data + DATA_PAD, QOA_MIN_FILESIZE, sample->qoa.desc);
+ uint32_t ffp = qoa_decode_header((uint8_t *)data + DATA_PAD, data_bytes, sample->qoa.desc);
+ ERR_FAIL_COND_V(ffp != 8, Ref<AudioStreamPlaybackWAV>());
sample->qoa.frame_len = qoa_max_frame_size(sample->qoa.desc);
int samples_len = (sample->qoa.desc->samples > QOA_FRAME_LEN ? QOA_FRAME_LEN : sample->qoa.desc->samples);
int alloc_len = sample->qoa.desc->channels * samples_len * sizeof(int16_t);
diff --git a/scene/resources/canvas_item_material.cpp b/scene/resources/canvas_item_material.cpp
index 31c8e68ea5..76e99aca92 100644
--- a/scene/resources/canvas_item_material.cpp
+++ b/scene/resources/canvas_item_material.cpp
@@ -33,13 +33,11 @@
#include "core/version.h"
Mutex CanvasItemMaterial::material_mutex;
-SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = nullptr;
+SelfList<CanvasItemMaterial>::List CanvasItemMaterial::dirty_materials;
HashMap<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData, CanvasItemMaterial::MaterialKey> CanvasItemMaterial::shader_map;
CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = nullptr;
void CanvasItemMaterial::init_shaders() {
- dirty_materials = memnew(SelfList<CanvasItemMaterial>::List);
-
shader_names = memnew(ShaderNames);
shader_names->particles_anim_h_frames = "particles_anim_h_frames";
@@ -48,14 +46,13 @@ void CanvasItemMaterial::init_shaders() {
}
void CanvasItemMaterial::finish_shaders() {
- memdelete(dirty_materials);
+ dirty_materials.clear();
+
memdelete(shader_names);
- dirty_materials = nullptr;
+ shader_names = nullptr;
}
void CanvasItemMaterial::_update_shader() {
- dirty_materials->remove(&element);
-
MaterialKey mk = _compute_key();
if (mk.key == current_key.key) {
return; //no update required in the end
@@ -153,8 +150,9 @@ void CanvasItemMaterial::_update_shader() {
void CanvasItemMaterial::flush_changes() {
MutexLock lock(material_mutex);
- while (dirty_materials->first()) {
- dirty_materials->first()->self()->_update_shader();
+ while (dirty_materials.first()) {
+ dirty_materials.first()->self()->_update_shader();
+ dirty_materials.first()->remove_from_list();
}
}
@@ -162,16 +160,10 @@ void CanvasItemMaterial::_queue_shader_change() {
MutexLock lock(material_mutex);
if (_is_initialized() && !element.in_list()) {
- dirty_materials->add(&element);
+ dirty_materials.add(&element);
}
}
-bool CanvasItemMaterial::_is_shader_dirty() const {
- MutexLock lock(material_mutex);
-
- return element.in_list();
-}
-
void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) {
blend_mode = p_blend_mode;
_queue_shader_change();
@@ -288,7 +280,7 @@ CanvasItemMaterial::CanvasItemMaterial() :
current_key.invalid_key = 1;
- _mark_initialized(callable_mp(this, &CanvasItemMaterial::_queue_shader_change));
+ _mark_initialized(callable_mp(this, &CanvasItemMaterial::_queue_shader_change), callable_mp(this, &CanvasItemMaterial::_update_shader));
}
CanvasItemMaterial::~CanvasItemMaterial() {
diff --git a/scene/resources/canvas_item_material.h b/scene/resources/canvas_item_material.h
index 7dddd74a31..ef498c2ff6 100644
--- a/scene/resources/canvas_item_material.h
+++ b/scene/resources/canvas_item_material.h
@@ -98,12 +98,11 @@ private:
}
static Mutex material_mutex;
- static SelfList<CanvasItemMaterial>::List *dirty_materials;
+ static SelfList<CanvasItemMaterial>::List dirty_materials;
SelfList<CanvasItemMaterial> element;
void _update_shader();
_FORCE_INLINE_ void _queue_shader_change();
- _FORCE_INLINE_ bool _is_shader_dirty() const;
BlendMode blend_mode = BLEND_MODE_MIX;
LightMode light_mode = LIGHT_MODE_NORMAL;
diff --git a/scene/resources/curve_texture.cpp b/scene/resources/curve_texture.cpp
index 488a527bbb..4ba5393110 100644
--- a/scene/resources/curve_texture.cpp
+++ b/scene/resources/curve_texture.cpp
@@ -30,8 +30,6 @@
#include "curve_texture.h"
-#include "core/core_string_names.h"
-
void CurveTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveTexture::set_width);
diff --git a/scene/resources/gradient_texture.cpp b/scene/resources/gradient_texture.cpp
index 327a99c6ad..7df439a799 100644
--- a/scene/resources/gradient_texture.cpp
+++ b/scene/resources/gradient_texture.cpp
@@ -30,7 +30,6 @@
#include "gradient_texture.h"
-#include "core/core_string_names.h"
#include "core/math/geometry_2d.h"
GradientTexture1D::GradientTexture1D() {
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 15b40e776c..27da825bfe 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -35,7 +35,6 @@
#include "core/error/error_macros.h"
#include "core/version.h"
#include "scene/main/scene_tree.h"
-#include "scene/scene_string_names.h"
void Material::set_next_pass(const Ref<Material> &p_pass) {
for (Ref<Material> pass_child = p_pass; pass_child != nullptr; pass_child = pass_child->get_next_pass()) {
@@ -82,24 +81,25 @@ void Material::_validate_property(PropertyInfo &p_property) const {
}
}
-void Material::_mark_initialized(const Callable &p_queue_shader_change_callable) {
+void Material::_mark_ready() {
+ init_state = INIT_STATE_INITIALIZING;
+}
+
+void Material::_mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader) {
// If this is happening as part of resource loading, it is not safe to queue the update
- // as an addition to the dirty list, unless the load is happening on the main thread.
- if (ResourceLoader::is_within_load() && Thread::get_caller_id() != Thread::get_main_id()) {
+ // as an addition to the dirty list. It would be if the load is happening on the main thread,
+ // but even so we'd rather perform the update directly instead of using the dirty list.
+ if (ResourceLoader::is_within_load()) {
DEV_ASSERT(init_state != INIT_STATE_READY);
if (init_state == INIT_STATE_UNINITIALIZED) { // Prevent queueing twice.
- // Let's mark this material as being initialized.
init_state = INIT_STATE_INITIALIZING;
- // Knowing that the ResourceLoader will eventually feed deferred calls into the main message queue, let's do these:
- // 1. Queue setting the init state to INIT_STATE_READY finally.
- callable_mp(this, &Material::_mark_initialized).bind(p_queue_shader_change_callable).call_deferred();
- // 2. Queue an individual update of this material.
- p_queue_shader_change_callable.call_deferred();
+ callable_mp(this, &Material::_mark_ready).call_deferred();
+ p_update_shader.call_deferred();
}
} else {
// Straightforward conditions.
init_state = INIT_STATE_READY;
- p_queue_shader_change_callable.callv(Array());
+ p_add_to_dirty_list.call();
}
}
@@ -603,8 +603,6 @@ void BaseMaterial3D::finish_shaders() {
}
void BaseMaterial3D::_update_shader() {
- dirty_materials.remove(&element);
-
MaterialKey mk = _compute_key();
if (mk == current_key) {
return; //no update required in the end
@@ -1855,6 +1853,7 @@ void BaseMaterial3D::flush_changes() {
while (dirty_materials.first()) {
dirty_materials.first()->self()->_update_shader();
+ dirty_materials.first()->remove_from_list();
}
}
@@ -1866,12 +1865,6 @@ void BaseMaterial3D::_queue_shader_change() {
}
}
-bool BaseMaterial3D::_is_shader_dirty() const {
- MutexLock lock(material_mutex);
-
- return element.in_list();
-}
-
void BaseMaterial3D::set_albedo(const Color &p_albedo) {
albedo = p_albedo;
@@ -2824,7 +2817,7 @@ BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const {
RID BaseMaterial3D::get_shader_rid() const {
MutexLock lock(material_mutex);
- if (element.in_list()) { // _is_shader_dirty() would create anoder mutex lock
+ if (element.in_list()) {
((BaseMaterial3D *)this)->_update_shader();
}
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
@@ -3412,7 +3405,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
current_key.invalid_key = 1;
- _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change));
+ _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change), callable_mp(this, &BaseMaterial3D::_update_shader));
}
BaseMaterial3D::~BaseMaterial3D() {
diff --git a/scene/resources/material.h b/scene/resources/material.h
index ecf79c581b..50a774e961 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -62,7 +62,8 @@ protected:
void _validate_property(PropertyInfo &p_property) const;
- void _mark_initialized(const Callable &p_queue_shader_change_callable);
+ void _mark_ready();
+ void _mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader);
bool _is_initialized() { return init_state == INIT_STATE_READY; }
GDVIRTUAL0RC(RID, _get_shader_rid)
@@ -466,7 +467,6 @@ private:
void _update_shader();
_FORCE_INLINE_ void _queue_shader_change();
- _FORCE_INLINE_ bool _is_shader_dirty() const;
bool orm;
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 73f3009fd1..8b5e438aea 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -1880,7 +1880,7 @@ void ArrayMesh::set_blend_shape_name(int p_index, const StringName &p_name) {
do {
shape_name = String(p_name) + " " + itos(count);
count++;
- } while (blend_shapes.find(shape_name) != -1);
+ } while (blend_shapes.has(shape_name));
}
blend_shapes.write[p_index] = shape_name;
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 94a031947a..5e50b9a240 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -32,7 +32,6 @@
#include "core/config/engine.h"
#include "core/config/project_settings.h"
-#include "core/core_string_names.h"
#include "core/io/missing_resource.h"
#include "core/io/resource_loader.h"
#include "core/templates/local_vector.h"
@@ -191,6 +190,7 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
Node *node = nullptr;
MissingNode *missing_node = nullptr;
+ bool is_inherited_scene = false;
if (i == 0 && base_scene_idx >= 0) {
// Scene inheritance on root node.
@@ -201,7 +201,7 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
if (p_edit_state != GEN_EDIT_STATE_DISABLED) {
node->set_scene_inherited_state(sdata->get_state());
}
-
+ is_inherited_scene = true;
} else if (n.instance >= 0) {
// Instance a scene into this node.
if (n.instance & FLAG_INSTANCE_IS_PLACEHOLDER) {
@@ -327,7 +327,7 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
ERR_FAIL_INDEX_V(nprops[j].name, sname_count, nullptr);
- if (snames[nprops[j].name] == CoreStringNames::get_singleton()->_script) {
+ if (snames[nprops[j].name] == CoreStringName(script)) {
//work around to avoid old script variables from disappearing, should be the proper fix to:
//https://github.com/godotengine/godot/issues/2958
@@ -346,6 +346,12 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
} else {
Variant value = props[nprops[j].value];
+ // Making sure that instances of inherited scenes don't share the same
+ // reference between them.
+ if (is_inherited_scene) {
+ value = value.duplicate(true);
+ }
+
if (value.get_type() == Variant::OBJECT) {
//handle resources that are local to scene by duplicating them if needed
Ref<Resource> res = value;
diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp
index 0b12ba870e..01d26a8bed 100644
--- a/scene/resources/particle_process_material.cpp
+++ b/scene/resources/particle_process_material.cpp
@@ -33,14 +33,12 @@
#include "core/version.h"
Mutex ParticleProcessMaterial::material_mutex;
-SelfList<ParticleProcessMaterial>::List *ParticleProcessMaterial::dirty_materials = nullptr;
+SelfList<ParticleProcessMaterial>::List ParticleProcessMaterial::dirty_materials;
HashMap<ParticleProcessMaterial::MaterialKey, ParticleProcessMaterial::ShaderData, ParticleProcessMaterial::MaterialKey> ParticleProcessMaterial::shader_map;
RBSet<String> ParticleProcessMaterial::min_max_properties;
ParticleProcessMaterial::ShaderNames *ParticleProcessMaterial::shader_names = nullptr;
void ParticleProcessMaterial::init_shaders() {
- dirty_materials = memnew(SelfList<ParticleProcessMaterial>::List);
-
shader_names = memnew(ShaderNames);
shader_names->direction = "direction";
@@ -140,15 +138,13 @@ void ParticleProcessMaterial::init_shaders() {
}
void ParticleProcessMaterial::finish_shaders() {
- memdelete(dirty_materials);
- dirty_materials = nullptr;
+ dirty_materials.clear();
memdelete(shader_names);
+ shader_names = nullptr;
}
void ParticleProcessMaterial::_update_shader() {
- dirty_materials->remove(&element);
-
MaterialKey mk = _compute_key();
if (mk == current_key) {
return; //no update required in the end
@@ -634,7 +630,7 @@ void ParticleProcessMaterial::_update_shader() {
if (emission_shape == EMISSION_SHAPE_RING) {
code += " \n";
code += " float ring_spawn_angle = rand_from_seed(alt_seed) * 2.0 * pi;\n";
- code += " float ring_random_radius = sqrt(rand_from_seed(alt_seed) * (emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);\n";
+ code += " float ring_random_radius = sqrt(rand_from_seed(alt_seed) * (emission_ring_radius * emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);\n";
code += " vec3 axis = emission_ring_axis == vec3(0.0) ? vec3(0.0, 0.0, 1.0) : normalize(emission_ring_axis);\n";
code += " vec3 ortho_axis = vec3(0.0);\n";
code += " if (abs(axis) == vec3(1.0, 0.0, 0.0)) {\n";
@@ -1172,8 +1168,9 @@ void ParticleProcessMaterial::_update_shader() {
void ParticleProcessMaterial::flush_changes() {
MutexLock lock(material_mutex);
- while (dirty_materials->first()) {
- dirty_materials->first()->self()->_update_shader();
+ while (dirty_materials.first()) {
+ dirty_materials.first()->self()->_update_shader();
+ dirty_materials.first()->remove_from_list();
}
}
@@ -1181,16 +1178,10 @@ void ParticleProcessMaterial::_queue_shader_change() {
MutexLock lock(material_mutex);
if (_is_initialized() && !element.in_list()) {
- dirty_materials->add(&element);
+ dirty_materials.add(&element);
}
}
-bool ParticleProcessMaterial::_is_shader_dirty() const {
- MutexLock lock(material_mutex);
-
- return element.in_list();
-}
-
bool ParticleProcessMaterial::has_min_max_property(const String &p_name) {
return min_max_properties.has(p_name);
}
@@ -2332,7 +2323,7 @@ ParticleProcessMaterial::ParticleProcessMaterial() :
current_key.invalid_key = 1;
- _mark_initialized(callable_mp(this, &ParticleProcessMaterial::_queue_shader_change));
+ _mark_initialized(callable_mp(this, &ParticleProcessMaterial::_queue_shader_change), callable_mp(this, &ParticleProcessMaterial::_update_shader));
}
ParticleProcessMaterial::~ParticleProcessMaterial() {
diff --git a/scene/resources/particle_process_material.h b/scene/resources/particle_process_material.h
index 94b2009654..25046b51cd 100644
--- a/scene/resources/particle_process_material.h
+++ b/scene/resources/particle_process_material.h
@@ -186,7 +186,7 @@ private:
}
static Mutex material_mutex;
- static SelfList<ParticleProcessMaterial>::List *dirty_materials;
+ static SelfList<ParticleProcessMaterial>::List dirty_materials;
struct ShaderNames {
StringName direction;
@@ -293,7 +293,6 @@ private:
void _update_shader();
_FORCE_INLINE_ void _queue_shader_change();
- _FORCE_INLINE_ bool _is_shader_dirty() const;
Vector3 direction;
float spread = 0.0f;
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 0087a5e7f2..5e9510c1ac 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -31,7 +31,6 @@
#include "shader.h"
#include "core/io/file_access.h"
-#include "scene/scene_string_names.h"
#include "servers/rendering/shader_language.h"
#include "servers/rendering/shader_preprocessor.h"
#include "servers/rendering_server.h"
diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp
index 42ffa2d25a..6e43ea9b17 100644
--- a/scene/resources/sprite_frames.cpp
+++ b/scene/resources/sprite_frames.cpp
@@ -277,5 +277,5 @@ void SpriteFrames::_bind_methods() {
}
SpriteFrames::SpriteFrames() {
- add_animation(SceneStringNames::get_singleton()->_default);
+ add_animation(SceneStringName(default_));
}
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
index c735395829..6da4215031 100644
--- a/scene/resources/syntax_highlighter.cpp
+++ b/scene/resources/syntax_highlighter.cpp
@@ -303,7 +303,7 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
}
// Check for dot or underscore or 'x' for hex notation in floating point number or 'e' for scientific notation.
- if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'f' || str[j] == 'e') && !in_word && prev_is_number && !is_number) {
+ if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'f' || str[j] == 'e' || (uint_suffix_enabled && str[j] == 'u')) && !in_word && prev_is_number && !is_number) {
is_number = true;
is_a_symbol = false;
is_char = false;
@@ -617,6 +617,10 @@ void CodeHighlighter::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "color_regions"), "set_color_regions", "get_color_regions");
}
+void CodeHighlighter::set_uint_suffix_enabled(bool p_enabled) {
+ uint_suffix_enabled = p_enabled;
+}
+
void CodeHighlighter::set_number_color(Color p_color) {
number_color = p_color;
clear_highlighting_cache();
diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h
index cac2807ee2..02afd9045e 100644
--- a/scene/resources/syntax_highlighter.h
+++ b/scene/resources/syntax_highlighter.h
@@ -93,6 +93,8 @@ private:
Color symbol_color;
Color number_color;
+ bool uint_suffix_enabled = false;
+
protected:
static void _bind_methods();
@@ -139,6 +141,8 @@ public:
void set_member_variable_color(Color p_color);
Color get_member_variable_color() const;
+
+ void set_uint_suffix_enabled(bool p_enabled);
};
#endif // SYNTAX_HIGHLIGHTER_H
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 4b51f6c471..601e8c52a4 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -585,12 +585,12 @@ int VisualShaderNodeCustom::get_input_port_count() const {
VisualShaderNodeCustom::PortType VisualShaderNodeCustom::get_input_port_type(int p_port) const {
ERR_FAIL_INDEX_V(p_port, input_ports.size(), PORT_TYPE_SCALAR);
- return (PortType)input_ports[p_port].type;
+ return (PortType)input_ports.get(p_port).type;
}
String VisualShaderNodeCustom::get_input_port_name(int p_port) const {
ERR_FAIL_INDEX_V(p_port, input_ports.size(), "");
- return input_ports[p_port].name;
+ return input_ports.get(p_port).name;
}
int VisualShaderNodeCustom::get_default_input_port(PortType p_type) const {
@@ -605,12 +605,12 @@ int VisualShaderNodeCustom::get_output_port_count() const {
VisualShaderNodeCustom::PortType VisualShaderNodeCustom::get_output_port_type(int p_port) const {
ERR_FAIL_INDEX_V(p_port, output_ports.size(), PORT_TYPE_SCALAR);
- return (PortType)output_ports[p_port].type;
+ return (PortType)output_ports.get(p_port).type;
}
String VisualShaderNodeCustom::get_output_port_name(int p_port) const {
ERR_FAIL_INDEX_V(p_port, output_ports.size(), "");
- return output_ports[p_port].name;
+ return output_ports.get(p_port).name;
}
String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
@@ -865,7 +865,7 @@ int VisualShader::get_varyings_count() const {
const VisualShader::Varying *VisualShader::get_varying_by_index(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, varyings_list.size(), nullptr);
- return &varyings_list[p_idx];
+ return &varyings_list.get(p_idx);
}
void VisualShader::set_varying_mode(const String &p_name, VaryingMode p_mode) {
@@ -1101,6 +1101,42 @@ bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_nod
return result;
}
+bool VisualShader::_check_reroute_subgraph(Type p_type, int p_target_port_type, int p_reroute_node, List<int> *r_visited_reroute_nodes) const {
+ const Graph *g = &graph[p_type];
+
+ // BFS to check whether connecting to the given subgraph (rooted at p_reroute_node) is valid.
+ List<int> queue;
+ queue.push_back(p_reroute_node);
+ if (r_visited_reroute_nodes != nullptr) {
+ r_visited_reroute_nodes->push_back(p_reroute_node);
+ }
+ while (!queue.is_empty()) {
+ int current_node_id = queue.front()->get();
+ VisualShader::Node current_node = g->nodes[current_node_id];
+ queue.pop_front();
+ for (const int &next_node_id : current_node.next_connected_nodes) {
+ Ref<VisualShaderNodeReroute> next_vsnode = g->nodes[next_node_id].node;
+ if (next_vsnode.is_valid()) {
+ queue.push_back(next_node_id);
+ if (r_visited_reroute_nodes != nullptr) {
+ r_visited_reroute_nodes->push_back(next_node_id);
+ }
+ continue;
+ }
+ // Check whether all ports connected with the reroute node are compatible.
+ for (const Connection &c : g->connections) {
+ VisualShaderNode::PortType to_port_type = g->nodes[next_node_id].node->get_input_port_type(c.to_port);
+ if (c.from_node == current_node_id &&
+ c.to_node == next_node_id &&
+ !is_port_types_compatible(p_target_port_type, to_port_type)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
const Graph *g = &graph[p_type];
@@ -1128,7 +1164,12 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port);
VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port);
- if (!is_port_types_compatible(from_port_type, to_port_type)) {
+ Ref<VisualShaderNodeReroute> to_node_reroute = g->nodes[p_to_node].node;
+ if (to_node_reroute.is_valid()) {
+ if (!_check_reroute_subgraph(p_type, from_port_type, p_to_node)) {
+ return false;
+ }
+ } else if (!is_port_types_compatible(from_port_type, to_port_type)) {
return false;
}
@@ -1141,7 +1182,6 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
if (is_nodes_connected_relatively(g, p_from_node, p_to_node)) {
return false;
}
-
return true;
}
@@ -1179,6 +1219,28 @@ void VisualShader::detach_node_from_frame(Type p_type, int p_node) {
g->nodes[p_node].node->set_frame(-1);
}
+String VisualShader::get_reroute_parameter_name(Type p_type, int p_reroute_node) const {
+ ERR_FAIL_INDEX_V(p_type, TYPE_MAX, "");
+ const Graph *g = &graph[p_type];
+
+ ERR_FAIL_COND_V(!g->nodes.has(p_reroute_node), "");
+
+ const VisualShader::Node *node = &g->nodes[p_reroute_node];
+ while (node->prev_connected_nodes.size() > 0) {
+ int connected_node_id = node->prev_connected_nodes[0];
+ node = &g->nodes[connected_node_id];
+ Ref<VisualShaderNodeParameter> parameter_node = node->node;
+ if (parameter_node.is_valid() && parameter_node->get_output_port_type(0) == VisualShaderNode::PORT_TYPE_SAMPLER) {
+ return parameter_node->get_parameter_name();
+ }
+ Ref<VisualShaderNodeInput> input_node = node->node;
+ if (input_node.is_valid() && input_node->get_output_port_type(0) == VisualShaderNode::PORT_TYPE_SAMPLER) {
+ return input_node->get_input_real_name();
+ }
+ }
+ return "";
+}
+
void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
ERR_FAIL_INDEX(p_type, TYPE_MAX);
Graph *g = &graph[p_type];
@@ -1217,10 +1279,30 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
ERR_FAIL_COND_V(!g->nodes.has(p_to_node), ERR_INVALID_PARAMETER);
ERR_FAIL_INDEX_V(p_to_port, g->nodes[p_to_node].node->get_input_port_count(), ERR_INVALID_PARAMETER);
+ Ref<VisualShaderNodeReroute> from_node_reroute = g->nodes[p_from_node].node;
+ Ref<VisualShaderNodeReroute> to_node_reroute = g->nodes[p_to_node].node;
+
+ // Allow connection with incompatible port types only if the reroute node isn't connected to anything.
VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port);
VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port);
+ bool port_types_are_compatible = is_port_types_compatible(from_port_type, to_port_type);
+
+ if (to_node_reroute.is_valid()) {
+ List<int> visited_reroute_nodes;
+ port_types_are_compatible = _check_reroute_subgraph(p_type, from_port_type, p_to_node, &visited_reroute_nodes);
+ if (port_types_are_compatible) {
+ // Set the port type of all reroute nodes.
+ for (const int &E : visited_reroute_nodes) {
+ Ref<VisualShaderNodeReroute> reroute_node = g->nodes[E].node;
+ reroute_node->_set_port_type(from_port_type);
+ }
+ }
+ } else if (from_node_reroute.is_valid() && !from_node_reroute->is_input_port_connected(0)) {
+ from_node_reroute->_set_port_type(to_port_type);
+ port_types_are_compatible = true;
+ }
- ERR_FAIL_COND_V_MSG(!is_port_types_compatible(from_port_type, to_port_type), ERR_INVALID_PARAMETER, "Incompatible port types (scalar/vec/bool) with transform.");
+ ERR_FAIL_COND_V_MSG(!port_types_are_compatible, ERR_INVALID_PARAMETER, "Incompatible port types.");
for (const Connection &E : g->connections) {
if (E.from_node == p_from_node && E.from_port == p_from_port && E.to_node == p_to_node && E.to_port == p_to_port) {
@@ -1904,12 +1986,18 @@ Error VisualShader::_write_node(Type type, StringBuilder *p_global_code, StringB
if (in_type == VisualShaderNode::PORT_TYPE_SAMPLER && out_type == VisualShaderNode::PORT_TYPE_SAMPLER) {
VisualShaderNode *ptr = const_cast<VisualShaderNode *>(graph[type].nodes[from_node].node.ptr());
+ // FIXME: This needs to be refactored at some point.
if (ptr->has_method("get_input_real_name")) {
inputs[i] = ptr->call("get_input_real_name");
} else if (ptr->has_method("get_parameter_name")) {
inputs[i] = ptr->call("get_parameter_name");
} else {
- inputs[i] = "";
+ Ref<VisualShaderNodeReroute> reroute = graph[type].nodes[from_node].node;
+ if (reroute.is_valid()) {
+ inputs[i] = get_reroute_parameter_name(type, from_node);
+ } else {
+ inputs[i] = "";
+ }
}
} else if (in_type == out_type) {
inputs[i] = src_var;
@@ -2478,10 +2566,11 @@ void VisualShader::_update_shader() const {
}
}
- for (int i = 0; i < parameters.size(); i++) {
- VisualShaderNodeParameter *parameter = parameters[i];
+ int idx = 0;
+ for (List<VisualShaderNodeParameter *>::Iterator itr = parameters.begin(); itr != parameters.end(); ++itr, ++idx) {
+ VisualShaderNodeParameter *parameter = *itr;
if (used_parameter_names.has(parameter->get_parameter_name())) {
- global_code += parameter->generate_global(get_mode(), Type(i), -1);
+ global_code += parameter->generate_global(get_mode(), Type(idx), -1);
const_cast<VisualShaderNodeParameter *>(parameter)->set_global_code_generated(true);
} else {
const_cast<VisualShaderNodeParameter *>(parameter)->set_global_code_generated(false);
@@ -2791,12 +2880,13 @@ void VisualShader::_update_shader() const {
const_cast<VisualShader *>(this)->set_code(final_code);
for (int i = 0; i < default_tex_params.size(); i++) {
- for (int j = 0; j < default_tex_params[i].params.size(); j++) {
- const_cast<VisualShader *>(this)->set_default_texture_parameter(default_tex_params[i].name, default_tex_params[i].params[j], j);
+ int j = 0;
+ for (List<Ref<Texture2D>>::ConstIterator itr = default_tex_params[i].params.begin(); itr != default_tex_params[i].params.end(); ++itr, ++j) {
+ const_cast<VisualShader *>(this)->set_default_texture_parameter(default_tex_params[i].name, *itr, j);
}
}
if (previous_code != final_code) {
- const_cast<VisualShader *>(this)->emit_signal(SNAME("changed"));
+ const_cast<VisualShader *>(this)->emit_signal(CoreStringName(changed));
}
previous_code = final_code;
}
@@ -3684,7 +3774,7 @@ String VisualShaderNodeParameterRef::get_parameter_name_by_index(int p_idx) cons
ERR_FAIL_COND_V(!shader_rid.is_valid(), String());
if (p_idx >= 0 && p_idx < parameters[shader_rid].size()) {
- return parameters[shader_rid][p_idx].name;
+ return parameters[shader_rid].get(p_idx).name;
}
return "";
}
@@ -3692,9 +3782,9 @@ String VisualShaderNodeParameterRef::get_parameter_name_by_index(int p_idx) cons
VisualShaderNodeParameterRef::ParameterType VisualShaderNodeParameterRef::get_parameter_type_by_name(const String &p_name) const {
ERR_FAIL_COND_V(!shader_rid.is_valid(), PARAMETER_TYPE_FLOAT);
- for (int i = 0; i < parameters[shader_rid].size(); i++) {
- if (parameters[shader_rid][i].name == p_name) {
- return parameters[shader_rid][i].type;
+ for (const VisualShaderNodeParameterRef::Parameter &parameter : parameters[shader_rid]) {
+ if (parameter.name == p_name) {
+ return parameter.type;
}
}
return PARAMETER_TYPE_FLOAT;
@@ -3704,7 +3794,7 @@ VisualShaderNodeParameterRef::ParameterType VisualShaderNodeParameterRef::get_pa
ERR_FAIL_COND_V(!shader_rid.is_valid(), PARAMETER_TYPE_FLOAT);
if (p_idx >= 0 && p_idx < parameters[shader_rid].size()) {
- return parameters[shader_rid][p_idx].type;
+ return parameters[shader_rid].get(p_idx).type;
}
return PARAMETER_TYPE_FLOAT;
}
@@ -3713,7 +3803,7 @@ VisualShaderNodeParameterRef::PortType VisualShaderNodeParameterRef::get_port_ty
ERR_FAIL_COND_V(!shader_rid.is_valid(), PORT_TYPE_SCALAR);
if (p_idx >= 0 && p_idx < parameters[shader_rid].size()) {
- switch (parameters[shader_rid][p_idx].type) {
+ switch (parameters[shader_rid].get(p_idx).type) {
case PARAMETER_TYPE_FLOAT:
return PORT_TYPE_SCALAR;
case PARAMETER_TYPE_INT:
@@ -4984,15 +5074,15 @@ int VisualShaderNodeVarying::get_varyings_count() const {
String VisualShaderNodeVarying::get_varying_name_by_index(int p_idx) const {
if (p_idx >= 0 && p_idx < varyings.size()) {
- return varyings[p_idx].name;
+ return varyings.get(p_idx).name;
}
return "";
}
VisualShader::VaryingType VisualShaderNodeVarying::get_varying_type_by_name(const String &p_name) const {
- for (int i = 0; i < varyings.size(); i++) {
- if (varyings[i].name == p_name) {
- return varyings[i].type;
+ for (const VisualShaderNodeVarying::Varying &varying : varyings) {
+ if (varying.name == p_name) {
+ return varying.type;
}
}
return VisualShader::VARYING_TYPE_FLOAT;
@@ -5000,15 +5090,15 @@ VisualShader::VaryingType VisualShaderNodeVarying::get_varying_type_by_name(cons
VisualShader::VaryingType VisualShaderNodeVarying::get_varying_type_by_index(int p_idx) const {
if (p_idx >= 0 && p_idx < varyings.size()) {
- return varyings[p_idx].type;
+ return varyings.get(p_idx).type;
}
return VisualShader::VARYING_TYPE_FLOAT;
}
VisualShader::VaryingMode VisualShaderNodeVarying::get_varying_mode_by_name(const String &p_name) const {
- for (int i = 0; i < varyings.size(); i++) {
- if (varyings[i].name == p_name) {
- return varyings[i].mode;
+ for (const VisualShaderNodeVarying::Varying &varying : varyings) {
+ if (varying.name == p_name) {
+ return varying.mode;
}
}
return VisualShader::VARYING_MODE_VERTEX_TO_FRAG_LIGHT;
@@ -5016,14 +5106,14 @@ VisualShader::VaryingMode VisualShaderNodeVarying::get_varying_mode_by_name(cons
VisualShader::VaryingMode VisualShaderNodeVarying::get_varying_mode_by_index(int p_idx) const {
if (p_idx >= 0 && p_idx < varyings.size()) {
- return varyings[p_idx].mode;
+ return varyings.get(p_idx).mode;
}
return VisualShader::VARYING_MODE_VERTEX_TO_FRAG_LIGHT;
}
VisualShaderNodeVarying::PortType VisualShaderNodeVarying::get_port_type_by_index(int p_idx) const {
if (p_idx >= 0 && p_idx < varyings.size()) {
- return get_port_type(varyings[p_idx].type, 0);
+ return get_port_type(varyings.get(p_idx).type, 0);
}
return PORT_TYPE_SCALAR;
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index d32e2465b9..18cdc8342b 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -163,6 +163,8 @@ private:
void _input_type_changed(Type p_type, int p_id);
bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const;
+ bool _check_reroute_subgraph(Type p_type, int p_target_port_type, int p_reroute_node, List<int> *r_visited_reroute_nodes = nullptr) const;
+
protected:
virtual void _update_shader() const override;
static void _bind_methods();
@@ -229,6 +231,8 @@ public: // internal methods
void attach_node_to_frame(Type p_type, int p_node, int p_frame);
void detach_node_from_frame(Type p_type, int p_node);
+ String get_reroute_parameter_name(Type p_type, int p_reroute_node) const;
+
void rebuild();
void get_node_connections(Type p_type, List<Connection> *r_connections) const;
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index ccd730eef2..d5394c8af5 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -8150,3 +8150,82 @@ VisualShaderNodeRotationByAxis::VisualShaderNodeRotationByAxis() {
simple_decl = false;
}
+
+String VisualShaderNodeReroute::get_caption() const {
+ return "Reroute";
+}
+
+int VisualShaderNodeReroute::get_input_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeReroute::PortType VisualShaderNodeReroute::get_input_port_type(int p_port) const {
+ return input_port_type;
+}
+
+String VisualShaderNodeReroute::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeReroute::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeReroute::PortType VisualShaderNodeReroute::get_output_port_type(int p_port) const {
+ return input_port_type;
+}
+
+String VisualShaderNodeReroute::get_output_port_name(int p_port) const {
+ return String();
+}
+
+String VisualShaderNodeReroute::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ String code;
+ for (int i = 0; i < get_output_port_count(); i++) {
+ if (input_port_type == PORT_TYPE_SAMPLER) {
+ continue;
+ }
+
+ String input = p_input_vars[0];
+ if (input.is_empty()) {
+ code += vformat(" %s;\n", p_output_vars[i]);
+ continue;
+ }
+ code += vformat(" %s = %s;\n", p_output_vars[i], input);
+ }
+ return code;
+}
+
+void VisualShaderNodeReroute::_set_port_type(PortType p_type) {
+ input_port_type = p_type;
+ switch (p_type) {
+ case PORT_TYPE_SCALAR:
+ set_input_port_default_value(0, 0.0);
+ break;
+ case PORT_TYPE_VECTOR_2D:
+ set_input_port_default_value(0, Vector2());
+ break;
+ case PORT_TYPE_VECTOR_3D:
+ set_input_port_default_value(0, Vector3());
+ break;
+ case PORT_TYPE_VECTOR_4D:
+ set_input_port_default_value(0, Vector4());
+ break;
+ case PORT_TYPE_TRANSFORM:
+ set_input_port_default_value(0, Transform3D());
+ break;
+ default:
+ break;
+ }
+}
+
+void VisualShaderNodeReroute::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_set_port_type", "port_type"), &VisualShaderNodeReroute::_set_port_type);
+ ClassDB::bind_method(D_METHOD("get_port_type"), &VisualShaderNodeReroute::get_port_type);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "port_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_port_type", "get_port_type");
+}
+
+VisualShaderNodeReroute::VisualShaderNodeReroute() {
+ set_input_port_default_value(0, 0.0);
+}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 0bd0c631b8..a23ae72def 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -3092,4 +3092,35 @@ public:
VisualShaderNodeRotationByAxis();
};
+class VisualShaderNodeReroute : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeReroute, VisualShaderNode);
+
+ PortType input_port_type = PORT_TYPE_SCALAR;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+ virtual bool has_output_port_preview(int p_port) const override { return false; }
+ virtual bool is_output_port_expandable(int p_port) const override { return false; }
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ virtual Category get_category() const override { return CATEGORY_SPECIAL; }
+
+ void _set_port_type(PortType p_type);
+ PortType get_port_type() const { return input_port_type; }
+
+ VisualShaderNodeReroute();
+};
+
#endif // VISUAL_SHADER_NODES_H
diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp
index 5ff1f79a22..cc88876232 100644
--- a/scene/resources/visual_shader_particle_nodes.cpp
+++ b/scene/resources/visual_shader_particle_nodes.cpp
@@ -1641,11 +1641,11 @@ String VisualShaderNodeParticleEmit::generate_code(Shader::Mode p_mode, VisualSh
String flags_str;
- for (int i = 0; i < flags_arr.size(); i++) {
- if (i > 0) {
+ for (List<String>::ConstIterator itr = flags_arr.begin(); itr != flags_arr.end(); ++itr) {
+ if (itr != flags_arr.begin()) {
flags_str += "|";
}
- flags_str += flags_arr[i];
+ flags_str += *itr;
}
if (flags_str.is_empty()) {