| 8617 | } |
| 8618 | |
| 8619 | PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref<GLTFState> p_state, Error *r_err) { |
| 8620 | Error err = _encode_buffer_glb(p_state, ""); |
| 8621 | if (r_err) { |
| 8622 | *r_err = err; |
| 8623 | } |
| 8624 | ERR_FAIL_COND_V(err != OK, PackedByteArray()); |
| 8625 | String json_string = Variant(p_state->json).to_json_string(); |
| 8626 | |
| 8627 | constexpr uint64_t header_size = 12; |
| 8628 | constexpr uint64_t chunk_header_size = 8; |
| 8629 | constexpr uint32_t magic = 0x46546C67; // The byte sequence "glTF" as little-endian. |
| 8630 | constexpr uint32_t text_chunk_type = 0x4E4F534A; // The byte sequence "JSON" as little-endian. |
| 8631 | constexpr uint32_t binary_chunk_type = 0x004E4942; // The byte sequence "BIN\0" as little-endian. |
| 8632 | const CharString cs = json_string.utf8(); |
| 8633 | const uint64_t text_data_length = cs.length(); |
| 8634 | const uint64_t text_chunk_length = ((text_data_length + 3) & (~3)); |
| 8635 | |
| 8636 | uint64_t total_file_length = header_size + chunk_header_size + text_chunk_length; |
| 8637 | ERR_FAIL_COND_V(total_file_length > (uint64_t)UINT32_MAX, PackedByteArray()); |
| 8638 | uint64_t binary_data_length = 0; |
| 8639 | if (p_state->buffers.size() > 0) { |
| 8640 | binary_data_length = p_state->buffers[0].size(); |
| 8641 | const uint64_t file_length_with_buffer = total_file_length + chunk_header_size + binary_data_length; |
| 8642 | total_file_length = file_length_with_buffer; |
| 8643 | } |
| 8644 | ERR_FAIL_COND_V_MSG(total_file_length > (uint64_t)UINT32_MAX, PackedByteArray(), |
| 8645 | "glTF: File size exceeds glTF Binary's maximum of 4 GiB. Cannot serialize as a single GLB in-memory buffer."); |
| 8646 | const uint32_t binary_chunk_length = binary_data_length; |
| 8647 | |
| 8648 | Ref<StreamPeerBuffer> buffer; |
| 8649 | buffer.instantiate(); |
| 8650 | buffer->put_32(magic); |
| 8651 | buffer->put_32(p_state->major_version); // version |
| 8652 | buffer->put_32((uint32_t)total_file_length); // length |
| 8653 | buffer->put_32((uint32_t)text_chunk_length); |
| 8654 | buffer->put_32(text_chunk_type); |
| 8655 | buffer->put_data((uint8_t *)&cs[0], text_data_length); |
| 8656 | for (uint64_t pad_i = text_data_length; pad_i < text_chunk_length; pad_i++) { |
| 8657 | buffer->put_8(' '); |
| 8658 | } |
| 8659 | if (binary_chunk_length) { |
| 8660 | buffer->put_32(binary_chunk_length); |
| 8661 | buffer->put_32(binary_chunk_type); |
| 8662 | buffer->put_data(p_state->buffers[0].ptr(), binary_data_length); |
| 8663 | } |
| 8664 | return buffer->get_data_array(); |
| 8665 | } |
| 8666 | |
| 8667 | Node *GLTFDocument::_generate_scene_node_tree(Ref<GLTFState> p_state) { |
| 8668 | // Generate the skeletons and skins (if any). |
nothing calls this directly
no test coverage detected