summaryrefslogtreecommitdiffstats
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/2d/navigation_mesh_source_geometry_data_2d.h2
-rw-r--r--scene/resources/2d/navigation_polygon.cpp4
-rw-r--r--scene/resources/2d/navigation_polygon.h5
-rw-r--r--scene/resources/2d/skeleton/skeleton_modification_stack_2d.h2
-rw-r--r--scene/resources/2d/tile_set.cpp48
-rw-r--r--scene/resources/2d/tile_set.h5
-rw-r--r--scene/resources/3d/convex_polygon_shape_3d.cpp2
-rw-r--r--scene/resources/3d/importer_mesh.cpp103
-rw-r--r--scene/resources/3d/importer_mesh.h2
-rw-r--r--scene/resources/3d/shape_3d.cpp2
-rw-r--r--scene/resources/audio_stream_wav.cpp2
-rw-r--r--scene/resources/curve.cpp21
-rw-r--r--scene/resources/environment.cpp5
-rw-r--r--scene/resources/font.cpp42
-rw-r--r--scene/resources/mesh.cpp6
-rw-r--r--scene/resources/navigation_mesh.cpp4
-rw-r--r--scene/resources/packed_scene.cpp20
-rw-r--r--scene/resources/portable_compressed_texture.cpp4
-rw-r--r--scene/resources/resource_format_text.cpp35
-rw-r--r--scene/resources/resource_format_text.h1
-rw-r--r--scene/resources/surface_tool.cpp2
-rw-r--r--scene/resources/surface_tool.h8
-rw-r--r--scene/resources/syntax_highlighter.cpp4
-rw-r--r--scene/resources/text_paragraph.cpp45
-rw-r--r--scene/resources/text_paragraph.h6
-rw-r--r--scene/resources/texture_rd.cpp2
-rw-r--r--scene/resources/visual_shader.cpp6
27 files changed, 278 insertions, 110 deletions
diff --git a/scene/resources/2d/navigation_mesh_source_geometry_data_2d.h b/scene/resources/2d/navigation_mesh_source_geometry_data_2d.h
index b29c106fb5..2812925770 100644
--- a/scene/resources/2d/navigation_mesh_source_geometry_data_2d.h
+++ b/scene/resources/2d/navigation_mesh_source_geometry_data_2d.h
@@ -36,6 +36,8 @@
#include "scene/resources/2d/navigation_polygon.h"
class NavigationMeshSourceGeometryData2D : public Resource {
+ friend class NavMeshGenerator2D;
+
GDCLASS(NavigationMeshSourceGeometryData2D, Resource);
RWLock geometry_rwlock;
diff --git a/scene/resources/2d/navigation_polygon.cpp b/scene/resources/2d/navigation_polygon.cpp
index 3dfa906e3b..37240e8038 100644
--- a/scene/resources/2d/navigation_polygon.cpp
+++ b/scene/resources/2d/navigation_polygon.cpp
@@ -36,7 +36,7 @@
#include "thirdparty/misc/polypartition.h"
-#ifdef TOOLS_ENABLED
+#ifdef DEBUG_ENABLED
Rect2 NavigationPolygon::_edit_get_rect() const {
RWLockRead read_lock(rwlock);
if (rect_cache_dirty) {
@@ -79,7 +79,7 @@ bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double
}
return false;
}
-#endif
+#endif // DEBUG_ENABLED
void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) {
RWLockWrite write_lock(rwlock);
diff --git a/scene/resources/2d/navigation_polygon.h b/scene/resources/2d/navigation_polygon.h
index ed2c606c55..59e5eeed68 100644
--- a/scene/resources/2d/navigation_polygon.h
+++ b/scene/resources/2d/navigation_polygon.h
@@ -68,10 +68,11 @@ protected:
TypedArray<Vector<Vector2>> _get_outlines() const;
public:
-#ifdef TOOLS_ENABLED
+#ifdef DEBUG_ENABLED
Rect2 _edit_get_rect() const;
bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
-#endif
+#endif // DEBUG_ENABLED
+
enum SamplePartitionType {
SAMPLE_PARTITION_CONVEX_PARTITION = 0,
SAMPLE_PARTITION_TRIANGULATE,
diff --git a/scene/resources/2d/skeleton/skeleton_modification_stack_2d.h b/scene/resources/2d/skeleton/skeleton_modification_stack_2d.h
index 0732153997..d1e50cb702 100644
--- a/scene/resources/2d/skeleton/skeleton_modification_stack_2d.h
+++ b/scene/resources/2d/skeleton/skeleton_modification_stack_2d.h
@@ -64,7 +64,7 @@ public:
execution_mode_physics_process
};
- Vector<Ref<SkeletonModification2D>> modifications = Vector<Ref<SkeletonModification2D>>();
+ Vector<Ref<SkeletonModification2D>> modifications;
void setup();
void execute(float p_delta, int p_execution_mode);
diff --git a/scene/resources/2d/tile_set.cpp b/scene/resources/2d/tile_set.cpp
index ca80486363..5ecfc32622 100644
--- a/scene/resources/2d/tile_set.cpp
+++ b/scene/resources/2d/tile_set.cpp
@@ -699,6 +699,17 @@ uint32_t TileSet::get_physics_layer_collision_mask(int p_layer_index) const {
return physics_layers[p_layer_index].collision_mask;
}
+void TileSet::set_physics_layer_collision_priority(int p_layer_index, real_t p_priority) {
+ ERR_FAIL_INDEX(p_layer_index, physics_layers.size());
+ physics_layers.write[p_layer_index].collision_priority = p_priority;
+ emit_changed();
+}
+
+real_t TileSet::get_physics_layer_collision_priority(int p_layer_index) const {
+ ERR_FAIL_INDEX_V(p_layer_index, physics_layers.size(), 0);
+ return physics_layers[p_layer_index].collision_priority;
+}
+
void TileSet::set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material) {
ERR_FAIL_INDEX(p_layer_index, physics_layers.size());
physics_layers.write[p_layer_index].physics_material = p_physics_material;
@@ -3900,6 +3911,13 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
}
set_physics_layer_collision_mask(index, p_value);
return true;
+ } else if (components[1] == "collision_priority") {
+ ERR_FAIL_COND_V(p_value.get_type() != Variant::FLOAT, false);
+ while (index >= physics_layers.size()) {
+ add_physics_layer();
+ }
+ set_physics_layer_collision_priority(index, p_value);
+ return true;
} else if (components[1] == "physics_material") {
Ref<PhysicsMaterial> physics_material = p_value;
while (index >= physics_layers.size()) {
@@ -4051,6 +4069,9 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
} else if (components[1] == "collision_mask") {
r_ret = get_physics_layer_collision_mask(index);
return true;
+ } else if (components[1] == "collision_priority") {
+ r_ret = get_physics_layer_collision_priority(index);
+ return true;
} else if (components[1] == "physics_material") {
r_ret = get_physics_layer_physics_material(index);
return true;
@@ -4176,6 +4197,13 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
}
p_list->push_back(property_info);
+ // physics_layer_%d/collision_priority
+ property_info = PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/collision_priority", i));
+ if (physics_layers[i].collision_priority == 1.0) {
+ property_info.usage ^= PROPERTY_USAGE_STORAGE;
+ }
+ p_list->push_back(property_info);
+
// physics_layer_%d/physics_material
property_info = PropertyInfo(Variant::OBJECT, vformat("physics_layer_%d/physics_material", i), PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial");
if (!physics_layers[i].physics_material.is_valid()) {
@@ -4220,10 +4248,10 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
// Tile Proxies.
// Note: proxies need to be set after sources are set.
- p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Tile Proxies", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
- p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/source_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
- p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/coords_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
- p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/alternative_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::NIL, "Tile Proxies", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/source_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/coords_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/alternative_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
// Patterns.
for (unsigned int pattern_index = 0; pattern_index < patterns.size(); pattern_index++) {
@@ -4287,6 +4315,8 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_physics_layer_collision_layer", "layer_index"), &TileSet::get_physics_layer_collision_layer);
ClassDB::bind_method(D_METHOD("set_physics_layer_collision_mask", "layer_index", "mask"), &TileSet::set_physics_layer_collision_mask);
ClassDB::bind_method(D_METHOD("get_physics_layer_collision_mask", "layer_index"), &TileSet::get_physics_layer_collision_mask);
+ ClassDB::bind_method(D_METHOD("set_physics_layer_collision_priority", "layer_index", "priority"), &TileSet::set_physics_layer_collision_priority);
+ ClassDB::bind_method(D_METHOD("get_physics_layer_collision_priority", "layer_index"), &TileSet::get_physics_layer_collision_priority);
ClassDB::bind_method(D_METHOD("set_physics_layer_physics_material", "layer_index", "physics_material"), &TileSet::set_physics_layer_physics_material);
ClassDB::bind_method(D_METHOD("get_physics_layer_physics_material", "layer_index"), &TileSet::get_physics_layer_physics_material);
@@ -4931,10 +4961,13 @@ void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const {
}
for (const KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) {
+ const String formatted_key = itos(E_alternative.key);
+
// Add a dummy property to show the alternative exists.
- tile_property_list.push_back(PropertyInfo(Variant::INT, vformat("%d", E_alternative.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+ tile_property_list.push_back(PropertyInfo(Variant::INT, formatted_key, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
// Get the alternative tile's properties and append them to the list of properties.
+ const String alternative_property_info_prefix = formatted_key + '/';
List<PropertyInfo> alternative_property_list;
E_alternative.value->get_property_list(&alternative_property_list);
for (PropertyInfo &alternative_property_info : alternative_property_list) {
@@ -4943,14 +4976,15 @@ void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const {
if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) {
alternative_property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
- alternative_property_info.name = vformat("%s/%s", vformat("%d", E_alternative.key), alternative_property_info.name);
+ alternative_property_info.name = alternative_property_info_prefix + alternative_property_info.name;
tile_property_list.push_back(alternative_property_info);
}
}
// Add all alternative.
+ const String property_info_prefix = vformat("%d:%d/", E_tile.key.x, E_tile.key.y);
for (PropertyInfo &tile_property_info : tile_property_list) {
- tile_property_info.name = vformat("%s/%s", vformat("%d:%d", E_tile.key.x, E_tile.key.y), tile_property_info.name);
+ tile_property_info.name = property_info_prefix + tile_property_info.name;
p_list->push_back(tile_property_info);
}
}
diff --git a/scene/resources/2d/tile_set.h b/scene/resources/2d/tile_set.h
index 7979e2ca39..6d3ccd1d2d 100644
--- a/scene/resources/2d/tile_set.h
+++ b/scene/resources/2d/tile_set.h
@@ -327,6 +327,7 @@ private:
struct PhysicsLayer {
uint32_t collision_layer = 1;
uint32_t collision_mask = 1;
+ real_t collision_priority = 1.0;
Ref<PhysicsMaterial> physics_material;
};
Vector<PhysicsLayer> physics_layers;
@@ -448,6 +449,8 @@ public:
uint32_t get_physics_layer_collision_layer(int p_layer_index) const;
void set_physics_layer_collision_mask(int p_layer_index, uint32_t p_mask);
uint32_t get_physics_layer_collision_mask(int p_layer_index) const;
+ void set_physics_layer_collision_priority(int p_layer_index, real_t p_priority);
+ real_t get_physics_layer_collision_priority(int p_layer_index) const;
void set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material);
Ref<PhysicsMaterial> get_physics_layer_physics_material(int p_layer_index) const;
@@ -836,7 +839,7 @@ private:
bool flip_v = false;
bool transpose = false;
Vector2i texture_origin;
- Ref<Material> material = Ref<Material>();
+ Ref<Material> material;
Color modulate = Color(1.0, 1.0, 1.0, 1.0);
int z_index = 0;
int y_sort_origin = 0;
diff --git a/scene/resources/3d/convex_polygon_shape_3d.cpp b/scene/resources/3d/convex_polygon_shape_3d.cpp
index 3bfeeca461..586d5f4678 100644
--- a/scene/resources/3d/convex_polygon_shape_3d.cpp
+++ b/scene/resources/3d/convex_polygon_shape_3d.cpp
@@ -35,7 +35,7 @@
Vector<Vector3> ConvexPolygonShape3D::get_debug_mesh_lines() const {
Vector<Vector3> poly_points = get_points();
- if (poly_points.size() > 3) {
+ if (poly_points.size() > 1) { // Need at least 2 points for a line.
Vector<Vector3> varr = Variant(poly_points);
Geometry3D::MeshData md;
Error err = ConvexHullComputer::convex_hull(varr, md);
diff --git a/scene/resources/3d/importer_mesh.cpp b/scene/resources/3d/importer_mesh.cpp
index e255cb077f..f040f04cd8 100644
--- a/scene/resources/3d/importer_mesh.cpp
+++ b/scene/resources/3d/importer_mesh.cpp
@@ -168,10 +168,56 @@ void ImporterMesh::set_surface_material(int p_surface, const Ref<Material> &p_ma
mesh.unref();
}
-void ImporterMesh::optimize_indices_for_cache() {
+template <typename T>
+static Vector<T> _remap_array(Vector<T> p_array, const Vector<uint32_t> &p_remap, uint32_t p_vertex_count) {
+ ERR_FAIL_COND_V(p_array.size() % p_remap.size() != 0, p_array);
+ int num_elements = p_array.size() / p_remap.size();
+ T *data = p_array.ptrw();
+ SurfaceTool::remap_vertex_func(data, data, p_remap.size(), sizeof(T) * num_elements, p_remap.ptr());
+ p_array.resize(p_vertex_count * num_elements);
+ return p_array;
+}
+
+static void _remap_arrays(Array &r_arrays, const Vector<uint32_t> &p_remap, uint32_t p_vertex_count) {
+ for (int i = 0; i < r_arrays.size(); i++) {
+ if (i == RS::ARRAY_INDEX) {
+ continue;
+ }
+
+ switch (r_arrays[i].get_type()) {
+ case Variant::NIL:
+ break;
+ case Variant::PACKED_VECTOR3_ARRAY:
+ r_arrays[i] = _remap_array<Vector3>(r_arrays[i], p_remap, p_vertex_count);
+ break;
+ case Variant::PACKED_VECTOR2_ARRAY:
+ r_arrays[i] = _remap_array<Vector2>(r_arrays[i], p_remap, p_vertex_count);
+ break;
+ case Variant::PACKED_FLOAT32_ARRAY:
+ r_arrays[i] = _remap_array<float>(r_arrays[i], p_remap, p_vertex_count);
+ break;
+ case Variant::PACKED_INT32_ARRAY:
+ r_arrays[i] = _remap_array<int32_t>(r_arrays[i], p_remap, p_vertex_count);
+ break;
+ case Variant::PACKED_BYTE_ARRAY:
+ r_arrays[i] = _remap_array<uint8_t>(r_arrays[i], p_remap, p_vertex_count);
+ break;
+ case Variant::PACKED_COLOR_ARRAY:
+ r_arrays[i] = _remap_array<Color>(r_arrays[i], p_remap, p_vertex_count);
+ break;
+ default:
+ ERR_FAIL_MSG("Unhandled array type.");
+ }
+ }
+}
+
+void ImporterMesh::optimize_indices() {
if (!SurfaceTool::optimize_vertex_cache_func) {
return;
}
+ if (!SurfaceTool::optimize_vertex_fetch_remap_func || !SurfaceTool::remap_vertex_func || !SurfaceTool::remap_index_func) {
+ return;
+ }
for (int i = 0; i < surfaces.size(); i++) {
if (surfaces[i].primitive != Mesh::PRIMITIVE_TRIANGLES) {
@@ -188,10 +234,48 @@ void ImporterMesh::optimize_indices_for_cache() {
continue;
}
+ // Optimize indices for vertex cache to establish final triangle order.
int *indices_ptr = indices.ptrw();
SurfaceTool::optimize_vertex_cache_func((unsigned int *)indices_ptr, (const unsigned int *)indices_ptr, index_count, vertex_count);
+ surfaces.write[i].arrays[RS::ARRAY_INDEX] = indices;
+
+ for (int j = 0; j < surfaces[i].lods.size(); ++j) {
+ Surface::LOD &lod = surfaces.write[i].lods.write[j];
+ int *lod_indices_ptr = lod.indices.ptrw();
+ SurfaceTool::optimize_vertex_cache_func((unsigned int *)lod_indices_ptr, (const unsigned int *)lod_indices_ptr, lod.indices.size(), vertex_count);
+ }
+ // Concatenate indices for all LODs in the order of coarse->fine; this establishes the effective order of vertices,
+ // and is important to optimize for vertex fetch (all GPUs) and shading (Mali GPUs)
+ PackedInt32Array merged_indices;
+ for (int j = surfaces[i].lods.size() - 1; j >= 0; --j) {
+ merged_indices.append_array(surfaces[i].lods[j].indices);
+ }
+ merged_indices.append_array(indices);
+
+ // Generate remap array that establishes optimal vertex order according to the order of indices above.
+ Vector<uint32_t> remap;
+ remap.resize(vertex_count);
+ unsigned int new_vertex_count = SurfaceTool::optimize_vertex_fetch_remap_func(remap.ptrw(), (const unsigned int *)merged_indices.ptr(), merged_indices.size(), vertex_count);
+
+ // We need to remap all vertex and index arrays in lockstep according to the remap.
+ SurfaceTool::remap_index_func((unsigned int *)indices_ptr, (const unsigned int *)indices_ptr, index_count, remap.ptr());
surfaces.write[i].arrays[RS::ARRAY_INDEX] = indices;
+
+ for (int j = 0; j < surfaces[i].lods.size(); ++j) {
+ Surface::LOD &lod = surfaces.write[i].lods.write[j];
+ int *lod_indices_ptr = lod.indices.ptrw();
+ SurfaceTool::remap_index_func((unsigned int *)lod_indices_ptr, (const unsigned int *)lod_indices_ptr, lod.indices.size(), remap.ptr());
+ }
+
+ _remap_arrays(surfaces.write[i].arrays, remap, new_vertex_count);
+ for (int j = 0; j < surfaces[i].blend_shape_data.size(); j++) {
+ _remap_arrays(surfaces.write[i].blend_shape_data.write[j].arrays, remap, new_vertex_count);
+ }
+ }
+
+ if (shadow_mesh.is_valid()) {
+ shadow_mesh->optimize_indices();
}
}
@@ -215,9 +299,6 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transf
if (!SurfaceTool::simplify_with_attrib_func) {
return;
}
- if (!SurfaceTool::optimize_vertex_cache_func) {
- return;
- }
LocalVector<Transform3D> bone_transform_vector;
for (int i = 0; i < p_bone_transform_array.size(); i++) {
@@ -431,12 +512,6 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transf
}
surfaces.write[i].lods.sort_custom<Surface::LODComparator>();
-
- for (int j = 0; j < surfaces.write[i].lods.size(); j++) {
- Surface::LOD &lod = surfaces.write[i].lods.write[j];
- unsigned int *lod_indices_ptr = (unsigned int *)lod.indices.ptrw();
- SurfaceTool::optimize_vertex_cache_func(lod_indices_ptr, lod_indices_ptr, lod.indices.size(), vertex_count);
- }
}
}
@@ -574,10 +649,6 @@ void ImporterMesh::create_shadow_mesh() {
index_wptr[j] = vertex_remap[index];
}
- if (SurfaceTool::optimize_vertex_cache_func && surfaces[i].primitive == Mesh::PRIMITIVE_TRIANGLES) {
- SurfaceTool::optimize_vertex_cache_func((unsigned int *)index_wptr, (const unsigned int *)index_wptr, index_count, new_vertices.size());
- }
-
new_surface[RS::ARRAY_INDEX] = new_indices;
// Make sure the same LODs as the full version are used.
@@ -596,10 +667,6 @@ void ImporterMesh::create_shadow_mesh() {
index_wptr[k] = vertex_remap[index];
}
- if (SurfaceTool::optimize_vertex_cache_func && surfaces[i].primitive == Mesh::PRIMITIVE_TRIANGLES) {
- SurfaceTool::optimize_vertex_cache_func((unsigned int *)index_wptr, (const unsigned int *)index_wptr, index_count, new_vertices.size());
- }
-
lods[surfaces[i].lods[j].distance] = new_indices;
}
}
diff --git a/scene/resources/3d/importer_mesh.h b/scene/resources/3d/importer_mesh.h
index 7776e78f11..2bdf759da6 100644
--- a/scene/resources/3d/importer_mesh.h
+++ b/scene/resources/3d/importer_mesh.h
@@ -113,7 +113,7 @@ public:
void set_surface_material(int p_surface, const Ref<Material> &p_material);
- void optimize_indices_for_cache();
+ void optimize_indices();
void generate_lods(float p_normal_merge_angle, Array p_skin_pose_transform_array);
diff --git a/scene/resources/3d/shape_3d.cpp b/scene/resources/3d/shape_3d.cpp
index 5a79392ba5..259d82b7a0 100644
--- a/scene/resources/3d/shape_3d.cpp
+++ b/scene/resources/3d/shape_3d.cpp
@@ -73,7 +73,7 @@ Ref<ArrayMesh> Shape3D::get_debug_mesh() {
Vector<Vector3> lines = get_debug_mesh_lines();
- debug_mesh_cache = Ref<ArrayMesh>(memnew(ArrayMesh));
+ debug_mesh_cache.instantiate();
if (!lines.is_empty()) {
//make mesh
diff --git a/scene/resources/audio_stream_wav.cpp b/scene/resources/audio_stream_wav.cpp
index f9787dde2e..539001bf25 100644
--- a/scene/resources/audio_stream_wav.cpp
+++ b/scene/resources/audio_stream_wav.cpp
@@ -624,7 +624,7 @@ Error AudioStreamWAV::save_to_wav(const String &p_path) {
}
String file_path = p_path;
- if (!(file_path.substr(file_path.length() - 4, 4) == ".wav")) {
+ if (file_path.substr(file_path.length() - 4, 4).to_lower() != ".wav") {
file_path += ".wav";
}
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index dc509a4669..91d3757590 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -479,6 +479,9 @@ void Curve::set_bake_resolution(int p_resolution) {
}
real_t Curve::sample_baked(real_t p_offset) const {
+ // Make sure that p_offset is finite.
+ ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), 0, "Offset is non-finite");
+
if (_baked_cache_dirty) {
// Last-second bake if not done already
const_cast<Curve *>(this)->bake();
@@ -981,6 +984,9 @@ Transform2D Curve2D::_sample_posture(Interval p_interval) const {
}
Vector2 Curve2D::sample_baked(real_t p_offset, bool p_cubic) const {
+ // Make sure that p_offset is finite.
+ ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), Vector2(), "Offset is non-finite");
+
if (baked_cache_dirty) {
_bake();
}
@@ -1000,6 +1006,9 @@ Vector2 Curve2D::sample_baked(real_t p_offset, bool p_cubic) const {
}
Transform2D Curve2D::sample_baked_with_rotation(real_t p_offset, bool p_cubic) const {
+ // Make sure that p_offset is finite.
+ ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), Transform2D(), "Offset is non-finite");
+
if (baked_cache_dirty) {
_bake();
}
@@ -1908,6 +1917,9 @@ Basis Curve3D::get_point_baked_posture(int p_index, bool p_apply_tilt) const {
#endif
Vector3 Curve3D::sample_baked(real_t p_offset, bool p_cubic) const {
+ // Make sure that p_offset is finite.
+ ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), Vector3(), "Offset is non-finite");
+
if (baked_cache_dirty) {
_bake();
}
@@ -1927,6 +1939,9 @@ Vector3 Curve3D::sample_baked(real_t p_offset, bool p_cubic) const {
}
Transform3D Curve3D::sample_baked_with_rotation(real_t p_offset, bool p_cubic, bool p_apply_tilt) const {
+ // Make sure that p_offset is finite.
+ ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), Transform3D(), "Offset is non-finite");
+
if (baked_cache_dirty) {
_bake();
}
@@ -1956,6 +1971,9 @@ Transform3D Curve3D::sample_baked_with_rotation(real_t p_offset, bool p_cubic, b
}
real_t Curve3D::sample_baked_tilt(real_t p_offset) const {
+ // Make sure that p_offset is finite.
+ ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), 0, "Offset is non-finite");
+
if (baked_cache_dirty) {
_bake();
}
@@ -1975,6 +1993,9 @@ real_t Curve3D::sample_baked_tilt(real_t p_offset) const {
}
Vector3 Curve3D::sample_baked_up_vector(real_t p_offset, bool p_apply_tilt) const {
+ // Make sure that p_offset is finite.
+ ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), Vector3(0, 1, 0), "Offset is non-finite");
+
if (baked_cache_dirty) {
_bake();
}
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index f8c70c3002..b5e23e9832 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -130,10 +130,7 @@ int Environment::get_canvas_max_layer() const {
void Environment::set_camera_feed_id(int p_id) {
bg_camera_feed_id = p_id;
-// FIXME: Disabled during Vulkan refactoring, should be ported.
-#if 0
- RS::get_singleton()->environment_set_camera_feed_id(environment, camera_feed_id);
-#endif
+ RS::get_singleton()->environment_set_camera_feed_id(environment, bg_camera_feed_id);
}
int Environment::get_camera_feed_id() const {
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 5e4136f449..ae70443e6a 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -647,13 +647,13 @@ void FontFile::_convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz)
wa[ofs_dst + 1] = r[ofs_src + 3];
}
}
- Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r));
+ Ref<Image> img_r = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_r));
set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r);
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
+ Ref<Image> img_g = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_g));
set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g);
- Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b));
+ Ref<Image> img_b = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_b));
set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b);
- Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a));
+ Ref<Image> img_a = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_a));
set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
}
@@ -738,22 +738,22 @@ void FontFile::_convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz)
}
}
}
- Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r));
+ Ref<Image> img_r = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_r));
set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r);
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
+ Ref<Image> img_g = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_g));
set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g);
- Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b));
+ Ref<Image> img_b = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_b));
set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b);
- Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a));
+ Ref<Image> img_a = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_a));
set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
- Ref<Image> img_ro = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ro));
+ Ref<Image> img_ro = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_ro));
set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 0, img_ro);
- Ref<Image> img_go = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_go));
+ Ref<Image> img_go = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_go));
set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 1, img_go);
- Ref<Image> img_bo = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_bo));
+ Ref<Image> img_bo = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_bo));
set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 2, img_bo);
- Ref<Image> img_ao = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ao));
+ Ref<Image> img_ao = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_ao));
set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 3, img_ao);
}
@@ -806,10 +806,10 @@ void FontFile::_convert_rgba_4bit(Ref<Image> &p_source, int p_page, int p_sz) {
}
}
}
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_g));
+ Ref<Image> img_g = memnew(Image(w, h, false, Image::FORMAT_RGBA8, imgdata_g));
set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g);
- Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_o));
+ Ref<Image> img_o = memnew(Image(w, h, false, Image::FORMAT_RGBA8, imgdata_o));
set_texture_image(0, Vector2i(p_sz, 1), p_page, img_o);
}
@@ -838,7 +838,7 @@ void FontFile::_convert_mono_8bit(Ref<Image> &p_source, int p_page, int p_ch, in
wg[ofs_dst + 1] = r[ofs_src + p_ch];
}
}
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
+ Ref<Image> img_g = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_g));
set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_g);
}
@@ -878,10 +878,10 @@ void FontFile::_convert_mono_4bit(Ref<Image> &p_source, int p_page, int p_ch, in
}
}
}
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
+ Ref<Image> img_g = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_g));
set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g);
- Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_o));
+ Ref<Image> img_o = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_o));
set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_o);
}
@@ -1734,7 +1734,7 @@ Error FontFile::_load_bitmap_font(const String &p_path, List<String> *r_image_fi
while (true) {
String line = f->get_line();
- int delimiter = line.find(" ");
+ int delimiter = line.find_char(' ');
String type = line.substr(0, delimiter);
int pos = delimiter + 1;
HashMap<String, String> keys;
@@ -1744,7 +1744,7 @@ Error FontFile::_load_bitmap_font(const String &p_path, List<String> *r_image_fi
}
while (pos < line.size()) {
- int eq = line.find("=", pos);
+ int eq = line.find_char('=', pos);
if (eq == -1) {
break;
}
@@ -1752,14 +1752,14 @@ Error FontFile::_load_bitmap_font(const String &p_path, List<String> *r_image_fi
int end = -1;
String value;
if (line[eq + 1] == '"') {
- end = line.find("\"", eq + 2);
+ end = line.find_char('"', eq + 2);
if (end == -1) {
break;
}
value = line.substr(eq + 2, end - 1 - eq - 1);
pos = end + 1;
} else {
- end = line.find(" ", eq + 1);
+ end = line.find_char(' ', eq + 1);
if (end == -1) {
end = line.size();
}
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 848ae2713d..8c0e087902 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -385,7 +385,7 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
}
}
- triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh));
+ triangle_mesh.instantiate();
triangle_mesh->create(faces);
return triangle_mesh;
@@ -1315,7 +1315,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
String sname = p_name;
if (sname.begins_with("surface_")) {
- int sl = sname.find("/");
+ int sl = sname.find_char('/');
if (sl == -1) {
return false;
}
@@ -1708,7 +1708,7 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
String sname = p_name;
if (sname.begins_with("surface_")) {
- int sl = sname.find("/");
+ int sl = sname.find_char('/');
if (sl == -1) {
return false;
}
diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp
index 67ed65df0d..034d4d6996 100644
--- a/scene/resources/navigation_mesh.cpp
+++ b/scene/resources/navigation_mesh.cpp
@@ -392,8 +392,8 @@ Ref<ArrayMesh> NavigationMesh::get_debug_mesh() {
return debug_mesh;
}
- if (!debug_mesh.is_valid()) {
- debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
+ if (debug_mesh.is_null()) {
+ debug_mesh.instantiate();
} else {
debug_mesh->clear_surfaces();
}
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index d6fe4385c4..d7036fd6d5 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -786,7 +786,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
Dictionary missing_resource_properties = p_node->get_meta(META_MISSING_RESOURCES, Dictionary());
for (const PropertyInfo &E : plist) {
- if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
+ if (!(E.usage & PROPERTY_USAGE_STORAGE) && !missing_resource_properties.has(E.name)) {
continue;
}
@@ -822,10 +822,10 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
value = missing_resource_properties[E.name];
}
} else if (E.type == Variant::ARRAY && E.hint == PROPERTY_HINT_TYPE_STRING) {
- int hint_subtype_separator = E.hint_string.find(":");
+ int hint_subtype_separator = E.hint_string.find_char(':');
if (hint_subtype_separator >= 0) {
String subtype_string = E.hint_string.substr(0, hint_subtype_separator);
- int slash_pos = subtype_string.find("/");
+ int slash_pos = subtype_string.find_char('/');
PropertyHint subtype_hint = PropertyHint::PROPERTY_HINT_NONE;
if (slash_pos >= 0) {
subtype_hint = PropertyHint(subtype_string.get_slice("/", 1).to_int());
@@ -851,11 +851,11 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
}
}
} else if (E.type == Variant::DICTIONARY && E.hint == PROPERTY_HINT_TYPE_STRING) {
- int key_value_separator = E.hint_string.find(";");
+ int key_value_separator = E.hint_string.find_char(';');
if (key_value_separator >= 0) {
- int key_subtype_separator = E.hint_string.find(":");
+ int key_subtype_separator = E.hint_string.find_char(':');
String key_subtype_string = E.hint_string.substr(0, key_subtype_separator);
- int key_slash_pos = key_subtype_string.find("/");
+ int key_slash_pos = key_subtype_string.find_char('/');
PropertyHint key_subtype_hint = PropertyHint::PROPERTY_HINT_NONE;
if (key_slash_pos >= 0) {
key_subtype_hint = PropertyHint(key_subtype_string.get_slice("/", 1).to_int());
@@ -864,9 +864,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
Variant::Type key_subtype = Variant::Type(key_subtype_string.to_int());
bool convert_key = key_subtype == Variant::OBJECT && key_subtype_hint == PROPERTY_HINT_NODE_TYPE;
- int value_subtype_separator = E.hint_string.find(":", key_value_separator) - (key_value_separator + 1);
+ int value_subtype_separator = E.hint_string.find_char(':', key_value_separator) - (key_value_separator + 1);
String value_subtype_string = E.hint_string.substr(key_value_separator + 1, value_subtype_separator);
- int value_slash_pos = value_subtype_string.find("/");
+ int value_slash_pos = value_subtype_string.find_char('/');
PropertyHint value_subtype_hint = PropertyHint::PROPERTY_HINT_NONE;
if (value_slash_pos >= 0) {
value_subtype_hint = PropertyHint(value_subtype_string.get_slice("/", 1).to_int());
@@ -2195,7 +2195,7 @@ void PackedScene::replace_state(Ref<SceneState> p_by) {
}
void PackedScene::recreate_state() {
- state = Ref<SceneState>(memnew(SceneState));
+ state.instantiate();
state->set_path(get_path());
#ifdef TOOLS_ENABLED
state->set_last_modified_time(get_last_modified_time());
@@ -2286,5 +2286,5 @@ void PackedScene::_bind_methods() {
}
PackedScene::PackedScene() {
- state = Ref<SceneState>(memnew(SceneState));
+ state.instantiate();
}
diff --git a/scene/resources/portable_compressed_texture.cpp b/scene/resources/portable_compressed_texture.cpp
index 06b5ec6d5a..55bbed7c47 100644
--- a/scene/resources/portable_compressed_texture.cpp
+++ b/scene/resources/portable_compressed_texture.cpp
@@ -89,7 +89,7 @@ void PortableCompressedTexture2D::_set_data(const Vector<uint8_t> &p_data) {
data_size -= mipsize;
}
- image = Ref<Image>(memnew(Image(size.width, size.height, mipmaps, format, image_data)));
+ image.instantiate(size.width, size.height, mipmaps, format, image_data);
} break;
case COMPRESSION_MODE_BASIS_UNIVERSAL: {
@@ -100,7 +100,7 @@ void PortableCompressedTexture2D::_set_data(const Vector<uint8_t> &p_data) {
case COMPRESSION_MODE_S3TC:
case COMPRESSION_MODE_ETC2:
case COMPRESSION_MODE_BPTC: {
- image = Ref<Image>(memnew(Image(size.width, size.height, mipmaps, format, p_data.slice(20))));
+ image.instantiate(size.width, size.height, mipmaps, format, p_data.slice(20));
} break;
}
ERR_FAIL_COND(image.is_null());
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 4a318a10f0..03f0e107e4 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -600,7 +600,7 @@ Error ResourceLoaderText::load() {
if (do_assign) {
bool set_valid = true;
- if (value.get_type() == Variant::OBJECT && missing_resource != nullptr) {
+ if (value.get_type() == Variant::OBJECT && missing_resource == nullptr && ResourceLoader::is_creating_missing_resources_if_class_unavailable_enabled()) {
// If the property being set is a missing resource (and the parent is not),
// then setting it will most likely not work.
// Instead, save it as metadata.
@@ -723,24 +723,25 @@ Error ResourceLoaderText::load() {
if (error) {
if (error != ERR_FILE_EOF) {
_printerr();
- } else {
- error = OK;
- if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
- if (!ResourceCache::has(res_path)) {
- resource->set_path(res_path);
- }
- resource->set_as_translation_remapped(translation_remapped);
- } else {
- resource->set_path_cache(res_path);
+ return error;
+ }
+ // EOF, Done parsing.
+ error = OK;
+ if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
+ if (!ResourceCache::has(res_path)) {
+ resource->set_path(res_path);
}
+ resource->set_as_translation_remapped(translation_remapped);
+ } else {
+ resource->set_path_cache(res_path);
}
- return error;
+ break;
}
if (!assign.is_empty()) {
bool set_valid = true;
- if (value.get_type() == Variant::OBJECT && missing_resource != nullptr) {
+ if (value.get_type() == Variant::OBJECT && missing_resource == nullptr && ResourceLoader::is_creating_missing_resources_if_class_unavailable_enabled()) {
// If the property being set is a missing resource (and the parent is not),
// then setting it will most likely not work.
// Instead, save it as metadata.
@@ -1525,6 +1526,10 @@ ResourceUID::ID ResourceFormatLoaderText::get_resource_uid(const String &p_path)
return loader.get_uid(f);
}
+bool ResourceFormatLoaderText::has_custom_uid_support() const {
+ return true;
+}
+
void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
if (f.is_null()) {
@@ -1777,7 +1782,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
for (KeyValue<Ref<Resource>, String> &E : external_resources) {
String cached_id = E.key->get_id_for_path(local_path);
if (cached_id.is_empty() || cached_ids_found.has(cached_id)) {
- int sep_pos = E.value.find("_");
+ int sep_pos = E.value.find_char('_');
if (sep_pos != -1) {
E.value = E.value.substr(0, sep_pos + 1); // Keep the order found, for improved thread loading performance.
} else {
@@ -1900,7 +1905,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
#endif
}
- Dictionary missing_resource_properties = p_resource->get_meta(META_MISSING_RESOURCES, Dictionary());
+ Dictionary missing_resource_properties = res->get_meta(META_MISSING_RESOURCES, Dictionary());
List<PropertyInfo> property_list;
res->get_property_list(&property_list);
@@ -1912,7 +1917,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
continue;
}
- if (PE->get().usage & PROPERTY_USAGE_STORAGE) {
+ if (PE->get().usage & PROPERTY_USAGE_STORAGE || missing_resource_properties.has(PE->get().name)) {
String name = PE->get().name;
Variant value;
if (PE->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h
index 8397bc985f..4c0bf3d917 100644
--- a/scene/resources/resource_format_text.h
+++ b/scene/resources/resource_format_text.h
@@ -155,6 +155,7 @@ public:
virtual String get_resource_type(const String &p_path) const override;
virtual String get_resource_script_class(const String &p_path) const override;
virtual ResourceUID::ID get_resource_uid(const String &p_path) const override;
+ virtual bool has_custom_uid_support() const override;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false) override;
virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map) override;
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 6921885ee0..c230cf1b70 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -33,10 +33,10 @@
#define EQ_VERTEX_DIST 0.00001
SurfaceTool::OptimizeVertexCacheFunc SurfaceTool::optimize_vertex_cache_func = nullptr;
+SurfaceTool::OptimizeVertexFetchRemapFunc SurfaceTool::optimize_vertex_fetch_remap_func = nullptr;
SurfaceTool::SimplifyFunc SurfaceTool::simplify_func = nullptr;
SurfaceTool::SimplifyWithAttribFunc SurfaceTool::simplify_with_attrib_func = nullptr;
SurfaceTool::SimplifyScaleFunc SurfaceTool::simplify_scale_func = nullptr;
-SurfaceTool::SimplifySloppyFunc SurfaceTool::simplify_sloppy_func = nullptr;
SurfaceTool::GenerateRemapFunc SurfaceTool::generate_remap_func = nullptr;
SurfaceTool::RemapVertexFunc SurfaceTool::remap_vertex_func = nullptr;
SurfaceTool::RemapIndexFunc SurfaceTool::remap_index_func = nullptr;
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 3b18e082a1..68dc9e7198 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -90,14 +90,14 @@ public:
typedef void (*OptimizeVertexCacheFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, size_t vertex_count);
static OptimizeVertexCacheFunc optimize_vertex_cache_func;
+ typedef size_t (*OptimizeVertexFetchRemapFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, size_t vertex_count);
+ static OptimizeVertexFetchRemapFunc optimize_vertex_fetch_remap_func;
typedef size_t (*SimplifyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float *r_error);
static SimplifyFunc simplify_func;
typedef size_t (*SimplifyWithAttribFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_data, size_t vertex_count, size_t vertex_stride, const float *attributes, size_t attribute_stride, const float *attribute_weights, size_t attribute_count, const unsigned char *vertex_lock, size_t target_index_count, float target_error, unsigned int options, float *result_error);
static SimplifyWithAttribFunc simplify_with_attrib_func;
typedef float (*SimplifyScaleFunc)(const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
static SimplifyScaleFunc simplify_scale_func;
- typedef size_t (*SimplifySloppyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *out_result_error);
- static SimplifySloppyFunc simplify_sloppy_func;
typedef size_t (*GenerateRemapFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const void *vertices, size_t vertex_count, size_t vertex_size);
static GenerateRemapFunc generate_remap_func;
typedef void (*RemapVertexFunc)(void *destination, const void *vertices, size_t vertex_count, size_t vertex_size, const unsigned int *remap);
@@ -222,7 +222,9 @@ public:
void clear();
- LocalVector<Vertex> &get_vertex_array() { return vertex_array; }
+ LocalVector<Vertex> &get_vertex_array() {
+ return vertex_array;
+ }
void create_from_triangle_arrays(const Array &p_arrays);
void create_from_arrays(const Array &p_arrays, Mesh::PrimitiveType p_primitive_type = Mesh::PRIMITIVE_TRIANGLES);
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
index da90ba1ef2..4bc03a049a 100644
--- a/scene/resources/syntax_highlighter.cpp
+++ b/scene/resources/syntax_highlighter.cpp
@@ -205,7 +205,7 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) {
if (from + end_key_length > line_length && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
// If it's key length and there is a '\', dont skip to highlight esc chars.
- if (str.find("\\", from) >= 0) {
+ if (str.find_char('\\', from) >= 0) {
break;
}
}
@@ -242,7 +242,7 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
for (; from < line_length; from++) {
if (line_length - from < end_key_length) {
// Don't break if '\' to highlight esc chars.
- if (!is_string || str.find("\\", from) < 0) {
+ if (!is_string || str.find_char('\\', from) < 0) {
break;
}
}
diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp
index 29a8541cb0..65c6e40241 100644
--- a/scene/resources/text_paragraph.cpp
+++ b/scene/resources/text_paragraph.cpp
@@ -112,6 +112,11 @@ void TextParagraph::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_lines_visible"), "set_max_lines_visible", "get_max_lines_visible");
+ ClassDB::bind_method(D_METHOD("set_line_spacing", "line_spacing"), &TextParagraph::set_line_spacing);
+ ClassDB::bind_method(D_METHOD("get_line_spacing"), &TextParagraph::get_line_spacing);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "line_spacing"), "set_line_spacing", "get_line_spacing");
+
ClassDB::bind_method(D_METHOD("get_line_objects", "line"), &TextParagraph::get_line_objects);
ClassDB::bind_method(D_METHOD("get_line_object_rect", "line", "key"), &TextParagraph::get_line_object_rect);
ClassDB::bind_method(D_METHOD("get_line_size", "line"), &TextParagraph::get_line_size);
@@ -180,6 +185,7 @@ void TextParagraph::_shape_lines() {
for (int i = 0; i < line_breaks.size(); i = i + 2) {
RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]);
float h = (TS->shaped_text_get_orientation(line) == TextServer::ORIENTATION_HORIZONTAL) ? TS->shaped_text_get_size(line).y : TS->shaped_text_get_size(line).x;
+ h += line_spacing;
if (!tab_stops.is_empty()) {
TS->shaped_text_tab_align(line, tab_stops);
}
@@ -574,12 +580,18 @@ Size2 TextParagraph::get_size() const {
}
size.x = MAX(size.x, lsize.x);
size.y += lsize.y;
+ if (i != visible_lines - 1) {
+ size.y += line_spacing;
+ }
} else {
if (h_offset > 0 && i <= dropcap_lines) {
lsize.y += h_offset;
}
size.x += lsize.x;
size.y = MAX(size.y, lsize.y);
+ if (i != visible_lines - 1) {
+ size.x += line_spacing;
+ }
}
}
if (h_offset > 0) {
@@ -612,6 +624,19 @@ int TextParagraph::get_max_lines_visible() const {
return max_lines_visible;
}
+void TextParagraph::set_line_spacing(float p_spacing) {
+ _THREAD_SAFE_METHOD_
+
+ if (line_spacing != p_spacing) {
+ line_spacing = p_spacing;
+ lines_dirty = true;
+ }
+}
+
+float TextParagraph::get_line_spacing() const {
+ return line_spacing;
+}
+
Array TextParagraph::get_line_objects(int p_line) const {
_THREAD_SAFE_METHOD_
@@ -697,10 +722,10 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const {
if (i != p_line) {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = 0.f;
- ofs.y += TS->shaped_text_get_descent(lines_rid[i]);
+ ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing;
} else {
ofs.y = 0.f;
- ofs.x += TS->shaped_text_get_descent(lines_rid[i]);
+ ofs.x += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing;
}
}
}
@@ -872,10 +897,10 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
TS->shaped_text_draw(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_color);
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
- ofs.y += TS->shaped_text_get_descent(lines_rid[i]);
+ ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing;
} else {
ofs.y = p_pos.y;
- ofs.x += TS->shaped_text_get_descent(lines_rid[i]);
+ ofs.x += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing;
}
}
}
@@ -974,10 +999,10 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
TS->shaped_text_draw_outline(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_outline_size, p_color);
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
- ofs.y += TS->shaped_text_get_descent(lines_rid[i]);
+ ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing;
} else {
ofs.y = p_pos.y;
- ofs.x += TS->shaped_text_get_descent(lines_rid[i]);
+ ofs.x += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing;
}
}
}
@@ -1001,17 +1026,21 @@ int TextParagraph::hit_test(const Point2 &p_coords) const {
if ((p_coords.y >= ofs.y) && (p_coords.y <= ofs.y + TS->shaped_text_get_size(line_rid).y)) {
return TS->shaped_text_hit_test_position(line_rid, p_coords.x);
}
- ofs.y += TS->shaped_text_get_size(line_rid).y;
+ ofs.y += TS->shaped_text_get_size(line_rid).y + line_spacing;
} else {
if ((p_coords.x >= ofs.x) && (p_coords.x <= ofs.x + TS->shaped_text_get_size(line_rid).x)) {
return TS->shaped_text_hit_test_position(line_rid, p_coords.y);
}
- ofs.y += TS->shaped_text_get_size(line_rid).x;
+ ofs.y += TS->shaped_text_get_size(line_rid).x + line_spacing;
}
}
return TS->shaped_text_get_range(rid).y;
}
+bool TextParagraph::is_dirty() {
+ return lines_dirty;
+}
+
void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color &p_color) const {
_THREAD_SAFE_METHOD_
diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h
index 8b7f21fa9a..966ce556d5 100644
--- a/scene/resources/text_paragraph.h
+++ b/scene/resources/text_paragraph.h
@@ -51,6 +51,7 @@ private:
bool lines_dirty = true;
+ float line_spacing = 0.0;
float width = -1.0;
int max_lines_visible = -1;
@@ -122,6 +123,9 @@ public:
void set_max_lines_visible(int p_lines);
int get_max_lines_visible() const;
+ void set_line_spacing(float p_spacing);
+ float get_line_spacing() const;
+
Size2 get_non_wrapped_size() const;
Size2 get_size() const;
@@ -152,6 +156,8 @@ public:
int hit_test(const Point2 &p_coords) const;
+ bool is_dirty();
+
Mutex &get_mutex() const { return _thread_safe_; }
TextParagraph(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", float p_width = -1.f, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
diff --git a/scene/resources/texture_rd.cpp b/scene/resources/texture_rd.cpp
index 531dbcbe7e..8e7eeb0ff4 100644
--- a/scene/resources/texture_rd.cpp
+++ b/scene/resources/texture_rd.cpp
@@ -197,7 +197,7 @@ void TextureLayeredRD::_set_texture_rd_rid(RID p_texture_rd_rid) {
RS::TextureLayeredType rs_layer_type;
RD::TextureFormat tf = RD::get_singleton()->texture_get_format(p_texture_rd_rid);
- ERR_FAIL_COND(tf.texture_type != RD::TEXTURE_TYPE_2D_ARRAY);
+ ERR_FAIL_COND(tf.texture_type != RD::TEXTURE_TYPE_2D_ARRAY && tf.texture_type != RD::TEXTURE_TYPE_CUBE && tf.texture_type != RD::TEXTURE_TYPE_CUBE_ARRAY);
ERR_FAIL_COND(tf.depth > 1);
switch (layer_type) {
case LAYERED_TYPE_2D_ARRAY: {
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 933e990920..847867fa4d 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -1368,7 +1368,7 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por
ERR_FAIL_INDEX(p_type, TYPE_MAX);
Graph *g = &graph[p_type];
- for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
+ for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
g->connections.erase(E);
g->nodes[p_from_node].next_connected_nodes.erase(p_to_node);
@@ -1921,13 +1921,13 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
}
for (const KeyValue<String, Varying> &E : varyings) {
- p_list->push_back(PropertyInfo(Variant::STRING, vformat("%s/%s", PNAME("varyings"), E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::STRING, vformat("%s/%s", "varyings", E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
}
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
for (const KeyValue<String, Variant> &E : preview_params) {
- p_list->push_back(PropertyInfo(Variant::STRING, vformat("%s/%s", PNAME("preview_params"), E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::STRING, vformat("%s/%s", "preview_params", E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
}
}
#endif // TOOLS_ENABLED