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: GltfFileStream and rewritten GltfDataBuffer #49

Merged
merged 9 commits into from
Apr 28, 2024
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/compiler_flags.cmake)

# Create the library target
add_library(fastgltf
"src/fastgltf.cpp" "src/base64.cpp"
"src/fastgltf.cpp" "src/base64.cpp" "src/io.cpp"
"include/fastgltf/base64.hpp" "include/fastgltf/glm_element_traits.hpp" "include/fastgltf/core.hpp" "include/fastgltf/tools.hpp" "include/fastgltf/types.hpp" "include/fastgltf/util.hpp")
add_library(fastgltf::fastgltf ALIAS fastgltf)

Expand Down
23 changes: 19 additions & 4 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -283,25 +283,39 @@ Expected
:undoc-members:


GltfDataBuffer
GltfDataGetter
--------------

.. doxygenfunction:: fastgltf::getGltfBufferPadding
.. doxygenclass:: fastgltf::GltfDataGetter
:members:
:undoc-members:


GltfDataBuffer
--------------

.. doxygenclass:: fastgltf::GltfDataBuffer
:members:
:undoc-members:


GltfFileStream
--------------

.. doxygenclass:: fastgltf::GltfFileStream
:members:
:undoc-members:


Parser
------

.. doxygenfunction:: fastgltf::determineGltfFileType

.. doxygenclass:: fastgltf::Parser
:members:
:undoc-members:

.. doxygenfunction:: fastgltf::determineGltfFileType

.. doxygenstruct:: fastgltf::BufferInfo
:members:

Expand All @@ -317,6 +331,7 @@ Exporter
:members:
:undoc-members:


Utility
=======

Expand Down
49 changes: 46 additions & 3 deletions docs/guides.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,46 @@ Guides

.. contents:: Table of Contents

How to load glTF files for parsing
==================================

Before you can have the ``fastgltf::Parser`` object parse the glTF, you need to load it into memory.
The ``loadGltf`` functions all take a reference to a ``fastgltf::GltfDataGetter``, which defines a common interface for reading memory.
**fastgltf** provides some implementations for this interface natively, which can be used out of the box.
Most notably, ``fastgltf::GltfDataBuffer`` and ``fastgltf::GltfFileStream``.

GltfDataBuffer
--------------

This basic class essentially holds a buffer with the contents of a glTF.
This buffer can be created and filled using the factory constructors.
These constructors return an ``Expected<T>`` which holds the buffer, as well as an error, if one occurred.
Be sure to always check if any of these functions returned an error.

.. code:: c++

auto gltfFile = fastgltf::GltfDataBuffer::FromPath("./asset.gltf");
auto gltfData = fastgltf::GltfDataBuffer::FromBytes(bytes.data(), bytes.size());

GltfFileStream
--------------

``GltfFileStream`` is a basic wrapper around ``std::ifstream``, implementing the ``fastgltf::GltfDataGetter`` interface.
The usage of this class is essentially just a cut down version of the stdlib class.

.. code:: c++

fastgltf::GltfFileStream fileStream("./asset.gltf");
if (!fileStream.isOpen())
return false;

AndroidGltfDataBuffer
---------------------

This is essentially the same interface as ``fastgltf::GltfDataBuffer``, but additionally supports loading APK assets.
See :ref:`this section <android-guide>` for more information.


How to read glTF extras
=======================

Expand Down Expand Up @@ -76,6 +116,7 @@ Additionally, ``fastgltf::Exporter`` also supports writing extras:
exporter.setExtrasWriteCallback(extrasWriteCallback);
auto exported = exporter.writeGltfJson(asset, fastgltf::ExportOptions::None);

.. _android-guide:

How to use fastgltf on Android
==============================
Expand All @@ -94,12 +135,14 @@ The glTF file itself, however, needs to be loaded using a special function:

.. code:: c++

fastgltf::AndroidGltfDataBuffer jsonData;
jsonData.loadFromAndroidAsset(filePath);
auto jsonData = fastgltf::AndroidGltfDataBuffer::FromAsset(filePath);
if (jsonData.error() != fastgltf::Error::None)
return false;

.. note::

Always check the return value from functions related to ``fastgltf::GltfDataBuffer``.
Always check the return value from the factory functions from classes inheriting ``fastgltf::GltfDataGetter``,
since they return an Expected<T> which could possibly contain an error.


How to load data from accessors
Expand Down
27 changes: 17 additions & 10 deletions docs/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -121,24 +121,29 @@ The following snippet illustrates how to use fastgltf to load a glTF file.
#include <fastgltf/core.hpp>
#include <fastgltf/types.hpp>

void load(std::filesystem::path path) {
bool load(std::filesystem::path path) {
// Creates a Parser instance. Optimally, you should reuse this across loads, but don't use it
// across threads. To enable extensions, you have to pass them into the parser's constructor.
fastgltf::Parser parser;

// The GltfDataBuffer class is designed for re-usability of the same JSON string. It contains
// utility functions to load data from a std::filesystem::path, copy from an existing buffer,
// or re-use an already existing allocation. Note that it has to outlive the process of every
// parsing function you call.
fastgltf::GltfDataBuffer data;
data.loadFromFile(path);
// The GltfDataBuffer class contains static factories which create a buffer for holding the
// glTF data. These return Expected<GltfDataBuffer>, which can be checked if an error occurs.
// The parser accepts any subtype of GltfDataGetter, which defines an interface for reading
// chunks of the glTF file for the Parser to handle. fastgltf provides a few predefined classes
// which inherit from GltfDataGetter, so choose whichever fits your usecase the best.
auto data = fastgltf::GltfDataBuffer::FromPath(path);
if (data.error() != fastgltf::Error::None) {
// The file couldn't be loaded, or the buffer could not be allocated.
return false;
}

// This loads the glTF file into the gltf object and parses the JSON.
// It automatically detects whether this is a JSON-based or binary glTF.
// If you know the type, you can also use loadGltfJson or loadGltfBinary.
auto asset = parser.loadGltf(&data, path.parent_path(), fastgltf::Options::None);
auto asset = parser.loadGltf(data.get(), path.parent_path(), fastgltf::Options::None);
if (auto error = asset.error(); error != fastgltf::Error::None) {
// Some error occurred while reading the buffer, parsing the JSON, or validating the data.
return false;
}

// The glTF 2.0 asset is now ready to be used. Simply call asset.get(), asset.get_if() or
Expand All @@ -153,12 +158,14 @@ The following snippet illustrates how to use fastgltf to load a glTF file.
// recommend it in a development environment or when debugging to avoid mishaps.

// fastgltf::validate(asset.get());

return true;
}


All the nodes, meshes, buffers, textures, ... can now be accessed through the ``fastgltf::Asset`` type.
References in between objects are done with a single ``size_t``,
which is used to index into the various vectors in the asset.
References in between objects are done with a single ``std::size_t``, which is used to index into the
various vectors in the asset.

.. _examples:

Expand Down
9 changes: 6 additions & 3 deletions examples/gl_viewer/gl_viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,10 +353,13 @@ bool loadGltf(Viewer* viewer, std::filesystem::path path) {
fastgltf::Options::LoadExternalImages |
fastgltf::Options::GenerateMeshIndices;

fastgltf::GltfDataBuffer data;
data.loadFromFile(path);
auto gltfFile = fastgltf::MappedGltfFile::FromPath(path);
if (!bool(gltfFile)) {
std::cerr << "Failed to open glTF file: " << fastgltf::getErrorMessage(gltfFile.error()) << '\n';
return false;
}

auto asset = parser.loadGltf(&data, path.parent_path(), gltfOptions);
auto asset = parser.loadGltf(gltfFile.get(), path.parent_path(), gltfOptions);
if (asset.error() != fastgltf::Error::None) {
std::cerr << "Failed to load glTF: " << fastgltf::getErrorMessage(asset.error()) << '\n';
return false;
Expand Down
Loading
Loading