summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/io/resource.cpp118
-rw-r--r--core/io/resource.h7
-rw-r--r--editor/renames_map_3_to_4.cpp3
-rw-r--r--modules/basis_universal/register_types.cpp2
-rw-r--r--modules/glslang/config.py4
-rw-r--r--scene/2d/skeleton_2d.cpp32
6 files changed, 116 insertions, 50 deletions
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 04ecabaf27..daa57be76f 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -204,7 +204,58 @@ void Resource::reload_from_file() {
copy_from(s);
}
-Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource>, Ref<Resource>> &remap_cache) {
+void Resource::_dupe_sub_resources(Variant &r_variant, Node *p_for_scene, HashMap<Ref<Resource>, Ref<Resource>> &p_remap_cache) {
+ switch (r_variant.get_type()) {
+ case Variant::ARRAY: {
+ Array a = r_variant;
+ for (int i = 0; i < a.size(); i++) {
+ _dupe_sub_resources(a[i], p_for_scene, p_remap_cache);
+ }
+ } break;
+ case Variant::DICTIONARY: {
+ Dictionary d = r_variant;
+ List<Variant> keys;
+ d.get_key_list(&keys);
+ for (Variant &k : keys) {
+ if (k.get_type() == Variant::OBJECT) {
+ // Replace in dictionary key.
+ Ref<Resource> sr = k;
+ if (sr.is_valid() && sr->is_local_to_scene()) {
+ if (p_remap_cache.has(sr)) {
+ d[p_remap_cache[sr]] = d[k];
+ d.erase(k);
+ } else {
+ Ref<Resource> dupe = sr->duplicate_for_local_scene(p_for_scene, p_remap_cache);
+ d[dupe] = d[k];
+ d.erase(k);
+ p_remap_cache[sr] = dupe;
+ }
+ }
+ } else {
+ _dupe_sub_resources(k, p_for_scene, p_remap_cache);
+ }
+
+ _dupe_sub_resources(d[k], p_for_scene, p_remap_cache);
+ }
+ } break;
+ case Variant::OBJECT: {
+ Ref<Resource> sr = r_variant;
+ if (sr.is_valid() && sr->is_local_to_scene()) {
+ if (p_remap_cache.has(sr)) {
+ r_variant = p_remap_cache[sr];
+ } else {
+ Ref<Resource> dupe = sr->duplicate_for_local_scene(p_for_scene, p_remap_cache);
+ r_variant = dupe;
+ p_remap_cache[sr] = dupe;
+ }
+ }
+ } break;
+ default: {
+ }
+ }
+}
+
+Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource>, Ref<Resource>> &p_remap_cache) {
List<PropertyInfo> plist;
get_property_list(&plist);
@@ -217,21 +268,9 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, HashMap<Ref
if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
continue;
}
- Variant p = get(E.name);
- if (p.get_type() == Variant::OBJECT) {
- Ref<Resource> sr = p;
- if (sr.is_valid()) {
- if (sr->is_local_to_scene()) {
- if (remap_cache.has(sr)) {
- p = remap_cache[sr];
- } else {
- Ref<Resource> dupe = sr->duplicate_for_local_scene(p_for_scene, remap_cache);
- p = dupe;
- remap_cache[sr] = dupe;
- }
- }
- }
- }
+ Variant p = get(E.name).duplicate(true);
+
+ _dupe_sub_resources(p, p_for_scene, p_remap_cache);
r->set(E.name, p);
}
@@ -239,7 +278,35 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, HashMap<Ref
return r;
}
-void Resource::configure_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource>, Ref<Resource>> &remap_cache) {
+void Resource::_find_sub_resources(const Variant &p_variant, HashSet<Ref<Resource>> &p_resources_found) {
+ switch (p_variant.get_type()) {
+ case Variant::ARRAY: {
+ Array a = p_variant;
+ for (int i = 0; i < a.size(); i++) {
+ _find_sub_resources(a[i], p_resources_found);
+ }
+ } break;
+ case Variant::DICTIONARY: {
+ Dictionary d = p_variant;
+ List<Variant> keys;
+ d.get_key_list(&keys);
+ for (const Variant &k : keys) {
+ _find_sub_resources(k, p_resources_found);
+ _find_sub_resources(d[k], p_resources_found);
+ }
+ } break;
+ case Variant::OBJECT: {
+ Ref<Resource> r = p_variant;
+ if (r.is_valid()) {
+ p_resources_found.insert(r);
+ }
+ } break;
+ default: {
+ }
+ }
+}
+
+void Resource::configure_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource>, Ref<Resource>> &p_remap_cache) {
List<PropertyInfo> plist;
get_property_list(&plist);
@@ -251,14 +318,15 @@ void Resource::configure_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource
continue;
}
Variant p = get(E.name);
- if (p.get_type() == Variant::OBJECT) {
- Ref<Resource> sr = p;
- if (sr.is_valid()) {
- if (sr->is_local_to_scene()) {
- if (!remap_cache.has(sr)) {
- sr->configure_for_local_scene(p_for_scene, remap_cache);
- remap_cache[sr] = sr;
- }
+
+ HashSet<Ref<Resource>> sub_resources;
+ _find_sub_resources(p, sub_resources);
+
+ for (Ref<Resource> sr : sub_resources) {
+ if (sr->is_local_to_scene()) {
+ if (!p_remap_cache.has(sr)) {
+ sr->configure_for_local_scene(p_for_scene, p_remap_cache);
+ p_remap_cache[sr] = sr;
}
}
}
diff --git a/core/io/resource.h b/core/io/resource.h
index 610c2150db..b885b773ac 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -74,6 +74,9 @@ private:
SelfList<Resource> remapped_list;
+ void _dupe_sub_resources(Variant &r_variant, Node *p_for_scene, HashMap<Ref<Resource>, Ref<Resource>> &p_remap_cache);
+ void _find_sub_resources(const Variant &p_variant, HashSet<Ref<Resource>> &p_resources_found);
+
protected:
virtual void _resource_path_changed();
static void _bind_methods();
@@ -111,8 +114,8 @@ public:
String get_scene_unique_id() const;
virtual Ref<Resource> duplicate(bool p_subresources = false) const;
- Ref<Resource> duplicate_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource>, Ref<Resource>> &remap_cache);
- void configure_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource>, Ref<Resource>> &remap_cache);
+ Ref<Resource> duplicate_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource>, Ref<Resource>> &p_remap_cache);
+ void configure_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource>, Ref<Resource>> &p_remap_cache);
void set_local_to_scene(bool p_enable);
bool is_local_to_scene() const;
diff --git a/editor/renames_map_3_to_4.cpp b/editor/renames_map_3_to_4.cpp
index 7460a2ed7e..ba6095db47 100644
--- a/editor/renames_map_3_to_4.cpp
+++ b/editor/renames_map_3_to_4.cpp
@@ -163,6 +163,7 @@ const char *RenamesMap3To4::gdscript_function_renames[][2] = {
// { "_set_name", "get_tracker_name" }, // XRPositionalTracker -- CameraFeed uses this.
// { "_unhandled_input", "_unhandled_key_input" }, // BaseButton, ViewportContainer -- Breaks Node, FileDialog, SubViewportContainer.
+ // { "add_animation", "add_animation_library" }, // AnimationPlayer -- Breaks SpriteFrames (and isn't a correct conversion).
// { "create_gizmo", "_create_gizmo" }, // EditorNode3DGizmoPlugin -- May be used.
// { "get_dependencies", "_get_dependencies" }, // ResourceFormatLoader -- Breaks ResourceLoader.
// { "get_extents", "get_size" }, // BoxShape, RectangleShape -- Breaks Decal, VoxelGI, GPUParticlesCollisionBox, GPUParticlesCollisionSDF, GPUParticlesCollisionHeightField, GPUParticlesAttractorBox, GPUParticlesAttractorVectorField, FogVolume
@@ -214,7 +215,6 @@ const char *RenamesMap3To4::gdscript_function_renames[][2] = {
{ "_set_current", "set_current" }, // Camera2D
{ "_set_editor_description", "set_editor_description" }, // Node
{ "_toplevel_raise_self", "_top_level_raise_self" }, // CanvasItem
- { "add_animation", "add_animation_library" }, // AnimationPlayer
{ "add_cancel", "add_cancel_button" }, // AcceptDialog
{ "add_central_force", "apply_central_force" }, //RigidBody2D
{ "add_child_below_node", "add_sibling" }, // Node
@@ -643,7 +643,6 @@ const char *RenamesMap3To4::csharp_function_renames[][2] = {
{ "_SetPlaying", "SetPlaying" }, // AnimatedSprite3D
{ "_ToplevelRaiseSelf", "_TopLevelRaiseSelf" }, // CanvasItem
{ "_UpdateWrapAt", "_UpdateWrapAtColumn" }, // TextEdit
- { "AddAnimation", "AddAnimationLibrary" }, // AnimationPlayer
{ "AddCancel", "AddCancelButton" }, // AcceptDialog
{ "AddCentralForce", "AddConstantCentralForce" }, //RigidBody2D
{ "AddChildBelowNode", "AddSibling" }, // Node
diff --git a/modules/basis_universal/register_types.cpp b/modules/basis_universal/register_types.cpp
index 7c0bc4ac82..f538fc6676 100644
--- a/modules/basis_universal/register_types.cpp
+++ b/modules/basis_universal/register_types.cpp
@@ -221,7 +221,7 @@ static Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size
imgfmt = Image::FORMAT_DXT5_RA_AS_RG;
} else if (RS::get_singleton()->has_os_feature("etc2")) {
format = basist::transcoder_texture_format::cTFETC2; // get this from renderer
- imgfmt = Image::FORMAT_ETC2_RGBA8;
+ imgfmt = Image::FORMAT_ETC2_RA_AS_RG;
} else {
//opengl most likely, bad for normal maps, nothing to do about this.
format = basist::transcoder_texture_format::cTFRGBA32;
diff --git a/modules/glslang/config.py b/modules/glslang/config.py
index d22f9454ed..1169776a73 100644
--- a/modules/glslang/config.py
+++ b/modules/glslang/config.py
@@ -1,5 +1,7 @@
def can_build(env, platform):
- return True
+ # glslang is only needed when Vulkan or Direct3D 12-based renderers are available,
+ # as OpenGL doesn't use glslang.
+ return env["vulkan"] or env["d3d12"]
def configure(env):
diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp
index b8632b500b..69e0414855 100644
--- a/scene/2d/skeleton_2d.cpp
+++ b/scene/2d/skeleton_2d.cpp
@@ -433,29 +433,23 @@ PackedStringArray Bone2D::get_configuration_warnings() const {
}
void Bone2D::calculate_length_and_rotation() {
- // if there is at least a single child Bone2D node, we can calculate
+ // If there is at least a single child Bone2D node, we can calculate
// the length and direction. We will always just use the first Bone2D for this.
- bool calculated = false;
int child_count = get_child_count();
- if (child_count > 0) {
- for (int i = 0; i < child_count; i++) {
- Bone2D *child = Object::cast_to<Bone2D>(get_child(i));
- if (child) {
- Vector2 child_local_pos = to_local(child->get_global_position());
- length = child_local_pos.length();
- bone_angle = child_local_pos.normalized().angle();
- calculated = true;
- break;
- }
+ Transform2D global_inv = get_global_transform().affine_inverse();
+
+ for (int i = 0; i < child_count; i++) {
+ Bone2D *child = Object::cast_to<Bone2D>(get_child(i));
+ if (child) {
+ Vector2 child_local_pos = global_inv.xform(child->get_global_position());
+ length = child_local_pos.length();
+ bone_angle = child_local_pos.angle();
+ return; // Finished!
}
}
- if (calculated) {
- return; // Finished!
- } else {
- WARN_PRINT("No Bone2D children of node " + get_name() + ". Cannot calculate bone length or angle reliably.\nUsing transform rotation for bone angle");
- bone_angle = get_transform().get_rotation();
- return;
- }
+
+ WARN_PRINT("No Bone2D children of node " + get_name() + ". Cannot calculate bone length or angle reliably.\nUsing transform rotation for bone angle.");
+ bone_angle = get_transform().get_rotation();
}
void Bone2D::set_autocalculate_length_and_angle(bool p_autocalculate) {