Skip to content

Commit

Permalink
gltf: Fix validation errors due to chunk padding and empty skins.
Browse files Browse the repository at this point in the history
GLB chunk padding length calculation was backwards and missing for the BIN chunk.
Fixed error caused by "skins":[] when no skins were present.
Finally, encode animations before textures to avoid accessor misalignment due to texture byteLength.
  • Loading branch information
lyuma committed Oct 26, 2021
1 parent 64faa37 commit cada1a4
Showing 1 changed file with 25 additions and 18 deletions.
43 changes: 25 additions & 18 deletions modules/gltf/gltf_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,26 +120,26 @@ Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String &
return Error::FAILED;
}

/* STEP 7 SERIALIZE IMAGES */
err = _serialize_images(state, p_path);
/* STEP 7 SERIALIZE ANIMATIONS */
err = _serialize_animations(state);
if (err != OK) {
return Error::FAILED;
}

/* STEP 8 SERIALIZE TEXTURES */
err = _serialize_textures(state);
/* STEP 8 SERIALIZE ACCESSORS */
err = _encode_accessors(state);
if (err != OK) {
return Error::FAILED;
}

// /* STEP 9 SERIALIZE ANIMATIONS */
err = _serialize_animations(state);
/* STEP 9 SERIALIZE IMAGES */
err = _serialize_images(state, p_path);
if (err != OK) {
return Error::FAILED;
}

/* STEP 10 SERIALIZE ACCESSORS */
err = _encode_accessors(state);
/* STEP 10 SERIALIZE TEXTURES */
err = _serialize_textures(state);
if (err != OK) {
return Error::FAILED;
}
Expand Down Expand Up @@ -4369,6 +4369,10 @@ Error GLTFDocument::_serialize_skins(Ref<GLTFState> state) {
json_skin["name"] = gltf_skin->get_name();
json_skins.push_back(json_skin);
}
if (!state->skins.size()) {
return OK;
}

state->json["skins"] = json_skins;
return OK;
}
Expand Down Expand Up @@ -6756,33 +6760,36 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> state, const String p_path) {
const uint32_t magic = 0x46546C67; // GLTF
const int32_t header_size = 12;
const int32_t chunk_header_size = 8;

for (int32_t pad_i = 0; pad_i < (chunk_header_size + json.utf8().length()) % 4; pad_i++) {
json += " ";
}
CharString cs = json.utf8();
const uint32_t text_chunk_length = cs.length();

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
int32_t binary_data_length = 0;

uint32_t binary_data_length = 0;
if (state->buffers.size()) {
binary_data_length = state->buffers[0].size();
}
const int32_t binary_chunk_length = binary_data_length;
const int32_t binary_chunk_type = 0x004E4942; //BIN
const uint32_t binary_chunk_length = ((binary_data_length + 3) & (~3));
const uint32_t binary_chunk_type = 0x004E4942; //BIN

f->create(FileAccess::ACCESS_RESOURCES);
f->store_32(magic);
f->store_32(state->major_version); // version
f->store_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_data_length); // length
f->store_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_chunk_length); // length
f->store_32(text_chunk_length);
f->store_32(text_chunk_type);
f->store_buffer((uint8_t *)&cs[0], cs.length());
for (uint32_t pad_i = text_data_length; pad_i < text_chunk_length; pad_i++) {
f->store_8(' ');
}
if (binary_chunk_length) {
f->store_32(binary_chunk_length);
f->store_32(binary_chunk_type);
f->store_buffer(state->buffers[0].ptr(), binary_data_length);
}
for (uint32_t pad_i = binary_data_length; pad_i < binary_chunk_length; pad_i++) {
f->store_8(0);
}

f->close();
} else {
Expand Down

0 comments on commit cada1a4

Please sign in to comment.