GLTF: Support 64-bit sizes in glTF import and export

This commit is contained in:
Aaron Franke 2025-05-08 19:18:39 -07:00
parent 5dd76968d8
commit 61ff5f1bdd
No known key found for this signature in database
GPG Key ID: 40A1750B977E56BF
10 changed files with 462 additions and 255 deletions

View File

@ -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.

View File

@ -21,7 +21,7 @@
<member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0">
The offset relative to the start of the buffer view in bytes.
</member>
<member name="component_type" type="int" setter="set_component_type" getter="get_component_type" default="0">
<member name="component_type" type="int" setter="set_component_type" getter="get_component_type" enum="GLTFAccessor.GLTFComponentType" default="0">
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.
</member>
<member name="count" type="int" setter="set_count" getter="get_count" default="0">
@ -45,7 +45,7 @@
<member name="sparse_indices_byte_offset" type="int" setter="set_sparse_indices_byte_offset" getter="get_sparse_indices_byte_offset" default="0">
The offset relative to the start of the buffer view in bytes.
</member>
<member name="sparse_indices_component_type" type="int" setter="set_sparse_indices_component_type" getter="get_sparse_indices_component_type" default="0">
<member name="sparse_indices_component_type" type="int" setter="set_sparse_indices_component_type" getter="get_sparse_indices_component_type" enum="GLTFAccessor.GLTFComponentType" default="0">
The indices component data type as an enum. Possible values are 5121 for "UNSIGNED_BYTE", 5123 for "UNSIGNED_SHORT", and 5125 for "UNSIGNED_INT".
</member>
<member name="sparse_values_buffer_view" type="int" setter="set_sparse_values_buffer_view" getter="get_sparse_values_buffer_view" default="0">

View File

@ -333,10 +333,7 @@ Error GLTFDocument::_parse_glb(Ref<FileAccess> p_file, Ref<GLTFState> 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<GLTFState> 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<uint8_t> 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<GLTFState> 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<uint8_t> buffer_data;
if (buffer.has("uri")) {
String uri = buffer["uri"];
} else {
const Dictionary &buffer = buffers[i];
if (buffer.has("uri")) {
Vector<uint8_t> 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>";
}
Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> 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<GLTFState> 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<GLTFState> p_state, const double *p_
const uint32_t offset = bv->byte_offset = p_byte_offset;
Vector<uint8_t> &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<GLTFState> 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<GLTFState> p_state, const double *p_
case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: {
Vector<int8_t> 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<GLTFState> p_state, const double *p_
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: {
Vector<uint8_t> 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<GLTFState> p_state, const double *p_
case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: {
Vector<int16_t> 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<GLTFState> p_state, const double *p_
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: {
Vector<uint16_t> 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<GLTFState> p_state, const double *p_
case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT: {
Vector<int32_t> 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<GLTFState> p_state, const double *p_
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT: {
Vector<uint32_t> 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<GLTFState> p_state, const double *p_
case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT: {
Vector<float> 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<GLTFState> p_state, const double *p_
case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT: {
Vector<double> 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<GLTFState> p_state, const double *p_
case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG: {
Vector<int64_t> 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<GLTFState> p_state, const double *p_
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG: {
Vector<uint64_t> 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<GLTFState> 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<GLTFState> p_state, const double *p_
return OK;
}
Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> 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<GLTFState> 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<GLTFBufferView> 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<GLTFState> 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<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTF
ERR_FAIL_COND_V(component_size == 0, Vector<double>());
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<double> GLTFDocument::_decode_accessor(Ref<GLTFState> 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<double> GLTFDocument::_decode_accessor(Ref<GLTFState> 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<GLTFState> p_state,
Vector<double> 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<int> GLTFDocument::_decode_accessor_as_ints(Ref<GLTFState> 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<float> GLTFDocument::_decode_accessor_as_floats(Ref<GLTFState> 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<GLTFState> 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<double> attribs;
attribs.resize(ret_size);
Vector<double> type_max;
@ -1803,7 +1799,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> p_state,
Vector<double> 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<GLTFState> p_state
return -1;
}
const int ret_size = p_attribs.size() * 4;
const int64_t ret_size = p_attribs.size() * 4;
Vector<double> attribs;
attribs.resize(ret_size);
@ -1853,7 +1849,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> p_state
type_max.resize(element_count);
Vector<double> 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<GLTFState> p_state
return p_state->accessors.size() - 1;
}
void GLTFDocument::_calc_accessor_min_max(int p_i, const int p_element_count, Vector<double> &p_type_max, Vector<double> p_attribs, Vector<double> &p_type_min) {
void GLTFDocument::_calc_accessor_min_max(int p_i, const int64_t p_element_count, Vector<double> &p_type_max, Vector<double> p_attribs, Vector<double> &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<GLTFState> p_sta
return -1;
}
const int ret_size = p_attribs.size() * 4;
const int64_t ret_size = p_attribs.size() * 4;
Vector<double> attribs;
attribs.resize(ret_size);
@ -1920,7 +1916,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> p_sta
type_max.resize(element_count);
Vector<double> 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<GLTFState> 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<double> attribs;
attribs.resize(ret_size);
@ -1973,7 +1969,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> p_stat
type_max.resize(element_count);
Vector<double> 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<GLTFState> 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<double> attribs;
attribs.resize(ret_size);
@ -2024,7 +2020,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref<GLTFState> p
type_max.resize(element_count);
Vector<double> 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<Vector2> GLTFDocument::_decode_accessor_as_vec2(Ref<GLTFState> 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<GLTFState> 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<double> attribs;
attribs.resize(ret_size);
@ -2103,7 +2099,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> p_stat
Vector<double> 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<GLTFState> 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<double> attribs;
attribs.resize(ret_size);
@ -2151,7 +2147,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> p_state,
type_max.resize(element_count);
Vector<double> 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<GLTFState> p
Vector<double> 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<GLTFState> 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<GLTFState> 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<double> attribs;
attribs.resize(ret_size);
@ -2310,7 +2306,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> p_state
type_max.resize(element_count);
Vector<double> 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<Vector3> GLTFDocument::_decode_accessor_as_vec3(Ref<GLTFState> 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<Color> GLTFDocument::_decode_accessor_as_color(Ref<GLTFState> 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<Color> GLTFDocument::_decode_accessor_as_color(Ref<GLTFState> 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<Quaternion> GLTFDocument::_decode_accessor_as_quaternion(Ref<GLTFState> 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<Transform2D> GLTFDocument::_decode_accessor_as_xform2d(Ref<GLTFState> 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<Basis> GLTFDocument::_decode_accessor_as_basis(Ref<GLTFState> 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<Transform3D> GLTFDocument::_decode_accessor_as_xform(Ref<GLTFState> 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<Variant> GLTFDocument::_decode_accessor_as_variant(Ref<GLTFState> 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<GLTFState> p_sta
type_max.resize(accessor_component_count);
Vector<double> 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<GLTFState> p_state) {
{
Vector<real_t> a = array[Mesh::ARRAY_TANGENT];
if (a.size()) {
const int ret_size = a.size() / 4;
const int64_t ret_size = a.size() / 4;
Vector<Color> 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<GLTFState> p_state) {
{
Vector<Vector3> a = array[Mesh::ARRAY_NORMAL];
if (a.size()) {
const int ret_size = a.size();
const int64_t ret_size = a.size();
Vector<Vector3> 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<GLTFState> p_state, String p_path, Ref<FileAccess
p_file->seek(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<GLTFState> p_state, const String p_path)
Ref<FileAccess> 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<GLTFState> 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<StreamPeerBuffer> 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) {

View File

@ -142,11 +142,11 @@ private:
Error _parse_accessors(Ref<GLTFState> p_state);
Error _decode_buffer_view(Ref<GLTFState> 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<double> _decode_accessor(Ref<GLTFState> p_state,
const GLTFAccessorIndex p_accessor,
@ -251,14 +251,14 @@ private:
const Vector<Vector2> p_attribs,
const bool p_for_vertex);
void _calc_accessor_vec2_min_max(int p_i, const int p_element_count, Vector<double> &p_type_max, Vector2 p_attribs, Vector<double> &p_type_min) {
void _calc_accessor_vec2_min_max(int p_i, const int64_t p_element_count, Vector<double> &p_type_max, Vector2 p_attribs, Vector<double> &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<Color> p_attribs,
const bool p_for_vertex);
void _calc_accessor_min_max(int p_i, const int p_element_count, Vector<double> &p_type_max, Vector<double> p_attribs, Vector<double> &p_type_min);
void _calc_accessor_min_max(int p_i, const int64_t p_element_count, Vector<double> &p_type_max, Vector<double> p_attribs, Vector<double> &p_type_min);
GLTFAccessorIndex _encode_accessor_as_ints(Ref<GLTFState> p_state,
const Vector<int32_t> p_attribs,
@ -284,9 +284,9 @@ private:
const Vector<Transform3D> p_attribs,
const bool p_for_vertex);
Error _encode_buffer_view(Ref<GLTFState> 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<GLTFState> p_state);

View File

@ -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<double> GLTFAccessor::_get_min_bind_compat_106220() {
return get_min();
}
Vector<double> 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

View File

@ -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<double> GLTFAccessor::get_min() {
Vector<double> GLTFAccessor::get_min() const {
return min;
}
@ -164,7 +165,7 @@ void GLTFAccessor::set_min(Vector<double> p_min) {
min = p_min;
}
Vector<double> GLTFAccessor::get_max() {
Vector<double> GLTFAccessor::get_max() const {
return max;
}
@ -172,50 +173,50 @@ void GLTFAccessor::set_max(Vector<double> 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;
}

View File

@ -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<double> min;
Vector<double> 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<double> _get_min_bind_compat_106220();
Vector<double> _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<double> get_min();
Vector<double> get_min() const;
void set_min(Vector<double> p_min);
Vector<double> get_max();
Vector<double> get_max() const;
void set_max(Vector<double> 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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);