More cosmetic improvements in the GLTF code

This commit is contained in:
Aaron Franke 2023-08-03 01:18:45 -05:00
parent 237bd0a615
commit bc68fa368d
No known key found for this signature in database
GPG Key ID: 40A1750B977E56BF
4 changed files with 64 additions and 61 deletions

View File

@ -1,11 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GLTFDocument" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
Class for importing and exporting glTF files in and out of Godot.
</brief_description>
<description>
Append a glTF2 3d format from a file, buffer or scene and then write to the filesystem, buffer or scene.
GLTFDocument supports reading data from a glTF file, buffer, or Godot scene. This data can then be written to the filesystem, buffer, or used to create a Godot scene.
All of the data in a GLTF scene is stored in the [GLTFState] class. GLTFDocument processes state objects, but does not contain any scene data itself.
GLTFDocument can be extended with arbitrary functionality by extending the [GLTFDocumentExtension] class and registering it with GLTFDocument via [method register_gltf_document_extension]. This allows for custom data to be imported and exported.
</description>
<tutorials>
<link title="glTF 'What the duck?' guide">https://www.khronos.org/files/gltf20-reference-guide.pdf</link>
<link title="Khronos glTF specification">https://registry.khronos.org/glTF/</link>
</tutorials>
<methods>
<method name="append_from_buffer">

View File

@ -30,8 +30,6 @@
#include "gltf_document_extension_texture_webp.h"
#include "scene/3d/area_3d.h"
// Import process.
Error GLTFDocumentExtensionTextureWebP::import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions) {
if (!p_extensions.has("EXT_texture_webp")) {

View File

@ -2998,7 +2998,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) {
Error GLTFDocument::_serialize_images(Ref<GLTFState> p_state, const String &p_path) {
Array images;
for (int i = 0; i < p_state->images.size(); i++) {
Dictionary d;
Dictionary image_dict;
ERR_CONTINUE(p_state->images[i].is_null());
@ -3031,8 +3031,8 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> p_state, const String &p_pa
p_state->buffer_views.push_back(bv);
bvi = p_state->buffer_views.size() - 1;
d["bufferView"] = bvi;
d["mimeType"] = "image/png";
image_dict["bufferView"] = bvi;
image_dict["mimeType"] = "image/png";
} else {
ERR_FAIL_COND_V(p_path.is_empty(), ERR_INVALID_PARAMETER);
String img_name = p_state->images[i]->get_name();
@ -3041,17 +3041,17 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> p_state, const String &p_pa
}
img_name = _gen_unique_name(p_state, img_name);
img_name = img_name.pad_zeros(3) + ".png";
String texture_dir = "textures";
String path = p_path.get_base_dir();
String new_texture_dir = path + "/" + texture_dir;
Ref<DirAccess> da = DirAccess::open(path);
if (!da->dir_exists(new_texture_dir)) {
da->make_dir(new_texture_dir);
String relative_texture_dir = "textures";
String parent_path = p_path.get_base_dir();
String full_texture_dir = parent_path + "/" + relative_texture_dir;
Ref<DirAccess> da = DirAccess::open(parent_path);
if (!da->dir_exists(full_texture_dir)) {
da->make_dir(full_texture_dir);
}
image->save_png(new_texture_dir.path_join(img_name));
d["uri"] = texture_dir.path_join(img_name).uri_encode();
image->save_png(full_texture_dir.path_join(img_name));
image_dict["uri"] = relative_texture_dir.path_join(img_name).uri_encode();
}
images.push_back(d);
images.push_back(image_dict);
}
print_verbose("Total images: " + itos(p_state->images.size()));
@ -3312,16 +3312,16 @@ Error GLTFDocument::_serialize_textures(Ref<GLTFState> p_state) {
Array textures;
for (int32_t i = 0; i < p_state->textures.size(); i++) {
Dictionary d;
Ref<GLTFTexture> t = p_state->textures[i];
ERR_CONTINUE(t->get_src_image() == -1);
d["source"] = t->get_src_image();
Dictionary texture_dict;
Ref<GLTFTexture> gltf_texture = p_state->textures[i];
ERR_CONTINUE(gltf_texture->get_src_image() == -1);
texture_dict["source"] = gltf_texture->get_src_image();
GLTFTextureSamplerIndex sampler_index = t->get_sampler();
GLTFTextureSamplerIndex sampler_index = gltf_texture->get_sampler();
if (sampler_index != -1) {
d["sampler"] = sampler_index;
texture_dict["sampler"] = sampler_index;
}
textures.push_back(d);
textures.push_back(texture_dict);
}
p_state->json["textures"] = textures;
@ -3335,28 +3335,28 @@ Error GLTFDocument::_parse_textures(Ref<GLTFState> p_state) {
const Array &textures = p_state->json["textures"];
for (GLTFTextureIndex i = 0; i < textures.size(); i++) {
const Dictionary &dict = textures[i];
Ref<GLTFTexture> texture;
texture.instantiate();
const Dictionary &texture_dict = textures[i];
Ref<GLTFTexture> gltf_texture;
gltf_texture.instantiate();
// Check if any GLTFDocumentExtensions want to handle this texture JSON.
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
ERR_CONTINUE(ext.is_null());
Error err = ext->parse_texture_json(p_state, dict, texture);
ERR_CONTINUE_MSG(err != OK, "GLTF: Encountered error " + itos(err) + " when parsing texture JSON " + String(Variant(dict)) + " in file " + p_state->filename + ". Continuing.");
if (texture->get_src_image() != -1) {
Error err = ext->parse_texture_json(p_state, texture_dict, gltf_texture);
ERR_CONTINUE_MSG(err != OK, "GLTF: Encountered error " + itos(err) + " when parsing texture JSON " + String(Variant(texture_dict)) + " in file " + p_state->filename + ". Continuing.");
if (gltf_texture->get_src_image() != -1) {
break;
}
}
if (texture->get_src_image() == -1) {
if (gltf_texture->get_src_image() == -1) {
// No extensions handled it, so use the base GLTF source.
// This may be the fallback, or the only option anyway.
ERR_FAIL_COND_V(!dict.has("source"), ERR_PARSE_ERROR);
texture->set_src_image(dict["source"]);
ERR_FAIL_COND_V(!texture_dict.has("source"), ERR_PARSE_ERROR);
gltf_texture->set_src_image(texture_dict["source"]);
}
if (texture->get_sampler() == -1 && dict.has("sampler")) {
texture->set_sampler(dict["sampler"]);
if (gltf_texture->get_sampler() == -1 && texture_dict.has("sampler")) {
gltf_texture->set_sampler(texture_dict["sampler"]);
}
p_state->textures.push_back(texture);
p_state->textures.push_back(gltf_texture);
}
return OK;
@ -7280,44 +7280,44 @@ Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, boo
return root;
}
Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> r_state, uint32_t p_flags) {
ERR_FAIL_COND_V(r_state.is_null(), FAILED);
r_state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
r_state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
if (!r_state->buffers.size()) {
r_state->buffers.push_back(Vector<uint8_t>());
Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> p_state, uint32_t p_flags) {
ERR_FAIL_COND_V(p_state.is_null(), FAILED);
p_state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
p_state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
if (!p_state->buffers.size()) {
p_state->buffers.push_back(Vector<uint8_t>());
}
// Perform export preflight for document extensions. Only extensions that
// return OK will be used for the rest of the export steps.
document_extensions.clear();
for (Ref<GLTFDocumentExtension> ext : all_document_extensions) {
ERR_CONTINUE(ext.is_null());
Error err = ext->export_preflight(r_state, p_node);
Error err = ext->export_preflight(p_state, p_node);
if (err == OK) {
document_extensions.push_back(ext);
}
}
// Add the root node(s) and their descendants to the state.
_convert_scene_node(r_state, p_node, -1, -1);
_convert_scene_node(p_state, p_node, -1, -1);
return OK;
}
Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> r_state, uint32_t p_flags) {
ERR_FAIL_COND_V(r_state.is_null(), FAILED);
Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> p_state, uint32_t p_flags) {
ERR_FAIL_COND_V(p_state.is_null(), FAILED);
// TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire
Error err = FAILED;
r_state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
r_state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
p_state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
p_state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
Ref<FileAccessMemory> file_access;
file_access.instantiate();
file_access->open_custom(p_bytes.ptr(), p_bytes.size());
r_state->base_path = p_base_path.get_base_dir();
err = _parse(r_state, r_state->base_path, file_access);
p_state->base_path = p_base_path.get_base_dir();
err = _parse(p_state, p_state->base_path, file_access);
ERR_FAIL_COND_V(err != OK, err);
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
ERR_CONTINUE(ext.is_null());
err = ext->import_post_parse(r_state);
err = ext->import_post_parse(p_state);
ERR_FAIL_COND_V(err != OK, err);
}
return OK;
@ -7436,14 +7436,14 @@ Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> p_state, const String &p_se
return OK;
}
Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> r_state, uint32_t p_flags, String p_base_path) {
Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> p_state, uint32_t p_flags, String p_base_path) {
// TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire
if (r_state == Ref<GLTFState>()) {
r_state.instantiate();
if (p_state == Ref<GLTFState>()) {
p_state.instantiate();
}
r_state->filename = p_path.get_file().get_basename();
r_state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
r_state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
p_state->filename = p_path.get_file().get_basename();
p_state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS;
p_state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS;
Error err;
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ, &err);
ERR_FAIL_COND_V(err != OK, ERR_FILE_CANT_OPEN);
@ -7452,12 +7452,12 @@ Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> r_state, uint
if (base_path.is_empty()) {
base_path = p_path.get_base_dir();
}
r_state->base_path = base_path;
err = _parse(r_state, base_path, file);
p_state->base_path = base_path;
err = _parse(p_state, base_path, file);
ERR_FAIL_COND_V(err != OK, err);
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
ERR_CONTINUE(ext.is_null());
err = ext->import_post_parse(r_state);
err = ext->import_post_parse(p_state);
ERR_FAIL_COND_V(err != OK, err);
}
return OK;

View File

@ -293,9 +293,9 @@ private:
static float get_max_component(const Color &p_color);
public:
Error append_from_file(String p_path, Ref<GLTFState> r_state, uint32_t p_flags = 0, String p_base_path = String());
Error append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> r_state, uint32_t p_flags = 0);
Error append_from_scene(Node *p_node, Ref<GLTFState> r_state, uint32_t p_flags = 0);
Error append_from_file(String p_path, Ref<GLTFState> p_state, uint32_t p_flags = 0, String p_base_path = String());
Error append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> p_state, uint32_t p_flags = 0);
Error append_from_scene(Node *p_node, Ref<GLTFState> p_state, uint32_t p_flags = 0);
public:
Node *generate_scene(Ref<GLTFState> p_state, float p_bake_fps = 30.0f, bool p_trimming = false, bool p_remove_immutable_tracks = true);