diff options
-rw-r--r-- | core/variant/variant_utility.cpp | 3 | ||||
-rw-r--r-- | doc/classes/@GlobalScope.xml | 2 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 35 | ||||
-rw-r--r-- | modules/gltf/doc_classes/GLTFDocument.xml | 9 | ||||
-rw-r--r-- | modules/gltf/gltf_document.cpp | 6 | ||||
-rw-r--r-- | modules/gltf/gltf_document.h | 1 | ||||
-rw-r--r-- | modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs | 5 | ||||
-rw-r--r-- | modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs | 19 | ||||
-rw-r--r-- | modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs | 45 | ||||
-rw-r--r-- | modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs | 16 | ||||
-rw-r--r-- | scene/animation/animation_tree.cpp | 16 | ||||
-rw-r--r-- | scene/animation/animation_tree.h | 1 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 1 | ||||
-rw-r--r-- | scene/resources/bit_map.cpp | 101 | ||||
-rw-r--r-- | servers/rendering/shader_language.cpp | 32 |
15 files changed, 187 insertions, 105 deletions
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 3843c32bcc..f274b80729 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -335,6 +335,9 @@ struct VariantUtilityFunctions { } switch (from.get_type()) { + case Variant::INT: { + return lerpf(VariantInternalAccessor<int64_t>::get(&from), to, weight); + } break; case Variant::FLOAT: { return lerpf(VariantInternalAccessor<double>::get(&from), to, weight); } break; diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 09713bce2f..34f706b6f9 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -527,7 +527,7 @@ <param index="2" name="weight" type="Variant" /> <description> Linearly interpolates between two values by the factor defined in [param weight]. To perform interpolation, [param weight] should be between [code]0.0[/code] and [code]1.0[/code] (inclusive). However, values outside this range are allowed and can be used to perform [i]extrapolation[/i]. If this is not desired, use [method clamp] on the result of this function. - Both [param from] and [param to] must be the same type. Supported types: [float], [Vector2], [Vector3], [Vector4], [Color], [Quaternion], [Basis]. + Both [param from] and [param to] must be the same type. Supported types: [int], [float], [Vector2], [Vector3], [Vector4], [Color], [Quaternion], [Basis]. [codeblock] lerp(0, 4, 0.75) # Returns 3.0 [/codeblock] diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 7c323a8524..8c0a30836f 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/resource_saver.h" +#include "core/object/class_db.h" #include "core/object/message_queue.h" #include "core/os/keyboard.h" #include "editor/debugger/editor_debugger_node.h" @@ -2605,7 +2606,39 @@ void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) { Ref<Script> scr = ResourceLoader::load(p_file); ERR_FAIL_COND(!scr.is_valid()); - if (Node *n = get_node(p_to)) { + Node *n = get_node(p_to); + + if (!n) { + return; + } + + if (Input::get_singleton()->is_key_pressed(Key::CTRL)) { + Object *obj = ClassDB::instantiate(scr->get_instance_base_type()); + ERR_FAIL_NULL(obj); + + Node *new_node = Object::cast_to<Node>(obj); + if (!new_node) { + if (!obj->is_ref_counted()) { + memdelete(obj); + } + ERR_FAIL_MSG("Script does not extend Node-derived type."); + } + new_node->set_name(Node::adjust_name_casing(p_file.get_file().get_basename())); + new_node->set_script(scr); + + editor_data->get_undo_redo()->create_action(TTR("Instantiate Script")); + editor_data->get_undo_redo()->add_do_method(n, "add_child", new_node, true); + editor_data->get_undo_redo()->add_do_method(new_node, "set_owner", edited_scene); + editor_data->get_undo_redo()->add_do_method(editor_selection, "clear"); + editor_data->get_undo_redo()->add_do_method(editor_selection, "add_node", new_node); + editor_data->get_undo_redo()->add_do_reference(new_node); + editor_data->get_undo_redo()->add_undo_method(n, "remove_child", new_node); + + EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); + editor_data->get_undo_redo()->add_do_method(ed, "live_debug_create_node", edited_scene->get_path_to(n), new_node->get_class(), new_node->get_name()); + editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(n)).path_join(new_node->get_name()))); + editor_data->get_undo_redo()->commit_action(); + } else { editor_data->get_undo_redo()->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, n); editor_data->get_undo_redo()->add_do_method(InspectorDock::get_singleton(), "store_script_properties", n); editor_data->get_undo_redo()->add_undo_method(InspectorDock::get_singleton(), "store_script_properties", n); diff --git a/modules/gltf/doc_classes/GLTFDocument.xml b/modules/gltf/doc_classes/GLTFDocument.xml index 1967df5218..588015de62 100644 --- a/modules/gltf/doc_classes/GLTFDocument.xml +++ b/modules/gltf/doc_classes/GLTFDocument.xml @@ -62,10 +62,17 @@ <param index="0" name="extension" type="GLTFDocumentExtension" /> <param index="1" name="first_priority" type="bool" default="false" /> <description> - Registers this GLTFDocumentExtension instance with GLTFDocument. If [param first_priority] is true, this extension will be ran first. Otherwise, it will be ran last. + Registers the given [GLTFDocumentExtension] instance with GLTFDocument. If [param first_priority] is true, this extension will be run first. Otherwise, it will be run last. [b]Note:[/b] Like GLTFDocument itself, all GLTFDocumentExtension classes must be stateless in order to function properly. If you need to store data, use the [code]set_additional_data[/code] and [code]get_additional_data[/code] methods in [GLTFState] or [GLTFNode]. </description> </method> + <method name="unregister_gltf_document_extension" qualifiers="static"> + <return type="void" /> + <param index="0" name="extension" type="GLTFDocumentExtension" /> + <description> + Unregisters the given [GLTFDocumentExtension] instance. + </description> + </method> <method name="write_to_filesystem"> <return type="int" enum="Error" /> <param index="0" name="state" type="GLTFState" /> diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index faa8ed267a..f27e2385c6 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -6761,6 +6761,8 @@ void GLTFDocument::_bind_methods() { ClassDB::bind_static_method("GLTFDocument", D_METHOD("register_gltf_document_extension", "extension", "first_priority"), &GLTFDocument::register_gltf_document_extension, DEFVAL(false)); + ClassDB::bind_static_method("GLTFDocument", D_METHOD("unregister_gltf_document_extension", "extension"), + &GLTFDocument::unregister_gltf_document_extension); } void GLTFDocument::_build_parent_hierachy(Ref<GLTFState> state) { @@ -6789,6 +6791,10 @@ void GLTFDocument::register_gltf_document_extension(Ref<GLTFDocumentExtension> p } } +void GLTFDocument::unregister_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension) { + all_document_extensions.erase(p_extension); +} + void GLTFDocument::unregister_all_gltf_document_extensions() { all_document_extensions.clear(); } diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 15099efe33..5a0e4ff498 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -77,6 +77,7 @@ protected: public: static void register_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension, bool p_first_priority = false); + static void unregister_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension); static void unregister_all_gltf_document_extensions(); private: diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs index ac8d6473a6..9a46b7d164 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; #pragma warning disable CS0169 @@ -83,6 +84,10 @@ namespace Godot.SourceGenerators.Sample [Export] private StringName[] field_StringNameArray = { "foo", "bar" }; [Export] private NodePath[] field_NodePathArray = { "foo", "bar" }; [Export] private RID[] field_RIDArray = { default, default, default }; + // Note we use Array and not System.Array. This tests the generated namespace qualification. + [Export] private Int32[] field_empty_Int32Array = Array.Empty<Int32>(); + // Note we use List and not System.Collections.Generic. + [Export] private int[] field_array_from_list = new List<int>(Array.Empty<int>()).ToArray(); // Variant [Export] private Variant field_Variant = "foo"; diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs new file mode 100644 index 0000000000..a6c8e52667 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs @@ -0,0 +1,19 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +#pragma warning disable CS0169 +#pragma warning disable CS0414 + +namespace Godot.SourceGenerators.Sample +{ + [SuppressMessage("ReSharper", "BuiltInTypeReferenceStyle")] + [SuppressMessage("ReSharper", "RedundantNameQualifier")] + [SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeEvident")] + [SuppressMessage("ReSharper", "InconsistentNaming")] + // We split the definition of ExportedFields to verify properties work across multiple files. + public partial class ExportedFields : Godot.Object + { + // Note we use Array and not System.Array. This tests the generated namespace qualification. + [Export] private Int64[] field_empty_Int64Array = Array.Empty<Int64>(); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs index 8de12de23b..9e3add4262 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -165,6 +166,50 @@ namespace Godot.SourceGenerators public static string FullQualifiedName(this INamespaceSymbol namespaceSymbol) => namespaceSymbol.ToDisplayString(FullyQualifiedFormatOmitGlobal); + public static string FullQualifiedName(this ISymbol symbol) + => symbol.ToDisplayString(FullyQualifiedFormatOmitGlobal); + + public static string FullQualifiedSyntax(this SyntaxNode node, SemanticModel sm) + { + StringBuilder sb = new(); + FullQualifiedSyntax_(node, sm, sb, true); + return sb.ToString(); + } + + private static void FullQualifiedSyntax_(SyntaxNode node, SemanticModel sm, StringBuilder sb, bool isFirstNode) + { + if (node is NameSyntax ns && isFirstNode) + { + SymbolInfo nameInfo = sm.GetSymbolInfo(ns); + sb.Append(nameInfo.Symbol?.FullQualifiedName() ?? ns.ToString()); + return; + } + + bool innerIsFirstNode = true; + foreach (var child in node.ChildNodesAndTokens()) + { + if (child.HasLeadingTrivia) + { + sb.Append(child.GetLeadingTrivia()); + } + + if (child.IsNode) + { + FullQualifiedSyntax_(child.AsNode()!, sm, sb, isFirstNode: innerIsFirstNode); + innerIsFirstNode = false; + } + else + { + sb.Append(child); + } + + if (child.HasTrailingTrivia) + { + sb.Append(child.GetTrailingTrivia()); + } + } + } + public static string SanitizeQualifiedNameForUniqueHint(this string qualifiedName) => qualifiedName // AddSource() doesn't support angle brackets diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs index 98b9745c16..9a18ba3ab2 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs @@ -170,7 +170,13 @@ namespace Godot.SourceGenerators .Select(s => s?.Initializer ?? null) .FirstOrDefault(); - string? value = initializer?.Value.ToString(); + // Fully qualify the value to avoid issues with namespaces. + string? value = null; + if (initializer != null) + { + var sm = context.Compilation.GetSemanticModel(initializer.SyntaxTree); + value = initializer.Value.FullQualifiedSyntax(sm); + } exportedMembers.Add(new ExportedPropertyMetadata( property.Name, marshalType.Value, propertyType, value)); @@ -207,7 +213,13 @@ namespace Godot.SourceGenerators .Select(s => s.Initializer) .FirstOrDefault(i => i != null); - string? value = initializer?.Value.ToString(); + // This needs to be fully qualified to avoid issues with namespaces. + string? value = null; + if (initializer != null) + { + var sm = context.Compilation.GetSemanticModel(initializer.SyntaxTree); + value = initializer.Value.FullQualifiedSyntax(sm); + } exportedMembers.Add(new ExportedPropertyMetadata( field.Name, marshalType.Value, fieldType, value)); diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index e148512963..99d450fa5b 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -221,7 +221,7 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri } blendw[i] = blendr[i] * p_blend; - if (blendw[i] > CMP_EPSILON) { + if (!Math::is_zero_approx(blendw[i])) { any_valid = true; } } @@ -236,7 +236,7 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri } blendw[i] = blendr[i] * p_blend; - if (blendw[i] > CMP_EPSILON) { + if (!Math::is_zero_approx(blendw[i])) { any_valid = true; } } @@ -252,7 +252,7 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri blendw[i] = blendr[i]; //not filtered, do not blend } - if (blendw[i] > CMP_EPSILON) { + if (!Math::is_zero_approx(blendw[i])) { any_valid = true; } } @@ -263,7 +263,7 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri for (int i = 0; i < blend_count; i++) { //regular blend blendw[i] = blendr[i] * p_blend; - if (blendw[i] > CMP_EPSILON) { + if (!Math::is_zero_approx(blendw[i])) { any_valid = true; } } @@ -586,6 +586,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { track_value->object = child; } + track_value->is_discrete = anim->value_track_get_update_mode(i) == Animation::UPDATE_DISCRETE || anim->value_track_get_update_mode(i) == Animation::UPDATE_TRIGGER; track_value->is_using_angle = anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_LINEAR_ANGLE || anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_CUBIC_ANGLE; track_value->subpath = leftover_path; @@ -800,6 +801,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { } else if (track_cache_type == Animation::TYPE_VALUE) { // If it has at least one angle interpolation, it also uses angle interpolation for blending. TrackCacheValue *track_value = memnew(TrackCacheValue); + track_value->is_discrete |= anim->value_track_get_update_mode(i) == Animation::UPDATE_DISCRETE || anim->value_track_get_update_mode(i) == Animation::UPDATE_TRIGGER; track_value->is_using_angle |= anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_LINEAR_ANGLE || anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_CUBIC_ANGLE; } @@ -1025,7 +1027,7 @@ void AnimationTree::_process_graph(double p_delta) { int blend_idx = state.track_map[path]; ERR_CONTINUE(blend_idx < 0 || blend_idx >= state.track_count); real_t blend = (*as.track_blends)[blend_idx] * weight; - if (blend < CMP_EPSILON) { + if (Math::is_zero_approx(blend)) { continue; // Nothing to blend. } @@ -1658,6 +1660,10 @@ void AnimationTree::_process_graph(double p_delta) { case Animation::TYPE_VALUE: { TrackCacheValue *t = static_cast<TrackCacheValue *>(track); + if (t->is_discrete) { + break; // Don't overwrite the value set by UPDATE_DISCRETE or UPDATE_TRIGGER. + } + if (t->init_value.get_type() == Variant::BOOL) { t->object->set_indexed(t->subpath, t->value.operator real_t() >= 0.5); } else { diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 493cd894d0..84d0a8190a 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -232,6 +232,7 @@ private: Variant init_value; Variant value; Vector<StringName> subpath; + bool is_discrete = false; bool is_using_angle = false; TrackCacheValue() { type = Animation::TYPE_VALUE; } }; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 9e440405af..345d5de937 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -362,6 +362,7 @@ void Viewport::_notification(int p_what) { current_canvas = find_world_2d()->get_canvas(); RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas); + RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, current_canvas, canvas_transform); RenderingServer::get_singleton()->viewport_set_canvas_cull_mask(viewport, canvas_cull_mask); _update_audio_listener_2d(); #ifndef _3D_DISABLED diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index 4afc82576d..0df61871d8 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -169,14 +169,6 @@ Dictionary BitMap::_get_data() const { return d; } -struct CrossStackEntry { - Point2i cross; - Vector<int> ranges; - - _FORCE_INLINE_ bool operator==(const CrossStackEntry &p_other) const { return cross == p_other.cross; } - _FORCE_INLINE_ bool operator!=(const CrossStackEntry &p_other) const { return cross != p_other.cross; } -}; - Vector<Vector<Vector2>> BitMap::_march_square(const Rect2i &p_rect, const Point2i &p_start) const { int stepx = 0; int stepy = 0; @@ -188,14 +180,11 @@ Vector<Vector<Vector2>> BitMap::_march_square(const Rect2i &p_rect, const Point2 int cury = starty; unsigned int count = 0; - Vector<CrossStackEntry> cross_stack; - int cross_stack_size = 0; + HashMap<Point2i, int> cross_map; - // Add starting point to stack as the default entry. - cross_stack.push_back({ Point2i(-1, -1), Vector<int>({ 0 }) }); - cross_stack_size++; + Vector<Vector2> _points; + int points_size = 0; - Vector<Point2i> _points; Vector<Vector<Vector2>> ret; // Add starting entry at start of return. @@ -326,52 +315,25 @@ Vector<Vector<Vector2>> BitMap::_march_square(const Rect2i &p_rect, const Point2 // Handle crossing points. if (sv == 6 || sv == 9) { - const int new_index = _points.size() - 1; - - // Add previous point to last stack entry. - cross_stack.write[cross_stack_size - 1].ranges.push_back(new_index); - - // Create temporary entry to maybe insert, for searching. - const CrossStackEntry new_entry = { _points[new_index], Vector<int>({ new_index }) }; - - // Attempt to find matching entry. - const int found = cross_stack.rfind(new_entry, cross_stack_size - 1); + const Point2i cur_pos(curx, cury); - if (found != -1) { - Vector<Vector2> tmp; + // Find if this point has occured before. + if (HashMap<Point2i, int>::Iterator found = cross_map.find(cur_pos)) { + // Add points after the previous crossing to the result. + ret.push_back(_points.slice(found->value + 1, points_size)); - // Iterate over entries between end of stack and found, adding ranges to result. - for (int i = found; i < cross_stack_size; i++) { - const Vector<int> &ranges = cross_stack[i].ranges; + // Remove points after crossing point. + points_size = found->value + 1; - for (int j = 0; j < ranges.size() / 2; j++) { - int first = ranges[2 * j]; - const int last = ranges[2 * j + 1]; - - int new_pos = tmp.size(); - - tmp.resize(tmp.size() + (last - first)); - - Vector2 *tmp_ptrw = tmp.ptrw(); - - for (; first < last; first++, new_pos++) { - tmp_ptrw[new_pos].x = (float)(_points[first].x - p_rect.position.x); - tmp_ptrw[new_pos].y = (float)(_points[first].y - p_rect.position.y); - } - } + // Erase trailing map elements. + while (cross_map.last() != found) { + cross_map.remove(cross_map.last()); } - ret.push_back(tmp); - - // Shrink stack. - cross_stack_size = found; - - // Add previous point to last stack entry. - cross_stack.write[cross_stack_size - 1].ranges.push_back(new_index); + cross_map.erase(cur_pos); } else { - cross_stack.resize(MAX(cross_stack_size + 1, cross_stack.size())); - cross_stack.set(cross_stack_size, new_entry); - cross_stack_size++; + // Add crossing point to map. + cross_map.insert(cur_pos, points_size - 1); } } @@ -381,10 +343,11 @@ Vector<Vector<Vector2>> BitMap::_march_square(const Rect2i &p_rect, const Point2 curx += stepx; cury += stepy; if (stepx == prevx && stepy == prevy) { - _points.write[_points.size() - 1].x = curx; - _points.write[_points.size() - 1].y = cury; + _points.set(points_size - 1, Vector2(curx, cury) - p_rect.position); } else { - _points.push_back(Point2i(curx, cury)); + _points.resize(MAX(points_size + 1, _points.size())); + _points.set(points_size, Vector2(curx, cury) - p_rect.position); + points_size++; } count++; @@ -394,28 +357,10 @@ Vector<Vector<Vector2>> BitMap::_march_square(const Rect2i &p_rect, const Point2 ERR_FAIL_COND_V((int)count > width * height, Vector<Vector<Vector2>>()); } while (curx != startx || cury != starty); - // Add last position to last stack entry. - cross_stack.write[cross_stack_size - 1].ranges.push_back(_points.size()); - - for (int i = 0; i < cross_stack_size; i++) { - const Vector<int> &ranges = cross_stack[i].ranges; - - for (int j = 0; j < ranges.size() / 2; j++) { - int first = ranges[2 * j]; - const int last = ranges[2 * j + 1]; - - int new_pos = ret[0].size(); + // Add remaining points to result. + _points.resize(points_size); - ret.write[0].resize(ret[0].size() + (last - first)); - - Vector2 *tmp_ptrw = ret.write[0].ptrw(); - - for (; first < last; first++, new_pos++) { - tmp_ptrw[new_pos].x = (float)(_points[first].x - p_rect.position.x); - tmp_ptrw[new_pos].y = (float)(_points[first].y - p_rect.position.y); - } - } - } + ret.set(0, _points); return ret; } diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 79fbc59b06..92b8d7350e 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -4110,43 +4110,41 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform case ShaderLanguage::TYPE_USAMPLER2D: { if (p_uniform.array_size > 0) { pi.type = Variant::ARRAY; + pi.hint = PROPERTY_HINT_ARRAY_TYPE; + pi.hint_string = vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"); } else { pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "Texture2D"; } - pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "Texture2D"; } break; case ShaderLanguage::TYPE_SAMPLER2DARRAY: case ShaderLanguage::TYPE_ISAMPLER2DARRAY: - case ShaderLanguage::TYPE_USAMPLER2DARRAY: { + case ShaderLanguage::TYPE_USAMPLER2DARRAY: + case ShaderLanguage::TYPE_SAMPLERCUBE: + case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { if (p_uniform.array_size > 0) { pi.type = Variant::ARRAY; + pi.hint = PROPERTY_HINT_ARRAY_TYPE; + pi.hint_string = vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "TextureLayered"); } else { pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "TextureLayered"; } - pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "TextureLayered"; } break; case ShaderLanguage::TYPE_SAMPLER3D: case ShaderLanguage::TYPE_ISAMPLER3D: case ShaderLanguage::TYPE_USAMPLER3D: { if (p_uniform.array_size > 0) { pi.type = Variant::ARRAY; + pi.hint = PROPERTY_HINT_ARRAY_TYPE; + pi.hint_string = vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"); } else { pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "Texture3D"; } - pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "Texture3D"; - } break; - case ShaderLanguage::TYPE_SAMPLERCUBE: - case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { - if (p_uniform.array_size > 0) { - pi.type = Variant::ARRAY; - } else { - pi.type = Variant::OBJECT; - } - pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "TextureLayered"; } break; case ShaderLanguage::TYPE_STRUCT: { // FIXME: Implement this. |