diff --git a/inferno/src/inferno/io/gltffile.cpp b/inferno/src/inferno/io/gltffile.cpp index 35c55dd..42145fe 100644 --- a/inferno/src/inferno/io/gltffile.cpp +++ b/inferno/src/inferno/io/gltffile.cpp @@ -19,7 +19,7 @@ namespace Inferno { return glb(path); } else if (extension.compare(".gltf") == 0) { - return gltf(path); + return { File::raw(path), nullptr }; } ASSERT(false, "GltfFile unknown file extension!"); @@ -100,23 +100,4 @@ namespace Inferno { return { chunkData, chunkLengthInt }; } - std::pair, std::shared_ptr> GltfFile::gltf(const std::string& path) - { - auto jsonContent = File::raw(path); - - json json = json::parse(jsonContent.get()); - ASSERT(Json::hasProperty(json, "buffers"), "GltfFile missing required property 'buffers'"); - - std::shared_ptr binaryContent { nullptr }; - for (auto& [key, buffer] : json["buffers"].items()) { - auto uri = Json::parseStringProperty(buffer, "uri", true); - ASSERT(uri, "GltfFile missing required property 'uri'"); - ASSERT(uri.value().find("data:", 0) == std::string::npos, "GltfFile embedded binary data is unsupported"); - binaryContent = File::raw("assets/gltf/" + uri.value()); - break; - } - - return { jsonContent, binaryContent }; - } - } // namespace Inferno diff --git a/inferno/src/inferno/io/gltffile.h b/inferno/src/inferno/io/gltffile.h index 2a582fa..b24cf2f 100644 --- a/inferno/src/inferno/io/gltffile.h +++ b/inferno/src/inferno/io/gltffile.h @@ -15,8 +15,6 @@ namespace Inferno { private: static std::pair, std::shared_ptr> glb(const std::string& path); static std::pair, uint32_t> readChunk(std::ifstream& ifstream, uint32_t offset, uint32_t type); - - static std::pair, std::shared_ptr> gltf(const std::string& path); }; } // namespace Inferno diff --git a/inferno/src/inferno/render/gltf.cpp b/inferno/src/inferno/render/gltf.cpp index 7554705..f98d74d 100644 --- a/inferno/src/inferno/render/gltf.cpp +++ b/inferno/src/inferno/render/gltf.cpp @@ -1,11 +1,14 @@ #include // std::copy +#include // std::move #include "nlohmann/json.hpp" #include "inferno/assert.h" +#include "inferno/io/file.h" #include "inferno/io/gltffile.h" #include "inferno/io/log.h" #include "inferno/render/gltf.h" +#include "inferno/util/integer.h" namespace Inferno { @@ -13,10 +16,15 @@ namespace Inferno { : m_path(path) { auto gltf = GltfFile::read(path); - ASSERT(gltf.first && gltf.second, "GlTF model was incomplete '{}'", path); + ASSERT(gltf.first, "Gltf model invalid JSON content '{}'", path); json json = json::parse(gltf.first.get()); + // Add binary data from .glb files + if (gltf.second) { + m_model.data.emplace(0, std::move(gltf.second)); + } + // Properties // Asset @@ -113,10 +121,11 @@ namespace Inferno { for (auto& [key, object] : buffers.items()) { glTF::Buffer buffer; - parseBuffer(&buffer, key, object); + parseBuffer(&buffer, key, object, &m_model.data); m_model.buffers.emplace_back(std::move(buffer)); } } + } Gltf::~Gltf() @@ -307,9 +316,15 @@ namespace Inferno { bufferView->name = name ? name.value() : key; } - void Gltf::parseBuffer(glTF::Buffer* buffer, const std::string& key, const json& object) + void Gltf::parseBuffer(glTF::Buffer* buffer, const std::string& key, const json& object, std::map>* data) { - auto uri = Json::parseStringProperty(object, "buffer", false); + auto uri = Json::parseStringProperty(object, "uri", false); + + // Load external binary data + if (uri) { + ASSERT(uri.value().find("data:", 0) == std::string::npos, "GltfFile embedded binary data is unsupported"); + data->emplace(std::stou(key), File::raw("assets/gltf/" + uri.value())); + } auto byteLength = Json::parseUnsignedProperty(object, "byteLength", true); ASSERT(byteLength, "Gltf buffer '{}' missing required property 'byteLength'", key); diff --git a/inferno/src/inferno/render/gltf.h b/inferno/src/inferno/render/gltf.h index 27d742e..05da7d3 100644 --- a/inferno/src/inferno/render/gltf.h +++ b/inferno/src/inferno/render/gltf.h @@ -97,6 +97,8 @@ namespace Inferno { std::vector accessors; std::vector bufferViews; std::vector buffers; + + std::map> data; }; } // namespace glTF @@ -118,7 +120,7 @@ namespace Inferno { static void parseMesh(glTF::Mesh* mesh, const std::string& key, const json& object); static void parseAccessor(glTF::Accessor* accessor, const std::string& key, const json& object); static void parseBufferView(glTF::BufferView* bufferView, const std::string& key, const json& object); - static void parseBuffer(glTF::Buffer* buffer, const std::string& key, const json& object); + static void parseBuffer(glTF::Buffer* buffer, const std::string& key, const json& object, std::map>* data); std::string m_path; glTF::Model m_model;