summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/variant/variant_utility.cpp3
-rw-r--r--doc/classes/@GlobalScope.xml2
-rw-r--r--editor/scene_tree_dock.cpp35
-rw-r--r--modules/gltf/doc_classes/GLTFDocument.xml9
-rw-r--r--modules/gltf/gltf_document.cpp6
-rw-r--r--modules/gltf/gltf_document.h1
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs5
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs19
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs45
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs16
-rw-r--r--scene/animation/animation_tree.cpp16
-rw-r--r--scene/animation/animation_tree.h1
-rw-r--r--scene/main/viewport.cpp1
-rw-r--r--scene/resources/bit_map.cpp101
-rw-r--r--servers/rendering/shader_language.cpp32
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.