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.
This commit is contained in:
Rémi Verschelde 2024-05-03 00:17:34 +02:00
parent b9f01dcf87
commit 7aacb098f0
No known key found for this signature in database
GPG Key ID: C3336907360768E1
3 changed files with 50 additions and 6 deletions

View File

@ -85,15 +85,18 @@ enum {
VARIANT_VECTOR4 = 50, VARIANT_VECTOR4 = 50,
VARIANT_VECTOR4I = 51, VARIANT_VECTOR4I = 51,
VARIANT_PROJECTION = 52, VARIANT_PROJECTION = 52,
VARIANT_PACKED_VECTOR4_ARRAY = 53, // For compat with 4.3, parsing only.
OBJECT_EMPTY = 0, OBJECT_EMPTY = 0,
OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_EXTERNAL_RESOURCE = 1,
OBJECT_INTERNAL_RESOURCE = 2, OBJECT_INTERNAL_RESOURCE = 2,
OBJECT_EXTERNAL_RESOURCE_INDEX = 3, OBJECT_EXTERNAL_RESOURCE_INDEX = 3,
// Version 2: added 64 bits support for float and int. // Version 2: Added 64 bits support for float and int.
// Version 3: changed nodepath encoding. // Version 3: Changed nodepath encoding.
// Version 4: new string ID for ext/subresources, breaks forward compat. // Version 4: New string ID for ext/subresources, breaks forward compat.
// Version 5: Ability to store script class in the header. // Version 5: Ability to store script class in the header.
FORMAT_VERSION = 5, FORMAT_VERSION = 5,
// Version 6: Added PackedVector4Array variant. Parsing only.
FORMAT_VERSION_READABLE = 6,
FORMAT_VERSION_CAN_RENAME_DEPS = 1, FORMAT_VERSION_CAN_RENAME_DEPS = 1,
FORMAT_VERSION_NO_NODEPATH_PROPERTY = 3, FORMAT_VERSION_NO_NODEPATH_PROPERTY = 3,
}; };
@ -653,6 +656,27 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
r_v = array; r_v = array;
} break; } break;
case VARIANT_PACKED_VECTOR4_ARRAY: {
// For compatibility with 4.3, parsing only.
// Parse to a Vector<real_t> and then convert to a plain Array.
uint32_t len = f->get_32();
Vector<real_t> 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<real_t *>(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: { default: {
ERR_FAIL_V(ERR_FILE_CORRUPT); ERR_FAIL_V(ERR_FILE_CORRUPT);
} break; } break;

View File

@ -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<real_t> args;
Error err = _parse_construct<real_t>(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; value = arr;
} else if (id == "PackedColorArray" || id == "PoolColorArray" || id == "ColorArray") { } else if (id == "PackedColorArray" || id == "PoolColorArray" || id == "ColorArray") {
Vector<float> args; Vector<float> args;

View File

@ -37,10 +37,11 @@
#include "core/object/script_language.h" #include "core/object/script_language.h"
#include "core/version.h" #include "core/version.h"
// Version 2: changed names for Basis, AABB, Vectors, etc. // Version 2: Changed names for Basis, AABB, Vectors, etc.
// Version 3: new string ID for ext/subresources, breaks forward compat. // Version 3: New string ID for ext/subresources, breaks forward compat.
// Version 4: PackedByteArray is now stored as base64 encoded.
#define FORMAT_VERSION 3 #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 FORMAT_VERSION_READABLE 4
#define BINARY_FORMAT_VERSION 4 #define BINARY_FORMAT_VERSION 4