Skip to content

Commit

Permalink
Change: Combine loadGLTF and loadBinaryGLTF
Browse files Browse the repository at this point in the history
  • Loading branch information
spnda committed Dec 30, 2023
1 parent a2bb23a commit 9976fc9
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 68 deletions.
8 changes: 4 additions & 4 deletions docs/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,10 @@ The following snippet illustrates how to use fastgltf to load a glTF file.
fastgltf::GltfDataBuffer data;
data.loadFromFile(path);

// This loads the glTF file into the gltf object and parses the JSON. For GLB files, use
// Parser::loadBinaryGLTF instead.
// You can detect the type of glTF using fastgltf::determineGltfFileType.
auto asset = parser.loadGLTF(&data, path.parent_path(), fastgltf::Options::None);
// 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);
if (auto error = asset.error(); error != fastgltf::Error::None) {
// Some error occurred while reading the buffer, parsing the JSON, or validating the data.
}
Expand Down
12 changes: 1 addition & 11 deletions examples/gl_viewer/gl_viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,17 +305,7 @@ bool loadGltf(Viewer* viewer, std::string_view cPath) {
fastgltf::GltfDataBuffer data;
data.loadFromFile(path);

auto type = fastgltf::determineGltfFileType(&data);
fastgltf::Expected<fastgltf::Asset> asset(fastgltf::Error::None);
if (type == fastgltf::GltfType::glTF) {
asset = parser.loadGLTF(&data, path.parent_path(), gltfOptions);
} else if (type == fastgltf::GltfType::GLB) {
asset = parser.loadBinaryGLTF(&data, path.parent_path(), gltfOptions);
} else {
std::cerr << "Failed to determine glTF container" << '\n';
return false;
}

auto asset = parser.loadGltf(&data, 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
22 changes: 18 additions & 4 deletions include/fastgltf/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ namespace fastgltf {
MissingExternalBuffer = 9, ///< With Options::LoadExternalBuffers, an external buffer was not found.
UnsupportedVersion = 10, ///< The glTF version is not supported by fastgltf.
InvalidURI = 11, ///< A URI from a buffer or image failed to be parsed.
InvalidFileData = 12, ///< The file data is invalid, or the file type could not be determined.
};

inline std::string_view getErrorName(Error error) {
Expand All @@ -102,6 +103,7 @@ namespace fastgltf {
case Error::MissingExternalBuffer: return "MissingExternalBuffer";
case Error::UnsupportedVersion: return "UnsupportedVersion";
case Error::InvalidURI: return "InvalidURI";
case Error::InvalidFileData: return "InvalidFileData";
default: FASTGLTF_UNREACHABLE
}
}
Expand All @@ -120,6 +122,7 @@ namespace fastgltf {
case Error::MissingExternalBuffer: return "An external buffer was not found.";
case Error::UnsupportedVersion: return "The glTF version is not supported by fastgltf.";
case Error::InvalidURI: return "A URI from a buffer or image failed to be parsed.";
case Error::InvalidFileData: return "The file data is invalid, or the file type could not be determined.";
default: FASTGLTF_UNREACHABLE
}
}
Expand Down Expand Up @@ -541,7 +544,9 @@ namespace fastgltf {

/**
* This function starts reading into the buffer and tries to determine what type of glTF container it is.
* This should be used to know whether to call Parser::loadGLTF or Parser::loadBinaryGLTF.
* This should be used to know whether to call Parser::loadGltfJson or Parser::loadGltfBinary.
*
* @note Usually, you'll want to just use Parser::loadGltf, which will call this itself.
*
* @return The type of the glTF file, either glTF, GLB, or Invalid if it was not determinable. If this function
* returns Invalid it is highly likely that the buffer does not actually represent a valid glTF file.
Expand Down Expand Up @@ -585,7 +590,7 @@ namespace fastgltf {
/**
* Saves the pointer including its range. Does not copy any data. This requires the
* original allocation to outlive the parsing of the glTF, so after the last relevant
* call to fastgltf::Parser::loadGLTF. However, this function asks for a capacity size, as
* call to fastgltf::Parser::loadGltf. However, this function asks for a capacity size, as
* the JSON parsing requires some padding. See fastgltf::getGltfBufferPadding for more information.
* If the capacity does not have enough padding, the function will instead copy the bytes
* with the copyBytes method. Also, it will set the padding bytes all to 0, so be sure to
Expand Down Expand Up @@ -703,19 +708,28 @@ namespace fastgltf {

~Parser();

/**
* Loads a glTF file from pre-loaded bytes.
*
* This function tries to detect wether the bytes represent a standard JSON glTF or a binary glTF.
*
* @return An Asset wrapped in an Expected type, which may contain an error if one occurred.
*/
[[nodiscard]] Expected<Asset> loadGltf(GltfDataBuffer* buffer, std::filesystem::path directory, Options options = Options::None, Category categories = Category::All);

/**
* Loads a glTF file from pre-loaded bytes representing a JSON file.
*
* @return An Asset wrapped in an Expected type, which may contain an error if one occurred.
*/
[[nodiscard]] Expected<Asset> loadGLTF(GltfDataBuffer* buffer, std::filesystem::path directory, Options options = Options::None, Category categories = Category::All);
[[nodiscard]] Expected<Asset> loadGltfJson(GltfDataBuffer* buffer, std::filesystem::path directory, Options options = Options::None, Category categories = Category::All);

/**
* Loads a glTF file embedded within a GLB container, which may contain the first buffer of the glTF asset.
*
* @return An Asset wrapped in an Expected type, which may contain an error if one occurred.
*/
[[nodiscard]] Expected<Asset> loadBinaryGLTF(GltfDataBuffer* buffer, std::filesystem::path directory, Options options = Options::None, Category categories = Category::All);
[[nodiscard]] Expected<Asset> loadGltfBinary(GltfDataBuffer* buffer, std::filesystem::path directory, Options options = Options::None, Category categories = Category::All);

/**
* This function can be used to set callbacks so that you can control memory allocation for
Expand Down
2 changes: 1 addition & 1 deletion include/fastgltf/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ namespace fastgltf {
}

// We use geometric growth, similarly to std::vector.
newCapacity = std::size_t(1) << std::numeric_limits<decltype(newCapacity)>::digits - clz(newCapacity);
newCapacity = std::size_t(1) << (std::numeric_limits<decltype(newCapacity)>::digits - clz(newCapacity));

T* alloc = allocator.allocate(newCapacity);

Expand Down
22 changes: 18 additions & 4 deletions src/fastgltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3344,7 +3344,21 @@ fg::Parser& fg::Parser::operator=(Parser&& other) noexcept {

fg::Parser::~Parser() = default;

fg::Expected<fg::Asset> fg::Parser::loadGLTF(GltfDataBuffer* buffer, fs::path directory, Options options, Category categories) {
fg::Expected<fg::Asset> fg::Parser::loadGltf(GltfDataBuffer* buffer, fs::path directory, Options options, Category categories) {
auto type = fastgltf::determineGltfFileType(buffer);

if (type == fastgltf::GltfType::glTF) {
return loadGltfJson(buffer, std::move(directory), options, categories);
}

if (type == fastgltf::GltfType::GLB) {
return loadGltfBinary(buffer, std::move(directory), options, categories);
}

return Expected<Asset> { Error::InvalidFileData };
}

fg::Expected<fg::Asset> fg::Parser::loadGltfJson(GltfDataBuffer* buffer, fs::path directory, Options options, Category categories) {
using namespace simdjson;

// If we never have to load the files ourselves, we're fine with the directory being invalid/blank.
Expand All @@ -3353,7 +3367,7 @@ fg::Expected<fg::Asset> fg::Parser::loadGLTF(GltfDataBuffer* buffer, fs::path di
}

this->options = options;
this->directory = directory;
this->directory = std::move(directory);

// If we own the allocation of the JSON data, we'll try to minify the JSON, which, in most cases,
// will speed up the parsing by a small amount.
Expand All @@ -3377,7 +3391,7 @@ fg::Expected<fg::Asset> fg::Parser::loadGLTF(GltfDataBuffer* buffer, fs::path di
return parse(root, categories);
}

fg::Expected<fg::Asset> fg::Parser::loadBinaryGLTF(GltfDataBuffer* buffer, fs::path directory, Options options, Category categories) {
fg::Expected<fg::Asset> fg::Parser::loadGltfBinary(GltfDataBuffer* buffer, fs::path directory, Options options, Category categories) {
using namespace simdjson;

// If we never have to load the files ourselves, we're fine with the directory being invalid/blank.
Expand All @@ -3386,7 +3400,7 @@ fg::Expected<fg::Asset> fg::Parser::loadBinaryGLTF(GltfDataBuffer* buffer, fs::p
}

this->options = options;
this->directory = directory;
this->directory = std::move(directory);

std::size_t offset = 0UL;
auto read = [&buffer, &offset](void* dst, std::size_t size) mutable {
Expand Down
4 changes: 2 additions & 2 deletions tests/accessor_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ TEST_CASE("Test accessor", "[gltf-tools]") {
REQUIRE(jsonData.loadFromFile(lightsLamp / "LightsPunctualLamp.gltf"));

fastgltf::Parser parser(fastgltf::Extensions::KHR_lights_punctual);
auto asset = parser.loadGLTF(&jsonData, lightsLamp, fastgltf::Options::LoadExternalBuffers,
auto asset = parser.loadGltfJson(&jsonData, lightsLamp, fastgltf::Options::LoadExternalBuffers,
fastgltf::Category::Buffers | fastgltf::Category::BufferViews | fastgltf::Category::Accessors);
REQUIRE(asset.error() == fastgltf::Error::None);

Expand Down Expand Up @@ -133,7 +133,7 @@ TEST_CASE("Test sparse accessor", "[gltf-tools]") {
REQUIRE(jsonData->loadFromFile(simpleSparseAccessor / "SimpleSparseAccessor.gltf"));

fastgltf::Parser parser;
auto asset = parser.loadGLTF(jsonData.get(), simpleSparseAccessor, fastgltf::Options::LoadExternalBuffers,
auto asset = parser.loadGltfJson(jsonData.get(), simpleSparseAccessor, fastgltf::Options::LoadExternalBuffers,
fastgltf::Category::Buffers | fastgltf::Category::BufferViews | fastgltf::Category::Accessors);
REQUIRE(asset.error() == fastgltf::Error::None);

Expand Down
4 changes: 2 additions & 2 deletions tests/base64_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ TEST_CASE("Test base64 buffer decoding", "[base64]") {
REQUIRE(btJsonData->loadFromFile(boxTextured / "BoxTextured.gltf"));

SECTION("Validate large buffer load from glTF") {
auto asset = parser.loadGLTF(tceJsonData.get(), cylinderEngine, fastgltf::Options::None, fastgltf::Category::Buffers);
auto asset = parser.loadGltfJson(tceJsonData.get(), cylinderEngine, fastgltf::Options::None, fastgltf::Category::Buffers);
REQUIRE(asset.error() == fastgltf::Error::None);

REQUIRE(asset->buffers.size() == 1);
Expand All @@ -93,7 +93,7 @@ TEST_CASE("Test base64 buffer decoding", "[base64]") {
}

SECTION("Validate base64 buffer and image load from glTF") {
auto asset = parser.loadGLTF(btJsonData.get(), boxTextured, fastgltf::Options::None, fastgltf::Category::Images | fastgltf::Category::Buffers);
auto asset = parser.loadGltfJson(btJsonData.get(), boxTextured, fastgltf::Options::None, fastgltf::Category::Images | fastgltf::Category::Buffers);
REQUIRE(asset.error() == fastgltf::Error::None);

REQUIRE(asset->buffers.size() == 1);
Expand Down
Loading

0 comments on commit 9976fc9

Please sign in to comment.