Skip to content

Commit

Permalink
Fix #48: Allow exporting ByteView in GLB & catch file write errors
Browse files Browse the repository at this point in the history
  • Loading branch information
spnda committed Feb 29, 2024
1 parent f8ed5a0 commit d133ae9
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Additionally, this is a list of some interesting projects using fastgltf:
- [Fwog](https://github.com/JuanDiegoMontoya/Fwog): The examples of this modern OpenGL 4.6 abstraction make use of fastgltf.
- [wad2gltf](https://github.com/DethRaid/wad2gltf): A WAD to glTF converter
- [Castor3D](https://github.com/DragonJoker/Castor3D): A multi-OS 3D engine
- [Raz](https://github.com/Razakhel/RaZ): A modern & multiplatform 3D game engine in C++17


## License
Expand Down
2 changes: 2 additions & 0 deletions docs/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ Additionally, this is a list of some interesting projects using fastgltf:
- `Fwog <https://github.com/JuanDiegoMontoya/Fwog>`_: The examples of this modern OpenGL 4.6 abstraction make use of fastgltf.
- `wad2gltf <https://github.com/DethRaid/wad2gltf>`_: A WAD to glTF converter
- `Castor3D <https://github.com/DragonJoker/Castor3D>`_: A multi-OS 3D engine
- `Raz <https://github.com/Razakhel/RaZ>`_: A modern & multiplatform 3D game engine in C++17



.. _accessor-tools:
Expand Down
3 changes: 3 additions & 0 deletions include/fastgltf/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ namespace fastgltf {
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.
FailedWritingFiles = 13, ///< The exporter failed to write some files (buffers/images) to disk.
};

inline std::string_view getErrorName(Error error) {
Expand All @@ -104,6 +105,7 @@ namespace fastgltf {
case Error::UnsupportedVersion: return "UnsupportedVersion";
case Error::InvalidURI: return "InvalidURI";
case Error::InvalidFileData: return "InvalidFileData";
case Error::FailedWritingFiles: return "FailedWritingFiles";
default: FASTGLTF_UNREACHABLE
}
}
Expand All @@ -123,6 +125,7 @@ namespace fastgltf {
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.";
case Error::FailedWritingFiles: return "The exporter failed to write some files (buffers/images) to disk.";
default: FASTGLTF_UNREACHABLE
}
}
Expand Down
62 changes: 42 additions & 20 deletions src/fastgltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4205,6 +4205,10 @@ void fg::Exporter::writeBuffers(const Asset& asset, std::string& json) {
bufferPaths.emplace_back(path);
},
[&](const sources::ByteView& view) {
if (bufferIdx == 0 && exportingBinary) {
bufferPaths.emplace_back(std::nullopt);
return;
}
auto path = getBufferFilePath(asset, bufferIdx);
json += std::string(R"("uri":")") + fg::escapeString(path.string()) + '"' + ',';
bufferPaths.emplace_back(path);
Expand Down Expand Up @@ -5436,46 +5440,60 @@ fg::Expected<fg::ExportResult<std::vector<std::byte>>> fg::Exporter::writeGltfBi
}

namespace fastgltf {
void writeFile(const DataSource& dataSource, fs::path baseFolder, fs::path filePath) {
std::visit(visitor {
[](auto& arg) {},
bool writeFile(const DataSource& dataSource, fs::path baseFolder, fs::path filePath) {
return std::visit(visitor {
[](auto& arg) {
return false;
},
[&](const sources::Array& vector) {
std::ofstream file(baseFolder / filePath, std::ios::out | std::ios::binary);
if (!file.is_open())
return false;
file.write(reinterpret_cast<const char *>(vector.bytes.data()),
static_cast<std::streamsize>(vector.bytes.size()));
file.close();
return file.good();
},
[&](const sources::Vector& vector) {
std::ofstream file(baseFolder / filePath, std::ios::out | std::ios::binary);
if (!file.is_open())
return false;
file.write(reinterpret_cast<const char *>(vector.bytes.data()),
static_cast<std::streamsize>(vector.bytes.size()));
file.close();
return file.good();
},
[&](const sources::ByteView& view) {
std::ofstream file(baseFolder / filePath, std::ios::out | std::ios::binary);
if (!file.is_open())
return false;
file.write(reinterpret_cast<const char *>(view.bytes.data()),
static_cast<std::streamsize>(view.bytes.size()));
file.close();
return file.good();
},
}, dataSource);
}

template<typename T>
void writeFiles(const Asset& asset, ExportResult<T> &result, fs::path baseFolder) {
for (std::size_t i = 0; i < asset.buffers.size(); ++i) {
auto &path = result.bufferPaths[i];
if (path.has_value()) {
writeFile(asset.buffers[i].data, baseFolder, path.value());
}
}
template<typename T>
bool writeFiles(const Asset& asset, ExportResult<T> &result, fs::path baseFolder) {
for (std::size_t i = 0; i < asset.buffers.size(); ++i) {
auto &path = result.bufferPaths[i];
if (path.has_value()) {
if (!writeFile(asset.buffers[i].data, baseFolder, path.value()))
return false;
}
}

for (std::size_t i = 0; i < asset.images.size(); ++i) {
auto &path = result.imagePaths[i];
if (path.has_value()) {
writeFile(asset.images[i].data, baseFolder, path.value());
}
}
}
for (std::size_t i = 0; i < asset.images.size(); ++i) {
auto &path = result.imagePaths[i];
if (path.has_value()) {
if (!writeFile(asset.images[i].data, baseFolder, path.value()))
return false;
}
}
return true;
}
} // namespace fastgltf

fg::Error fg::FileExporter::writeGltfJson(const Asset& asset, std::filesystem::path target, ExportOptions options) {
Expand All @@ -5494,7 +5512,9 @@ fg::Error fg::FileExporter::writeGltfJson(const Asset& asset, std::filesystem::p
file << result.output;
file.close();

writeFiles(asset, result, target.parent_path());
if (!writeFiles(asset, result, target.parent_path())) {
return Error::FailedWritingFiles;
}
return Error::None;
}

Expand All @@ -5514,7 +5534,9 @@ fg::Error fg::FileExporter::writeGltfBinary(const Asset& asset, std::filesystem:
file.write(reinterpret_cast<const char*>(result.output.data()),
static_cast<std::streamsize>(result.output.size()));

writeFiles(asset, result, target.parent_path());
if (!writeFiles(asset, result, target.parent_path())) {
return Error::FailedWritingFiles;
}
return Error::None;
}
#pragma endregion
Expand Down

0 comments on commit d133ae9

Please sign in to comment.