diff options
Diffstat (limited to 'scene/resources')
31 files changed, 285 insertions, 419 deletions
diff --git a/scene/resources/2d/navigation_mesh_source_geometry_data_2d.cpp b/scene/resources/2d/navigation_mesh_source_geometry_data_2d.cpp index e3f14539a8..07e9caa713 100644 --- a/scene/resources/2d/navigation_mesh_source_geometry_data_2d.cpp +++ b/scene/resources/2d/navigation_mesh_source_geometry_data_2d.cpp @@ -43,7 +43,7 @@ void NavigationMeshSourceGeometryData2D::clear() { bool NavigationMeshSourceGeometryData2D::has_data() { RWLockRead read_lock(geometry_rwlock); return traversable_outlines.size(); -}; +} void NavigationMeshSourceGeometryData2D::clear_projected_obstructions() { RWLockWrite write_lock(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 229e18be23..5ecfc32622 100644 --- a/scene/resources/2d/tile_set.cpp +++ b/scene/resources/2d/tile_set.cpp @@ -174,13 +174,13 @@ void TileMapPattern::set_size(const Size2i &p_size) { bool TileMapPattern::is_empty() const { return pattern.is_empty(); -}; +} void TileMapPattern::clear() { size = Size2i(); pattern.clear(); emit_changed(); -}; +} bool TileMapPattern::_set(const StringName &p_name, const Variant &p_value) { if (p_name == "tile_data") { @@ -571,11 +571,11 @@ void TileSet::set_uv_clipping(bool p_uv_clipping) { bool TileSet::is_uv_clipping() const { return uv_clipping; -}; +} int TileSet::get_occlusion_layers_count() const { return occlusion_layers.size(); -}; +} void TileSet::add_occlusion_layer(int p_index) { if (p_index < 0) { @@ -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; @@ -3691,7 +3702,7 @@ Array TileSet::compatibility_tilemap_map(int p_tile_id, Vector2i p_coords, bool return cannot_convert_array; break; } -}; +} #endif // DISABLE_DEPRECATED @@ -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); @@ -4432,7 +4462,7 @@ TileSet *TileSetSource::get_tile_set() const { void TileSetSource::reset_state() { tile_set = nullptr; -}; +} void TileSetSource::_bind_methods() { // Base tiles @@ -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); } } @@ -6480,9 +6514,9 @@ int TileData::get_terrain_set() const { } void TileData::set_terrain(int p_terrain) { - ERR_FAIL_COND(terrain_set < 0); ERR_FAIL_COND(p_terrain < -1); - if (tile_set) { + ERR_FAIL_COND(terrain_set < 0 && p_terrain != -1); + if (tile_set && terrain_set >= 0) { ERR_FAIL_COND(p_terrain >= tile_set->get_terrains_count(terrain_set)); } terrain = p_terrain; @@ -6495,9 +6529,9 @@ int TileData::get_terrain() const { void TileData::set_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit, int p_terrain_index) { ERR_FAIL_INDEX(p_peering_bit, TileSet::CellNeighbor::CELL_NEIGHBOR_MAX); - ERR_FAIL_COND(terrain_set < 0); ERR_FAIL_COND(p_terrain_index < -1); - if (tile_set) { + ERR_FAIL_COND(terrain_set < 0 && p_terrain_index != -1); + if (tile_set && terrain_set >= 0) { ERR_FAIL_COND(p_terrain_index >= tile_set->get_terrains_count(terrain_set)); ERR_FAIL_COND(!is_valid_terrain_peering_bit(p_peering_bit)); } diff --git a/scene/resources/2d/tile_set.h b/scene/resources/2d/tile_set.h index 15e1a16359..6d3ccd1d2d 100644 --- a/scene/resources/2d/tile_set.h +++ b/scene/resources/2d/tile_set.h @@ -278,7 +278,7 @@ public: bool operator==(const TerrainsPattern &p_terrains_pattern) const; bool operator!=(const TerrainsPattern &p_terrains_pattern) const { return !operator==(p_terrains_pattern); - }; + } void set_terrain(int p_terrain); int get_terrain() const; @@ -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; @@ -812,8 +815,8 @@ public: // Scenes accessors. Lot are similar to "Alternative tiles". int get_scene_tiles_count() { return get_alternative_tiles_count(Vector2i()); } - int get_scene_tile_id(int p_index) { return get_alternative_tile_id(Vector2i(), p_index); }; - bool has_scene_tile_id(int p_id) { return has_alternative_tile(Vector2i(), p_id); }; + int get_scene_tile_id(int p_index) { return get_alternative_tile_id(Vector2i(), p_index); } + bool has_scene_tile_id(int p_id) { return has_alternative_tile(Vector2i(), p_id); } int create_scene_tile(Ref<PackedScene> p_packed_scene = Ref<PackedScene>(), int p_id_override = -1); void set_scene_tile_id(int p_id, int p_new_id); void set_scene_tile_scene(int p_id, Ref<PackedScene> p_packed_scene); @@ -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 47cd64f19a..f040f04cd8 100644 --- a/scene/resources/3d/importer_mesh.cpp +++ b/scene/resources/3d/importer_mesh.cpp @@ -33,108 +33,10 @@ #include "core/io/marshalls.h" #include "core/math/convex_hull.h" #include "core/math/random_pcg.h" -#include "core/math/static_raycaster.h" -#include "scene/resources/animation_library.h" #include "scene/resources/surface_tool.h" #include <cstdint> -void ImporterMesh::Surface::split_normals(const LocalVector<int> &p_indices, const LocalVector<Vector3> &p_normals) { - _split_normals(arrays, p_indices, p_normals); - - for (BlendShape &blend_shape : blend_shape_data) { - _split_normals(blend_shape.arrays, p_indices, p_normals); - } -} - -void ImporterMesh::Surface::_split_normals(Array &r_arrays, const LocalVector<int> &p_indices, const LocalVector<Vector3> &p_normals) { - ERR_FAIL_COND(r_arrays.size() != RS::ARRAY_MAX); - - const PackedVector3Array &vertices = r_arrays[RS::ARRAY_VERTEX]; - int current_vertex_count = vertices.size(); - int new_vertex_count = p_indices.size(); - int final_vertex_count = current_vertex_count + new_vertex_count; - const int *indices_ptr = p_indices.ptr(); - - for (int i = 0; i < r_arrays.size(); i++) { - if (i == RS::ARRAY_INDEX) { - continue; - } - - if (r_arrays[i].get_type() == Variant::NIL) { - continue; - } - - switch (r_arrays[i].get_type()) { - case Variant::PACKED_VECTOR3_ARRAY: { - PackedVector3Array data = r_arrays[i]; - data.resize(final_vertex_count); - Vector3 *data_ptr = data.ptrw(); - if (i == RS::ARRAY_NORMAL) { - const Vector3 *normals_ptr = p_normals.ptr(); - memcpy(&data_ptr[current_vertex_count], normals_ptr, sizeof(Vector3) * new_vertex_count); - } else { - for (int j = 0; j < new_vertex_count; j++) { - data_ptr[current_vertex_count + j] = data_ptr[indices_ptr[j]]; - } - } - r_arrays[i] = data; - } break; - case Variant::PACKED_VECTOR2_ARRAY: { - PackedVector2Array data = r_arrays[i]; - data.resize(final_vertex_count); - Vector2 *data_ptr = data.ptrw(); - for (int j = 0; j < new_vertex_count; j++) { - data_ptr[current_vertex_count + j] = data_ptr[indices_ptr[j]]; - } - r_arrays[i] = data; - } break; - case Variant::PACKED_FLOAT32_ARRAY: { - PackedFloat32Array data = r_arrays[i]; - int elements = data.size() / current_vertex_count; - data.resize(final_vertex_count * elements); - float *data_ptr = data.ptrw(); - for (int j = 0; j < new_vertex_count; j++) { - memcpy(&data_ptr[(current_vertex_count + j) * elements], &data_ptr[indices_ptr[j] * elements], sizeof(float) * elements); - } - r_arrays[i] = data; - } break; - case Variant::PACKED_INT32_ARRAY: { - PackedInt32Array data = r_arrays[i]; - int elements = data.size() / current_vertex_count; - data.resize(final_vertex_count * elements); - int32_t *data_ptr = data.ptrw(); - for (int j = 0; j < new_vertex_count; j++) { - memcpy(&data_ptr[(current_vertex_count + j) * elements], &data_ptr[indices_ptr[j] * elements], sizeof(int32_t) * elements); - } - r_arrays[i] = data; - } break; - case Variant::PACKED_BYTE_ARRAY: { - PackedByteArray data = r_arrays[i]; - int elements = data.size() / current_vertex_count; - data.resize(final_vertex_count * elements); - uint8_t *data_ptr = data.ptrw(); - for (int j = 0; j < new_vertex_count; j++) { - memcpy(&data_ptr[(current_vertex_count + j) * elements], &data_ptr[indices_ptr[j] * elements], sizeof(uint8_t) * elements); - } - r_arrays[i] = data; - } break; - case Variant::PACKED_COLOR_ARRAY: { - PackedColorArray data = r_arrays[i]; - data.resize(final_vertex_count); - Color *data_ptr = data.ptrw(); - for (int j = 0; j < new_vertex_count; j++) { - data_ptr[current_vertex_count + j] = data_ptr[indices_ptr[j]]; - } - r_arrays[i] = data; - } break; - default: { - ERR_FAIL_MSG("Unhandled array type."); - } break; - } - } -} - String ImporterMesh::validate_blend_shape_name(const String &p_name) { String name = p_name; const char *characters = ":"; @@ -266,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) { @@ -286,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(); } } @@ -306,16 +292,13 @@ void ImporterMesh::optimize_indices_for_cache() { } \ write_array[vert_idx] = transformed_vert; -void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_split_angle, Array p_bone_transform_array, bool p_raycast_normals) { +void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transform_array) { if (!SurfaceTool::simplify_scale_func) { return; } 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++) { @@ -379,8 +362,6 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli } float normal_merge_threshold = Math::cos(Math::deg_to_rad(p_normal_merge_angle)); - float normal_pre_split_threshold = Math::cos(Math::deg_to_rad(MIN(180.0f, p_normal_split_angle * 2.0f))); - float normal_split_threshold = Math::cos(Math::deg_to_rad(p_normal_split_angle)); const Vector3 *normals_ptr = normals.ptr(); HashMap<Vector3, LocalVector<Pair<int, int>>> unique_vertices; @@ -469,22 +450,6 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli unsigned int index_target = 12; // Start with the smallest target, 4 triangles unsigned int last_index_count = 0; - // Only used for normal raycasting - int split_vertex_count = vertex_count; - LocalVector<Vector3> split_vertex_normals; - LocalVector<int> split_vertex_indices; - split_vertex_normals.reserve(index_count / 3); - split_vertex_indices.reserve(index_count / 3); - - RandomPCG pcg; - pcg.seed(123456789); // Keep seed constant across imports - - Ref<StaticRaycaster> raycaster = p_raycast_normals ? StaticRaycaster::create() : Ref<StaticRaycaster>(); - if (raycaster.is_valid()) { - raycaster->add_mesh(vertices, indices, 0); - raycaster->commit(); - } - const float max_mesh_error = FLT_MAX; // We don't want to limit by error, just by index target float mesh_error = 0.0f; @@ -503,6 +468,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli merged_normals_f32.ptr(), sizeof(float) * 3, // Attribute stride normal_weights, 3, + nullptr, // Vertex lock index_target, max_mesh_error, simplify_options, @@ -533,173 +499,6 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli } } - if (raycaster.is_valid()) { - LocalVector<LocalVector<int>> vertex_corners; - vertex_corners.resize(vertex_count); - - int *ptrw = new_indices.ptrw(); - for (unsigned int j = 0; j < new_index_count; j++) { - vertex_corners[ptrw[j]].push_back(j); - } - - float error_factor = 1.0f / (scale * MAX(mesh_error, 0.15)); - const float ray_bias = 0.05; - float ray_length = ray_bias + mesh_error * scale * 3.0f; - - Vector<StaticRaycaster::Ray> rays; - LocalVector<Vector2> ray_uvs; - - int32_t *new_indices_ptr = new_indices.ptrw(); - - int current_ray_count = 0; - for (unsigned int j = 0; j < new_index_count; j += 3) { - const Vector3 &v0 = vertices_ptr[new_indices_ptr[j + 0]]; - const Vector3 &v1 = vertices_ptr[new_indices_ptr[j + 1]]; - const Vector3 &v2 = vertices_ptr[new_indices_ptr[j + 2]]; - Vector3 face_normal = vec3_cross(v0 - v2, v0 - v1); - float face_area = face_normal.length(); // Actually twice the face area, since it's the same error_factor on all faces, we don't care - if (!Math::is_finite(face_area) || face_area == 0) { - WARN_PRINT_ONCE("Ignoring face with non-finite normal in LOD generation."); - continue; - } - - Vector3 dir = face_normal / face_area; - int ray_count = CLAMP(5.0 * face_area * error_factor, 16, 64); - - rays.resize(current_ray_count + ray_count); - StaticRaycaster::Ray *rays_ptr = rays.ptrw(); - - ray_uvs.resize(current_ray_count + ray_count); - Vector2 *ray_uvs_ptr = ray_uvs.ptr(); - - for (int k = 0; k < ray_count; k++) { - float u = pcg.randf(); - float v = pcg.randf(); - - if (u + v >= 1.0f) { - u = 1.0f - u; - v = 1.0f - v; - } - - u = 0.9f * u + 0.05f / 3.0f; // Give barycentric coordinates some padding, we don't want to sample right on the edge - v = 0.9f * v + 0.05f / 3.0f; // v = (v - one_third) * 0.95f + one_third; - float w = 1.0f - u - v; - - Vector3 org = v0 * w + v1 * u + v2 * v; - org -= dir * ray_bias; - rays_ptr[current_ray_count + k] = StaticRaycaster::Ray(org, dir, 0.0f, ray_length); - rays_ptr[current_ray_count + k].id = j / 3; - ray_uvs_ptr[current_ray_count + k] = Vector2(u, v); - } - - current_ray_count += ray_count; - } - - raycaster->intersect(rays); - - LocalVector<Vector3> ray_normals; - LocalVector<real_t> ray_normal_weights; - - ray_normals.resize(new_index_count); - ray_normal_weights.resize(new_index_count); - - for (unsigned int j = 0; j < new_index_count; j++) { - ray_normal_weights[j] = 0.0f; - } - - const StaticRaycaster::Ray *rp = rays.ptr(); - for (int j = 0; j < rays.size(); j++) { - if (rp[j].geomID != 0) { // Ray missed - continue; - } - - if (rp[j].normal.normalized().dot(rp[j].dir) > 0.0f) { // Hit a back face. - continue; - } - - const float &u = rp[j].u; - const float &v = rp[j].v; - const float w = 1.0f - u - v; - - const unsigned int &hit_tri_id = rp[j].primID; - const unsigned int &orig_tri_id = rp[j].id; - - const Vector3 &n0 = normals_ptr[indices_ptr[hit_tri_id * 3 + 0]]; - const Vector3 &n1 = normals_ptr[indices_ptr[hit_tri_id * 3 + 1]]; - const Vector3 &n2 = normals_ptr[indices_ptr[hit_tri_id * 3 + 2]]; - Vector3 normal = n0 * w + n1 * u + n2 * v; - - Vector2 orig_uv = ray_uvs[j]; - const real_t orig_bary[3] = { 1.0f - orig_uv.x - orig_uv.y, orig_uv.x, orig_uv.y }; - for (int k = 0; k < 3; k++) { - int idx = orig_tri_id * 3 + k; - real_t weight = orig_bary[k]; - ray_normals[idx] += normal * weight; - ray_normal_weights[idx] += weight; - } - } - - for (unsigned int j = 0; j < new_index_count; j++) { - if (ray_normal_weights[j] < 1.0f) { // Not enough data, the new normal would be just a bad guess - ray_normals[j] = Vector3(); - } else { - ray_normals[j] /= ray_normal_weights[j]; - } - } - - LocalVector<LocalVector<int>> normal_group_indices; - LocalVector<Vector3> normal_group_averages; - normal_group_indices.reserve(24); - normal_group_averages.reserve(24); - - for (unsigned int j = 0; j < vertex_count; j++) { - const LocalVector<int> &corners = vertex_corners[j]; - const Vector3 &vertex_normal = normals_ptr[j]; - - for (const int &corner_idx : corners) { - const Vector3 &ray_normal = ray_normals[corner_idx]; - - if (ray_normal.length_squared() < CMP_EPSILON2) { - continue; - } - - bool found = false; - for (unsigned int l = 0; l < normal_group_indices.size(); l++) { - LocalVector<int> &group_indices = normal_group_indices[l]; - Vector3 n = normal_group_averages[l] / group_indices.size(); - if (n.dot(ray_normal) > normal_pre_split_threshold) { - found = true; - group_indices.push_back(corner_idx); - normal_group_averages[l] += ray_normal; - break; - } - } - - if (!found) { - normal_group_indices.push_back({ corner_idx }); - normal_group_averages.push_back(ray_normal); - } - } - - for (unsigned int k = 0; k < normal_group_indices.size(); k++) { - LocalVector<int> &group_indices = normal_group_indices[k]; - Vector3 n = normal_group_averages[k] / group_indices.size(); - - if (vertex_normal.dot(n) < normal_split_threshold) { - split_vertex_indices.push_back(j); - split_vertex_normals.push_back(n); - int new_idx = split_vertex_count++; - for (const int &index : group_indices) { - new_indices_ptr[index] = new_idx; - } - } - } - - normal_group_indices.clear(); - normal_group_averages.clear(); - } - } - Surface::LOD lod; lod.distance = MAX(mesh_error * scale, CMP_EPSILON2); lod.indices = new_indices; @@ -712,22 +511,13 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli } } - if (raycaster.is_valid()) { - surfaces.write[i].split_normals(split_vertex_indices, split_vertex_normals); - } - 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(), split_vertex_count); - } } } void ImporterMesh::_generate_lods_bind(float p_normal_merge_angle, float p_normal_split_angle, Array p_skin_pose_transform_array) { - generate_lods(p_normal_merge_angle, p_normal_split_angle, p_skin_pose_transform_array); + // p_normal_split_angle is unused, but kept for compatibility + generate_lods(p_normal_merge_angle, p_skin_pose_transform_array); } bool ImporterMesh::has_mesh() const { @@ -859,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. @@ -881,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 c7e3a059d6..2bdf759da6 100644 --- a/scene/resources/3d/importer_mesh.h +++ b/scene/resources/3d/importer_mesh.h @@ -68,9 +68,6 @@ class ImporterMesh : public Resource { return l.distance < r.distance; } }; - - void split_normals(const LocalVector<int> &p_indices, const LocalVector<Vector3> &p_normals); - static void _split_normals(Array &r_arrays, const LocalVector<int> &p_indices, const LocalVector<Vector3> &p_normals); }; Vector<Surface> surfaces; Vector<String> blend_shapes; @@ -116,9 +113,9 @@ 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, float p_normal_split_angle, Array p_skin_pose_transform_array, bool p_raycast_normals = false); + void generate_lods(float p_normal_merge_angle, Array p_skin_pose_transform_array); void create_shadow_mesh(); Ref<ImporterMesh> get_shadow_mesh() const; diff --git a/scene/resources/3d/navigation_mesh_source_geometry_data_3d.cpp b/scene/resources/3d/navigation_mesh_source_geometry_data_3d.cpp index 59366592ce..74dca88423 100644 --- a/scene/resources/3d/navigation_mesh_source_geometry_data_3d.cpp +++ b/scene/resources/3d/navigation_mesh_source_geometry_data_3d.cpp @@ -71,7 +71,7 @@ void NavigationMeshSourceGeometryData3D::append_arrays(const Vector<float> &p_ve bool NavigationMeshSourceGeometryData3D::has_data() { RWLockRead read_lock(geometry_rwlock); return vertices.size() && indices.size(); -}; +} void NavigationMeshSourceGeometryData3D::clear() { RWLockWrite write_lock(geometry_rwlock); diff --git a/scene/resources/3d/primitive_meshes.h b/scene/resources/3d/primitive_meshes.h index 85f46a482a..e68ac7fb26 100644 --- a/scene/resources/3d/primitive_meshes.h +++ b/scene/resources/3d/primitive_meshes.h @@ -545,7 +545,7 @@ private: ContourPoint(const Vector2 &p_pt, bool p_sharp) { point = p_pt; sharp = p_sharp; - }; + } }; struct ContourInfo { diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 57a4e35f7a..f0b182503a 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -1048,7 +1048,7 @@ int Animation::find_track(const NodePath &p_path, const TrackType p_type) const } }; return -1; -}; +} Animation::TrackType Animation::get_cache_type(TrackType p_type) { if (p_type == Animation::TYPE_BEZIER) { 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/camera_attributes.cpp b/scene/resources/camera_attributes.cpp index 3a021720c6..3a0c207a5d 100644 --- a/scene/resources/camera_attributes.cpp +++ b/scene/resources/camera_attributes.cpp @@ -487,7 +487,7 @@ void CameraAttributesPhysical::_bind_methods() { ADD_GROUP("Auto Exposure", "auto_exposure_"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_min_exposure_value", PROPERTY_HINT_RANGE, "-16.0,16.0,0.01,or_greater,suffix:EV100"), "set_auto_exposure_min_exposure_value", "get_auto_exposure_min_exposure_value"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_max_exposure_value", PROPERTY_HINT_RANGE, "-16.0,16.0,0.01,or_greater,suffix:EV100"), "set_auto_exposure_max_exposure_value", "get_auto_exposure_max_exposure_value"); -}; +} CameraAttributesPhysical::CameraAttributesPhysical() { _update_exposure(); 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/external_texture.cpp b/scene/resources/external_texture.cpp index 0552bbd081..c8b714372a 100644 --- a/scene/resources/external_texture.cpp +++ b/scene/resources/external_texture.cpp @@ -39,12 +39,14 @@ void ExternalTexture::_bind_methods() { } uint64_t ExternalTexture::get_external_texture_id() const { + _ensure_created(); return RenderingServer::get_singleton()->texture_get_native_handle(texture); } void ExternalTexture::set_size(const Size2 &p_size) { if (p_size.width > 0 && p_size.height > 0 && p_size != size) { size = p_size; + _ensure_created(); RenderingServer::get_singleton()->texture_external_update(texture, size.width, size.height, external_buffer); emit_changed(); } @@ -57,6 +59,7 @@ Size2 ExternalTexture::get_size() const { void ExternalTexture::set_external_buffer_id(uint64_t p_external_buffer) { if (p_external_buffer != external_buffer) { external_buffer = p_external_buffer; + _ensure_created(); RenderingServer::get_singleton()->texture_external_update(texture, size.width, size.height, external_buffer); } } @@ -74,11 +77,29 @@ bool ExternalTexture::has_alpha() const { } RID ExternalTexture::get_rid() const { + if (!texture.is_valid()) { + texture = RenderingServer::get_singleton()->texture_2d_placeholder_create(); + using_placeholder = true; + } return texture; } +void ExternalTexture::_ensure_created() const { + if (texture.is_valid() && !using_placeholder) { + return; + } + + RID new_texture = RenderingServer::get_singleton()->texture_external_create(size.width, size.height); + if (using_placeholder) { + DEV_ASSERT(texture.is_valid()); + RenderingServer::get_singleton()->texture_replace(texture, new_texture); + using_placeholder = false; + } else { + texture = new_texture; + } +} + ExternalTexture::ExternalTexture() { - texture = RenderingServer::get_singleton()->texture_external_create(size.width, size.height); } ExternalTexture::~ExternalTexture() { diff --git a/scene/resources/external_texture.h b/scene/resources/external_texture.h index 96bcd8d0fe..cd60bcc030 100644 --- a/scene/resources/external_texture.h +++ b/scene/resources/external_texture.h @@ -38,10 +38,13 @@ class ExternalTexture : public Texture2D { GDCLASS(ExternalTexture, Texture2D); private: - RID texture; + mutable RID texture; + mutable bool using_placeholder = false; Size2 size = Size2(256, 256); uint64_t external_buffer = 0; + void _ensure_created() const; + protected: static void _bind_methods(); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 5e4136f449..a4677d917d 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); } diff --git a/scene/resources/immediate_mesh.cpp b/scene/resources/immediate_mesh.cpp index 907c0ab4ca..072542f0ad 100644 --- a/scene/resources/immediate_mesh.cpp +++ b/scene/resources/immediate_mesh.cpp @@ -312,6 +312,8 @@ void ImmediateMesh::surface_end() { uses_uv2s = false; surface_active = false; + + emit_changed(); } void ImmediateMesh::clear_surfaces() { diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 9df009ec28..ecc1982aa5 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -382,14 +382,11 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { bool ShaderMaterial::_property_can_revert(const StringName &p_name) const { if (shader.is_valid()) { - const StringName *pr = remap_cache.getptr(p_name); - if (pr) { - Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), *pr); - Variant current_value = get_shader_parameter(*pr); - return default_value.get_type() != Variant::NIL && default_value != current_value; - } else if (p_name == "render_priority" || p_name == "next_pass") { + if (remap_cache.has(p_name)) { return true; } + const String sname = p_name; + return sname == "render_priority" || sname == "next_pass"; } return false; } diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 4d1d733f8b..848ae2713d 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -45,23 +45,23 @@ void MeshConvexDecompositionSettings::set_max_concavity(real_t p_max_concavity) real_t MeshConvexDecompositionSettings::get_max_concavity() const { return max_concavity; -}; +} void MeshConvexDecompositionSettings::set_symmetry_planes_clipping_bias(real_t p_symmetry_planes_clipping_bias) { symmetry_planes_clipping_bias = CLAMP(p_symmetry_planes_clipping_bias, 0.0, 1.0); -}; +} real_t MeshConvexDecompositionSettings::get_symmetry_planes_clipping_bias() const { return symmetry_planes_clipping_bias; -}; +} void MeshConvexDecompositionSettings::set_revolution_axes_clipping_bias(real_t p_revolution_axes_clipping_bias) { revolution_axes_clipping_bias = CLAMP(p_revolution_axes_clipping_bias, 0.0, 1.0); -}; +} real_t MeshConvexDecompositionSettings::get_revolution_axes_clipping_bias() const { return revolution_axes_clipping_bias; -}; +} void MeshConvexDecompositionSettings::set_min_volume_per_convex_hull(real_t p_min_volume_per_convex_hull) { min_volume_per_convex_hull = CLAMP(p_min_volume_per_convex_hull, 0.0001, 0.01); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index d6fe4385c4..bb3aad0f28 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; } diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index e234a81c88..535903a1b6 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. @@ -1431,8 +1432,8 @@ void ResourceFormatLoaderText::get_recognized_extensions_for_type(const String & p_extensions->push_back("tscn"); } - // Don't allow .tres for PackedScenes. - if (p_type != "PackedScene") { + // Don't allow .tres for PackedScenes or GDExtension. + if (p_type != "PackedScene" && p_type != "GDExtension") { p_extensions->push_back("tres"); } } @@ -1900,7 +1901,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 +1913,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/shader.cpp b/scene/resources/shader.cpp index 24d17108d5..d163a42fa9 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -32,6 +32,7 @@ #include "shader.compat.inc" #include "core/io/file_access.h" +#include "scene/main/scene_tree.h" #include "servers/rendering/shader_language.h" #include "servers/rendering/shader_preprocessor.h" #include "servers/rendering_server.h" @@ -138,6 +139,14 @@ String Shader::get_code() const { return code; } +void Shader::inspect_native_shader_code() { + SceneTree *st = SceneTree::get_singleton(); + RID _shader = get_rid(); + if (st && _shader.is_valid()) { + st->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, "_native_shader_source_visualizer", "_inspect_shader", _shader); + } +} + void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups) const { _update_shader(); _check_shader_rid(); @@ -267,6 +276,9 @@ void Shader::_bind_methods() { ClassDB::bind_method(D_METHOD("get_shader_uniform_list", "get_groups"), &Shader::_get_shader_uniform_list, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("inspect_native_shader_code"), &Shader::inspect_native_shader_code); + ClassDB::set_method_flags(get_class_static(), _scs_create("inspect_native_shader_code"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_code", "get_code"); BIND_ENUM_CONSTANT(MODE_SPATIAL); diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 18197419f3..7234d37579 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -88,6 +88,8 @@ public: void set_code(const String &p_code); String get_code() const; + void inspect_native_shader_code(); + void get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups = false) const; void set_default_texture_parameter(const StringName &p_name, const Ref<Texture> &p_texture, int p_index = 0); diff --git a/scene/resources/style_box_flat.cpp b/scene/resources/style_box_flat.cpp index 15816925c1..202ab3615b 100644 --- a/scene/resources/style_box_flat.cpp +++ b/scene/resources/style_box_flat.cpp @@ -596,10 +596,10 @@ void StyleBoxFlat::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "skew"), "set_skew", "get_skew"); ADD_GROUP("Border Width", "border_width_"); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_left", PROPERTY_HINT_RANGE, "0,1024,1,suffix:px"), "set_border_width", "get_border_width", SIDE_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_top", PROPERTY_HINT_RANGE, "0,1024,1,suffix:px"), "set_border_width", "get_border_width", SIDE_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_right", PROPERTY_HINT_RANGE, "0,1024,1,suffix:px"), "set_border_width", "get_border_width", SIDE_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_bottom", PROPERTY_HINT_RANGE, "0,1024,1,suffix:px"), "set_border_width", "get_border_width", SIDE_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_left", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_border_width", "get_border_width", SIDE_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_top", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_border_width", "get_border_width", SIDE_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_right", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_border_width", "get_border_width", SIDE_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_bottom", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_border_width", "get_border_width", SIDE_BOTTOM); ADD_GROUP("Border", "border_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "border_color"), "set_border_color", "get_border_color"); @@ -607,18 +607,18 @@ void StyleBoxFlat::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "border_blend"), "set_border_blend", "get_border_blend"); ADD_GROUP("Corner Radius", "corner_radius_"); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "corner_radius_top_left", PROPERTY_HINT_RANGE, "0,1024,1,suffix:px"), "set_corner_radius", "get_corner_radius", CORNER_TOP_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "corner_radius_top_right", PROPERTY_HINT_RANGE, "0,1024,1,suffix:px"), "set_corner_radius", "get_corner_radius", CORNER_TOP_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "corner_radius_bottom_right", PROPERTY_HINT_RANGE, "0,1024,1,suffix:px"), "set_corner_radius", "get_corner_radius", CORNER_BOTTOM_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "corner_radius_bottom_left", PROPERTY_HINT_RANGE, "0,1024,1,suffix:px"), "set_corner_radius", "get_corner_radius", CORNER_BOTTOM_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "corner_radius_top_left", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_corner_radius", "get_corner_radius", CORNER_TOP_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "corner_radius_top_right", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_corner_radius", "get_corner_radius", CORNER_TOP_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "corner_radius_bottom_right", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_corner_radius", "get_corner_radius", CORNER_BOTTOM_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "corner_radius_bottom_left", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_corner_radius", "get_corner_radius", CORNER_BOTTOM_LEFT); ADD_PROPERTY(PropertyInfo(Variant::INT, "corner_detail", PROPERTY_HINT_RANGE, "1,20,1"), "set_corner_detail", "get_corner_detail"); ADD_GROUP("Expand Margins", "expand_margin_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_left", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_top", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,100,1,or_greater,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_BOTTOM); ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color"); 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 a072df5bee..68dc9e7198 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -80,18 +80,24 @@ public: enum { /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */ SIMPLIFY_LOCK_BORDER = 1 << 0, // From meshopt_SimplifyLockBorder + /* Improve simplification performance assuming input indices are a sparse subset of the mesh. Note that error becomes relative to subset extents. */ + SIMPLIFY_SPARSE = 1 << 1, // From meshopt_SimplifySparse + /* Treat error limit and resulting error as absolute instead of relative to mesh extents. */ + SIMPLIFY_ERROR_ABSOLUTE = 1 << 2, // From meshopt_SimplifyErrorAbsolute + /* Remove disconnected parts of the mesh during simplification incrementally, regardless of the topological restrictions inside components. */ + SIMPLIFY_PRUNE = 1 << 3, // From meshopt_SimplifyPrune }; 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, size_t target_index_count, float target_error, unsigned int options, float *result_error); + 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); @@ -113,7 +119,7 @@ private: SmoothGroupVertex(const Vertex &p_vertex) { vertex = p_vertex.vertex; smooth_group = p_vertex.smooth_group; - }; + } }; struct SmoothGroupVertexHasher { @@ -216,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/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 2f0b626601..65c6e40241 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -1037,6 +1037,10 @@ int TextParagraph::hit_test(const Point2 &p_coords) const { 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 c12fc34c04..966ce556d5 100644 --- a/scene/resources/text_paragraph.h +++ b/scene/resources/text_paragraph.h @@ -156,7 +156,9 @@ public: int hit_test(const Point2 &p_coords) const; - Mutex &get_mutex() const { return _thread_safe_; }; + 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); TextParagraph(); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index d0e55f4065..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); @@ -1560,7 +1560,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port shader_code += " COLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n"; } break; case VisualShaderNode::PORT_TYPE_VECTOR_4D: { - shader_code += " COLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ".xyz;\n"; + shader_code += " COLOR = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n"; } break; default: { shader_code += " COLOR.rgb = vec3(0.0);\n"; @@ -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 |