diff --git a/misc/extension_api_validation/4.4-stable.expected b/misc/extension_api_validation/4.4-stable.expected index 376e3388473..1837338392d 100644 --- a/misc/extension_api_validation/4.4-stable.expected +++ b/misc/extension_api_validation/4.4-stable.expected @@ -267,3 +267,48 @@ Validate extension JSON: JSON file: Field was added in a way that breaks compati Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/RichTextLabel/methods/push_underline': arguments Optional "color" argument added. Compatibility methods registered. + + +GH-106220 +--------- +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_accessor_type': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_buffer_view': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_byte_offset': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_byte_offset/return_value': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_component_type': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_component_type': meta was removed. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_component_type/return_value': type changed value in new API, from "int" to "enum::GLTFAccessor.GLTFComponentType". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_count': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_count/return_value': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_max': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_min': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_normalized': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_count': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_count/return_value': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_indices_buffer_view': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_indices_byte_offset': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_indices_byte_offset/return_value': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_indices_component_type': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_indices_component_type': meta was removed. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_indices_component_type/return_value': type changed value in new API, from "int" to "enum::GLTFAccessor.GLTFComponentType". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_values_buffer_view': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_values_byte_offset': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_sparse_values_byte_offset/return_value': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/get_type': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/set_byte_offset/arguments/0': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/set_component_type/arguments': meta was removed. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/set_component_type/arguments/0': type changed value in new API, from "int" to "enum::GLTFAccessor.GLTFComponentType". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/set_count/arguments/0': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/set_sparse_count/arguments/0': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/set_sparse_indices_byte_offset/arguments/0': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/set_sparse_indices_component_type/arguments': meta was removed. +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/set_sparse_indices_component_type/arguments/0': type changed value in new API, from "int" to "enum::GLTFAccessor.GLTFComponentType". +Validate extension JSON: Error: Field 'classes/GLTFAccessor/methods/set_sparse_values_byte_offset/arguments/0': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFBufferView/methods/get_byte_length/return_value': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFBufferView/methods/get_byte_offset/return_value': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFBufferView/methods/get_byte_stride/return_value': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFBufferView/methods/set_byte_length/arguments/0': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFBufferView/methods/set_byte_offset/arguments/0': meta changed value in new API, from "int32" to "int64". +Validate extension JSON: Error: Field 'classes/GLTFBufferView/methods/set_byte_stride/arguments/0': meta changed value in new API, from "int32" to "int64". + +GLTFBufferView and GLTFAccessor now use int64 for offsets and lengths. Compatibility methods registered. diff --git a/modules/gltf/doc_classes/GLTFAccessor.xml b/modules/gltf/doc_classes/GLTFAccessor.xml index 905eb5570c2..b0d4cc5d707 100644 --- a/modules/gltf/doc_classes/GLTFAccessor.xml +++ b/modules/gltf/doc_classes/GLTFAccessor.xml @@ -21,7 +21,7 @@ The offset relative to the start of the buffer view in bytes. - + The glTF component type as an enum. See [enum GLTFComponentType] for possible values. Within the core glTF specification, a value of 5125 or "UNSIGNED_INT" must not be used for any accessor that is not referenced by mesh.primitive.indices. @@ -45,7 +45,7 @@ The offset relative to the start of the buffer view in bytes. - + The indices component data type as an enum. Possible values are 5121 for "UNSIGNED_BYTE", 5123 for "UNSIGNED_SHORT", and 5125 for "UNSIGNED_INT". diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 664fdba7ee1..9ec0687ea7a 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -333,10 +333,7 @@ Error GLTFDocument::_parse_glb(Ref p_file, Ref p_state) { JSON json; Error err = json.parse(text); - if (err != OK) { - _err_print_error("", "", json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT); - return err; - } + ERR_FAIL_COND_V_MSG(err != OK, err, "glTF Binary: Error parsing .glb file's JSON data: " + json.get_error_message() + " at line: " + itos(json.get_error_line())); p_state->json = json.get_data(); @@ -747,7 +744,7 @@ Error GLTFDocument::_encode_buffer_glb(Ref p_state, const String &p_p buffers.push_back(gltf_buffer); } - for (GLTFBufferIndex i = 1; i < p_state->buffers.size() - 1; i++) { + for (GLTFBufferIndex i = 1; i < p_state->buffers.size(); i++) { Vector buffer_data = p_state->buffers[i]; Dictionary gltf_buffer; String filename = p_path.get_basename().get_file() + itos(i) + ".bin"; @@ -810,37 +807,36 @@ Error GLTFDocument::_parse_buffers(Ref p_state, const String &p_base_ const Array &buffers = p_state->json["buffers"]; for (GLTFBufferIndex i = 0; i < buffers.size(); i++) { - if (i == 0 && p_state->glb_data.size()) { - p_state->buffers.push_back(p_state->glb_data); + const Dictionary &buffer = buffers[i]; + Vector buffer_data; + if (buffer.has("uri")) { + String uri = buffer["uri"]; - } else { - const Dictionary &buffer = buffers[i]; - if (buffer.has("uri")) { - Vector buffer_data; - String uri = buffer["uri"]; - - if (uri.begins_with("data:")) { // Embedded data using base64. - // Validate data MIME types and throw an error if it's one we don't know/support. - if (!uri.begins_with("data:application/octet-stream;base64") && - !uri.begins_with("data:application/gltf-buffer;base64")) { - ERR_PRINT("glTF: Got buffer with an unknown URI data type: " + uri); - } - buffer_data = _parse_base64_uri(uri); - } else { // Relative path to an external image file. - ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER); - uri = uri.uri_file_decode(); - uri = p_base_path.path_join(uri).replace_char('\\', '/'); // Fix for Windows. - ERR_FAIL_COND_V_MSG(!FileAccess::exists(uri), ERR_FILE_NOT_FOUND, "glTF: Binary file not found: " + uri); - buffer_data = FileAccess::get_file_as_bytes(uri); - ERR_FAIL_COND_V_MSG(buffer_data.is_empty(), ERR_PARSE_ERROR, "glTF: Couldn't load binary file as an array: " + uri); + if (uri.begins_with("data:")) { // Embedded data using base64. + // Validate data MIME types and throw an error if it's one we don't know/support. + if (!uri.begins_with("data:application/octet-stream;base64") && + !uri.begins_with("data:application/gltf-buffer;base64")) { + ERR_PRINT("glTF: Got buffer with an unknown URI data type: " + uri); } - - ERR_FAIL_COND_V(!buffer.has("byteLength"), ERR_PARSE_ERROR); - int byteLength = buffer["byteLength"]; - ERR_FAIL_COND_V(byteLength < buffer_data.size(), ERR_PARSE_ERROR); - p_state->buffers.push_back(buffer_data); + buffer_data = _parse_base64_uri(uri); + } else { // Relative path to an external image file. + ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER); + uri = uri.uri_file_decode(); + uri = p_base_path.path_join(uri).replace_char('\\', '/'); // Fix for Windows. + ERR_FAIL_COND_V_MSG(!FileAccess::exists(uri), ERR_FILE_NOT_FOUND, "glTF: Binary file not found: " + uri); + buffer_data = FileAccess::get_file_as_bytes(uri); + ERR_FAIL_COND_V_MSG(buffer_data.is_empty(), ERR_PARSE_ERROR, "glTF: Couldn't load binary file as an array: " + uri); } + + ERR_FAIL_COND_V(!buffer.has("byteLength"), ERR_PARSE_ERROR); + int64_t byteLength = buffer["byteLength"]; + ERR_FAIL_COND_V(byteLength < buffer_data.size(), ERR_PARSE_ERROR); + } else if (i == 0 && p_state->glb_data.size()) { + buffer_data = p_state->glb_data; + } else { + ERR_PRINT("glTF: Buffer " + itos(i) + " has no data and cannot be loaded."); } + p_state->buffers.push_back(buffer_data); } print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size())); @@ -1148,13 +1144,13 @@ String GLTFDocument::_get_component_type_name(const GLTFAccessor::GLTFComponentT return ""; } -Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_src, const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const GLTFAccessor::GLTFComponentType p_component_type, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor, const bool p_for_vertex_indices) { +Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_src, const int64_t p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const GLTFAccessor::GLTFComponentType p_component_type, const bool p_normalized, const int64_t p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor, const bool p_for_vertex_indices) { const int component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[p_accessor_type]; const int component_size = _get_component_type_size(p_component_type); ERR_FAIL_COND_V(component_size == 0, FAILED); - int skip_every = 0; - int skip_bytes = 0; + int64_t skip_every = 0; + int64_t skip_bytes = 0; //special case of alignments, as described in spec switch (p_component_type) { case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: @@ -1184,7 +1180,7 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ const uint32_t offset = bv->byte_offset = p_byte_offset; Vector &gltf_buffer = p_state->buffers.write[0]; - int stride = component_count * component_size; + int64_t stride = component_count * component_size; if (p_for_vertex && stride % 4) { stride += 4 - (stride % 4); //according to spec must be multiple of 4 } @@ -1193,7 +1189,7 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ print_verbose("glTF: encoding accessor offset " + itos(p_byte_offset) + " view offset: " + itos(bv->byte_offset) + " total buffer len: " + itos(gltf_buffer.size()) + " view len " + itos(bv->byte_length)); - const int buffer_end = (stride * (p_count - 1)) + component_size; + const int64_t buffer_end = (stride * (p_count - 1)) + component_size; // TODO define bv->byte_stride bv->byte_offset = gltf_buffer.size(); if (p_for_vertex_indices) { @@ -1210,9 +1206,9 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: { Vector buffer; buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } @@ -1235,9 +1231,9 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: { Vector buffer; buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } @@ -1258,9 +1254,9 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: { Vector buffer; buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } @@ -1283,9 +1279,9 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: { Vector buffer; buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } @@ -1308,9 +1304,9 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT: { Vector buffer; buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } @@ -1329,9 +1325,9 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT: { Vector buffer; buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } @@ -1350,9 +1346,9 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT: { Vector buffer; buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } @@ -1371,9 +1367,9 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT: { Vector buffer; buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } @@ -1395,9 +1391,9 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG: { Vector buffer; buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } @@ -1417,9 +1413,9 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG: { Vector buffer; buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } @@ -1440,8 +1436,8 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ ERR_FAIL_COND_V(buffer_end > bv->byte_length, ERR_INVALID_DATA); ERR_FAIL_COND_V((int)(offset + buffer_end) > gltf_buffer.size(), ERR_INVALID_DATA); - int pad_bytes = (4 - gltf_buffer.size()) & 3; - for (int i = 0; i < pad_bytes; i++) { + int64_t pad_bytes = (4 - gltf_buffer.size()) & 3; + for (int64_t i = 0; i < pad_bytes; i++) { gltf_buffer.push_back(0); } @@ -1450,10 +1446,10 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ return OK; } -Error GLTFDocument::_decode_buffer_view(Ref p_state, double *p_dst, const GLTFBufferViewIndex p_buffer_view, const int p_skip_every, const int p_skip_bytes, const int p_element_size, const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const int p_component_count, const GLTFAccessor::GLTFComponentType p_component_type, const int p_component_size, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex) { +Error GLTFDocument::_decode_buffer_view(Ref p_state, double *p_dst, const GLTFBufferViewIndex p_buffer_view, const int64_t p_skip_every, const int64_t p_skip_bytes, const int64_t p_element_size, const int64_t p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const int64_t p_component_count, const GLTFAccessor::GLTFComponentType p_component_type, const int64_t p_component_size, const bool p_normalized, const int64_t p_byte_offset, const bool p_for_vertex) { const Ref bv = p_state->buffer_views[p_buffer_view]; - int stride = p_element_size; + int64_t stride = p_element_size; if (bv->byte_stride > 0) { stride = bv->byte_stride; } @@ -1471,17 +1467,17 @@ Error GLTFDocument::_decode_buffer_view(Ref p_state, double *p_dst, c print_verbose("glTF: accessor type " + _get_accessor_type_name(p_accessor_type) + " component type: " + _get_component_type_name(p_component_type) + " stride: " + itos(stride) + " amount " + itos(p_count)); print_verbose("glTF: accessor offset " + itos(p_byte_offset) + " view offset: " + itos(bv->byte_offset) + " total buffer len: " + itos(buffer.size()) + " view len " + itos(bv->byte_length)); - const int buffer_end = (stride * (p_count - 1)) + p_element_size; + const int64_t buffer_end = (stride * (p_count - 1)) + p_element_size; ERR_FAIL_COND_V(buffer_end > bv->byte_length, ERR_PARSE_ERROR); ERR_FAIL_COND_V((int)(offset + buffer_end) > buffer.size(), ERR_PARSE_ERROR); //fill everything as doubles - for (int i = 0; i < p_count; i++) { + for (int64_t i = 0; i < p_count; i++) { const uint8_t *src = &bufptr[offset + i * stride]; - for (int j = 0; j < p_component_count; j++) { + for (int64_t j = 0; j < p_component_count; j++) { if (p_skip_every && j > 0 && (j % p_skip_every) == 0) { src += p_skip_bytes; } @@ -1591,8 +1587,8 @@ Vector GLTFDocument::_decode_accessor(Ref p_state, const GLTF ERR_FAIL_COND_V(component_size == 0, Vector()); int element_size = component_count * component_size; - int skip_every = 0; - int skip_bytes = 0; + int64_t skip_every = 0; + int64_t skip_bytes = 0; //special case of alignments, as described in spec switch (a->component_type) { case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: @@ -1633,7 +1629,7 @@ Vector GLTFDocument::_decode_accessor(Ref p_state, const GLTF } } else { //fill with zeros, as bufferview is not defined. - for (int i = 0; i < (a->count * component_count); i++) { + for (int64_t i = 0; i < (a->count * component_count); i++) { dst_buffer.write[i] = 0; } } @@ -1657,7 +1653,7 @@ Vector GLTFDocument::_decode_accessor(Ref p_state, const GLTF } for (int i = 0; i < indices.size(); i++) { - const int write_offset = int(indices[i]) * component_count; + const int64_t write_offset = int(indices[i]) * component_count; for (int j = 0; j < component_count; j++) { dst[write_offset + j] = data[i * component_count + j]; @@ -1681,7 +1677,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref p_state, Vector type_min; type_min.resize(element_count); int max_index = 0; - for (int i = 0; i < p_attribs.size(); i++) { + for (int64_t i = 0; i < p_attribs.size(); i++) { attribs.write[i] = p_attribs[i]; if (p_attribs[i] > max_index) { max_index = p_attribs[i]; @@ -1739,14 +1735,14 @@ Vector GLTFDocument::_decode_accessor_as_ints(Ref p_state, const } const double *attribs_ptr = attribs.ptr(); - int ret_size = attribs.size(); + int64_t ret_size = attribs.size(); if (!p_packed_vertex_ids.is_empty()) { ERR_FAIL_COND_V(p_packed_vertex_ids[p_packed_vertex_ids.size() - 1] >= ret_size, ret); ret_size = p_packed_vertex_ids.size(); } ret.resize(ret_size); - for (int i = 0; i < ret_size; i++) { - int src_i = i; + for (int64_t i = 0; i < ret_size; i++) { + int64_t src_i = i; if (!p_packed_vertex_ids.is_empty()) { src_i = p_packed_vertex_ids[i]; } @@ -1764,14 +1760,14 @@ Vector GLTFDocument::_decode_accessor_as_floats(Ref p_state, c } const double *attribs_ptr = attribs.ptr(); - int ret_size = attribs.size(); + int64_t ret_size = attribs.size(); if (!p_packed_vertex_ids.is_empty()) { ERR_FAIL_COND_V(p_packed_vertex_ids[p_packed_vertex_ids.size() - 1] >= ret_size, ret); ret_size = p_packed_vertex_ids.size(); } ret.resize(ret_size); - for (int i = 0; i < ret_size; i++) { - int src_i = i; + for (int64_t i = 0; i < ret_size; i++) { + int64_t src_i = i; if (!p_packed_vertex_ids.is_empty()) { src_i = p_packed_vertex_ids[i]; } @@ -1795,7 +1791,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref p_state, } const int element_count = 2; - const int ret_size = p_attribs.size() * element_count; + const int64_t ret_size = p_attribs.size() * element_count; Vector attribs; attribs.resize(ret_size); Vector type_max; @@ -1803,7 +1799,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref p_state, Vector type_min; type_min.resize(element_count); - for (int i = 0; i < p_attribs.size(); i++) { + for (int64_t i = 0; i < p_attribs.size(); i++) { Vector2 attrib = p_attribs[i]; attribs.write[(i * element_count) + 0] = _filter_number(attrib.x); attribs.write[(i * element_count) + 1] = _filter_number(attrib.y); @@ -1844,7 +1840,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref p_state return -1; } - const int ret_size = p_attribs.size() * 4; + const int64_t ret_size = p_attribs.size() * 4; Vector attribs; attribs.resize(ret_size); @@ -1853,7 +1849,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref p_state type_max.resize(element_count); Vector type_min; type_min.resize(element_count); - for (int i = 0; i < p_attribs.size(); i++) { + for (int64_t i = 0; i < p_attribs.size(); i++) { Color attrib = p_attribs[i]; attribs.write[(i * element_count) + 0] = _filter_number(attrib.r); attribs.write[(i * element_count) + 1] = _filter_number(attrib.g); @@ -1892,7 +1888,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref p_state return p_state->accessors.size() - 1; } -void GLTFDocument::_calc_accessor_min_max(int p_i, const int p_element_count, Vector &p_type_max, Vector p_attribs, Vector &p_type_min) { +void GLTFDocument::_calc_accessor_min_max(int p_i, const int64_t p_element_count, Vector &p_type_max, Vector p_attribs, Vector &p_type_min) { if (p_i == 0) { for (int32_t type_i = 0; type_i < p_element_count; type_i++) { p_type_max.write[type_i] = p_attribs[(p_i * p_element_count) + type_i]; @@ -1910,7 +1906,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref p_sta return -1; } - const int ret_size = p_attribs.size() * 4; + const int64_t ret_size = p_attribs.size() * 4; Vector attribs; attribs.resize(ret_size); @@ -1920,7 +1916,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref p_sta type_max.resize(element_count); Vector type_min; type_min.resize(element_count); - for (int i = 0; i < p_attribs.size(); i++) { + for (int64_t i = 0; i < p_attribs.size(); i++) { Color attrib = p_attribs[i]; attribs.write[(i * element_count) + 0] = _filter_number(attrib.r); attribs.write[(i * element_count) + 1] = _filter_number(attrib.g); @@ -1965,7 +1961,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref p_stat } const int element_count = 4; - const int ret_size = p_attribs.size() * element_count; + const int64_t ret_size = p_attribs.size() * element_count; Vector attribs; attribs.resize(ret_size); @@ -1973,7 +1969,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref p_stat type_max.resize(element_count); Vector type_min; type_min.resize(element_count); - for (int i = 0; i < p_attribs.size(); i++) { + for (int64_t i = 0; i < p_attribs.size(); i++) { Color attrib = p_attribs[i]; attribs.write[(i * element_count) + 0] = _filter_number(attrib.r); attribs.write[(i * element_count) + 1] = _filter_number(attrib.g); @@ -2016,7 +2012,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref p } const int element_count = 4; - const int ret_size = p_attribs.size() * element_count; + const int64_t ret_size = p_attribs.size() * element_count; Vector attribs; attribs.resize(ret_size); @@ -2024,7 +2020,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref p type_max.resize(element_count); Vector type_min; type_min.resize(element_count); - for (int i = 0; i < p_attribs.size(); i++) { + for (int64_t i = 0; i < p_attribs.size(); i++) { Quaternion quaternion = p_attribs[i]; attribs.write[(i * element_count) + 0] = _filter_number(quaternion.x); attribs.write[(i * element_count) + 1] = _filter_number(quaternion.y); @@ -2073,14 +2069,14 @@ Vector GLTFDocument::_decode_accessor_as_vec2(Ref p_state, c ERR_FAIL_COND_V(attribs.size() % 2 != 0, ret); const double *attribs_ptr = attribs.ptr(); - int ret_size = attribs.size() / 2; + int64_t ret_size = attribs.size() / 2; if (!p_packed_vertex_ids.is_empty()) { ERR_FAIL_COND_V(p_packed_vertex_ids[p_packed_vertex_ids.size() - 1] >= ret_size, ret); ret_size = p_packed_vertex_ids.size(); } ret.resize(ret_size); - for (int i = 0; i < ret_size; i++) { - int src_i = i; + for (int64_t i = 0; i < ret_size; i++) { + int64_t src_i = i; if (!p_packed_vertex_ids.is_empty()) { src_i = p_packed_vertex_ids[i]; } @@ -2094,7 +2090,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref p_stat return -1; } const int element_count = 1; - const int ret_size = p_attribs.size(); + const int64_t ret_size = p_attribs.size(); Vector attribs; attribs.resize(ret_size); @@ -2103,7 +2099,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref p_stat Vector type_min; type_min.resize(element_count); - for (int i = 0; i < p_attribs.size(); i++) { + for (int64_t i = 0; i < p_attribs.size(); i++) { attribs.write[i] = _filter_number(p_attribs[i]); _calc_accessor_min_max(i, element_count, type_max, attribs, type_min); @@ -2143,7 +2139,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref p_state, return -1; } const int element_count = 3; - const int ret_size = p_attribs.size() * element_count; + const int64_t ret_size = p_attribs.size() * element_count; Vector attribs; attribs.resize(ret_size); @@ -2151,7 +2147,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref p_state, type_max.resize(element_count); Vector type_min; type_min.resize(element_count); - for (int i = 0; i < p_attribs.size(); i++) { + for (int64_t i = 0; i < p_attribs.size(); i++) { Vector3 attrib = p_attribs[i]; attribs.write[(i * element_count) + 0] = _filter_number(attrib.x); attribs.write[(i * element_count) + 1] = _filter_number(attrib.y); @@ -2205,7 +2201,7 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref p Vector changed_values; int max_changed_index = 0; - for (int i = 0; i < p_attribs.size(); i++) { + for (int64_t i = 0; i < p_attribs.size(); i++) { Vector3 attrib = p_attribs[i]; bool is_different = false; if (i < p_reference_attribs.size()) { @@ -2258,10 +2254,10 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref p } sparse_accessor->max = type_max; sparse_accessor->min = type_min; - int sparse_accessor_index_stride = max_changed_index > 65535 ? 4 : 2; + int64_t sparse_accessor_index_stride = max_changed_index > 65535 ? 4 : 2; - int sparse_accessor_storage_size = changed_indices.size() * (sparse_accessor_index_stride + element_count * sizeof(float)); - int conventional_storage_size = p_attribs.size() * element_count * sizeof(float); + int64_t sparse_accessor_storage_size = changed_indices.size() * (sparse_accessor_index_stride + element_count * sizeof(float)); + int64_t conventional_storage_size = p_attribs.size() * element_count * sizeof(float); if (changed_indices.size() > 0 && sparse_accessor_storage_size < conventional_storage_size) { // It must be worthwhile to use a sparse accessor. @@ -2301,8 +2297,8 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref p_state if (p_attribs.is_empty()) { return -1; } - const int element_count = 16; - const int ret_size = p_attribs.size() * element_count; + const int64_t element_count = 16; + const int64_t ret_size = p_attribs.size() * element_count; Vector attribs; attribs.resize(ret_size); @@ -2310,7 +2306,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref p_state type_max.resize(element_count); Vector type_min; type_min.resize(element_count); - for (int i = 0; i < p_attribs.size(); i++) { + for (int64_t i = 0; i < p_attribs.size(); i++) { Transform3D attrib = p_attribs[i]; Basis basis = attrib.get_basis(); Vector3 axis_0 = basis.get_column(Vector3::AXIS_X); @@ -2379,14 +2375,14 @@ Vector GLTFDocument::_decode_accessor_as_vec3(Ref p_state, c ERR_FAIL_COND_V(attribs.size() % 3 != 0, ret); const double *attribs_ptr = attribs.ptr(); - int ret_size = attribs.size() / 3; + int64_t ret_size = attribs.size() / 3; if (!p_packed_vertex_ids.is_empty()) { ERR_FAIL_COND_V(p_packed_vertex_ids[p_packed_vertex_ids.size() - 1] >= ret_size, ret); ret_size = p_packed_vertex_ids.size(); } ret.resize(ret_size); - for (int i = 0; i < ret_size; i++) { - int src_i = i; + for (int64_t i = 0; i < ret_size; i++) { + int64_t src_i = i; if (!p_packed_vertex_ids.is_empty()) { src_i = p_packed_vertex_ids[i]; } @@ -2403,7 +2399,7 @@ Vector GLTFDocument::_decode_accessor_as_color(Ref p_state, co return ret; } - const int accessor_type = p_state->accessors[p_accessor]->accessor_type; + const GLTFAccessor::GLTFAccessorType accessor_type = p_state->accessors[p_accessor]->accessor_type; ERR_FAIL_COND_V(!(accessor_type == GLTFAccessor::TYPE_VEC3 || accessor_type == GLTFAccessor::TYPE_VEC4), ret); int vec_len = 3; if (accessor_type == GLTFAccessor::TYPE_VEC4) { @@ -2412,14 +2408,14 @@ Vector GLTFDocument::_decode_accessor_as_color(Ref p_state, co ERR_FAIL_COND_V(attribs.size() % vec_len != 0, ret); const double *attribs_ptr = attribs.ptr(); - int ret_size = attribs.size() / vec_len; + int64_t ret_size = attribs.size() / vec_len; if (!p_packed_vertex_ids.is_empty()) { ERR_FAIL_COND_V(p_packed_vertex_ids[p_packed_vertex_ids.size() - 1] >= ret_size, ret); ret_size = p_packed_vertex_ids.size(); } ret.resize(ret_size); - for (int i = 0; i < ret_size; i++) { - int src_i = i; + for (int64_t i = 0; i < ret_size; i++) { + int64_t src_i = i; if (!p_packed_vertex_ids.is_empty()) { src_i = p_packed_vertex_ids[i]; } @@ -2437,10 +2433,10 @@ Vector GLTFDocument::_decode_accessor_as_quaternion(Ref p ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret); const double *attribs_ptr = attribs.ptr(); - const int ret_size = attribs.size() / 4; + const int64_t ret_size = attribs.size() / 4; ret.resize(ret_size); { - for (int i = 0; i < ret_size; i++) { + for (int64_t i = 0; i < ret_size; i++) { ret.write[i] = Quaternion(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]).normalized(); } } @@ -2456,7 +2452,7 @@ Vector GLTFDocument::_decode_accessor_as_xform2d(Ref p_s ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret); ret.resize(attribs.size() / 4); - for (int i = 0; i < ret.size(); i++) { + for (int64_t i = 0; i < ret.size(); i++) { ret.write[i][0] = Vector2(attribs[i * 4 + 0], attribs[i * 4 + 1]); ret.write[i][1] = Vector2(attribs[i * 4 + 2], attribs[i * 4 + 3]); } @@ -2473,7 +2469,7 @@ Vector GLTFDocument::_decode_accessor_as_basis(Ref p_state, co ERR_FAIL_COND_V(attribs.size() % 9 != 0, ret); ret.resize(attribs.size() / 9); - for (int i = 0; i < ret.size(); i++) { + for (int64_t i = 0; i < ret.size(); i++) { ret.write[i].set_column(0, Vector3(attribs[i * 9 + 0], attribs[i * 9 + 1], attribs[i * 9 + 2])); ret.write[i].set_column(1, Vector3(attribs[i * 9 + 3], attribs[i * 9 + 4], attribs[i * 9 + 5])); ret.write[i].set_column(2, Vector3(attribs[i * 9 + 6], attribs[i * 9 + 7], attribs[i * 9 + 8])); @@ -2491,7 +2487,7 @@ Vector GLTFDocument::_decode_accessor_as_xform(Ref p_sta ERR_FAIL_COND_V(attribs.size() % 16 != 0, ret); ret.resize(attribs.size() / 16); - for (int i = 0; i < ret.size(); i++) { + for (int64_t i = 0; i < ret.size(); i++) { ret.write[i].basis.set_column(0, Vector3(attribs[i * 16 + 0], attribs[i * 16 + 1], attribs[i * 16 + 2])); ret.write[i].basis.set_column(1, Vector3(attribs[i * 16 + 4], attribs[i * 16 + 5], attribs[i * 16 + 6])); ret.write[i].basis.set_column(2, Vector3(attribs[i * 16 + 8], attribs[i * 16 + 9], attribs[i * 16 + 10])); @@ -2506,9 +2502,9 @@ Vector GLTFDocument::_decode_accessor_as_variant(Ref p_state ERR_FAIL_COND_V_MSG(attribs.is_empty(), ret, "glTF: The accessor was empty."); const int component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[p_accessor_type]; ERR_FAIL_COND_V_MSG(attribs.size() % component_count != 0, ret, "glTF: The accessor size was not a multiple of the component count."); - const int ret_size = attribs.size() / component_count; + const int64_t ret_size = attribs.size() / component_count; ret.resize(ret_size); - for (int i = 0; i < ret_size; i++) { + for (int64_t i = 0; i < ret_size; i++) { switch (p_variant_type) { case Variant::BOOL: { ret.write[i] = attribs[i * component_count] != 0.0; @@ -2783,7 +2779,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_variant(Ref p_sta type_max.resize(accessor_component_count); Vector type_min; type_min.resize(accessor_component_count); - for (int i = 0; i < encoded_attribs.size(); i++) { + for (int64_t i = 0; i < encoded_attribs.size(); i++) { if (Math::is_zero_approx(encoded_attribs[i])) { encoded_attribs.write[i] = 0.0; } else { @@ -2886,10 +2882,10 @@ Error GLTFDocument::_serialize_meshes(Ref p_state) { { Vector a = array[Mesh::ARRAY_TANGENT]; if (a.size()) { - const int ret_size = a.size() / 4; + const int64_t ret_size = a.size() / 4; Vector attribs; attribs.resize(ret_size); - for (int i = 0; i < ret_size; i++) { + for (int64_t i = 0; i < ret_size; i++) { Color out; out.r = a[(i * 4) + 0]; out.g = a[(i * 4) + 1]; @@ -2903,10 +2899,10 @@ Error GLTFDocument::_serialize_meshes(Ref p_state) { { Vector a = array[Mesh::ARRAY_NORMAL]; if (a.size()) { - const int ret_size = a.size(); + const int64_t ret_size = a.size(); Vector attribs; attribs.resize(ret_size); - for (int i = 0; i < ret_size; i++) { + for (int64_t i = 0; i < ret_size; i++) { attribs.write[i] = Vector3(a[i]).normalized(); } attributes["NORMAL"] = _encode_accessor_as_vec3(p_state, attribs, true); @@ -8055,22 +8051,19 @@ Error GLTFDocument::_parse(Ref p_state, String p_path, Refseek(0); uint32_t magic = p_file->get_32(); if (magic == 0x46546C67) { - //binary file - //text file + // Binary file. p_file->seek(0); err = _parse_glb(p_file, p_state); if (err != OK) { return err; } } else { + // Text file. p_file->seek(0); String text = p_file->get_as_utf8_string(); JSON json; err = json.parse(text); - if (err != OK) { - _err_print_error("", "", json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT); - } - ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + ERR_FAIL_COND_V_MSG(err != OK, err, "glTF: Error parsing .gltf JSON data: " + json.get_error_message() + " at line: " + itos(json.get_error_line())); p_state->json = json.get_data(); } @@ -8157,43 +8150,59 @@ Error GLTFDocument::_serialize_file(Ref p_state, const String p_path) Ref file = FileAccess::open(p_path, FileAccess::WRITE, &err); ERR_FAIL_COND_V(file.is_null(), FAILED); - String json = Variant(p_state->json).to_json_string(); + constexpr uint64_t header_size = 12; + constexpr uint64_t chunk_header_size = 8; + constexpr uint32_t magic = 0x46546C67; // The byte sequence "glTF" as little-endian. + constexpr uint32_t text_chunk_type = 0x4E4F534A; // The byte sequence "JSON" as little-endian. + constexpr uint32_t binary_chunk_type = 0x004E4942; // The byte sequence "BIN\0" as little-endian. - const uint32_t magic = 0x46546C67; // GLTF - const int32_t header_size = 12; - const int32_t chunk_header_size = 8; - CharString cs = json.utf8(); - const uint32_t text_data_length = cs.length(); - const uint32_t text_chunk_length = ((text_data_length + 3) & (~3)); - const uint32_t text_chunk_type = 0x4E4F534A; //JSON - - uint32_t binary_data_length = 0; + String json_string = Variant(p_state->json).to_json_string(); + CharString cs = json_string.utf8(); + uint64_t text_data_length = cs.length(); + uint64_t text_chunk_length = ((text_data_length + 3) & (~3)); + uint64_t total_file_length = header_size + chunk_header_size + text_chunk_length; + uint64_t binary_data_length = 0; + uint64_t binary_chunk_length = 0; if (p_state->buffers.size() > 0) { binary_data_length = p_state->buffers[0].size(); + binary_chunk_length = ((binary_data_length + 3) & (~3)); + const uint64_t file_length_with_buffer = total_file_length + chunk_header_size + binary_chunk_length; + // Check if the file length with the buffer is greater than glTF's maximum of 4 GiB. + // If it is, we can't write the buffer into the file, but can write it separately. + if (unlikely(file_length_with_buffer > (uint64_t)UINT32_MAX)) { + err = _encode_buffer_bins(p_state, p_path); + ERR_FAIL_COND_V(err != OK, err); + // Since the buffer bins were re-encoded, we need to re-convert the JSON to string. + json_string = Variant(p_state->json).to_json_string(); + cs = json_string.utf8(); + text_data_length = cs.length(); + text_chunk_length = ((text_data_length + 3) & (~3)); + total_file_length = header_size + chunk_header_size + text_chunk_length; + binary_data_length = 0; + binary_chunk_length = 0; + } else { + total_file_length = file_length_with_buffer; + } } - const uint32_t binary_chunk_length = ((binary_data_length + 3) & (~3)); - const uint32_t binary_chunk_type = 0x004E4942; //BIN + ERR_FAIL_COND_V_MSG(total_file_length > (uint64_t)UINT32_MAX, ERR_CANT_CREATE, + "glTF: File size exceeds glTF Binary's maximum of 4 GiB. Cannot serialize as a GLB file."); file->create(FileAccess::ACCESS_RESOURCES); file->store_32(magic); file->store_32(p_state->major_version); // version - uint32_t total_length = header_size + chunk_header_size + text_chunk_length; - if (binary_chunk_length) { - total_length += chunk_header_size + binary_chunk_length; - } - file->store_32(total_length); + file->store_32(total_file_length); // Write the JSON text chunk. file->store_32(text_chunk_length); file->store_32(text_chunk_type); - file->store_buffer((uint8_t *)&cs[0], cs.length()); - for (uint32_t pad_i = text_data_length; pad_i < text_chunk_length; pad_i++) { + file->store_buffer((uint8_t *)&cs[0], text_data_length); + for (uint64_t pad_i = text_data_length; pad_i < text_chunk_length; pad_i++) { file->store_8(' '); } // Write a single binary chunk. if (binary_chunk_length) { - file->store_32(binary_chunk_length); + file->store_32((uint32_t)binary_chunk_length); file->store_32(binary_chunk_type); file->store_buffer(p_state->buffers[0].ptr(), binary_data_length); for (uint32_t pad_i = binary_data_length; pad_i < binary_chunk_length; pad_i++) { @@ -8341,34 +8350,38 @@ PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref p_state, Erro *r_err = err; } ERR_FAIL_COND_V(err != OK, PackedByteArray()); - String json = Variant(p_state->json).to_json_string(); + String json_string = Variant(p_state->json).to_json_string(); - const uint32_t magic = 0x46546C67; // GLTF - const int32_t header_size = 12; - const int32_t chunk_header_size = 8; + constexpr uint64_t header_size = 12; + constexpr uint64_t chunk_header_size = 8; + constexpr uint32_t magic = 0x46546C67; // The byte sequence "glTF" as little-endian. + constexpr uint32_t text_chunk_type = 0x4E4F534A; // The byte sequence "JSON" as little-endian. + constexpr uint32_t binary_chunk_type = 0x004E4942; // The byte sequence "BIN\0" as little-endian. + const CharString cs = json_string.utf8(); + const uint64_t text_data_length = cs.length(); + const uint64_t text_chunk_length = ((text_data_length + 3) & (~3)); - CharString cs = json.utf8(); - int32_t padding = (chunk_header_size + cs.length()) % 4; - - const uint32_t text_chunk_length = cs.length() + padding; - - const uint32_t text_chunk_type = 0x4E4F534A; //JSON - int32_t binary_data_length = 0; + uint64_t total_file_length = header_size + chunk_header_size + text_chunk_length; + ERR_FAIL_COND_V(total_file_length > (uint64_t)UINT32_MAX, PackedByteArray()); + uint64_t binary_data_length = 0; if (p_state->buffers.size() > 0) { binary_data_length = p_state->buffers[0].size(); + const uint64_t file_length_with_buffer = total_file_length + chunk_header_size + binary_data_length; + total_file_length = file_length_with_buffer; } - const int32_t binary_chunk_length = binary_data_length; - const int32_t binary_chunk_type = 0x004E4942; //BIN + ERR_FAIL_COND_V_MSG(total_file_length > (uint64_t)UINT32_MAX, PackedByteArray(), + "glTF: File size exceeds glTF Binary's maximum of 4 GiB. Cannot serialize as a single GLB in-memory buffer."); + const uint32_t binary_chunk_length = binary_data_length; Ref buffer; buffer.instantiate(); buffer->put_32(magic); buffer->put_32(p_state->major_version); // version - buffer->put_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_data_length); // length - buffer->put_32(text_chunk_length); + buffer->put_32((uint32_t)total_file_length); // length + buffer->put_32((uint32_t)text_chunk_length); buffer->put_32(text_chunk_type); - buffer->put_data((uint8_t *)&cs[0], cs.length()); - for (int i = 0; i < padding; i++) { + buffer->put_data((uint8_t *)&cs[0], text_data_length); + for (uint64_t pad_i = text_data_length; pad_i < text_chunk_length; pad_i++) { buffer->put_8(' '); } if (binary_chunk_length) { diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index c6df55a3171..def606f0c61 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -142,11 +142,11 @@ private: Error _parse_accessors(Ref p_state); Error _decode_buffer_view(Ref p_state, double *p_dst, const GLTFBufferViewIndex p_buffer_view, - const int p_skip_every, const int p_skip_bytes, - const int p_element_size, const int p_count, - const GLTFAccessor::GLTFAccessorType p_accessor_type, const int p_component_count, - const GLTFAccessor::GLTFComponentType p_component_type, const int p_component_size, - const bool p_normalized, const int p_byte_offset, + const int64_t p_skip_every, const int64_t p_skip_bytes, + const int64_t p_element_size, const int64_t p_count, + const GLTFAccessor::GLTFAccessorType p_accessor_type, const int64_t p_component_count, + const GLTFAccessor::GLTFComponentType p_component_type, const int64_t p_component_size, + const bool p_normalized, const int64_t p_byte_offset, const bool p_for_vertex); Vector _decode_accessor(Ref p_state, const GLTFAccessorIndex p_accessor, @@ -251,14 +251,14 @@ private: const Vector p_attribs, const bool p_for_vertex); - void _calc_accessor_vec2_min_max(int p_i, const int p_element_count, Vector &p_type_max, Vector2 p_attribs, Vector &p_type_min) { + void _calc_accessor_vec2_min_max(int p_i, const int64_t p_element_count, Vector &p_type_max, Vector2 p_attribs, Vector &p_type_min) { if (p_i == 0) { - for (int32_t type_i = 0; type_i < p_element_count; type_i++) { + for (int64_t type_i = 0; type_i < p_element_count; type_i++) { p_type_max.write[type_i] = p_attribs[(p_i * p_element_count) + type_i]; p_type_min.write[type_i] = p_attribs[(p_i * p_element_count) + type_i]; } } - for (int32_t type_i = 0; type_i < p_element_count; type_i++) { + for (int64_t type_i = 0; type_i < p_element_count; type_i++) { p_type_max.write[type_i] = MAX(p_attribs[(p_i * p_element_count) + type_i], p_type_max[type_i]); p_type_min.write[type_i] = MIN(p_attribs[(p_i * p_element_count) + type_i], p_type_min[type_i]); p_type_max.write[type_i] = _filter_number(p_type_max.write[type_i]); @@ -274,7 +274,7 @@ private: const Vector p_attribs, const bool p_for_vertex); - void _calc_accessor_min_max(int p_i, const int p_element_count, Vector &p_type_max, Vector p_attribs, Vector &p_type_min); + void _calc_accessor_min_max(int p_i, const int64_t p_element_count, Vector &p_type_max, Vector p_attribs, Vector &p_type_min); GLTFAccessorIndex _encode_accessor_as_ints(Ref p_state, const Vector p_attribs, @@ -284,9 +284,9 @@ private: const Vector p_attribs, const bool p_for_vertex); Error _encode_buffer_view(Ref p_state, const double *p_src, - const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, + const int64_t p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const GLTFAccessor::GLTFComponentType p_component_type, const bool p_normalized, - const int p_byte_offset, const bool p_for_vertex, + const int64_t p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor, const bool p_for_indices = false); Error _encode_accessors(Ref p_state); diff --git a/modules/gltf/structures/gltf_accessor.compat.inc b/modules/gltf/structures/gltf_accessor.compat.inc new file mode 100644 index 00000000000..3155b7d792b --- /dev/null +++ b/modules/gltf/structures/gltf_accessor.compat.inc @@ -0,0 +1,124 @@ +/**************************************************************************/ +/* gltf_accessor.compat.inc */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef DISABLE_DEPRECATED + +// 32-bit versions for compatibility. + +GLTFBufferViewIndex GLTFAccessor::_get_buffer_view_bind_compat_106220() { + return get_buffer_view(); +} + +int GLTFAccessor::_get_byte_offset_bind_compat_106220() { + return get_byte_offset(); +} + +int GLTFAccessor::_get_component_type_bind_compat_106220() { + return (int)get_component_type(); +} + +void GLTFAccessor::_set_component_type_bind_compat_106220(int p_component_type) { + set_component_type((GLTFComponentType)p_component_type); +} + +bool GLTFAccessor::_get_normalized_bind_compat_106220() { + return get_normalized(); +} + +int GLTFAccessor::_get_count_bind_compat_106220() { + return get_count(); +} + +GLTFAccessor::GLTFAccessorType GLTFAccessor::_get_accessor_type_bind_compat_106220() { + return get_accessor_type(); +} + +int GLTFAccessor::_get_type_bind_compat_106220() { + return (int)get_accessor_type(); +} + +Vector GLTFAccessor::_get_min_bind_compat_106220() { + return get_min(); +} + +Vector GLTFAccessor::_get_max_bind_compat_106220() { + return get_max(); +} + +int GLTFAccessor::_get_sparse_count_bind_compat_106220() { + return get_sparse_count(); +} + +int GLTFAccessor::_get_sparse_indices_buffer_view_bind_compat_106220() { + return get_sparse_indices_buffer_view(); +} + +int GLTFAccessor::_get_sparse_indices_byte_offset_bind_compat_106220() { + return get_sparse_indices_byte_offset(); +} + +int GLTFAccessor::_get_sparse_indices_component_type_bind_compat_106220() { + return (int)get_sparse_indices_component_type(); +} + +void GLTFAccessor::_set_sparse_indices_component_type_bind_compat_106220(int p_sparse_indices_component_type) { + set_sparse_indices_component_type((GLTFComponentType)p_sparse_indices_component_type); +} + +int GLTFAccessor::_get_sparse_values_buffer_view_bind_compat_106220() { + return get_sparse_values_buffer_view(); +} + +int GLTFAccessor::_get_sparse_values_byte_offset_bind_compat_106220() { + return get_sparse_values_byte_offset(); +} + +void GLTFAccessor::_bind_compatibility_methods() { + // 32-bit versions for compatibility. + ClassDB::bind_compatibility_method(D_METHOD("get_buffer_view"), &GLTFAccessor::_get_buffer_view_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_byte_offset"), &GLTFAccessor::_get_byte_offset_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_component_type"), &GLTFAccessor::_get_component_type_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("set_component_type", "component_type"), &GLTFAccessor::_set_component_type_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_normalized"), &GLTFAccessor::_get_normalized_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_count"), &GLTFAccessor::_get_count_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_accessor_type"), &GLTFAccessor::_get_accessor_type_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_type"), &GLTFAccessor::_get_type_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_min"), &GLTFAccessor::_get_min_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_max"), &GLTFAccessor::_get_max_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_sparse_count"), &GLTFAccessor::_get_sparse_count_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_sparse_indices_buffer_view"), &GLTFAccessor::_get_sparse_indices_buffer_view_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_sparse_indices_byte_offset"), &GLTFAccessor::_get_sparse_indices_byte_offset_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_sparse_indices_component_type"), &GLTFAccessor::_get_sparse_indices_component_type_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("set_sparse_indices_component_type", "sparse_indices_component_type"), &GLTFAccessor::_set_sparse_indices_component_type_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_sparse_values_buffer_view"), &GLTFAccessor::_get_sparse_values_buffer_view_bind_compat_106220); + ClassDB::bind_compatibility_method(D_METHOD("get_sparse_values_byte_offset"), &GLTFAccessor::_get_sparse_values_byte_offset_bind_compat_106220); +} + +#endif // DISABLE_DEPRECATED diff --git a/modules/gltf/structures/gltf_accessor.cpp b/modules/gltf/structures/gltf_accessor.cpp index 300fce09ff5..414e649bd60 100644 --- a/modules/gltf/structures/gltf_accessor.cpp +++ b/modules/gltf/structures/gltf_accessor.cpp @@ -29,6 +29,7 @@ /**************************************************************************/ #include "gltf_accessor.h" +#include "gltf_accessor.compat.inc" void GLTFAccessor::_bind_methods() { BIND_ENUM_CONSTANT(TYPE_SCALAR); @@ -100,7 +101,7 @@ void GLTFAccessor::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "sparse_values_byte_offset"), "set_sparse_values_byte_offset", "get_sparse_values_byte_offset"); // int } -GLTFBufferViewIndex GLTFAccessor::get_buffer_view() { +GLTFBufferViewIndex GLTFAccessor::get_buffer_view() const { return buffer_view; } @@ -108,23 +109,23 @@ void GLTFAccessor::set_buffer_view(GLTFBufferViewIndex p_buffer_view) { buffer_view = p_buffer_view; } -int GLTFAccessor::get_byte_offset() { +int64_t GLTFAccessor::get_byte_offset() const { return byte_offset; } -void GLTFAccessor::set_byte_offset(int p_byte_offset) { +void GLTFAccessor::set_byte_offset(int64_t p_byte_offset) { byte_offset = p_byte_offset; } -int GLTFAccessor::get_component_type() { +GLTFAccessor::GLTFComponentType GLTFAccessor::get_component_type() const { return component_type; } -void GLTFAccessor::set_component_type(int p_component_type) { +void GLTFAccessor::set_component_type(GLTFComponentType p_component_type) { component_type = (GLTFComponentType)p_component_type; } -bool GLTFAccessor::get_normalized() { +bool GLTFAccessor::get_normalized() const { return normalized; } @@ -132,15 +133,15 @@ void GLTFAccessor::set_normalized(bool p_normalized) { normalized = p_normalized; } -int GLTFAccessor::get_count() { +int64_t GLTFAccessor::get_count() const { return count; } -void GLTFAccessor::set_count(int p_count) { +void GLTFAccessor::set_count(int64_t p_count) { count = p_count; } -GLTFAccessor::GLTFAccessorType GLTFAccessor::get_accessor_type() { +GLTFAccessor::GLTFAccessorType GLTFAccessor::get_accessor_type() const { return accessor_type; } @@ -148,7 +149,7 @@ void GLTFAccessor::set_accessor_type(GLTFAccessorType p_accessor_type) { accessor_type = p_accessor_type; } -int GLTFAccessor::get_type() { +int GLTFAccessor::get_type() const { return (int)accessor_type; } @@ -156,7 +157,7 @@ void GLTFAccessor::set_type(int p_accessor_type) { accessor_type = (GLTFAccessorType)p_accessor_type; // TODO: Register enum } -Vector GLTFAccessor::get_min() { +Vector GLTFAccessor::get_min() const { return min; } @@ -164,7 +165,7 @@ void GLTFAccessor::set_min(Vector p_min) { min = p_min; } -Vector GLTFAccessor::get_max() { +Vector GLTFAccessor::get_max() const { return max; } @@ -172,50 +173,50 @@ void GLTFAccessor::set_max(Vector p_max) { max = p_max; } -int GLTFAccessor::get_sparse_count() { +int64_t GLTFAccessor::get_sparse_count() const { return sparse_count; } -void GLTFAccessor::set_sparse_count(int p_sparse_count) { +void GLTFAccessor::set_sparse_count(int64_t p_sparse_count) { sparse_count = p_sparse_count; } -int GLTFAccessor::get_sparse_indices_buffer_view() { +GLTFBufferViewIndex GLTFAccessor::get_sparse_indices_buffer_view() const { return sparse_indices_buffer_view; } -void GLTFAccessor::set_sparse_indices_buffer_view(int p_sparse_indices_buffer_view) { +void GLTFAccessor::set_sparse_indices_buffer_view(GLTFBufferViewIndex p_sparse_indices_buffer_view) { sparse_indices_buffer_view = p_sparse_indices_buffer_view; } -int GLTFAccessor::get_sparse_indices_byte_offset() { +int64_t GLTFAccessor::get_sparse_indices_byte_offset() const { return sparse_indices_byte_offset; } -void GLTFAccessor::set_sparse_indices_byte_offset(int p_sparse_indices_byte_offset) { +void GLTFAccessor::set_sparse_indices_byte_offset(int64_t p_sparse_indices_byte_offset) { sparse_indices_byte_offset = p_sparse_indices_byte_offset; } -int GLTFAccessor::get_sparse_indices_component_type() { +GLTFAccessor::GLTFComponentType GLTFAccessor::get_sparse_indices_component_type() const { return sparse_indices_component_type; } -void GLTFAccessor::set_sparse_indices_component_type(int p_sparse_indices_component_type) { +void GLTFAccessor::set_sparse_indices_component_type(GLTFComponentType p_sparse_indices_component_type) { sparse_indices_component_type = (GLTFComponentType)p_sparse_indices_component_type; } -int GLTFAccessor::get_sparse_values_buffer_view() { +GLTFBufferViewIndex GLTFAccessor::get_sparse_values_buffer_view() const { return sparse_values_buffer_view; } -void GLTFAccessor::set_sparse_values_buffer_view(int p_sparse_values_buffer_view) { +void GLTFAccessor::set_sparse_values_buffer_view(GLTFBufferViewIndex p_sparse_values_buffer_view) { sparse_values_buffer_view = p_sparse_values_buffer_view; } -int GLTFAccessor::get_sparse_values_byte_offset() { +int64_t GLTFAccessor::get_sparse_values_byte_offset() const { return sparse_values_byte_offset; } -void GLTFAccessor::set_sparse_values_byte_offset(int p_sparse_values_byte_offset) { +void GLTFAccessor::set_sparse_values_byte_offset(int64_t p_sparse_values_byte_offset) { sparse_values_byte_offset = p_sparse_values_byte_offset; } diff --git a/modules/gltf/structures/gltf_accessor.h b/modules/gltf/structures/gltf_accessor.h index aabd3783829..a5ff894fb26 100644 --- a/modules/gltf/structures/gltf_accessor.h +++ b/modules/gltf/structures/gltf_accessor.h @@ -66,68 +66,90 @@ public: private: GLTFBufferViewIndex buffer_view = -1; - int byte_offset = 0; + int64_t byte_offset = 0; GLTFComponentType component_type = COMPONENT_TYPE_NONE; bool normalized = false; - int count = 0; + int64_t count = 0; GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_SCALAR; Vector min; Vector max; - int sparse_count = 0; - int sparse_indices_buffer_view = 0; - int sparse_indices_byte_offset = 0; + int64_t sparse_count = 0; + GLTFBufferViewIndex sparse_indices_buffer_view = 0; + int64_t sparse_indices_byte_offset = 0; GLTFComponentType sparse_indices_component_type = COMPONENT_TYPE_NONE; - int sparse_values_buffer_view = 0; - int sparse_values_byte_offset = 0; + GLTFBufferViewIndex sparse_values_buffer_view = 0; + int64_t sparse_values_byte_offset = 0; protected: static void _bind_methods(); +#ifndef DISABLE_DEPRECATED + // 32-bit and non-const versions for compatibility. + GLTFBufferViewIndex _get_buffer_view_bind_compat_106220(); + int _get_byte_offset_bind_compat_106220(); + int _get_component_type_bind_compat_106220(); + void _set_component_type_bind_compat_106220(int p_component_type); + bool _get_normalized_bind_compat_106220(); + int _get_count_bind_compat_106220(); + GLTFAccessorType _get_accessor_type_bind_compat_106220(); + int _get_type_bind_compat_106220(); + Vector _get_min_bind_compat_106220(); + Vector _get_max_bind_compat_106220(); + int _get_sparse_count_bind_compat_106220(); + int _get_sparse_indices_buffer_view_bind_compat_106220(); + int _get_sparse_indices_byte_offset_bind_compat_106220(); + int _get_sparse_indices_component_type_bind_compat_106220(); + void _set_sparse_indices_component_type_bind_compat_106220(int p_sparse_indices_component_type); + int _get_sparse_values_buffer_view_bind_compat_106220(); + int _get_sparse_values_byte_offset_bind_compat_106220(); + static void _bind_compatibility_methods(); +#endif // DISABLE_DEPRECATED + public: - GLTFBufferViewIndex get_buffer_view(); + GLTFBufferViewIndex get_buffer_view() const; void set_buffer_view(GLTFBufferViewIndex p_buffer_view); - int get_byte_offset(); - void set_byte_offset(int p_byte_offset); + int64_t get_byte_offset() const; + void set_byte_offset(int64_t p_byte_offset); - int get_component_type(); - void set_component_type(int p_component_type); + GLTFComponentType get_component_type() const; + void set_component_type(GLTFComponentType p_component_type); - bool get_normalized(); + bool get_normalized() const; void set_normalized(bool p_normalized); - int get_count(); - void set_count(int p_count); + int64_t get_count() const; + void set_count(int64_t p_count); - GLTFAccessorType get_accessor_type(); + GLTFAccessorType get_accessor_type() const; void set_accessor_type(GLTFAccessorType p_accessor_type); - int get_type(); + int get_type() const; void set_type(int p_accessor_type); - Vector get_min(); + Vector get_min() const; void set_min(Vector p_min); - Vector get_max(); + Vector get_max() const; void set_max(Vector p_max); - int get_sparse_count(); - void set_sparse_count(int p_sparse_count); + int64_t get_sparse_count() const; + void set_sparse_count(int64_t p_sparse_count); - int get_sparse_indices_buffer_view(); - void set_sparse_indices_buffer_view(int p_sparse_indices_buffer_view); + GLTFBufferViewIndex get_sparse_indices_buffer_view() const; + void set_sparse_indices_buffer_view(GLTFBufferViewIndex p_sparse_indices_buffer_view); - int get_sparse_indices_byte_offset(); - void set_sparse_indices_byte_offset(int p_sparse_indices_byte_offset); + int64_t get_sparse_indices_byte_offset() const; + void set_sparse_indices_byte_offset(int64_t p_sparse_indices_byte_offset); - int get_sparse_indices_component_type(); - void set_sparse_indices_component_type(int p_sparse_indices_component_type); + GLTFComponentType get_sparse_indices_component_type() const; + void set_sparse_indices_component_type(GLTFComponentType p_sparse_indices_component_type); - int get_sparse_values_buffer_view(); - void set_sparse_values_buffer_view(int p_sparse_values_buffer_view); + GLTFBufferViewIndex get_sparse_values_buffer_view() const; + void set_sparse_values_buffer_view(GLTFBufferViewIndex p_sparse_values_buffer_view); - int get_sparse_values_byte_offset(); - void set_sparse_values_byte_offset(int p_sparse_values_byte_offset); + int64_t get_sparse_values_byte_offset() const; + void set_sparse_values_byte_offset(int64_t p_sparse_values_byte_offset); }; VARIANT_ENUM_CAST(GLTFAccessor::GLTFAccessorType); diff --git a/modules/gltf/structures/gltf_buffer_view.compat.inc b/modules/gltf/structures/gltf_buffer_view.compat.inc index db2600a071b..93624947aca 100644 --- a/modules/gltf/structures/gltf_buffer_view.compat.inc +++ b/modules/gltf/structures/gltf_buffer_view.compat.inc @@ -51,6 +51,7 @@ bool GLTFBufferView::_get_indices_bind_compat_86907() { } void GLTFBufferView::_bind_compatibility_methods() { + // Non-const versions for compatibility. ClassDB::bind_compatibility_method(D_METHOD("get_buffer"), &GLTFBufferView::_get_buffer_bind_compat_86907); ClassDB::bind_compatibility_method(D_METHOD("get_byte_offset"), &GLTFBufferView::_get_byte_offset_bind_compat_86907); ClassDB::bind_compatibility_method(D_METHOD("get_byte_length"), &GLTFBufferView::_get_byte_length_bind_compat_86907); diff --git a/modules/gltf/structures/gltf_buffer_view.cpp b/modules/gltf/structures/gltf_buffer_view.cpp index 0f3746ee34c..2b0ff7999ce 100644 --- a/modules/gltf/structures/gltf_buffer_view.cpp +++ b/modules/gltf/structures/gltf_buffer_view.cpp @@ -65,27 +65,27 @@ void GLTFBufferView::set_buffer(GLTFBufferIndex p_buffer) { buffer = p_buffer; } -int GLTFBufferView::get_byte_offset() const { +int64_t GLTFBufferView::get_byte_offset() const { return byte_offset; } -void GLTFBufferView::set_byte_offset(int p_byte_offset) { +void GLTFBufferView::set_byte_offset(int64_t p_byte_offset) { byte_offset = p_byte_offset; } -int GLTFBufferView::get_byte_length() const { +int64_t GLTFBufferView::get_byte_length() const { return byte_length; } -void GLTFBufferView::set_byte_length(int p_byte_length) { +void GLTFBufferView::set_byte_length(int64_t p_byte_length) { byte_length = p_byte_length; } -int GLTFBufferView::get_byte_stride() const { +int64_t GLTFBufferView::get_byte_stride() const { return byte_stride; } -void GLTFBufferView::set_byte_stride(int p_byte_stride) { +void GLTFBufferView::set_byte_stride(int64_t p_byte_stride) { byte_stride = p_byte_stride; } diff --git a/modules/gltf/structures/gltf_buffer_view.h b/modules/gltf/structures/gltf_buffer_view.h index 841b6f4af27..dda2e57ff6d 100644 --- a/modules/gltf/structures/gltf_buffer_view.h +++ b/modules/gltf/structures/gltf_buffer_view.h @@ -40,9 +40,9 @@ class GLTFBufferView : public Resource { private: GLTFBufferIndex buffer = -1; - int byte_offset = 0; - int byte_length = 0; - int byte_stride = -1; + int64_t byte_offset = 0; + int64_t byte_length = 0; + int64_t byte_stride = -1; bool indices = false; bool vertex_attributes = false; @@ -50,6 +50,7 @@ protected: static void _bind_methods(); #ifndef DISABLE_DEPRECATED + // Non-const versions for compatibility. GLTFBufferIndex _get_buffer_bind_compat_86907(); int _get_byte_offset_bind_compat_86907(); int _get_byte_length_bind_compat_86907(); @@ -62,14 +63,14 @@ public: GLTFBufferIndex get_buffer() const; void set_buffer(GLTFBufferIndex p_buffer); - int get_byte_offset() const; - void set_byte_offset(int p_byte_offset); + int64_t get_byte_offset() const; + void set_byte_offset(int64_t p_byte_offset); - int get_byte_length() const; - void set_byte_length(int p_byte_length); + int64_t get_byte_length() const; + void set_byte_length(int64_t p_byte_length); - int get_byte_stride() const; - void set_byte_stride(int p_byte_stride); + int64_t get_byte_stride() const; + void set_byte_stride(int64_t p_byte_stride); bool get_indices() const; void set_indices(bool p_indices);