From 7aacb098f0d46bdc102f83c371ec4f33c7d0488a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Fri, 3 May 2024 00:17:34 +0200 Subject: [PATCH] Add forward compat parsing of PackedVector4Array This new Variant type is being added in 4.3, and breaks compatibility with earlier releases. By adding minimal parsing support (converting to plain Array) we can at least open the scenes, and minimize the data loss when going back and forth between minor versions. --- core/io/resource_format_binary.cpp | 30 +++++++++++++++++++++--- core/variant/variant_parser.cpp | 19 +++++++++++++++ scene/resources/resource_format_text.cpp | 7 +++--- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 20c494516be..b6d878dab51 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -85,15 +85,18 @@ enum { VARIANT_VECTOR4 = 50, VARIANT_VECTOR4I = 51, VARIANT_PROJECTION = 52, + VARIANT_PACKED_VECTOR4_ARRAY = 53, // For compat with 4.3, parsing only. OBJECT_EMPTY = 0, OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_INTERNAL_RESOURCE = 2, OBJECT_EXTERNAL_RESOURCE_INDEX = 3, - // Version 2: added 64 bits support for float and int. - // Version 3: changed nodepath encoding. - // Version 4: new string ID for ext/subresources, breaks forward compat. + // Version 2: Added 64 bits support for float and int. + // Version 3: Changed nodepath encoding. + // Version 4: New string ID for ext/subresources, breaks forward compat. // Version 5: Ability to store script class in the header. FORMAT_VERSION = 5, + // Version 6: Added PackedVector4Array variant. Parsing only. + FORMAT_VERSION_READABLE = 6, FORMAT_VERSION_CAN_RENAME_DEPS = 1, FORMAT_VERSION_NO_NODEPATH_PROPERTY = 3, }; @@ -653,6 +656,27 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; + case VARIANT_PACKED_VECTOR4_ARRAY: { + // For compatibility with 4.3, parsing only. + // Parse to a Vector and then convert to a plain Array. + uint32_t len = f->get_32(); + + Vector array_real; + array_real.resize(len * 4); + real_t *w = array_real.ptrw(); + static_assert(sizeof(Vector4) == 4 * sizeof(real_t)); + const Error err = read_reals(reinterpret_cast(w), f, len * 4); + ERR_FAIL_COND_V(err != OK, err); + + Array array; + array.resize(len); + for (uint32_t i = 0; i < len; i++) { + array[i] = Vector4(w[i * 4 + 0], w[i * 4 + 1], w[i * 4 + 2], w[i * 4 + 3]); + } + + r_v = array; + + } break; default: { ERR_FAIL_V(ERR_FILE_CORRUPT); } break; diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 7c2e3ab15bf..7b38c5394ac 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -1394,6 +1394,25 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } } + value = arr; + } else if (id == "PackedVector4Array" || id == "PoolVector4Array" || id == "Vector4Array") { + // Not supported for writing, added for compatibility with 4.3. + // Handled as a plain array of Vector4 elements. + Vector args; + Error err = _parse_construct(p_stream, args, line, r_err_str); + if (err) { + return err; + } + + Array arr; + { + int len = args.size() / 4; + arr.resize(len); + for (int i = 0; i < len; i++) { + arr[i] = Vector4(args[i * 4 + 0], args[i * 4 + 1], args[i * 4 + 2], args[i * 4 + 3]); + } + } + value = arr; } else if (id == "PackedColorArray" || id == "PoolColorArray" || id == "ColorArray") { Vector args; diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 23574f1e8b3..adc86de3cd6 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -37,10 +37,11 @@ #include "core/object/script_language.h" #include "core/version.h" -// Version 2: changed names for Basis, AABB, Vectors, etc. -// Version 3: new string ID for ext/subresources, breaks forward compat. -// Version 4: PackedByteArray is now stored as base64 encoded. +// Version 2: Changed names for Basis, AABB, Vectors, etc. +// Version 3: New string ID for ext/subresources, breaks forward compat. #define FORMAT_VERSION 3 +// Version 4: PackedByteArray can be base64 encoded, and PackedVector4Array was added. +// Parsing only, for forward compat with 4.3+. #define FORMAT_VERSION_READABLE 4 #define BINARY_FORMAT_VERSION 4