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

Misc changes to the GLTF module before audio PR #87063

Merged
merged 1 commit into from
Jan 15, 2024
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
5 changes: 5 additions & 0 deletions modules/gltf/doc_classes/GLTFAccessor.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GLTFAccessor" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
Represents a GLTF accessor.
</brief_description>
<description>
GLTFAccessor is a data structure representing GLTF a [code]accessor[/code] that would be found in the [code]"accessors"[/code] array. A buffer is a blob of binary data. A buffer view is a slice of a buffer. An accessor is a typed interpretation of the data in a buffer view.
Most custom data stored in GLTF does not need accessors, only buffer views (see [GLTFBufferView]). Accessors are for more advanced use cases such as interleaved mesh data encoded for the GPU.
</description>
<tutorials>
<link title="Buffers, BufferViews, and Accessors in Khronos glTF specification">https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_005_BuffersBufferViewsAccessors.md</link>
<link title="Runtime file loading and saving">$DOCS_URL/tutorials/io/runtime_file_loading_and_saving.html</link>
</tutorials>
<members>
<member name="buffer_view" type="int" setter="set_buffer_view" getter="get_buffer_view" default="-1">
The index of the buffer view this accessor is referencing. If [code]-1[/code], this accessor is not referencing any buffer view.
</member>
<member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0">
</member>
Expand Down
18 changes: 18 additions & 0 deletions modules/gltf/doc_classes/GLTFBufferView.xml
Original file line number Diff line number Diff line change
@@ -1,22 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GLTFBufferView" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
Represents a GLTF buffer view.
</brief_description>
<description>
GLTFBufferView is a data structure representing GLTF a [code]bufferView[/code] that would be found in the [code]"bufferViews"[/code] array. A buffer is a blob of binary data. A buffer view is a slice of a buffer that can be used to identify and extract data from the buffer.
Most custom uses of buffers only need to use the [member buffer], [member byte_length], and [member byte_offset]. The [member byte_stride] and [member indices] properties are for more advanced use cases such as interleaved mesh data encoded for the GPU.
</description>
<tutorials>
<link title="Buffers, BufferViews, and Accessors in Khronos glTF specification">https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_005_BuffersBufferViewsAccessors.md</link>
<link title="Runtime file loading and saving">$DOCS_URL/tutorials/io/runtime_file_loading_and_saving.html</link>
</tutorials>
<methods>
<method name="load_buffer_view_data" qualifiers="const">
<return type="PackedByteArray" />
<param index="0" name="state" type="GLTFState" />
<description>
Loads the buffer view data from the buffer referenced by this buffer view in the given [GLTFState]. Interleaved data with a byte stride is not yet supported by this method. The data is returned as a [PackedByteArray].
</description>
</method>
</methods>
<members>
<member name="buffer" type="int" setter="set_buffer" getter="get_buffer" default="-1">
The index of the buffer this buffer view is referencing. If [code]-1[/code], this buffer view is not referencing any buffer.
</member>
<member name="byte_length" type="int" setter="set_byte_length" getter="get_byte_length" default="0">
The length, in bytes, of this buffer view. If [code]0[/code], this buffer view is empty.
</member>
<member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0">
The offset, in bytes, from the start of the buffer to the start of this buffer view.
</member>
<member name="byte_stride" type="int" setter="set_byte_stride" getter="get_byte_stride" default="-1">
The stride, in bytes, between interleaved data. If [code]-1[/code], this buffer view is not interleaved.
</member>
<member name="indices" type="bool" setter="set_indices" getter="get_indices" default="false">
True if the GLTFBufferView's OpenGL GPU buffer type is an [code]ELEMENT_ARRAY_BUFFER[/code] used for vertex indices (integer constant [code]34963[/code]). False if the buffer type is [code]ARRAY_BUFFER[/code] used for vertex attributes (integer constant [code]34962[/code]) or when any other value. See [url=https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_005_BuffersBufferViewsAccessors.md]Buffers, BufferViews, and Accessors[/url] for possible values. This property is set but never used, setting this property will do nothing.
fire marked this conversation as resolved.
Show resolved Hide resolved
</member>
</members>
</class>
4 changes: 2 additions & 2 deletions modules/gltf/doc_classes/GLTFDocumentExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<param index="3" name="node" type="Node" />
<description>
Part of the export process. This method is run after [method _get_saveable_image_formats] and before [method _export_post]. If this [GLTFDocumentExtension] is used for exporting images, this runs after [method _serialize_texture_json].
This method can be used to modify the final JSON of each node.
This method can be used to modify the final JSON of each node. Data should be primarily stored in [param gltf_node] prior to serializing the JSON, but the original Godot [param node] is also provided if available. The node may be null if not available, such as when exporting GLTF data not generated from a Godot scene.
</description>
</method>
<method name="_export_post" qualifiers="virtual">
Expand Down Expand Up @@ -114,7 +114,7 @@
<param index="0" name="state" type="GLTFState" />
<description>
Part of the import process. This method is run after [method _parse_node_extensions] and before [method _generate_scene_node].
This method can be used to modify any of the data imported so far, including any scene nodes, before running the final per-node import step.
This method can be used to modify any of the data imported so far after parsing, before generating the nodes and then running the final per-node import step.
</description>
</method>
<method name="_import_preflight" qualifiers="virtual">
Expand Down
8 changes: 8 additions & 0 deletions modules/gltf/doc_classes/GLTFState.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
Appends an extension to the list of extensions used by this GLTF file during serialization. If [param required] is true, the extension will also be added to the list of required extensions. Do not run this in [method GLTFDocumentExtension._export_post], as that stage is too late to add extensions. The final list is sorted alphabetically.
</description>
</method>
<method name="append_data_to_buffers">
<return type="int" />
<param index="0" name="data" type="PackedByteArray" />
<param index="1" name="deduplication" type="bool" />
<description>
Appends the given byte array data to the buffers and creates a [GLTFBufferView] for it. The index of the destination [GLTFBufferView] is returned. If [param deduplication] is true, the buffers will first be searched for duplicate data, otherwise new bytes will always be appended.
</description>
</method>
<method name="get_accessors">
<return type="GLTFAccessor[]" />
<description>
Expand Down
1 change: 0 additions & 1 deletion modules/gltf/extensions/gltf_document_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ Error GLTFDocumentExtension::serialize_texture_json(Ref<GLTFState> p_state, Dict
Error GLTFDocumentExtension::export_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_dict, Node *p_node) {
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
ERR_FAIL_NULL_V(p_gltf_node, ERR_INVALID_PARAMETER);
ERR_FAIL_NULL_V(p_node, ERR_INVALID_PARAMETER);
Error err = OK;
GDVIRTUAL_CALL(_export_node, p_state, p_gltf_node, r_dict, p_node, err);
return err;
Expand Down
20 changes: 13 additions & 7 deletions modules/gltf/gltf_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ static Vector<real_t> _xform_to_array(const Transform3D p_transform) {

Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) {
Array nodes;
const int scene_node_count = p_state->scene_nodes.size();
for (int i = 0; i < p_state->nodes.size(); i++) {
Dictionary node;
Ref<GLTFNode> gltf_node = p_state->nodes[i];
Expand Down Expand Up @@ -452,10 +453,13 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) {
node["children"] = children;
}

Node *scene_node = nullptr;
if (i < scene_node_count) {
scene_node = p_state->scene_nodes[i];
}
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
ERR_CONTINUE(ext.is_null());
ERR_CONTINUE(!p_state->scene_nodes.find(i));
Error err = ext->export_node(p_state, gltf_node, node, p_state->scene_nodes[i]);
Error err = ext->export_node(p_state, gltf_node, node, scene_node);
ERR_CONTINUE(err != OK);
}

Expand Down Expand Up @@ -7471,11 +7475,13 @@ Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, boo
ERR_CONTINUE(!E.value);
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
ERR_CONTINUE(ext.is_null());
ERR_CONTINUE(!p_state->json.has("nodes"));
Array nodes = p_state->json["nodes"];
ERR_CONTINUE(E.key >= nodes.size());
ERR_CONTINUE(E.key < 0);
Dictionary node_json = nodes[E.key];
Dictionary node_json;
if (p_state->json.has("nodes")) {
Array nodes = p_state->json["nodes"];
if (0 <= E.key && E.key < nodes.size()) {
node_json = nodes[E.key];
}
}
Ref<GLTFNode> gltf_node = p_state->nodes[E.key];
err = ext->import_node(p_state, gltf_node, node_json, E.value);
ERR_CONTINUE(err != OK);
Expand Down
28 changes: 28 additions & 0 deletions modules/gltf/gltf_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@

void GLTFState::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_used_extension", "extension_name", "required"), &GLTFState::add_used_extension);
ClassDB::bind_method(D_METHOD("append_data_to_buffers", "data", "deduplication"), &GLTFState::append_data_to_buffers);

ClassDB::bind_method(D_METHOD("get_json"), &GLTFState::get_json);
ClassDB::bind_method(D_METHOD("set_json", "json"), &GLTFState::set_json);
ClassDB::bind_method(D_METHOD("get_major_version"), &GLTFState::get_major_version);
Expand Down Expand Up @@ -399,3 +401,29 @@ Variant GLTFState::get_additional_data(const StringName &p_extension_name) {
void GLTFState::set_additional_data(const StringName &p_extension_name, Variant p_additional_data) {
additional_data[p_extension_name] = p_additional_data;
}

GLTFBufferViewIndex GLTFState::append_data_to_buffers(const Vector<uint8_t> &p_data, const bool p_deduplication = false) {
if (p_deduplication) {
for (int i = 0; i < buffer_views.size(); i++) {
Ref<GLTFBufferView> buffer_view = buffer_views[i];
Vector<uint8_t> buffer_view_data = buffer_view->load_buffer_view_data(this);
if (buffer_view_data == p_data) {
return i;
}
}
}
// Append the given data to a buffer and create a buffer view for it.
if (unlikely(buffers.is_empty())) {
buffers.push_back(Vector<uint8_t>());
}
Vector<uint8_t> &destination_buffer = buffers.write[0];
Ref<GLTFBufferView> buffer_view;
buffer_view.instantiate();
buffer_view->set_buffer(0);
buffer_view->set_byte_offset(destination_buffer.size());
buffer_view->set_byte_length(p_data.size());
destination_buffer.append_array(p_data);
const int new_index = buffer_views.size();
buffer_views.push_back(buffer_view);
return new_index;
}
1 change: 1 addition & 0 deletions modules/gltf/gltf_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class GLTFState : public Resource {

public:
void add_used_extension(const String &p_extension, bool p_required = false);
GLTFBufferViewIndex append_data_to_buffers(const Vector<uint8_t> &p_data, const bool p_deduplication);

enum GLTFHandleBinary {
HANDLE_BINARY_DISCARD_TEXTURES = 0,
Expand Down
1 change: 1 addition & 0 deletions modules/gltf/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ void initialize_gltf_module(ModuleInitializationLevel p_level) {
GDREGISTER_CLASS(GLTFTexture);
GDREGISTER_CLASS(GLTFTextureSampler);
// Register GLTFDocumentExtension classes with GLTFDocument.
// Ensure physics is first in this list so that physics nodes are created before other nodes.
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionPhysics);
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionTextureKTX);
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionTextureWebP);
Expand Down
13 changes: 13 additions & 0 deletions modules/gltf/structures/gltf_buffer_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@

#include "gltf_buffer_view.h"

#include "../gltf_state.h"

void GLTFBufferView::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_buffer_view_data", "state"), &GLTFBufferView::load_buffer_view_data);

ClassDB::bind_method(D_METHOD("get_buffer"), &GLTFBufferView::get_buffer);
ClassDB::bind_method(D_METHOD("set_buffer", "buffer"), &GLTFBufferView::set_buffer);
ClassDB::bind_method(D_METHOD("get_byte_offset"), &GLTFBufferView::get_byte_offset);
Expand Down Expand Up @@ -88,3 +92,12 @@ bool GLTFBufferView::get_indices() {
void GLTFBufferView::set_indices(bool p_indices) {
indices = p_indices;
}

Vector<uint8_t> GLTFBufferView::load_buffer_view_data(const Ref<GLTFState> p_state) const {
ERR_FAIL_COND_V_MSG(byte_stride > 0, Vector<uint8_t>(), "Buffer views with byte stride are not yet supported by this method.");
const TypedArray<Vector<uint8_t>> &buffers = p_state->get_buffers();
ERR_FAIL_INDEX_V(buffer, buffers.size(), Vector<uint8_t>());
const PackedByteArray &buffer_data = buffers[buffer];
const int64_t byte_end = byte_offset + byte_length;
return buffer_data.slice(byte_offset, byte_end);
}
3 changes: 2 additions & 1 deletion modules/gltf/structures/gltf_buffer_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ class GLTFBufferView : public Resource {

bool get_indices();
void set_indices(bool p_indices);
// matrices need to be transformed to this

Vector<uint8_t> load_buffer_view_data(const Ref<GLTFState> p_state) const;
};

#endif // GLTF_BUFFER_VIEW_H
Loading