GLTFDocument: don't serialize empty buffers

This commit is contained in:
nikitalita
2026-06-22 07:15:30 -07:00
parent f964fa714f
commit a41f7c57ef
+40 -17
View File
@@ -692,24 +692,40 @@ static Vector<uint8_t> _parse_base64_uri(const String &p_uri) {
return buf;
}
static inline bool _all_buffers_empty(const Vector<Vector<uint8_t>> &p_buffers, int start_idx = 0) {
for (int i = start_idx; i < p_buffers.size(); i++) {
if (!p_buffers[i].is_empty()) {
return false;
}
}
return true;
}
Error GLTFDocument::_encode_buffer_glb(Ref<GLTFState> p_state, const String &p_path) {
print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size()));
if (p_state->buffers.is_empty()) {
if (p_state->buffers.is_empty() || _all_buffers_empty(p_state->buffers)) {
ERR_FAIL_COND_V_MSG(!p_state->buffer_views.is_empty(), ERR_INVALID_DATA, "glTF: Buffer views are present, but buffers are empty.");
return OK;
}
Array buffers;
if (!p_state->buffers.is_empty()) {
Vector<uint8_t> buffer_data = p_state->buffers[0];
Dictionary gltf_buffer;
Dictionary first_buffer;
gltf_buffer["byteLength"] = buffer_data.size();
buffers.push_back(gltf_buffer);
}
first_buffer["byteLength"] = p_state->buffers[0].size();
buffers.push_back(first_buffer);
for (GLTFBufferIndex i = 1; i < p_state->buffers.size(); i++) {
Vector<uint8_t> buffer_data = p_state->buffers[i];
const Vector<uint8_t> &buffer_data = p_state->buffers[i];
Dictionary gltf_buffer;
if (buffer_data.is_empty()) {
if (i < p_state->buffers.size() - 1 && !_all_buffers_empty(p_state->buffers, i + 1)) {
// Have to push back an empty buffer to avoid changing the buffer index, even though this is against spec.
WARN_PRINT("glTF: Buffer " + itos(i) + " is empty, but there are non-empty subsequent buffers.");
gltf_buffer["byteLength"] = 0;
buffers.push_back(gltf_buffer);
}
continue;
}
String filename = p_path.get_basename().get_file() + itos(i) + ".bin";
String path = p_path.get_base_dir() + "/" + filename;
Error err;
@@ -717,9 +733,7 @@ Error GLTFDocument::_encode_buffer_glb(Ref<GLTFState> p_state, const String &p_p
if (file.is_null()) {
return err;
}
if (buffer_data.is_empty()) {
return OK;
}
file->create(FileAccess::ACCESS_RESOURCES);
file->store_buffer(buffer_data.ptr(), buffer_data.size());
gltf_buffer["uri"] = filename;
gltf_buffer["byteLength"] = buffer_data.size();
@@ -733,14 +747,24 @@ Error GLTFDocument::_encode_buffer_glb(Ref<GLTFState> p_state, const String &p_p
Error GLTFDocument::_encode_buffer_bins(Ref<GLTFState> p_state, const String &p_path) {
print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size()));
if (p_state->buffers.is_empty()) {
if (p_state->buffers.is_empty() || _all_buffers_empty(p_state->buffers)) {
ERR_FAIL_COND_V_MSG(!p_state->buffer_views.is_empty(), ERR_INVALID_DATA, "glTF: Buffer views are present, but buffers are empty.");
return OK;
}
Array buffers;
for (GLTFBufferIndex i = 0; i < p_state->buffers.size(); i++) {
Vector<uint8_t> buffer_data = p_state->buffers[i];
const Vector<uint8_t> &buffer_data = p_state->buffers[i];
Dictionary gltf_buffer;
if (buffer_data.is_empty()) {
if (i < p_state->buffers.size() - 1 && !_all_buffers_empty(p_state->buffers, i + 1)) {
// Have to push back an empty buffer to avoid changing the buffer index, even though this is against spec.
WARN_PRINT("glTF: Buffer " + itos(i) + " is empty, but there are non-empty subsequent buffers.");
gltf_buffer["byteLength"] = 0;
buffers.push_back(gltf_buffer);
}
continue;
}
String filename = p_path.get_basename().get_file() + itos(i) + ".bin";
String path = p_path.get_base_dir() + "/" + filename;
Error err;
@@ -748,15 +772,14 @@ Error GLTFDocument::_encode_buffer_bins(Ref<GLTFState> p_state, const String &p_
if (file.is_null()) {
return err;
}
if (buffer_data.is_empty()) {
return OK;
}
file->store_buffer(buffer_data.ptr(), buffer_data.size());
gltf_buffer["uri"] = filename;
gltf_buffer["byteLength"] = buffer_data.size();
buffers.push_back(gltf_buffer);
}
p_state->json["buffers"] = buffers;
if (!buffers.is_empty()) {
p_state->json["buffers"] = buffers;
}
return OK;
}