Support loading GLB assets
This commit is contained in:
parent
00231ce3f6
commit
c3d964fafd
2 changed files with 57 additions and 1 deletions
|
|
@ -140,6 +140,8 @@ namespace psemek::gfx
|
|||
{
|
||||
std::size_t length;
|
||||
std::string uri;
|
||||
|
||||
std::optional<util::blob> data; // for GLB buffer
|
||||
};
|
||||
|
||||
// KHR_lights_punctual
|
||||
|
|
@ -184,6 +186,7 @@ namespace psemek::gfx
|
|||
};
|
||||
|
||||
gltf_asset parse_gltf(io::istream && stream);
|
||||
gltf_asset parse_glb(io::istream && stream);
|
||||
|
||||
std::size_t attribute_size(gltf_asset::accessor::type_t type);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <psemek/geom/translation.hpp>
|
||||
#include <psemek/util/to_string.hpp>
|
||||
#include <psemek/util/exception.hpp>
|
||||
#include <psemek/io/memory_stream.hpp>
|
||||
#include <psemek/log/log.hpp>
|
||||
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
|
|
@ -378,7 +379,9 @@ namespace psemek::gfx
|
|||
auto & target = result.buffers.emplace_back();
|
||||
|
||||
target.length = buffer["byteLength"].GetUint64();
|
||||
target.uri = buffer["uri"].GetString();
|
||||
|
||||
if (buffer.HasMember("uri"))
|
||||
target.uri = buffer["uri"].GetString();
|
||||
}
|
||||
|
||||
if (document.HasMember("extensions")) for (auto const & extension : document["extensions"].GetObject())
|
||||
|
|
@ -451,6 +454,56 @@ namespace psemek::gfx
|
|||
return result;
|
||||
}
|
||||
|
||||
gltf_asset parse_glb(io::istream && stream)
|
||||
{
|
||||
std::uint32_t magic, version, length;
|
||||
stream.read_all((char *)&magic, 4);
|
||||
stream.read_all((char *)&version, 4);
|
||||
stream.read_all((char *)&length, 4);
|
||||
|
||||
if (magic != 0x46546c67u)
|
||||
throw std::runtime_error("Error parsing GLB magic");
|
||||
|
||||
if (version != 2)
|
||||
throw std::runtime_error("Unknown GLB file version");
|
||||
|
||||
length -= 12;
|
||||
|
||||
gltf_asset result;
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
std::uint32_t chunk_length, chunk_type;
|
||||
stream.read_all((char *)&chunk_length, 4);
|
||||
stream.read_all((char *)&chunk_type, 4);
|
||||
|
||||
util::blob data(chunk_length);
|
||||
stream.read_all(data.data(), chunk_length);
|
||||
|
||||
length -= 8;
|
||||
length -= chunk_length;
|
||||
|
||||
if (chunk_type == 0x4e4f534au)
|
||||
{
|
||||
result = parse_gltf(io::memory_istream(data.begin(), data.end()));
|
||||
}
|
||||
else if (chunk_type == 0x004e4942u)
|
||||
{
|
||||
if (result.buffers.empty())
|
||||
throw std::runtime_error("Error parsing GLB: glTF chunk has no buffers");
|
||||
|
||||
if (!result.buffers[0].uri.empty())
|
||||
throw std::runtime_error("Error parsing GLB: first glTF buffer has URI");
|
||||
|
||||
result.buffers[0].data = std::move(data);
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("Error parsing GLB: unknown chunk type");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::size_t attribute_size(gltf_asset::accessor::type_t type)
|
||||
{
|
||||
using type_t = gltf_asset::accessor::type_t;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue