Skip to content

Commit

Permalink
Merge pull request #91783 from ogapo/pr/gltf-export-fixes
Browse files Browse the repository at this point in the history
GLTF export improvements
  • Loading branch information
akien-mga committed May 13, 2024
2 parents 0ebba30 + 522f035 commit ba0dcf7
Showing 1 changed file with 57 additions and 16 deletions.
73 changes: 57 additions & 16 deletions modules/gltf/gltf_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,6 @@ static Ref<ImporterMesh> _mesh_to_importer_mesh(Ref<Mesh> p_mesh) {
}

Error GLTFDocument::_serialize(Ref<GLTFState> p_state) {
if (!p_state->buffers.size()) {
p_state->buffers.push_back(Vector<uint8_t>());
}

for (Ref<GLTFDocumentExtension> ext : document_extensions) {
ERR_CONTINUE(ext.is_null());
Error err = ext->export_preserialize(p_state);
Expand Down Expand Up @@ -243,15 +239,16 @@ Error GLTFDocument::_serialize_gltf_extensions(Ref<GLTFState> p_state) const {
}

Error GLTFDocument::_serialize_scenes(Ref<GLTFState> p_state) {
ERR_FAIL_COND_V_MSG(p_state->root_nodes.is_empty(), ERR_INVALID_DATA, "GLTF export: The scene must have at least one root node.");
// Godot only supports one scene per glTF file.
Array scenes;
Dictionary scene_dict;
scenes.append(scene_dict);
p_state->json["scenes"] = scenes;
p_state->json["scene"] = 0;
// Add nodes to the scene dict.
scene_dict["nodes"] = p_state->root_nodes;
if (!p_state->root_nodes.is_empty()) {
scene_dict["nodes"] = p_state->root_nodes;
}
if (!p_state->scene_name.is_empty()) {
scene_dict["name"] = p_state->scene_name;
}
Expand Down Expand Up @@ -458,9 +455,15 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) {
ERR_CONTINUE(err != OK);
}

if (extensions.is_empty()) {
node.erase("extensions");
}

nodes.push_back(node);
}
p_state->json["nodes"] = nodes;
if (!nodes.is_empty()) {
p_state->json["nodes"] = nodes;
}
return OK;
}

Expand Down Expand Up @@ -691,11 +694,11 @@ static Vector<uint8_t> _parse_base64_uri(const String &p_uri) {
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.size()) {
if (p_state->buffers.is_empty()) {
return OK;
}
Array buffers;
if (p_state->buffers.size()) {
if (!p_state->buffers.is_empty()) {
Vector<uint8_t> buffer_data = p_state->buffers[0];
Dictionary gltf_buffer;

Expand Down Expand Up @@ -730,7 +733,7 @@ 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.size()) {
if (p_state->buffers.is_empty()) {
return OK;
}
Array buffers;
Expand Down Expand Up @@ -1543,6 +1546,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> p_state,
Ref<GLTFAccessor> accessor;
accessor.instantiate();
GLTFBufferIndex buffer_view_i;
if (p_state->buffers.is_empty()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
int64_t size = p_state->buffers[0].size();
const GLTFType type = GLTFType::TYPE_SCALAR;
int component_type;
Expand Down Expand Up @@ -1654,6 +1660,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> p_state,
Ref<GLTFAccessor> accessor;
accessor.instantiate();
GLTFBufferIndex buffer_view_i;
if (p_state->buffers.is_empty()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
int64_t size = p_state->buffers[0].size();
const GLTFType type = GLTFType::TYPE_VEC2;
const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
Expand Down Expand Up @@ -1704,6 +1713,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> p_state
Ref<GLTFAccessor> accessor;
accessor.instantiate();
GLTFBufferIndex buffer_view_i;
if (p_state->buffers.is_empty()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
int64_t size = p_state->buffers[0].size();
const GLTFType type = GLTFType::TYPE_VEC4;
const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
Expand Down Expand Up @@ -1768,6 +1780,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> p_sta
Ref<GLTFAccessor> accessor;
accessor.instantiate();
GLTFBufferIndex buffer_view_i;
if (p_state->buffers.is_empty()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
int64_t size = p_state->buffers[0].size();
const GLTFType type = GLTFType::TYPE_VEC4;
const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
Expand Down Expand Up @@ -1816,6 +1831,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> p_stat
Ref<GLTFAccessor> accessor;
accessor.instantiate();
GLTFBufferIndex buffer_view_i;
if (p_state->buffers.is_empty()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
int64_t size = p_state->buffers[0].size();
const GLTFType type = GLTFType::TYPE_VEC4;
const int component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT;
Expand Down Expand Up @@ -1866,6 +1884,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref<GLTFState> p
Ref<GLTFAccessor> accessor;
accessor.instantiate();
GLTFBufferIndex buffer_view_i;
if (p_state->buffers.is_empty()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
int64_t size = p_state->buffers[0].size();
const GLTFType type = GLTFType::TYPE_VEC4;
const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
Expand Down Expand Up @@ -1938,6 +1959,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> p_stat
Ref<GLTFAccessor> accessor;
accessor.instantiate();
GLTFBufferIndex buffer_view_i;
if (p_state->buffers.is_empty()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
int64_t size = p_state->buffers[0].size();
const GLTFType type = GLTFType::TYPE_SCALAR;
const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
Expand Down Expand Up @@ -1985,6 +2009,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> p_state,
Ref<GLTFAccessor> accessor;
accessor.instantiate();
GLTFBufferIndex buffer_view_i;
if (p_state->buffers.is_empty()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
int64_t size = p_state->buffers[0].size();
const GLTFType type = GLTFType::TYPE_VEC3;
const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
Expand Down Expand Up @@ -2058,6 +2085,9 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref<GLTFState> p

Ref<GLTFAccessor> sparse_accessor;
sparse_accessor.instantiate();
if (p_state->buffers.is_empty()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
int64_t size = p_state->buffers[0].size();
const GLTFType type = GLTFType::TYPE_VEC3;
const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
Expand Down Expand Up @@ -2160,6 +2190,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> p_state
Ref<GLTFAccessor> accessor;
accessor.instantiate();
GLTFBufferIndex buffer_view_i;
if (p_state->buffers.is_empty()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
int64_t size = p_state->buffers[0].size();
const GLTFType type = GLTFType::TYPE_MAT4;
const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT;
Expand Down Expand Up @@ -6944,7 +6977,7 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> p_state, const String p_path)
const uint32_t text_chunk_type = 0x4E4F534A; //JSON

uint32_t binary_data_length = 0;
if (p_state->buffers.size()) {
if (p_state->buffers.size() > 0) {
binary_data_length = p_state->buffers[0].size();
}
const uint32_t binary_chunk_length = ((binary_data_length + 3) & (~3));
Expand All @@ -6953,20 +6986,28 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> p_state, const String p_path)
file->create(FileAccess::ACCESS_RESOURCES);
file->store_32(magic);
file->store_32(p_state->major_version); // version
file->store_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_chunk_length); // length
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);

// 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_8(' ');
}

// Write a single binary chunk.
if (binary_chunk_length) {
file->store_32(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++) {
file->store_8(0);
for (uint32_t pad_i = binary_data_length; pad_i < binary_chunk_length; pad_i++) {
file->store_8(0);
}
}
} else {
err = _encode_buffer_bins(p_state, p_path);
Expand Down Expand Up @@ -7073,7 +7114,7 @@ PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref<GLTFState> p_state, Erro

const uint32_t text_chunk_type = 0x4E4F534A; //JSON
int32_t binary_data_length = 0;
if (p_state->buffers.size()) {
if (p_state->buffers.size() > 0) {
binary_data_length = p_state->buffers[0].size();
}
const int32_t binary_chunk_length = binary_data_length;
Expand Down

0 comments on commit ba0dcf7

Please sign in to comment.