Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for extending GLTF with more texture formats and support WebP #76895

Merged
merged 1 commit into from
May 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions modules/gltf/doc_classes/GLTFDocumentExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@
The return value is used to determine if this [GLTFDocumentExtension] instance should be used for importing a given GLTF file. If [constant OK], the import will use this [GLTFDocumentExtension] instance. If not overridden, [constant OK] is returned.
</description>
</method>
<method name="_parse_image_data" qualifiers="virtual">
<return type="int" enum="Error" />
<param index="0" name="state" type="GLTFState" />
<param index="1" name="image_data" type="PackedByteArray" />
<param index="2" name="mime_type" type="String" />
<param index="3" name="ret_image" type="Image" />
<description>
Part of the import process. This method is run after [method _parse_node_extensions] and before [method _parse_texture_json].
Runs when parsing image data from a GLTF file. The data could be sourced from a separate file, a URI, or a buffer, and then is passed as a byte array.
</description>
</method>
<method name="_parse_node_extensions" qualifiers="virtual">
<return type="int" enum="Error" />
<param index="0" name="state" type="GLTFState" />
Expand All @@ -113,5 +124,15 @@
Runs when parsing the node extensions of a GLTFNode. This method can be used to process the extension JSON data into a format that can be used by [method _generate_scene_node]. The return value should be a member of the [enum Error] enum.
</description>
</method>
<method name="_parse_texture_json" qualifiers="virtual">
<return type="int" enum="Error" />
<param index="0" name="state" type="GLTFState" />
<param index="1" name="texture_json" type="Dictionary" />
<param index="2" name="ret_gltf_texture" type="GLTFTexture" />
<description>
Part of the import process. This method is run after [method _parse_image_data] and before [method _generate_scene_node].
Runs when parsing the texture JSON from the GLTF textures array. This can be used to set the source image index to use as the texture.
</description>
</method>
</methods>
</class>
2 changes: 2 additions & 0 deletions modules/gltf/doc_classes/GLTFState.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
<method name="get_images">
<return type="Texture2D[]" />
<description>
Gets the images of the GLTF file as an array of [Texture2D]s. These are the images that the [member GLTFTexture.src_image] index refers to.
</description>
</method>
<method name="get_lights">
Expand Down Expand Up @@ -182,6 +183,7 @@
<return type="void" />
<param index="0" name="images" type="Texture2D[]" />
<description>
Sets the images in the state stored as an array of [Texture2D]s. This can be used during export. These are the images that the [member GLTFTexture.src_image] index refers to.
</description>
</method>
<method name="set_lights">
Expand Down
3 changes: 2 additions & 1 deletion modules/gltf/doc_classes/GLTFTexture.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
<member name="sampler" type="int" setter="set_sampler" getter="get_sampler" default="-1">
ID of the texture sampler to use when sampling the image. If -1, then the default texture sampler is used (linear filtering, and repeat wrapping in both axes).
</member>
<member name="src_image" type="int" setter="set_src_image" getter="get_src_image" default="0">
<member name="src_image" type="int" setter="set_src_image" getter="get_src_image" default="-1">
The index of the image associated with this texture, see [method GLTFState.get_images]. If -1, then this texture does not have an image assigned.
</member>
</members>
</class>
18 changes: 18 additions & 0 deletions modules/gltf/extensions/gltf_document_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ void GLTFDocumentExtension::_bind_methods() {
GDVIRTUAL_BIND(_import_preflight, "state", "extensions");
GDVIRTUAL_BIND(_get_supported_extensions);
GDVIRTUAL_BIND(_parse_node_extensions, "state", "gltf_node", "extensions");
GDVIRTUAL_BIND(_parse_image_data, "state", "image_data", "mime_type", "ret_image");
GDVIRTUAL_BIND(_parse_texture_json, "state", "texture_json", "ret_gltf_texture");
GDVIRTUAL_BIND(_generate_scene_node, "state", "gltf_node", "scene_parent");
GDVIRTUAL_BIND(_import_post_parse, "state");
GDVIRTUAL_BIND(_import_node, "state", "gltf_node", "json", "node");
Expand Down Expand Up @@ -68,6 +70,22 @@ Error GLTFDocumentExtension::parse_node_extensions(Ref<GLTFState> p_state, Ref<G
return err;
}

Error GLTFDocumentExtension::parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image) {
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
ERR_FAIL_NULL_V(r_image, ERR_INVALID_PARAMETER);
Error err = OK;
GDVIRTUAL_CALL(_parse_image_data, p_state, p_image_data, p_mime_type, r_image, err);
return err;
}

Error GLTFDocumentExtension::parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture) {
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
ERR_FAIL_NULL_V(r_gltf_texture, ERR_INVALID_PARAMETER);
Error err = OK;
GDVIRTUAL_CALL(_parse_texture_json, p_state, p_texture_json, r_gltf_texture, err);
return err;
}

Node3D *GLTFDocumentExtension::generate_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent) {
ERR_FAIL_NULL_V(p_state, nullptr);
ERR_FAIL_NULL_V(p_gltf_node, nullptr);
Expand Down
4 changes: 4 additions & 0 deletions modules/gltf/extensions/gltf_document_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class GLTFDocumentExtension : public Resource {
virtual Error import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions);
virtual Vector<String> get_supported_extensions();
virtual Error parse_node_extensions(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &p_extensions);
virtual Error parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image);
virtual Error parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture);
virtual Node3D *generate_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent);
virtual Error import_post_parse(Ref<GLTFState> p_state);
virtual Error import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node);
Expand All @@ -58,6 +60,8 @@ class GLTFDocumentExtension : public Resource {
GDVIRTUAL2R(Error, _import_preflight, Ref<GLTFState>, Vector<String>);
GDVIRTUAL0R(Vector<String>, _get_supported_extensions);
GDVIRTUAL3R(Error, _parse_node_extensions, Ref<GLTFState>, Ref<GLTFNode>, Dictionary);
GDVIRTUAL4R(Error, _parse_image_data, Ref<GLTFState>, PackedByteArray, String, Ref<Image>);
GDVIRTUAL3R(Error, _parse_texture_json, Ref<GLTFState>, Dictionary, Ref<GLTFTexture>);
GDVIRTUAL3R(Node3D *, _generate_scene_node, Ref<GLTFState>, Ref<GLTFNode>, Node *);
GDVIRTUAL1R(Error, _import_post_parse, Ref<GLTFState>);
GDVIRTUAL4R(Error, _import_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**************************************************************************/
/* gltf_document_extension_texture_webp.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#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")) {
return ERR_SKIP;
}
return OK;
}

Vector<String> GLTFDocumentExtensionTextureWebP::get_supported_extensions() {
Vector<String> ret;
ret.push_back("EXT_texture_webp");
return ret;
}

Error GLTFDocumentExtensionTextureWebP::parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image) {
if (p_mime_type == "image/webp") {
return r_image->load_webp_from_buffer(p_image_data);
}
return OK;
}

Error GLTFDocumentExtensionTextureWebP::parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture) {
if (!p_texture_json.has("extensions")) {
return OK;
}
const Dictionary &extensions = p_texture_json["extensions"];
if (!extensions.has("EXT_texture_webp")) {
return OK;
}
const Dictionary &texture_webp = extensions["EXT_texture_webp"];
ERR_FAIL_COND_V(!texture_webp.has("source"), ERR_PARSE_ERROR);
r_gltf_texture->set_src_image(texture_webp["source"]);
return OK;
}
47 changes: 47 additions & 0 deletions modules/gltf/extensions/gltf_document_extension_texture_webp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**************************************************************************/
/* gltf_document_extension_texture_webp.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef GLTF_DOCUMENT_EXTENSION_TEXTURE_WEBP_H
#define GLTF_DOCUMENT_EXTENSION_TEXTURE_WEBP_H

#include "gltf_document_extension.h"

class GLTFDocumentExtensionTextureWebP : public GLTFDocumentExtension {
GDCLASS(GLTFDocumentExtensionTextureWebP, GLTFDocumentExtension);

public:
// Import process.
Error import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions) override;
Vector<String> get_supported_extensions() override;
Error parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image) override;
Error parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture) override;
};

#endif // GLTF_DOCUMENT_EXTENSION_TEXTURE_WEBP_H
Loading