Misc changes to the GLTF module before audio PR
This commit is contained in:
parent
26b1fd0d84
commit
d36a34edb7
11 changed files with 91 additions and 11 deletions
|
@ -1,14 +1,19 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?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">
|
<class name="GLTFAccessor" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
|
||||||
<brief_description>
|
<brief_description>
|
||||||
|
Represents a GLTF accessor.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<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>
|
</description>
|
||||||
<tutorials>
|
<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>
|
<link title="Runtime file loading and saving">$DOCS_URL/tutorials/io/runtime_file_loading_and_saving.html</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<members>
|
<members>
|
||||||
<member name="buffer_view" type="int" setter="set_buffer_view" getter="get_buffer_view" default="-1">
|
<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>
|
||||||
<member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0">
|
<member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0">
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -1,22 +1,40 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?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">
|
<class name="GLTFBufferView" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
|
||||||
<brief_description>
|
<brief_description>
|
||||||
|
Represents a GLTF buffer view.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<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>
|
</description>
|
||||||
<tutorials>
|
<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>
|
<link title="Runtime file loading and saving">$DOCS_URL/tutorials/io/runtime_file_loading_and_saving.html</link>
|
||||||
</tutorials>
|
</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>
|
<members>
|
||||||
<member name="buffer" type="int" setter="set_buffer" getter="get_buffer" default="-1">
|
<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>
|
||||||
<member name="byte_length" type="int" setter="set_byte_length" getter="get_byte_length" default="0">
|
<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>
|
||||||
<member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0">
|
<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>
|
||||||
<member name="byte_stride" type="int" setter="set_byte_stride" getter="get_byte_stride" default="-1">
|
<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>
|
||||||
<member name="indices" type="bool" setter="set_indices" getter="get_indices" default="false">
|
<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.
|
||||||
</member>
|
</member>
|
||||||
</members>
|
</members>
|
||||||
</class>
|
</class>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<param index="3" name="node" type="Node" />
|
<param index="3" name="node" type="Node" />
|
||||||
<description>
|
<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].
|
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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_export_post" qualifiers="virtual">
|
<method name="_export_post" qualifiers="virtual">
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
<param index="0" name="state" type="GLTFState" />
|
<param index="0" name="state" type="GLTFState" />
|
||||||
<description>
|
<description>
|
||||||
Part of the import process. This method is run after [method _parse_node_extensions] and before [method _generate_scene_node].
|
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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_import_preflight" qualifiers="virtual">
|
<method name="_import_preflight" qualifiers="virtual">
|
||||||
|
|
|
@ -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.
|
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>
|
</description>
|
||||||
</method>
|
</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">
|
<method name="get_accessors">
|
||||||
<return type="GLTFAccessor[]" />
|
<return type="GLTFAccessor[]" />
|
||||||
<description>
|
<description>
|
||||||
|
|
|
@ -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) {
|
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_state, ERR_INVALID_PARAMETER);
|
||||||
ERR_FAIL_NULL_V(p_gltf_node, 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;
|
Error err = OK;
|
||||||
GDVIRTUAL_CALL(_export_node, p_state, p_gltf_node, r_dict, p_node, err);
|
GDVIRTUAL_CALL(_export_node, p_state, p_gltf_node, r_dict, p_node, err);
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -405,6 +405,7 @@ static Vector<real_t> _xform_to_array(const Transform3D p_transform) {
|
||||||
|
|
||||||
Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) {
|
Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) {
|
||||||
Array nodes;
|
Array nodes;
|
||||||
|
const int scene_node_count = p_state->scene_nodes.size();
|
||||||
for (int i = 0; i < p_state->nodes.size(); i++) {
|
for (int i = 0; i < p_state->nodes.size(); i++) {
|
||||||
Dictionary node;
|
Dictionary node;
|
||||||
Ref<GLTFNode> gltf_node = p_state->nodes[i];
|
Ref<GLTFNode> gltf_node = p_state->nodes[i];
|
||||||
|
@ -452,10 +453,13 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) {
|
||||||
node["children"] = children;
|
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) {
|
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
|
||||||
ERR_CONTINUE(ext.is_null());
|
ERR_CONTINUE(ext.is_null());
|
||||||
ERR_CONTINUE(!p_state->scene_nodes.find(i));
|
Error err = ext->export_node(p_state, gltf_node, node, scene_node);
|
||||||
Error err = ext->export_node(p_state, gltf_node, node, p_state->scene_nodes[i]);
|
|
||||||
ERR_CONTINUE(err != OK);
|
ERR_CONTINUE(err != OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7471,11 +7475,13 @@ Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, boo
|
||||||
ERR_CONTINUE(!E.value);
|
ERR_CONTINUE(!E.value);
|
||||||
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
|
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
|
||||||
ERR_CONTINUE(ext.is_null());
|
ERR_CONTINUE(ext.is_null());
|
||||||
ERR_CONTINUE(!p_state->json.has("nodes"));
|
Dictionary node_json;
|
||||||
Array nodes = p_state->json["nodes"];
|
if (p_state->json.has("nodes")) {
|
||||||
ERR_CONTINUE(E.key >= nodes.size());
|
Array nodes = p_state->json["nodes"];
|
||||||
ERR_CONTINUE(E.key < 0);
|
if (0 <= E.key && E.key < nodes.size()) {
|
||||||
Dictionary node_json = nodes[E.key];
|
node_json = nodes[E.key];
|
||||||
|
}
|
||||||
|
}
|
||||||
Ref<GLTFNode> gltf_node = p_state->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 = ext->import_node(p_state, gltf_node, node_json, E.value);
|
||||||
ERR_CONTINUE(err != OK);
|
ERR_CONTINUE(err != OK);
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
|
|
||||||
void GLTFState::_bind_methods() {
|
void GLTFState::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("add_used_extension", "extension_name", "required"), &GLTFState::add_used_extension);
|
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("get_json"), &GLTFState::get_json);
|
||||||
ClassDB::bind_method(D_METHOD("set_json", "json"), &GLTFState::set_json);
|
ClassDB::bind_method(D_METHOD("set_json", "json"), &GLTFState::set_json);
|
||||||
ClassDB::bind_method(D_METHOD("get_major_version"), &GLTFState::get_major_version);
|
ClassDB::bind_method(D_METHOD("get_major_version"), &GLTFState::get_major_version);
|
||||||
|
@ -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) {
|
void GLTFState::set_additional_data(const StringName &p_extension_name, Variant p_additional_data) {
|
||||||
additional_data[p_extension_name] = 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;
|
||||||
|
}
|
||||||
|
|
|
@ -105,6 +105,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void add_used_extension(const String &p_extension, bool p_required = false);
|
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 {
|
enum GLTFHandleBinary {
|
||||||
HANDLE_BINARY_DISCARD_TEXTURES = 0,
|
HANDLE_BINARY_DISCARD_TEXTURES = 0,
|
||||||
|
|
|
@ -118,6 +118,7 @@ void initialize_gltf_module(ModuleInitializationLevel p_level) {
|
||||||
GDREGISTER_CLASS(GLTFTexture);
|
GDREGISTER_CLASS(GLTFTexture);
|
||||||
GDREGISTER_CLASS(GLTFTextureSampler);
|
GDREGISTER_CLASS(GLTFTextureSampler);
|
||||||
// Register GLTFDocumentExtension classes with GLTFDocument.
|
// 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(GLTFDocumentExtensionPhysics);
|
||||||
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionTextureKTX);
|
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionTextureKTX);
|
||||||
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionTextureWebP);
|
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionTextureWebP);
|
||||||
|
|
|
@ -30,7 +30,11 @@
|
||||||
|
|
||||||
#include "gltf_buffer_view.h"
|
#include "gltf_buffer_view.h"
|
||||||
|
|
||||||
|
#include "../gltf_state.h"
|
||||||
|
|
||||||
void GLTFBufferView::_bind_methods() {
|
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("get_buffer"), &GLTFBufferView::get_buffer);
|
||||||
ClassDB::bind_method(D_METHOD("set_buffer", "buffer"), &GLTFBufferView::set_buffer);
|
ClassDB::bind_method(D_METHOD("set_buffer", "buffer"), &GLTFBufferView::set_buffer);
|
||||||
ClassDB::bind_method(D_METHOD("get_byte_offset"), &GLTFBufferView::get_byte_offset);
|
ClassDB::bind_method(D_METHOD("get_byte_offset"), &GLTFBufferView::get_byte_offset);
|
||||||
|
@ -88,3 +92,12 @@ bool GLTFBufferView::get_indices() {
|
||||||
void GLTFBufferView::set_indices(bool p_indices) {
|
void GLTFBufferView::set_indices(bool p_indices) {
|
||||||
indices = 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);
|
||||||
|
}
|
||||||
|
|
|
@ -64,7 +64,8 @@ public:
|
||||||
|
|
||||||
bool get_indices();
|
bool get_indices();
|
||||||
void set_indices(bool p_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
|
#endif // GLTF_BUFFER_VIEW_H
|
||||||
|
|
Loading…
Reference in a new issue