summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/animation.cpp6
-rw-r--r--scene/resources/font.cpp38
-rw-r--r--scene/resources/font.h8
-rw-r--r--scene/resources/sprite_frames.cpp6
-rw-r--r--scene/resources/sprite_frames.h8
-rw-r--r--scene/resources/style_box.cpp21
-rw-r--r--scene/resources/style_box.h2
-rw-r--r--scene/resources/surface_tool.cpp46
-rw-r--r--scene/resources/surface_tool.h15
-rw-r--r--scene/resources/texture.cpp32
-rw-r--r--scene/resources/tile_set.cpp71
-rw-r--r--scene/resources/tile_set.h10
-rw-r--r--scene/resources/visual_shader_nodes.cpp62
-rw-r--r--scene/resources/visual_shader_nodes.h13
14 files changed, 267 insertions, 71 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 50f3015814..cb3c865f05 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -4691,6 +4691,7 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol
data_tracks.resize(tracks_to_compress.size());
time_tracks.resize(tracks_to_compress.size());
+ uint32_t needed_min_page_size = base_page_size;
for (uint32_t i = 0; i < data_tracks.size(); i++) {
data_tracks[i].split_tolerance = p_split_tolerance;
if (track_get_type(tracks_to_compress[i]) == TYPE_BLEND_SHAPE) {
@@ -4698,7 +4699,12 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol
} else {
data_tracks[i].components = 3;
}
+ needed_min_page_size += data_tracks[i].data.size() + data_tracks[i].get_temp_packet_size();
}
+ for (uint32_t i = 0; i < time_tracks.size(); i++) {
+ needed_min_page_size += time_tracks[i].packets.size() * 4; // time packet is 32 bits
+ }
+ ERR_FAIL_COND_MSG(p_page_size < needed_min_page_size, "Cannot compress with the given page size");
while (true) {
// Begin by finding the keyframe in all tracks with the time closest to the current time
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index deee187e8e..e5a1adff20 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -2868,6 +2868,12 @@ void SystemFont::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_multichannel_signed_distance_field", "msdf"), &SystemFont::set_multichannel_signed_distance_field);
ClassDB::bind_method(D_METHOD("is_multichannel_signed_distance_field"), &SystemFont::is_multichannel_signed_distance_field);
+ ClassDB::bind_method(D_METHOD("set_msdf_pixel_range", "msdf_pixel_range"), &SystemFont::set_msdf_pixel_range);
+ ClassDB::bind_method(D_METHOD("get_msdf_pixel_range"), &SystemFont::get_msdf_pixel_range);
+
+ ClassDB::bind_method(D_METHOD("set_msdf_size", "msdf_size"), &SystemFont::set_msdf_size);
+ ClassDB::bind_method(D_METHOD("get_msdf_size"), &SystemFont::get_msdf_size);
+
ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &SystemFont::set_oversampling);
ClassDB::bind_method(D_METHOD("get_oversampling"), &SystemFont::get_oversampling);
@@ -2890,6 +2896,8 @@ void SystemFont::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel"), "set_subpixel_positioning", "get_subpixel_positioning");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field"), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range"), "set_msdf_pixel_range", "get_msdf_pixel_range");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size"), "set_msdf_size", "get_msdf_size");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), "set_oversampling", "get_oversampling");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("Font")), "set_fallbacks", "get_fallbacks");
}
@@ -2987,6 +2995,8 @@ void SystemFont::_update_base_font() {
file->set_hinting(hinting);
file->set_subpixel_positioning(subpixel_positioning);
file->set_multichannel_signed_distance_field(msdf);
+ file->set_msdf_pixel_range(msdf_pixel_range);
+ file->set_msdf_size(msdf_size);
file->set_oversampling(oversampling);
base_font = file;
@@ -3186,6 +3196,34 @@ bool SystemFont::is_multichannel_signed_distance_field() const {
return msdf;
}
+void SystemFont::set_msdf_pixel_range(int p_msdf_pixel_range) {
+ if (msdf_pixel_range != p_msdf_pixel_range) {
+ msdf_pixel_range = p_msdf_pixel_range;
+ if (base_font.is_valid()) {
+ base_font->set_msdf_pixel_range(msdf_pixel_range);
+ }
+ emit_changed();
+ }
+}
+
+int SystemFont::get_msdf_pixel_range() const {
+ return msdf_pixel_range;
+}
+
+void SystemFont::set_msdf_size(int p_msdf_size) {
+ if (msdf_size != p_msdf_size) {
+ msdf_size = p_msdf_size;
+ if (base_font.is_valid()) {
+ base_font->set_msdf_size(msdf_size);
+ }
+ emit_changed();
+ }
+}
+
+int SystemFont::get_msdf_size() const {
+ return msdf_size;
+}
+
void SystemFont::set_oversampling(real_t p_oversampling) {
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 4d468a8841..ef79f8bd02 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -452,6 +452,8 @@ class SystemFont : public Font {
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
real_t oversampling = 0.f;
bool msdf = false;
+ int msdf_pixel_range = 16;
+ int msdf_size = 48;
protected:
static void _bind_methods();
@@ -488,6 +490,12 @@ public:
virtual void set_multichannel_signed_distance_field(bool p_msdf);
virtual bool is_multichannel_signed_distance_field() const;
+ virtual void set_msdf_pixel_range(int p_msdf_pixel_range);
+ virtual int get_msdf_pixel_range() const;
+
+ virtual void set_msdf_size(int p_msdf_size);
+ virtual int get_msdf_size() const;
+
virtual void set_font_names(const PackedStringArray &p_names);
virtual PackedStringArray get_font_names() const;
diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp
index c101974248..818be38681 100644
--- a/scene/resources/sprite_frames.cpp
+++ b/scene/resources/sprite_frames.cpp
@@ -36,7 +36,7 @@ void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture2D> &p_t
HashMap<StringName, Anim>::Iterator E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
- p_duration = MAX(0.0, p_duration);
+ p_duration = MAX(SPRITE_FRAME_MINIMUM_DURATION, p_duration);
Frame frame = { p_texture, p_duration };
@@ -57,7 +57,7 @@ void SpriteFrames::set_frame(const StringName &p_anim, int p_idx, const Ref<Text
return;
}
- p_duration = MAX(0.0, p_duration);
+ p_duration = MAX(SPRITE_FRAME_MINIMUM_DURATION, p_duration);
Frame frame = { p_texture, p_duration };
@@ -214,7 +214,7 @@ void SpriteFrames::_set_animations(const Array &p_animations) {
ERR_CONTINUE(!f.has("texture"));
ERR_CONTINUE(!f.has("duration"));
- Frame frame = { f["texture"], f["duration"] };
+ Frame frame = { f["texture"], MAX(SPRITE_FRAME_MINIMUM_DURATION, (float)f["duration"]) };
anim.frames.push_back(frame);
}
diff --git a/scene/resources/sprite_frames.h b/scene/resources/sprite_frames.h
index 61bead6948..6de2b4a37b 100644
--- a/scene/resources/sprite_frames.h
+++ b/scene/resources/sprite_frames.h
@@ -33,6 +33,8 @@
#include "scene/resources/texture.h"
+static const float SPRITE_FRAME_MINIMUM_DURATION = 0.01;
+
class SpriteFrames : public Resource {
GDCLASS(SpriteFrames, Resource);
@@ -89,10 +91,10 @@ public:
_FORCE_INLINE_ float get_frame_duration(const StringName &p_anim, int p_idx) const {
HashMap<StringName, Anim>::ConstIterator E = animations.find(p_anim);
- ERR_FAIL_COND_V_MSG(!E, 0.0, "Animation '" + String(p_anim) + "' doesn't exist.");
- ERR_FAIL_COND_V(p_idx < 0, 0.0);
+ ERR_FAIL_COND_V_MSG(!E, 1.0, "Animation '" + String(p_anim) + "' doesn't exist.");
+ ERR_FAIL_COND_V(p_idx < 0, 1.0);
if (p_idx >= E->value.frames.size()) {
- return 0.0;
+ return 1.0;
}
return E->value.frames[p_idx].duration;
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 4f16986392..fbbe98d022 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -151,11 +151,6 @@ void StyleBoxTexture::set_texture(Ref<Texture2D> p_texture) {
return;
}
texture = p_texture;
- if (p_texture.is_null()) {
- region_rect = Rect2(0, 0, 0, 0);
- } else {
- region_rect = Rect2(Point2(), texture->get_size());
- }
emit_changed();
}
@@ -231,22 +226,6 @@ bool StyleBoxTexture::is_draw_center_enabled() const {
return draw_center;
}
-Size2 StyleBoxTexture::get_minimum_size() const {
- Size2 min_size = StyleBox::get_minimum_size();
-
- // Make sure that the min size is no smaller than the used texture region.
- if (texture.is_valid()) {
- if (min_size.x < region_rect.size.x) {
- min_size.x = region_rect.size.x;
- }
- if (min_size.y < region_rect.size.y) {
- min_size.y = region_rect.size.y;
- }
- }
-
- return min_size;
-}
-
void StyleBoxTexture::set_expand_margin(Side p_side, float p_size) {
ERR_FAIL_INDEX((int)p_side, 4);
expand_margin[p_side] = p_size;
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 91033617ab..17acfd773e 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -107,8 +107,6 @@ protected:
static void _bind_methods();
public:
- virtual Size2 get_minimum_size() const override;
-
void set_expand_margin(Side p_expand_side, float p_size);
void set_expand_margin_all(float p_expand_margin_size);
void set_expand_margin_individual(float p_left, float p_top, float p_right, float p_bottom);
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 17e92ddfca..5a2b917b9a 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -146,6 +146,25 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) {
return h;
}
+bool SurfaceTool::SmoothGroupVertex::operator==(const SmoothGroupVertex &p_vertex) const {
+ if (vertex != p_vertex.vertex) {
+ return false;
+ }
+
+ if (smooth_group != p_vertex.smooth_group) {
+ return false;
+ }
+
+ return true;
+}
+
+uint32_t SurfaceTool::SmoothGroupVertexHasher::hash(const SmoothGroupVertex &p_vtx) {
+ uint32_t h = hash_djb2_buffer((const uint8_t *)&p_vtx.vertex, sizeof(real_t) * 3);
+ h = hash_murmur3_one_32(p_vtx.smooth_group, h);
+ h = hash_fmix32(h);
+ return h;
+}
+
uint32_t SurfaceTool::TriangleHasher::hash(const int *p_triangle) {
int t0 = p_triangle[0];
int t1 = p_triangle[1];
@@ -1152,7 +1171,7 @@ void SurfaceTool::generate_normals(bool p_flip) {
ERR_FAIL_COND((vertex_array.size() % 3) != 0);
- HashMap<Vertex, Vector3, VertexHasher> vertex_hash;
+ HashMap<SmoothGroupVertex, Vector3, SmoothGroupVertexHasher> smooth_hash;
for (uint32_t vi = 0; vi < vertex_array.size(); vi += 3) {
Vertex *v = &vertex_array[vi];
@@ -1165,21 +1184,28 @@ void SurfaceTool::generate_normals(bool p_flip) {
}
for (int i = 0; i < 3; i++) {
- Vector3 *lv = vertex_hash.getptr(v[i]);
- if (!lv) {
- vertex_hash.insert(v[i], normal);
+ // Add face normal to smooth vertex influence if vertex is member of a smoothing group
+ if (v[i].smooth_group != UINT32_MAX) {
+ Vector3 *lv = smooth_hash.getptr(v[i]);
+ if (!lv) {
+ smooth_hash.insert(v[i], normal);
+ } else {
+ (*lv) += normal;
+ }
} else {
- (*lv) += normal;
+ v[i].normal = normal;
}
}
}
for (Vertex &vertex : vertex_array) {
- Vector3 *lv = vertex_hash.getptr(vertex);
- if (!lv) {
- vertex.normal = Vector3();
- } else {
- vertex.normal = lv->normalized();
+ if (vertex.smooth_group != UINT32_MAX) {
+ Vector3 *lv = smooth_hash.getptr(vertex);
+ if (!lv) {
+ vertex.normal = Vector3();
+ } else {
+ vertex.normal = lv->normalized();
+ }
}
}
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 25e078d2ff..00438c4a53 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -97,6 +97,21 @@ private:
static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx);
};
+ struct SmoothGroupVertex {
+ Vector3 vertex;
+ uint32_t smooth_group = 0;
+ bool operator==(const SmoothGroupVertex &p_vertex) const;
+
+ SmoothGroupVertex(const Vertex &p_vertex) {
+ vertex = p_vertex.vertex;
+ smooth_group = p_vertex.smooth_group;
+ };
+ };
+
+ struct SmoothGroupVertexHasher {
+ static _FORCE_INLINE_ uint32_t hash(const SmoothGroupVertex &p_vtx);
+ };
+
struct TriangleHasher {
static _FORCE_INLINE_ uint32_t hash(const int *p_triangle);
static _FORCE_INLINE_ bool compare(const int *p_lhs, const int *p_rhs);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 85e21d6056..7e3156d2ff 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -653,7 +653,7 @@ Ref<Image> CompressedTexture2D::load_image_from_file(Ref<FileAccess> f, int p_si
uint32_t mipmaps = f->get_32();
Image::Format format = Image::Format(f->get_32());
- if (data_format == DATA_FORMAT_PNG || data_format == DATA_FORMAT_WEBP || data_format == DATA_FORMAT_BASIS_UNIVERSAL) {
+ if (data_format == DATA_FORMAT_PNG || data_format == DATA_FORMAT_WEBP) {
//look for a PNG or WebP file inside
int sw = w;
@@ -684,9 +684,7 @@ Ref<Image> CompressedTexture2D::load_image_from_file(Ref<FileAccess> f, int p_si
}
Ref<Image> img;
- if (data_format == DATA_FORMAT_BASIS_UNIVERSAL && Image::basis_universal_unpacker) {
- img = Image::basis_universal_unpacker(pv);
- } else if (data_format == DATA_FORMAT_PNG && Image::png_unpacker) {
+ if (data_format == DATA_FORMAT_PNG && Image::png_unpacker) {
img = Image::png_unpacker(pv);
} else if (data_format == DATA_FORMAT_WEBP && Image::webp_unpacker) {
img = Image::webp_unpacker(pv);
@@ -745,6 +743,32 @@ Ref<Image> CompressedTexture2D::load_image_from_file(Ref<FileAccess> f, int p_si
return image;
}
+ } else if (data_format == DATA_FORMAT_BASIS_UNIVERSAL) {
+ int sw = w;
+ int sh = h;
+ uint32_t size = f->get_32();
+ if (p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) {
+ //can't load this due to size limit
+ sw = MAX(sw >> 1, 1);
+ sh = MAX(sh >> 1, 1);
+ f->seek(f->get_position() + size);
+ return Ref<Image>();
+ }
+ Vector<uint8_t> pv;
+ pv.resize(size);
+ {
+ uint8_t *wr = pv.ptrw();
+ f->get_buffer(wr, size);
+ }
+ Ref<Image> img;
+ img = Image::basis_universal_unpacker(pv);
+ if (img.is_null() || img->is_empty()) {
+ ERR_FAIL_COND_V(img.is_null() || img->is_empty(), Ref<Image>());
+ }
+ format = img->get_format();
+ sw = MAX(sw >> 1, 1);
+ sh = MAX(sh >> 1, 1);
+ return img;
} else if (data_format == DATA_FORMAT_IMAGE) {
int size = Image::get_image_data_size(w, h, format, mipmaps ? true : false);
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 766f04a652..58a638804d 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -991,6 +991,28 @@ uint32_t TileSet::get_navigation_layer_layers(int p_layer_index) const {
return navigation_layers[p_layer_index].layers;
}
+void TileSet::set_navigation_layer_layer_value(int p_layer_index, int p_layer_number, bool p_value) {
+ ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive.");
+ ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive.");
+
+ uint32_t _navigation_layers = get_navigation_layer_layers(p_layer_index);
+
+ if (p_value) {
+ _navigation_layers |= 1 << (p_layer_number - 1);
+ } else {
+ _navigation_layers &= ~(1 << (p_layer_number - 1));
+ }
+
+ set_navigation_layer_layers(p_layer_index, _navigation_layers);
+}
+
+bool TileSet::get_navigation_layer_layer_value(int p_layer_index, int p_layer_number) const {
+ ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive.");
+ ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive.");
+
+ return get_navigation_layer_layers(p_layer_index) & (1 << (p_layer_number - 1));
+}
+
// Custom data.
int TileSet::get_custom_data_layers_count() const {
return custom_data_layers.size();
@@ -2630,6 +2652,7 @@ void TileSet::_compatibility_conversion() {
} break;
case COMPATIBILITY_TILE_MODE_AUTO_TILE: {
// Not supported. It would need manual conversion.
+ WARN_PRINT_ONCE("Could not convert 3.x autotiles to 4.x. This operation cannot be done automatically, autotiles must be re-created using the terrain system.");
} break;
case COMPATIBILITY_TILE_MODE_ATLAS_TILE: {
atlas_source->set_margins(ctd->region.get_position());
@@ -3447,6 +3470,8 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_navigation_layer", "layer_index"), &TileSet::remove_navigation_layer);
ClassDB::bind_method(D_METHOD("set_navigation_layer_layers", "layer_index", "layers"), &TileSet::set_navigation_layer_layers);
ClassDB::bind_method(D_METHOD("get_navigation_layer_layers", "layer_index"), &TileSet::get_navigation_layer_layers);
+ ClassDB::bind_method(D_METHOD("set_navigation_layer_layer_value", "layer_index", "layer_number", "value"), &TileSet::set_navigation_layer_layer_value);
+ ClassDB::bind_method(D_METHOD("get_navigation_layer_layer_value", "layer_index", "layer_number"), &TileSet::get_navigation_layer_layer_value);
// Custom data
ClassDB::bind_method(D_METHOD("get_custom_data_layers_count"), &TileSet::get_custom_data_layers_count);
@@ -4342,19 +4367,11 @@ Rect2i TileSetAtlasSource::get_tile_texture_region(Vector2i p_atlas_coords, int
return Rect2(origin, region_size);
}
-Vector2i TileSetAtlasSource::get_tile_effective_texture_offset(Vector2i p_atlas_coords, int p_alternative_tile) const {
- ERR_FAIL_COND_V_MSG(!tiles.has(p_atlas_coords), Vector2i(), vformat("TileSetAtlasSource has no tile at %s.", Vector2i(p_atlas_coords)));
- ERR_FAIL_COND_V_MSG(!has_alternative_tile(p_atlas_coords, p_alternative_tile), Vector2i(), vformat("TileSetAtlasSource has no alternative tile with id %d at %s.", p_alternative_tile, String(p_atlas_coords)));
- ERR_FAIL_COND_V(!tile_set, Vector2i());
+bool TileSetAtlasSource::is_position_in_tile_texture_region(const Vector2i p_atlas_coords, int p_alternative_tile, Vector2 p_position) const {
+ Size2 size = get_tile_texture_region(p_atlas_coords).size;
+ Rect2 rect = Rect2(-size / 2 - get_tile_data(p_atlas_coords, p_alternative_tile)->get_texture_origin(), size);
- Vector2 margin = (get_tile_texture_region(p_atlas_coords).size - tile_set->get_tile_size()) / 2;
- margin = Vector2i(MAX(0, margin.x), MAX(0, margin.y));
- Vector2i effective_texture_offset = get_tile_data(p_atlas_coords, p_alternative_tile)->get_texture_offset();
- if (ABS(effective_texture_offset.x) > margin.x || ABS(effective_texture_offset.y) > margin.y) {
- effective_texture_offset = effective_texture_offset.clamp(-margin, margin);
- }
-
- return effective_texture_offset;
+ return rect.has_point(p_position);
}
// Getters for texture and tile region (padded or not)
@@ -5106,7 +5123,7 @@ TileData *TileData::duplicate() {
output->flip_h = flip_h;
output->flip_v = flip_v;
output->transpose = transpose;
- output->tex_offset = tex_offset;
+ output->texture_origin = texture_origin;
output->material = material;
output->modulate = modulate;
output->z_index = z_index;
@@ -5156,13 +5173,13 @@ bool TileData::get_transpose() const {
return transpose;
}
-void TileData::set_texture_offset(Vector2i p_texture_offset) {
- tex_offset = p_texture_offset;
+void TileData::set_texture_origin(Vector2i p_texture_origin) {
+ texture_origin = p_texture_origin;
emit_signal(SNAME("changed"));
}
-Vector2i TileData::get_texture_offset() const {
- return tex_offset;
+Vector2i TileData::get_texture_origin() const {
+ return texture_origin;
}
void TileData::set_material(Ref<Material> p_material) {
@@ -5450,6 +5467,13 @@ Variant TileData::get_custom_data_by_layer_id(int p_layer_id) const {
}
bool TileData::_set(const StringName &p_name, const Variant &p_value) {
+#ifndef DISABLE_DEPRECATED
+ if (p_name == "texture_offset") {
+ texture_origin = p_value;
+ return true;
+ }
+#endif
+
Vector<String> components = String(p_name).split("/", true, 2);
if (components.size() == 2 && components[0].begins_with("occlusion_layer_") && components[0].trim_prefix("occlusion_layer_").is_valid_int()) {
@@ -5571,6 +5595,13 @@ bool TileData::_set(const StringName &p_name, const Variant &p_value) {
}
bool TileData::_get(const StringName &p_name, Variant &r_ret) const {
+#ifndef DISABLE_DEPRECATED
+ if (p_name == "texture_offset") {
+ r_ret = texture_origin;
+ return true;
+ }
+#endif
+
Vector<String> components = String(p_name).split("/", true, 2);
if (tile_set) {
@@ -5752,8 +5783,8 @@ void TileData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_transpose"), &TileData::get_transpose);
ClassDB::bind_method(D_METHOD("set_material", "material"), &TileData::set_material);
ClassDB::bind_method(D_METHOD("get_material"), &TileData::get_material);
- ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &TileData::set_texture_offset);
- ClassDB::bind_method(D_METHOD("get_texture_offset"), &TileData::get_texture_offset);
+ ClassDB::bind_method(D_METHOD("set_texture_origin", "texture_origin"), &TileData::set_texture_origin);
+ ClassDB::bind_method(D_METHOD("get_texture_origin"), &TileData::get_texture_origin);
ClassDB::bind_method(D_METHOD("set_modulate", "modulate"), &TileData::set_modulate);
ClassDB::bind_method(D_METHOD("get_modulate"), &TileData::get_modulate);
ClassDB::bind_method(D_METHOD("set_z_index", "z_index"), &TileData::set_z_index);
@@ -5806,7 +5837,7 @@ void TileData::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "get_flip_h");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "get_flip_v");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transpose"), "set_transpose", "get_transpose");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "texture_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_texture_offset", "get_texture_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "texture_origin", PROPERTY_HINT_NONE, "suffix:px"), "set_texture_origin", "get_texture_origin");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial,ShaderMaterial"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::INT, "z_index"), "set_z_index", "get_z_index");
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 76f1f3c185..ad25629a1c 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -476,6 +476,8 @@ public:
void remove_navigation_layer(int p_index);
void set_navigation_layer_layers(int p_layer_index, uint32_t p_layers);
uint32_t get_navigation_layer_layers(int p_layer_index) const;
+ void set_navigation_layer_layer_value(int p_layer_index, int p_layer_number, bool p_value);
+ bool get_navigation_layer_layer_value(int p_layer_index, int p_layer_number) const;
// Custom data
int get_custom_data_layers_count() const;
@@ -720,7 +722,7 @@ public:
// Helpers.
Vector2i get_atlas_grid_size() const;
Rect2i get_tile_texture_region(Vector2i p_atlas_coords, int p_frame = 0) const;
- Vector2i get_tile_effective_texture_offset(Vector2i p_atlas_coords, int p_alternative_tile) const;
+ bool is_position_in_tile_texture_region(const Vector2i p_atlas_coords, int p_alternative_tile, Vector2 p_position) const;
// Getters for texture and tile region (padded or not)
Ref<Texture2D> get_runtime_texture() const;
@@ -786,7 +788,7 @@ private:
bool flip_h = false;
bool flip_v = false;
bool transpose = false;
- Vector2i tex_offset;
+ Vector2i texture_origin;
Ref<Material> material = Ref<Material>();
Color modulate = Color(1.0, 1.0, 1.0, 1.0);
int z_index = 0;
@@ -865,8 +867,8 @@ public:
void set_transpose(bool p_transpose);
bool get_transpose() const;
- void set_texture_offset(Vector2i p_texture_offset);
- Vector2i get_texture_offset() const;
+ void set_texture_origin(Vector2i p_texture_origin);
+ Vector2i get_texture_origin() const;
void set_material(Ref<Material> p_material);
Ref<Material> get_material() const;
void set_modulate(Color p_modulate);
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index e78d9b924d..12be0f46a6 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -3690,16 +3690,47 @@ String VisualShaderNodeDerivativeFunc::get_output_port_name(int p_port) const {
String VisualShaderNodeDerivativeFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
static const char *functions[FUNC_MAX] = {
- "fwidth($)",
- "dFdx($)",
- "dFdy($)"
+ "fwidth$($)",
+ "dFdx$($)",
+ "dFdy$($)"
+ };
+
+ static const char *precisions[PRECISION_MAX] = {
+ "",
+ "Coarse",
+ "Fine"
};
String code;
- code += " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n";
+ if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
+ code += " " + p_output_vars[0] + " = " + String(functions[func]).replace_first("$", "").replace_first("$", p_input_vars[0]) + ";\n";
+ return code;
+ }
+
+ code += " " + p_output_vars[0] + " = " + String(functions[func]).replace_first("$", String(precisions[precision])).replace_first("$", p_input_vars[0]) + ";\n";
return code;
}
+String VisualShaderNodeDerivativeFunc::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
+ if (precision != PRECISION_NONE && OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
+ String precision_str;
+ switch (precision) {
+ case PRECISION_COARSE: {
+ precision_str = "Coarse";
+ } break;
+ case PRECISION_FINE: {
+ precision_str = "Fine";
+ } break;
+ default: {
+ } break;
+ }
+
+ return vformat(RTR("`%s` precision mode is not available for `gl_compatibility` profile.\nReverted to `None` precision."), precision_str);
+ }
+
+ return String();
+}
+
void VisualShaderNodeDerivativeFunc::set_op_type(OpType p_op_type) {
ERR_FAIL_INDEX((int)p_op_type, int(OP_TYPE_MAX));
if (op_type == p_op_type) {
@@ -3742,10 +3773,24 @@ VisualShaderNodeDerivativeFunc::Function VisualShaderNodeDerivativeFunc::get_fun
return func;
}
+void VisualShaderNodeDerivativeFunc::set_precision(Precision p_precision) {
+ ERR_FAIL_INDEX(int(p_precision), int(PRECISION_MAX));
+ if (precision == p_precision) {
+ return;
+ }
+ precision = p_precision;
+ emit_changed();
+}
+
+VisualShaderNodeDerivativeFunc::Precision VisualShaderNodeDerivativeFunc::get_precision() const {
+ return precision;
+}
+
Vector<StringName> VisualShaderNodeDerivativeFunc::get_editable_properties() const {
Vector<StringName> props;
props.push_back("op_type");
props.push_back("function");
+ props.push_back("precision");
return props;
}
@@ -3756,8 +3801,12 @@ void VisualShaderNodeDerivativeFunc::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeDerivativeFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeDerivativeFunc::get_function);
+ ClassDB::bind_method(D_METHOD("set_precision", "precision"), &VisualShaderNodeDerivativeFunc::set_precision);
+ ClassDB::bind_method(D_METHOD("get_precision"), &VisualShaderNodeDerivativeFunc::get_precision);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3,Vector4"), "set_op_type", "get_op_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sum,X,Y"), "set_function", "get_function");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "precision", PROPERTY_HINT_ENUM, "None,Coarse,Fine"), "set_precision", "get_precision");
BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
@@ -3769,6 +3818,11 @@ void VisualShaderNodeDerivativeFunc::_bind_methods() {
BIND_ENUM_CONSTANT(FUNC_X);
BIND_ENUM_CONSTANT(FUNC_Y);
BIND_ENUM_CONSTANT(FUNC_MAX);
+
+ BIND_ENUM_CONSTANT(PRECISION_NONE);
+ BIND_ENUM_CONSTANT(PRECISION_COARSE);
+ BIND_ENUM_CONSTANT(PRECISION_FINE);
+ BIND_ENUM_CONSTANT(PRECISION_MAX);
}
VisualShaderNodeDerivativeFunc::VisualShaderNodeDerivativeFunc() {
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index e3b101cf84..fa6b134526 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1536,9 +1536,17 @@ public:
FUNC_MAX,
};
+ enum Precision {
+ PRECISION_NONE,
+ PRECISION_COARSE,
+ PRECISION_FINE,
+ PRECISION_MAX,
+ };
+
protected:
OpType op_type = OP_TYPE_SCALAR;
Function func = FUNC_SUM;
+ Precision precision = PRECISION_NONE;
protected:
static void _bind_methods();
@@ -1555,6 +1563,7 @@ public:
virtual String get_output_port_name(int p_port) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
void set_op_type(OpType p_op_type);
OpType get_op_type() const;
@@ -1562,6 +1571,9 @@ public:
void set_function(Function p_func);
Function get_function() const;
+ void set_precision(Precision p_precision);
+ Precision get_precision() const;
+
virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeDerivativeFunc();
@@ -1569,6 +1581,7 @@ public:
VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::OpType)
VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::Function)
+VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::Precision)
///////////////////////////////////////
/// FACEFORWARD