Browse Source

Prevent double gltf json parsing

master
Riyyi 4 years ago
parent
commit
858a2bd0d4
  1. 21
      inferno/src/inferno/io/gltffile.cpp
  2. 2
      inferno/src/inferno/io/gltffile.h
  3. 23
      inferno/src/inferno/render/gltf.cpp
  4. 4
      inferno/src/inferno/render/gltf.h

21
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<char[]>, std::shared_ptr<char[]>> 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<char[]> 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

2
inferno/src/inferno/io/gltffile.h

@ -15,8 +15,6 @@ namespace Inferno {
private:
static std::pair<std::shared_ptr<char[]>, std::shared_ptr<char[]>> glb(const std::string& path);
static std::pair<std::shared_ptr<char[]>, uint32_t> readChunk(std::ifstream& ifstream, uint32_t offset, uint32_t type);
static std::pair<std::shared_ptr<char[]>, std::shared_ptr<char[]>> gltf(const std::string& path);
};
} // namespace Inferno

23
inferno/src/inferno/render/gltf.cpp

@ -1,11 +1,14 @@
#include <algorithm> // std::copy
#include <utility> // 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<uint32_t, std::shared_ptr<char[]>>* 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);

4
inferno/src/inferno/render/gltf.h

@ -97,6 +97,8 @@ namespace Inferno {
std::vector<Accessor> accessors;
std::vector<BufferView> bufferViews;
std::vector<Buffer> buffers;
std::map<uint32_t, std::shared_ptr<char[]>> 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<uint32_t, std::shared_ptr<char[]>>* data);
std::string m_path;
glTF::Model m_model;

Loading…
Cancel
Save