Skip to content

Commit

Permalink
Add embedded GLB buffer & customization
Browse files Browse the repository at this point in the history
  • Loading branch information
spnda committed Jan 2, 2024
1 parent a902b3a commit ee3a673
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
7 changes: 7 additions & 0 deletions include/fastgltf/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,8 @@ namespace fastgltf {
protected:
Error errorCode = Error::None;

Optional<std::size_t> binaryBufferIndex = 0;

std::filesystem::path bufferFolder = "";
std::filesystem::path imageFolder = "";

Expand Down Expand Up @@ -844,6 +846,11 @@ namespace fastgltf {
*/
void setImagePath(std::filesystem::path folder);

/**
* Sets the index of the buffer that should be embedded into the GLB file.
*/
void setBinaryBufferIndex(std::size_t idx);

/**
* Converts the Asset into a glTF JSON string.
*/
Expand Down
33 changes: 30 additions & 3 deletions src/fastgltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3574,6 +3574,10 @@ void fg::Exporter::setImagePath(std::filesystem::path folder) {
imageFolder = std::move(folder);
}

void fg::Exporter::setBinaryBufferIndex(std::size_t idx) {
binaryBufferIndex = idx;
}

void fg::Exporter::writeAccessors(const Asset& asset, std::string& json) {
if (asset.accessors.empty())
return;
Expand Down Expand Up @@ -3639,13 +3643,17 @@ void fg::Exporter::writeBuffers(const Asset& asset, std::string& json) {
for (auto it = asset.buffers.begin(); it != asset.buffers.end(); ++it) {
json += '{';

auto bufferIdx = std::distance(asset.buffers.begin(), it);
auto bufferIdx = static_cast<std::size_t>(std::distance(asset.buffers.begin(), it));
std::visit(visitor {
[&](auto arg) {
// Covers BufferView and CustomBuffer.
errorCode = Error::InvalidGltf;
},
[&](const sources::Vector& vector) {
if (binaryBufferIndex.has_value() && binaryBufferIndex.value() == bufferIdx) {
bufferPaths.emplace_back(std::nullopt);
return;
}
auto path = getBufferFilePath(asset, bufferIdx);
json += std::string(R"("uri":")") + path.string() + '"' + ',';
bufferPaths.emplace_back(path);
Expand Down Expand Up @@ -4370,6 +4378,11 @@ fg::Expected<fg::ExportResult<std::vector<std::byte>>> fg::Exporter::writeGltfBi

ExportResult<std::vector<std::byte>> result;

if (!binaryBufferIndex.has_value()) {
binaryBufferIndex = 0;
}
const std::size_t bufferIndex = binaryBufferIndex.value();

// Generate the JSON.
auto expected = writeGltfJson(asset, options);
if (expected.error() != Error::None) {
Expand All @@ -4379,8 +4392,10 @@ fg::Expected<fg::ExportResult<std::vector<std::byte>>> fg::Exporter::writeGltfBi
result.bufferPaths = std::move(json.bufferPaths);
result.imagePaths = std::move(json.imagePaths);

const bool withEmbeddedBuffer = false;
//const bool withEmbeddedBuffer = !asset.buffers.empty() || asset.buffers.front().byteLength < std::numeric_limits<std::uint32_t>::max();
const bool withEmbeddedBuffer = bufferIndex < asset.buffers.size()
&& std::get_if<sources::Vector>(&asset.buffers[bufferIndex].data) != nullptr // We only support writing Vectors as embedded buffers
&& asset.buffers[bufferIndex].byteLength < std::numeric_limits<decltype(BinaryGltfChunk::chunkLength)>::max();

std::size_t binarySize = sizeof(BinaryGltfHeader) + sizeof(BinaryGltfChunk) + json.output.size();
if (withEmbeddedBuffer) {
binarySize += sizeof(BinaryGltfChunk) + asset.buffers.front().byteLength;
Expand All @@ -4405,6 +4420,18 @@ fg::Expected<fg::ExportResult<std::vector<std::byte>>> fg::Exporter::writeGltfBi

write(json.output.data(), json.output.size() * sizeof(decltype(json.output)::value_type));

if (withEmbeddedBuffer) {
const auto& buffer = asset.buffers[bufferIndex];

BinaryGltfChunk dataChunk;
dataChunk.chunkType = binaryGltfDataChunkMagic;
dataChunk.chunkLength = buffer.byteLength;
write(&dataChunk, sizeof dataChunk);

const auto* vector = std::get_if<sources::Vector>(&buffer.data);
write(vector->bytes.data(), buffer.byteLength);
}

return Expected { std::move(result) };
}

Expand Down

0 comments on commit ee3a673

Please sign in to comment.