summaryrefslogtreecommitdiffstats
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/3d/light_3d.cpp15
-rw-r--r--scene/3d/light_3d.h4
-rw-r--r--scene/3d/skeleton_3d.h3
-rw-r--r--scene/animation/animation_mixer.cpp66
-rw-r--r--scene/animation/animation_mixer.h21
-rw-r--r--scene/animation/animation_node_state_machine.cpp2
-rw-r--r--scene/animation/animation_player.cpp4
-rw-r--r--scene/animation/animation_player.h4
-rw-r--r--scene/animation/animation_tree.cpp32
-rw-r--r--scene/animation/animation_tree.h47
-rw-r--r--scene/gui/button.cpp17
-rw-r--r--scene/gui/color_picker.cpp20
-rw-r--r--scene/gui/color_picker.h1
-rw-r--r--scene/gui/tree.cpp20
-rw-r--r--scene/main/canvas_item.cpp2
-rw-r--r--scene/main/viewport.cpp2
-rw-r--r--scene/property_utils.cpp10
-rw-r--r--scene/resources/2d/tile_set.cpp8
-rw-r--r--scene/resources/external_texture.cpp23
-rw-r--r--scene/resources/external_texture.h5
-rw-r--r--scene/resources/style_box_flat.cpp24
-rw-r--r--scene/scene_string_names.cpp2
-rw-r--r--scene/scene_string_names.h2
23 files changed, 227 insertions, 107 deletions
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 7b70986adc..2d18e62b10 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -146,6 +146,15 @@ bool Light3D::get_shadow_reverse_cull_face() const {
return reverse_cull;
}
+void Light3D::set_shadow_caster_mask(uint32_t p_caster_mask) {
+ shadow_caster_mask = p_caster_mask;
+ RS::get_singleton()->light_set_shadow_caster_mask(light, shadow_caster_mask);
+}
+
+uint32_t Light3D::get_shadow_caster_mask() const {
+ return shadow_caster_mask;
+}
+
AABB Light3D::get_aabb() const {
if (type == RenderingServer::LIGHT_DIRECTIONAL) {
return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
@@ -300,7 +309,7 @@ bool Light3D::is_editor_only() const {
}
void Light3D::_validate_property(PropertyInfo &p_property) const {
- if (!shadow && (p_property.name == "shadow_bias" || p_property.name == "shadow_normal_bias" || p_property.name == "shadow_reverse_cull_face" || p_property.name == "shadow_transmittance_bias" || p_property.name == "shadow_opacity" || p_property.name == "shadow_blur" || p_property.name == "distance_fade_shadow")) {
+ if (!shadow && (p_property.name == "shadow_bias" || p_property.name == "shadow_normal_bias" || p_property.name == "shadow_reverse_cull_face" || p_property.name == "shadow_transmittance_bias" || p_property.name == "shadow_opacity" || p_property.name == "shadow_blur" || p_property.name == "distance_fade_shadow" || p_property.name == "shadow_caster_mask")) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
@@ -354,6 +363,9 @@ void Light3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_reverse_cull_face", "enable"), &Light3D::set_shadow_reverse_cull_face);
ClassDB::bind_method(D_METHOD("get_shadow_reverse_cull_face"), &Light3D::get_shadow_reverse_cull_face);
+ ClassDB::bind_method(D_METHOD("set_shadow_caster_mask", "caster_mask"), &Light3D::set_shadow_caster_mask);
+ ClassDB::bind_method(D_METHOD("get_shadow_caster_mask"), &Light3D::get_shadow_caster_mask);
+
ClassDB::bind_method(D_METHOD("set_bake_mode", "bake_mode"), &Light3D::set_bake_mode);
ClassDB::bind_method(D_METHOD("get_bake_mode"), &Light3D::get_bake_mode);
@@ -388,6 +400,7 @@ void Light3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_OPACITY);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BLUR);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_caster_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_shadow_caster_mask", "get_shadow_caster_mask");
ADD_GROUP("Distance Fade", "distance_fade_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled");
diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h
index d6eca8d8b6..5f549469c6 100644
--- a/scene/3d/light_3d.h
+++ b/scene/3d/light_3d.h
@@ -75,6 +75,7 @@ private:
bool negative = false;
bool reverse_cull = false;
uint32_t cull_mask = 0;
+ uint32_t shadow_caster_mask = 0xFFFFFFFF;
bool distance_fade_enabled = false;
real_t distance_fade_begin = 40.0;
real_t distance_fade_shadow = 50.0;
@@ -136,6 +137,9 @@ public:
void set_shadow_reverse_cull_face(bool p_enable);
bool get_shadow_reverse_cull_face() const;
+ void set_shadow_caster_mask(uint32_t p_caster_mask);
+ uint32_t get_shadow_caster_mask() const;
+
void set_bake_mode(BakeMode p_mode);
BakeMode get_bake_mode() const;
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index 0db12600c3..ecfe095f1d 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -31,6 +31,7 @@
#ifndef SKELETON_3D_H
#define SKELETON_3D_H
+#include "core/templates/a_hash_map.h"
#include "scene/3d/node_3d.h"
#include "scene/resources/3d/skin.h"
@@ -159,7 +160,7 @@ private:
bool process_order_dirty = false;
Vector<int> parentless_bones;
- HashMap<String, int> name_to_bone_index;
+ AHashMap<String, int> name_to_bone_index;
mutable StringName concatenated_bone_names = StringName();
void _update_bone_names() const;
diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp
index eb8bc8c382..0fa6810d23 100644
--- a/scene/animation/animation_mixer.cpp
+++ b/scene/animation/animation_mixer.cpp
@@ -563,6 +563,7 @@ void AnimationMixer::_clear_caches() {
memdelete(K.value);
}
track_cache.clear();
+ animation_track_num_to_track_cashe.clear();
cache_valid = false;
capture_cache.clear();
@@ -922,6 +923,27 @@ bool AnimationMixer::_update_caches() {
idx++;
}
+ for (KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) {
+ K.value->blend_idx = track_map[K.value->path];
+ }
+
+ animation_track_num_to_track_cashe.clear();
+ LocalVector<TrackCache *> track_num_to_track_cashe;
+ for (const StringName &E : sname_list) {
+ Ref<Animation> anim = get_animation(E);
+ const Vector<Animation::Track *> tracks = anim->get_tracks();
+ track_num_to_track_cashe.resize(tracks.size());
+ for (int i = 0; i < tracks.size(); i++) {
+ TrackCache **track_ptr = track_cache.getptr(tracks[i]->thash);
+ if (track_ptr == nullptr) {
+ track_num_to_track_cashe[i] = nullptr;
+ } else {
+ track_num_to_track_cashe[i] = *track_ptr;
+ }
+ }
+ animation_track_num_to_track_cashe.insert(anim, track_num_to_track_cashe);
+ }
+
track_count = idx;
cache_valid = true;
@@ -946,7 +968,7 @@ void AnimationMixer::_process_animation(double p_delta, bool p_update_only) {
clear_animation_instances();
}
-Variant AnimationMixer::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, ObjectID p_object_id, int p_object_sub_idx) {
+Variant AnimationMixer::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant &p_value, ObjectID p_object_id, int p_object_sub_idx) {
#ifndef _3D_DISABLED
switch (p_anim->track_get_type(p_track)) {
case Animation::TYPE_POSITION_3D: {
@@ -1033,7 +1055,7 @@ void AnimationMixer::_blend_init() {
}
}
-bool AnimationMixer::_blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map) {
+bool AnimationMixer::_blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) {
return true;
}
@@ -1084,26 +1106,30 @@ void AnimationMixer::_blend_calc_total_weight() {
real_t weight = ai.playback_info.weight;
const real_t *track_weights_ptr = ai.playback_info.track_weights.ptr();
int track_weights_count = ai.playback_info.track_weights.size();
- static LocalVector<Animation::TypeHash> processed_hashes;
+ ERR_CONTINUE_EDMSG(!animation_track_num_to_track_cashe.has(a), "No animation in cache.");
+ LocalVector<TrackCache *> &track_num_to_track_cashe = animation_track_num_to_track_cashe[a];
+ thread_local HashSet<Animation::TypeHash, HashHasher> processed_hashes;
processed_hashes.clear();
const Vector<Animation::Track *> tracks = a->get_tracks();
- for (const Animation::Track *animation_track : tracks) {
+ Animation::Track *const *tracks_ptr = tracks.ptr();
+ int count = tracks.size();
+ for (int i = 0; i < count; i++) {
+ Animation::Track *animation_track = tracks_ptr[i];
if (!animation_track->enabled) {
continue;
}
Animation::TypeHash thash = animation_track->thash;
- TrackCache **track_ptr = track_cache.getptr(thash);
- if (track_ptr == nullptr || processed_hashes.has(thash)) {
+ TrackCache *track = track_num_to_track_cashe[i];
+ if (track == nullptr || processed_hashes.has(thash)) {
// No path, but avoid error spamming.
// Or, there is the case different track type with same path; These can be distinguished by hash. So don't add the weight doubly.
continue;
}
- TrackCache *track = *track_ptr;
- int blend_idx = track_map[track->path];
+ int blend_idx = track->blend_idx;
ERR_CONTINUE(blend_idx < 0 || blend_idx >= track_count);
real_t blend = blend_idx < track_weights_count ? track_weights_ptr[blend_idx] * weight : weight;
track->total_weight += blend;
- processed_hashes.push_back(thash);
+ processed_hashes.insert(thash);
}
}
}
@@ -1130,6 +1156,8 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
#ifndef _3D_DISABLED
bool calc_root = !seeked || is_external_seeking;
#endif // _3D_DISABLED
+ ERR_CONTINUE_EDMSG(!animation_track_num_to_track_cashe.has(a), "No animation in cache.");
+ LocalVector<TrackCache *> &track_num_to_track_cashe = animation_track_num_to_track_cashe[a];
const Vector<Animation::Track *> tracks = a->get_tracks();
Animation::Track *const *tracks_ptr = tracks.ptr();
real_t a_length = a->get_length();
@@ -1139,15 +1167,11 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
if (!animation_track->enabled) {
continue;
}
- Animation::TypeHash thash = animation_track->thash;
- TrackCache **track_ptr = track_cache.getptr(thash);
- if (track_ptr == nullptr) {
+ TrackCache *track = track_num_to_track_cashe[i];
+ if (track == nullptr) {
continue; // No path, but avoid error spamming.
}
- TrackCache *track = *track_ptr;
- int *blend_idx_ptr = track_map.getptr(track->path);
- ERR_CONTINUE(blend_idx_ptr == nullptr);
- int blend_idx = *blend_idx_ptr;
+ int blend_idx = track->blend_idx;
ERR_CONTINUE(blend_idx < 0 || blend_idx >= track_count);
real_t blend = blend_idx < track_weights_count ? track_weights_ptr[blend_idx] * weight : weight;
if (!deterministic) {
@@ -1581,7 +1605,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
track_info.loop = a->get_loop_mode() != Animation::LOOP_NONE;
track_info.backward = backward;
track_info.use_blend = a->audio_track_is_use_blend(i);
- HashMap<int, PlayingAudioStreamInfo> &map = track_info.stream_info;
+ AHashMap<int, PlayingAudioStreamInfo> &map = track_info.stream_info;
// Main process to fire key is started from here.
if (p_update_only) {
@@ -1850,7 +1874,7 @@ void AnimationMixer::_blend_apply() {
PlayingAudioTrackInfo &track_info = L.value;
float db = Math::linear_to_db(track_info.use_blend ? track_info.volume : 1.0);
LocalVector<int> erase_streams;
- HashMap<int, PlayingAudioStreamInfo> &map = track_info.stream_info;
+ AHashMap<int, PlayingAudioStreamInfo> &map = track_info.stream_info;
for (const KeyValue<int, PlayingAudioStreamInfo> &M : map) {
PlayingAudioStreamInfo pasi = M.value;
@@ -2134,7 +2158,7 @@ void AnimationMixer::restore(const Ref<AnimatedValuesBackup> &p_backup) {
ERR_FAIL_COND(p_backup.is_null());
track_cache = p_backup->get_data();
_blend_apply();
- track_cache = HashMap<Animation::TypeHash, AnimationMixer::TrackCache *>();
+ track_cache = AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher>();
cache_valid = false;
}
@@ -2370,7 +2394,7 @@ AnimationMixer::AnimationMixer() {
AnimationMixer::~AnimationMixer() {
}
-void AnimatedValuesBackup::set_data(const HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> p_data) {
+void AnimatedValuesBackup::set_data(const AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> p_data) {
clear_data();
for (const KeyValue<Animation::TypeHash, AnimationMixer::TrackCache *> &E : p_data) {
@@ -2383,7 +2407,7 @@ void AnimatedValuesBackup::set_data(const HashMap<Animation::TypeHash, Animation
}
}
-HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> AnimatedValuesBackup::get_data() const {
+AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> AnimatedValuesBackup::get_data() const {
HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> ret;
for (const KeyValue<Animation::TypeHash, AnimationMixer::TrackCache *> &E : data) {
AnimationMixer::TrackCache *track = get_cache_copy(E.value);
diff --git a/scene/animation/animation_mixer.h b/scene/animation/animation_mixer.h
index 27c9a00a9c..1906146c56 100644
--- a/scene/animation/animation_mixer.h
+++ b/scene/animation/animation_mixer.h
@@ -31,6 +31,7 @@
#ifndef ANIMATION_MIXER_H
#define ANIMATION_MIXER_H
+#include "core/templates/a_hash_map.h"
#include "scene/animation/tween.h"
#include "scene/main/node.h"
#include "scene/resources/animation.h"
@@ -102,7 +103,7 @@ public:
protected:
/* ---- Data lists ---- */
LocalVector<AnimationLibraryData> animation_libraries;
- HashMap<StringName, AnimationData> animation_set; // HashMap<Library name + Animation name, AnimationData>
+ AHashMap<StringName, AnimationData> animation_set; // HashMap<Library name + Animation name, AnimationData>
TypedArray<StringName> _get_animation_library_list() const;
Vector<String> _get_animation_list() const {
@@ -148,6 +149,7 @@ protected:
uint64_t setup_pass = 0;
Animation::TrackType type = Animation::TrackType::TYPE_ANIMATION;
NodePath path;
+ int blend_idx = -1;
ObjectID object_id;
real_t total_weight = 0.0;
@@ -269,7 +271,7 @@ protected:
// Audio track information for mixng and ending.
struct PlayingAudioTrackInfo {
- HashMap<int, PlayingAudioStreamInfo> stream_info;
+ AHashMap<int, PlayingAudioStreamInfo> stream_info;
double length = 0.0;
double time = 0.0;
real_t volume = 0.0;
@@ -308,7 +310,8 @@ protected:
};
RootMotionCache root_motion_cache;
- HashMap<Animation::TypeHash, TrackCache *> track_cache;
+ AHashMap<Animation::TypeHash, TrackCache *, HashHasher> track_cache;
+ AHashMap<Ref<Animation>, LocalVector<TrackCache *>> animation_track_num_to_track_cashe;
HashSet<TrackCache *> playing_caches;
Vector<Node *> playing_audio_stream_players;
@@ -324,7 +327,7 @@ protected:
/* ---- Blending processor ---- */
LocalVector<AnimationInstance> animation_instances;
- HashMap<NodePath, int> track_map;
+ AHashMap<NodePath, int> track_map;
int track_count = 0;
bool deterministic = false;
@@ -359,12 +362,12 @@ protected:
virtual void _process_animation(double p_delta, bool p_update_only = false);
// For post process with retrieved key value during blending.
- virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, ObjectID p_object_id, int p_object_sub_idx = -1);
+ virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant &p_value, ObjectID p_object_id, int p_object_sub_idx = -1);
Variant post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, ObjectID p_object_id, int p_object_sub_idx = -1);
GDVIRTUAL5RC(Variant, _post_process_key_value, Ref<Animation>, int, Variant, ObjectID, int);
void _blend_init();
- virtual bool _blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map);
+ virtual bool _blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map);
virtual void _blend_capture(double p_delta);
void _blend_calc_total_weight(); // For undeterministic blending.
void _blend_process(double p_delta, bool p_update_only = false);
@@ -485,11 +488,11 @@ public:
class AnimatedValuesBackup : public RefCounted {
GDCLASS(AnimatedValuesBackup, RefCounted);
- HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> data;
+ AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> data;
public:
- void set_data(const HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> p_data);
- HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> get_data() const;
+ void set_data(const AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> p_data);
+ AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> get_data() const;
void clear_data();
AnimationMixer::TrackCache *get_cache_copy(AnimationMixer::TrackCache *p_cache) const;
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index c3c5399a6b..5cc204100c 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -1619,7 +1619,7 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachine::_process(const AnimationM
playback_new = playback_new->duplicate(); // Don't process original when testing.
}
- return playback_new->process(node_state.base_path, this, p_playback_info, p_test_only);
+ return playback_new->process(node_state.get_base_path(), this, p_playback_info, p_test_only);
}
String AnimationNodeStateMachine::get_caption() const {
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 8a2ca47920..b3a75a75a0 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -133,7 +133,7 @@ void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const {
List<PropertyInfo> anim_names;
for (const KeyValue<StringName, AnimationData> &E : animation_set) {
- HashMap<StringName, StringName>::ConstIterator F = animation_next_set.find(E.key);
+ AHashMap<StringName, StringName>::ConstIterator F = animation_next_set.find(E.key);
if (F && F->value != StringName()) {
anim_names.push_back(PropertyInfo(Variant::STRING, "next/" + String(E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
}
@@ -299,7 +299,7 @@ void AnimationPlayer::_blend_playback_data(double p_delta, bool p_started) {
}
}
-bool AnimationPlayer::_blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map) {
+bool AnimationPlayer::_blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) {
if (!playback.current.from) {
_set_process(false);
return false;
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 3223e2522d..06b3eecb89 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -52,7 +52,7 @@ public:
#endif // DISABLE_DEPRECATED
private:
- HashMap<StringName, StringName> animation_next_set; // For auto advance.
+ AHashMap<StringName, StringName> animation_next_set; // For auto advance.
float speed_scale = 1.0;
double default_blend_time = 0.0;
@@ -138,7 +138,7 @@ protected:
static void _bind_methods();
// Make animation instances.
- virtual bool _blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map) override;
+ virtual bool _blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) override;
virtual void _blend_capture(double p_delta) override;
virtual void _blend_post_process() override;
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 19080e61de..d676e2acf4 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -75,20 +75,34 @@ void AnimationNode::set_parameter(const StringName &p_name, const Variant &p_val
if (process_state->is_testing) {
return;
}
+
+ const AHashMap<StringName, int>::Iterator it = property_cache.find(p_name);
+ if (it) {
+ process_state->tree->property_map.get_by_index(it->value).value.first = p_value;
+ return;
+ }
+
ERR_FAIL_COND(!process_state->tree->property_parent_map.has(node_state.base_path));
ERR_FAIL_COND(!process_state->tree->property_parent_map[node_state.base_path].has(p_name));
StringName path = process_state->tree->property_parent_map[node_state.base_path][p_name];
-
- process_state->tree->property_map[path].first = p_value;
+ int idx = process_state->tree->property_map.get_index(path);
+ property_cache.insert_new(p_name, idx);
+ process_state->tree->property_map.get_by_index(idx).value.first = p_value;
}
Variant AnimationNode::get_parameter(const StringName &p_name) const {
ERR_FAIL_NULL_V(process_state, Variant());
+ const AHashMap<StringName, int>::ConstIterator it = property_cache.find(p_name);
+ if (it) {
+ return process_state->tree->property_map.get_by_index(it->value).value.first;
+ }
ERR_FAIL_COND_V(!process_state->tree->property_parent_map.has(node_state.base_path), Variant());
ERR_FAIL_COND_V(!process_state->tree->property_parent_map[node_state.base_path].has(p_name), Variant());
StringName path = process_state->tree->property_parent_map[node_state.base_path][p_name];
- return process_state->tree->property_map[path].first;
+ int idx = process_state->tree->property_map.get_index(path);
+ property_cache.insert_new(p_name, idx);
+ return process_state->tree->property_map.get_by_index(idx).value.first;
}
void AnimationNode::set_node_time_info(const NodeTimeInfo &p_node_time_info) {
@@ -203,7 +217,7 @@ AnimationNode::NodeTimeInfo AnimationNode::_blend_node(Ref<AnimationNode> p_node
}
for (const KeyValue<NodePath, bool> &E : filter) {
- const HashMap<NodePath, int> &map = *process_state->track_map;
+ const AHashMap<NodePath, int> &map = *process_state->track_map;
if (!map.has(E.key)) {
continue;
}
@@ -292,7 +306,7 @@ AnimationNode::NodeTimeInfo AnimationNode::_blend_node(Ref<AnimationNode> p_node
// This process, which depends on p_sync is needed to process sync correctly in the case of
// that a synced AnimationNodeSync exists under the un-synced AnimationNodeSync.
- p_node->node_state.base_path = new_path;
+ p_node->set_node_state_base_path(new_path);
p_node->node_state.parent = new_parent;
if (!p_playback_info.seeked && !p_sync && !any_valid) {
p_playback_info.delta = 0.0;
@@ -603,7 +617,7 @@ Ref<AnimationRootNode> AnimationTree::get_root_animation_node() const {
return root_animation_node;
}
-bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map) {
+bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) {
_update_properties(); // If properties need updating, update them.
if (!root_animation_node.is_valid()) {
@@ -627,7 +641,7 @@ bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const
for (int i = 0; i < p_track_count; i++) {
src_blendsw[i] = 1.0; // By default all go to 1 for the root input.
}
- root_animation_node->node_state.base_path = SNAME(Animation::PARAMETERS_BASE_PATH.ascii().get_data());
+ root_animation_node->set_node_state_base_path(SNAME(Animation::PARAMETERS_BASE_PATH.ascii().get_data()));
root_animation_node->node_state.parent = nullptr;
}
@@ -732,7 +746,7 @@ void AnimationTree::_animation_node_removed(const ObjectID &p_oid, const StringN
void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<AnimationNode> p_node) {
ERR_FAIL_COND(p_node.is_null());
if (!property_parent_map.has(p_base_path)) {
- property_parent_map[p_base_path] = HashMap<StringName, StringName>();
+ property_parent_map[p_base_path] = AHashMap<StringName, StringName>();
}
if (!property_reference_map.has(p_node->get_instance_id())) {
property_reference_map[p_node->get_instance_id()] = p_base_path;
@@ -767,7 +781,7 @@ void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<A
pinfo.name = p_base_path + key;
properties.push_back(pinfo);
}
-
+ p_node->make_cache_dirty();
List<AnimationNode::ChildNode> children;
p_node->get_child_nodes(&children);
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index d4b7bf31c9..8ee80f29ee 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -60,7 +60,7 @@ public:
bool closable = false;
Vector<Input> inputs;
- HashMap<NodePath, bool> filter;
+ AHashMap<NodePath, bool> filter;
bool filter_enabled = false;
// To propagate information from upstream for use in estimation of playback progress.
@@ -97,22 +97,57 @@ public:
// Temporary state for blending process which needs to be stored in each AnimationNodes.
struct NodeState {
+ friend AnimationNode;
+
+ private:
StringName base_path;
+
+ public:
AnimationNode *parent = nullptr;
Vector<StringName> connections;
Vector<real_t> track_weights;
+
+ const StringName get_base_path() const {
+ return base_path;
+ }
+
} node_state;
// Temporary state for blending process which needs to be started in the AnimationTree, pass through the AnimationNodes, and then return to the AnimationTree.
struct ProcessState {
AnimationTree *tree = nullptr;
- const HashMap<NodePath, int> *track_map; // TODO: Is there a better way to manage filter/tracks?
+ const AHashMap<NodePath, int> *track_map; // TODO: Is there a better way to manage filter/tracks?
bool is_testing = false;
bool valid = false;
String invalid_reasons;
uint64_t last_pass = 0;
} *process_state = nullptr;
+private:
+ mutable AHashMap<StringName, int> property_cache;
+
+public:
+ void set_node_state_base_path(const StringName p_base_path) {
+ if (p_base_path != node_state.base_path) {
+ node_state.base_path = p_base_path;
+ make_cache_dirty();
+ }
+ }
+
+ void set_node_state_base_path(const String p_base_path) {
+ if (p_base_path != node_state.base_path) {
+ node_state.base_path = p_base_path;
+ make_cache_dirty();
+ }
+ }
+
+ const StringName get_node_state_base_path() const {
+ return node_state.get_base_path();
+ }
+
+ void make_cache_dirty() {
+ property_cache.clear();
+ }
Array _get_filters() const;
void _set_filters(const Array &p_filters);
friend class AnimationNodeBlendTree;
@@ -250,9 +285,9 @@ private:
friend class AnimationNode;
List<PropertyInfo> properties;
- HashMap<StringName, HashMap<StringName, StringName>> property_parent_map;
- HashMap<ObjectID, StringName> property_reference_map;
- HashMap<StringName, Pair<Variant, bool>> property_map; // Property value and read-only flag.
+ AHashMap<StringName, AHashMap<StringName, StringName>> property_parent_map;
+ AHashMap<ObjectID, StringName> property_reference_map;
+ AHashMap<StringName, Pair<Variant, bool>> property_map; // Property value and read-only flag.
bool properties_dirty = true;
@@ -286,7 +321,7 @@ private:
virtual void _set_active(bool p_active) override;
// Make animation instances.
- virtual bool _blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map) override;
+ virtual bool _blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) override;
#ifndef DISABLE_DEPRECATED
void _set_process_callback_bind_compat_80813(AnimationProcessCallback p_mode);
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 0a5f2ec6c7..9df4bfde92 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -296,19 +296,12 @@ void Button::_notification(int p_what) {
}
} break;
case DRAW_HOVER_PRESSED: {
- // Edge case for CheckButton and CheckBox.
- if (has_theme_stylebox("hover_pressed")) {
- if (has_theme_color(SNAME("font_hover_pressed_color"))) {
- font_color = theme_cache.font_hover_pressed_color;
- }
- if (has_theme_color(SNAME("icon_hover_pressed_color"))) {
- icon_modulate_color = theme_cache.icon_hover_pressed_color;
- }
-
- break;
+ font_color = theme_cache.font_hover_pressed_color;
+ if (has_theme_color(SNAME("icon_hover_pressed_color"))) {
+ icon_modulate_color = theme_cache.icon_hover_pressed_color;
}
- }
- [[fallthrough]];
+
+ } break;
case DRAW_PRESSED: {
if (has_theme_color(SNAME("font_pressed_color"))) {
font_color = theme_cache.font_pressed_color;
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index e92f979c32..2d88a9bddf 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -1553,23 +1553,21 @@ void ColorPicker::_pick_button_pressed_legacy() {
picker_texture_rect = memnew(TextureRect);
picker_texture_rect->set_anchors_preset(Control::PRESET_FULL_RECT);
+ picker_texture_rect->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE);
picker_window->add_child(picker_texture_rect);
picker_texture_rect->set_default_cursor_shape(CURSOR_POINTING_HAND);
picker_texture_rect->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_picker_texture_input));
- picker_preview = memnew(Panel);
- picker_preview->set_anchors_preset(Control::PRESET_CENTER_TOP);
- picker_preview->set_mouse_filter(MOUSE_FILTER_IGNORE);
- picker_window->add_child(picker_preview);
-
picker_preview_label = memnew(Label);
- picker_preview->set_anchors_preset(Control::PRESET_CENTER_TOP);
+ picker_preview_label->set_anchors_preset(Control::PRESET_CENTER_TOP);
picker_preview_label->set_text(ETR("Color Picking active"));
- picker_preview->add_child(picker_preview_label);
- picker_preview_style_box = (Ref<StyleBoxFlat>)memnew(StyleBoxFlat);
+ picker_preview_style_box.instantiate();
picker_preview_style_box->set_bg_color(Color(1.0, 1.0, 1.0));
- picker_preview->add_theme_style_override(SceneStringName(panel), picker_preview_style_box);
+ picker_preview_style_box->set_content_margin_all(4.0);
+ picker_preview_label->add_theme_style_override(CoreStringName(normal), picker_preview_style_box);
+
+ picker_window->add_child(picker_preview_label);
}
Rect2i screen_rect;
@@ -1611,7 +1609,7 @@ void ColorPicker::_pick_button_pressed_legacy() {
}
picker_window->set_size(screen_rect.size);
- picker_preview->set_size(screen_rect.size / 10.0); // 10% of size in each axis.
+ picker_preview_label->set_custom_minimum_size(screen_rect.size / 10); // 10% of size in each axis.
picker_window->popup();
}
@@ -1634,7 +1632,7 @@ void ColorPicker::_picker_texture_input(const Ref<InputEvent> &p_event) {
Vector2 ofs = mev->get_position();
picker_color = img->get_pixel(ofs.x, ofs.y);
picker_preview_style_box->set_bg_color(picker_color);
- picker_preview_label->set_self_modulate(picker_color.get_luminance() < 0.5 ? Color(1.0f, 1.0f, 1.0f) : Color(0.0f, 0.0f, 0.0f));
+ picker_preview_label->add_theme_color_override(SceneStringName(font_color), picker_color.get_luminance() < 0.5 ? Color(1.0f, 1.0f, 1.0f) : Color(0.0f, 0.0f, 0.0f));
}
}
}
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index ad028584b1..59540d9ace 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -130,7 +130,6 @@ private:
Popup *picker_window = nullptr;
// Legacy color picking.
TextureRect *picker_texture_rect = nullptr;
- Panel *picker_preview = nullptr;
Label *picker_preview_label = nullptr;
Ref<StyleBoxFlat> picker_preview_style_box;
Color picker_color;
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 6159e26efa..40917ee8f1 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -961,19 +961,17 @@ TreeItem *TreeItem::_get_prev_in_tree(bool p_wrap, bool p_include_invisible) {
if (!prev_item) {
current = current->parent;
- if (current == tree->root && tree->hide_root) {
- return nullptr;
- } else if (!current) {
- if (p_wrap) {
- current = this;
- TreeItem *temp = get_next_visible();
- while (temp) {
- current = temp;
- temp = temp->get_next_visible();
- }
- } else {
+ if (!current || (current == tree->root && tree->hide_root)) {
+ if (!p_wrap) {
return nullptr;
}
+ // Wrap around to the last visible item.
+ current = this;
+ TreeItem *temp = get_next_visible();
+ while (temp) {
+ current = temp;
+ temp = temp->get_next_visible();
+ }
}
} else {
current = prev_item;
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index c0386b056f..7c8bf9c809 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -1253,7 +1253,7 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("force_update_transform"), &CanvasItem::force_update_transform);
- ClassDB::bind_method(D_METHOD("make_canvas_position_local", "screen_point"), &CanvasItem::make_canvas_position_local);
+ ClassDB::bind_method(D_METHOD("make_canvas_position_local", "viewport_point"), &CanvasItem::make_canvas_position_local);
ClassDB::bind_method(D_METHOD("make_input_local", "event"), &CanvasItem::make_input_local);
ClassDB::bind_method(D_METHOD("set_visibility_layer", "layer"), &CanvasItem::set_visibility_layer);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 0cdb23618f..8755d5f51e 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1921,7 +1921,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_global_transform_with_canvas().affine_inverse().xform(mpos));
tooltip = tooltip.strip_edges();
- if (tooltip.is_empty() || tooltip != gui.tooltip_text) {
+ if (tooltip != gui.tooltip_text) {
_gui_cancel_tooltip();
} else {
is_tooltip_shown = true;
diff --git a/scene/property_utils.cpp b/scene/property_utils.cpp
index 94a037bd9b..f068e34beb 100644
--- a/scene/property_utils.cpp
+++ b/scene/property_utils.cpp
@@ -89,6 +89,16 @@ Variant PropertyUtils::get_property_default_value(const Object *p_object, const
*r_is_valid = false;
}
+ // Handle special case "script" property, where the default value is either null or the custom type script.
+ // Do this only if there's no states stack cache to trace for default values.
+ if (!p_states_stack_cache && p_property == CoreStringName(script) && p_object->has_meta(SceneStringName(_custom_type_script))) {
+ Ref<Script> ct_scr = p_object->get_meta(SceneStringName(_custom_type_script));
+ if (r_is_valid) {
+ *r_is_valid = true;
+ }
+ return ct_scr;
+ }
+
Ref<Script> topmost_script;
if (const Node *node = Object::cast_to<Node>(p_object)) {
diff --git a/scene/resources/2d/tile_set.cpp b/scene/resources/2d/tile_set.cpp
index 229e18be23..e624bdb32f 100644
--- a/scene/resources/2d/tile_set.cpp
+++ b/scene/resources/2d/tile_set.cpp
@@ -6480,9 +6480,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 +6495,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/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/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/scene_string_names.cpp b/scene/scene_string_names.cpp
index 140e588291..31daeb3ae3 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -130,6 +130,8 @@ SceneStringNames::SceneStringNames() {
shader_overrides_group = StaticCString::create("_shader_overrides_group_");
shader_overrides_group_active = StaticCString::create("_shader_overrides_group_active_");
+ _custom_type_script = StaticCString::create("_custom_type_script");
+
pressed = StaticCString::create("pressed");
id_pressed = StaticCString::create("id_pressed");
toggled = StaticCString::create("toggled");
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index fc22be33b2..0a2ebeda7a 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -143,6 +143,8 @@ public:
StringName shader_overrides_group;
StringName shader_overrides_group_active;
+ StringName _custom_type_script;
+
StringName pressed;
StringName id_pressed;
StringName toggled;