|
|
|
@ -3,8 +3,8 @@
|
|
|
|
|
#include <utility> // std::move |
|
|
|
|
|
|
|
|
|
#include "nlohmann/json.hpp" |
|
|
|
|
#include "ruc/meta/assert.h" |
|
|
|
|
|
|
|
|
|
#include "inferno/assert.h" |
|
|
|
|
#include "inferno/io/file.h" |
|
|
|
|
#include "inferno/io/gltffile.h" |
|
|
|
|
#include "inferno/io/log.h" |
|
|
|
@ -17,7 +17,7 @@ namespace Inferno {
|
|
|
|
|
: m_path(std::move(path)) |
|
|
|
|
{ |
|
|
|
|
auto gltf = GltfFile::read(path); |
|
|
|
|
ASSERT(gltf.first, "Gltf model invalid JSON content '{}'", path); |
|
|
|
|
VERIFY(gltf.first, "Gltf model invalid JSON content '{}'", path); |
|
|
|
|
|
|
|
|
|
json json = json::parse(gltf.first.get()); |
|
|
|
|
|
|
|
|
@ -31,9 +31,9 @@ namespace Inferno {
|
|
|
|
|
// Asset
|
|
|
|
|
// ---------------------------------
|
|
|
|
|
|
|
|
|
|
ASSERT(Json::hasProperty(json, "asset"), "GlTF model missing required property 'asset'"); |
|
|
|
|
VERIFY(Json::hasProperty(json, "asset"), "GlTF model missing required property 'asset'"); |
|
|
|
|
auto asset = json["asset"]; |
|
|
|
|
ASSERT(asset.is_object(), "Gltf model invalid property type 'asset'"); |
|
|
|
|
VERIFY(asset.is_object(), "Gltf model invalid property type 'asset'"); |
|
|
|
|
|
|
|
|
|
parseAsset(&m_model.asset, asset); |
|
|
|
|
|
|
|
|
@ -43,7 +43,7 @@ namespace Inferno {
|
|
|
|
|
if (Json::hasProperty(json, "scenes")) { |
|
|
|
|
|
|
|
|
|
auto scenes = json["scenes"]; |
|
|
|
|
ASSERT(scenes.is_array(), "Gltf model invalid property type 'scenes'"); |
|
|
|
|
VERIFY(scenes.is_array(), "Gltf model invalid property type 'scenes'"); |
|
|
|
|
|
|
|
|
|
for (auto& [key, object] : scenes.items()) { |
|
|
|
|
glTF::Scene scene; |
|
|
|
@ -58,7 +58,7 @@ namespace Inferno {
|
|
|
|
|
if (Json::hasProperty(json, "nodes")) { |
|
|
|
|
|
|
|
|
|
auto nodes = json["nodes"]; |
|
|
|
|
ASSERT(nodes.is_array(), "Gltf model invalid property type 'nodes'"); |
|
|
|
|
VERIFY(nodes.is_array(), "Gltf model invalid property type 'nodes'"); |
|
|
|
|
|
|
|
|
|
for (auto& [key, object] : nodes.items()) { |
|
|
|
|
glTF::Node node; |
|
|
|
@ -73,7 +73,7 @@ namespace Inferno {
|
|
|
|
|
if (Json::hasProperty(json, "meshes")) { |
|
|
|
|
|
|
|
|
|
auto meshes = json["meshes"]; |
|
|
|
|
ASSERT(meshes.is_array(), "Gltf model invalid property type 'meshes'"); |
|
|
|
|
VERIFY(meshes.is_array(), "Gltf model invalid property type 'meshes'"); |
|
|
|
|
|
|
|
|
|
for (auto& [key, object] : meshes.items()) { |
|
|
|
|
glTF::Mesh mesh; |
|
|
|
@ -88,7 +88,7 @@ namespace Inferno {
|
|
|
|
|
if (Json::hasProperty(json, "accessors")) { |
|
|
|
|
|
|
|
|
|
auto accessors = json["accessors"]; |
|
|
|
|
ASSERT(accessors.is_array(), "Gltf model invalid property type 'accessors'"); |
|
|
|
|
VERIFY(accessors.is_array(), "Gltf model invalid property type 'accessors'"); |
|
|
|
|
|
|
|
|
|
for (auto& [key, object] : accessors.items()) { |
|
|
|
|
glTF::Accessor accessor; |
|
|
|
@ -103,7 +103,7 @@ namespace Inferno {
|
|
|
|
|
if (Json::hasProperty(json, "bufferViews")) { |
|
|
|
|
|
|
|
|
|
auto bufferViews = json["bufferViews"]; |
|
|
|
|
ASSERT(bufferViews.is_array(), "Gltf model invalid property type 'bufferViews'"); |
|
|
|
|
VERIFY(bufferViews.is_array(), "Gltf model invalid property type 'bufferViews'"); |
|
|
|
|
|
|
|
|
|
for (auto& [key, object] : bufferViews.items()) { |
|
|
|
|
glTF::BufferView bufferView; |
|
|
|
@ -118,7 +118,7 @@ namespace Inferno {
|
|
|
|
|
if (Json::hasProperty(json, "buffers")) { |
|
|
|
|
|
|
|
|
|
auto buffers = json["buffers"]; |
|
|
|
|
ASSERT(buffers.is_array(), "Gltf model invalid property type 'buffers'"); |
|
|
|
|
VERIFY(buffers.is_array(), "Gltf model invalid property type 'buffers'"); |
|
|
|
|
|
|
|
|
|
for (auto& [key, object] : buffers.items()) { |
|
|
|
|
glTF::Buffer buffer; |
|
|
|
@ -140,8 +140,8 @@ namespace Inferno {
|
|
|
|
|
auto generator = Json::parseStringProperty(object, "generator", false); |
|
|
|
|
|
|
|
|
|
auto version = Json::parseStringProperty(object, "version", true); |
|
|
|
|
ASSERT(version, "GlTF model missing required property 'version'"); |
|
|
|
|
ASSERT(version.value().compare("2.0") == 0, "GlTF version unsupported '{}'", version.value()); |
|
|
|
|
VERIFY(version, "GlTF model missing required property 'version'"); |
|
|
|
|
VERIFY(version.value().compare("2.0") == 0, "GlTF version unsupported '{}'", version.value()); |
|
|
|
|
|
|
|
|
|
auto minVersion = Json::parseStringProperty(object, "minVersion", false); |
|
|
|
|
|
|
|
|
@ -154,7 +154,7 @@ namespace Inferno {
|
|
|
|
|
void Gltf::parseScene(glTF::Scene* scene, const std::string& key, const json& object) |
|
|
|
|
{ |
|
|
|
|
auto nodes = Json::parseFloatArrayProperty(object, "nodes", false); |
|
|
|
|
ASSERT(!nodes || nodes.value().size() > 0, "Gltf scene '{}' empty 'nodes' property", key); |
|
|
|
|
VERIFY(!nodes || nodes.value().size() > 0, "Gltf scene '{}' empty 'nodes' property", key); |
|
|
|
|
|
|
|
|
|
auto name = Json::parseStringProperty(object, "name", false); |
|
|
|
|
|
|
|
|
@ -166,26 +166,26 @@ namespace Inferno {
|
|
|
|
|
auto camera = Json::parseUnsignedProperty(object, "camera", false); |
|
|
|
|
|
|
|
|
|
auto children = Json::parseUnsignedArrayProperty(object, "children", false); |
|
|
|
|
ASSERT(!children || children.value().size() > 0, "Gltf node '{}' empty property 'children'", key); |
|
|
|
|
VERIFY(!children || children.value().size() > 0, "Gltf node '{}' empty property 'children'", key); |
|
|
|
|
|
|
|
|
|
auto skin = Json::parseUnsignedProperty(object, "skin", false); |
|
|
|
|
|
|
|
|
|
auto matrix = Json::parseFloatArrayProperty(object, "matrix", false); |
|
|
|
|
ASSERT(!matrix || matrix.value().size() == 16, "Gltf node '{}' property 'matrix' invalid size", key); |
|
|
|
|
VERIFY(!matrix || matrix.value().size() == 16, "Gltf node '{}' property 'matrix' invalid size", key); |
|
|
|
|
|
|
|
|
|
auto mesh = Json::parseUnsignedProperty(object, "mesh", false); |
|
|
|
|
|
|
|
|
|
auto rotation = Json::parseFloatArrayProperty(object, "rotation", false); |
|
|
|
|
ASSERT(!rotation || rotation.value().size() == 4, "Gltf node '{}' property 'rotation' invalid size", key); |
|
|
|
|
VERIFY(!rotation || rotation.value().size() == 4, "Gltf node '{}' property 'rotation' invalid size", key); |
|
|
|
|
|
|
|
|
|
auto scale = Json::parseFloatArrayProperty(object, "scale", false); |
|
|
|
|
ASSERT(!scale || scale.value().size() == 3, "Gltf node '{}' property 'scale' invalid size", key); |
|
|
|
|
VERIFY(!scale || scale.value().size() == 3, "Gltf node '{}' property 'scale' invalid size", key); |
|
|
|
|
|
|
|
|
|
auto translation = Json::parseFloatArrayProperty(object, "translation", false); |
|
|
|
|
ASSERT(!translation || translation.value().size() == 3, "Gltf node '{}' property 'translation' invalid size", key); |
|
|
|
|
VERIFY(!translation || translation.value().size() == 3, "Gltf node '{}' property 'translation' invalid size", key); |
|
|
|
|
|
|
|
|
|
auto weights = Json::parseFloatArrayProperty(object, "weights", false); |
|
|
|
|
ASSERT(!weights || weights.value().size() > 0, "Gltf node '{}' empty property 'weights'", key); |
|
|
|
|
VERIFY(!weights || weights.value().size() > 0, "Gltf node '{}' empty property 'weights'", key); |
|
|
|
|
|
|
|
|
|
auto name = Json::parseStringProperty(object, "name", false); |
|
|
|
|
|
|
|
|
@ -204,7 +204,7 @@ namespace Inferno {
|
|
|
|
|
void Gltf::parsePrimitive(glTF::Primitive* primitive, const std::string& key, const json& object) |
|
|
|
|
{ |
|
|
|
|
auto attributes = Json::parseUnsignedObjectProperty(object, "attributes", true); |
|
|
|
|
ASSERT(attributes && attributes.value().size() > 0, "Gltf primitive '{}' empty property 'attributes'", key); |
|
|
|
|
VERIFY(attributes && attributes.value().size() > 0, "Gltf primitive '{}' empty property 'attributes'", key); |
|
|
|
|
|
|
|
|
|
auto indices = Json::parseUnsignedProperty(object, "indices", false); |
|
|
|
|
|
|
|
|
@ -215,7 +215,7 @@ namespace Inferno {
|
|
|
|
|
if (Json::hasProperty(object, "targets")) { |
|
|
|
|
|
|
|
|
|
auto targets = object["targets"]; |
|
|
|
|
ASSERT(targets.is_array(), "Gltf primitive '{}' property 'targets' invalid type", key); |
|
|
|
|
VERIFY(targets.is_array(), "Gltf primitive '{}' property 'targets' invalid type", key); |
|
|
|
|
|
|
|
|
|
for (auto& targetObject : targets) { |
|
|
|
|
|
|
|
|
@ -226,7 +226,7 @@ namespace Inferno {
|
|
|
|
|
if (value) target.emplace(std::move(key), value.value()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ASSERT(target.size() > 0, "Gltf primitive '{}' empty 'target' object", key); |
|
|
|
|
VERIFY(target.size() > 0, "Gltf primitive '{}' empty 'target' object", key); |
|
|
|
|
primitive->targets.emplace_back(std::move(target)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -239,9 +239,9 @@ namespace Inferno {
|
|
|
|
|
|
|
|
|
|
void Gltf::parseMesh(glTF::Mesh* mesh, const std::string& key, const json& object) |
|
|
|
|
{ |
|
|
|
|
ASSERT(Json::hasProperty(object, "primitives"), "Gltf mesh '{}' missing required property 'primitives'", key); |
|
|
|
|
VERIFY(Json::hasProperty(object, "primitives"), "Gltf mesh '{}' missing required property 'primitives'", key); |
|
|
|
|
auto primitives = object["primitives"]; |
|
|
|
|
ASSERT(primitives.is_array(), "Gltf mesh '{}' property 'primitives' invalid type", key); |
|
|
|
|
VERIFY(primitives.is_array(), "Gltf mesh '{}' property 'primitives' invalid type", key); |
|
|
|
|
|
|
|
|
|
for (auto& primitiveObject : primitives) { |
|
|
|
|
glTF::Primitive primitive; |
|
|
|
@ -250,7 +250,7 @@ namespace Inferno {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auto weights = Json::parseFloatArrayProperty(object, "weights", false); |
|
|
|
|
ASSERT(!weights || weights.value().size() > 0, "Gltf mesh '{}' empty property 'weights'", key); |
|
|
|
|
VERIFY(!weights || weights.value().size() > 0, "Gltf mesh '{}' empty property 'weights'", key); |
|
|
|
|
|
|
|
|
|
auto name = Json::parseStringProperty(object, "name", false); |
|
|
|
|
|
|
|
|
@ -265,21 +265,21 @@ namespace Inferno {
|
|
|
|
|
auto byteOffset = Json::parseUnsignedProperty(object, "byteOffset", false); |
|
|
|
|
|
|
|
|
|
auto componentType = Json::parseUnsignedProperty(object, "componentType", true); |
|
|
|
|
ASSERT(componentType, "Gltf accessor '{}' missing required property 'componentType'", key); |
|
|
|
|
VERIFY(componentType, "Gltf accessor '{}' missing required property 'componentType'", key); |
|
|
|
|
|
|
|
|
|
auto normalized = Json::parseBoolProperty(object, "normalized", false); |
|
|
|
|
|
|
|
|
|
auto count = Json::parseUnsignedProperty(object, "count", true); |
|
|
|
|
ASSERT(count, "Gltf accessor '{}' missing required property 'count'", key); |
|
|
|
|
VERIFY(count, "Gltf accessor '{}' missing required property 'count'", key); |
|
|
|
|
|
|
|
|
|
auto type = Json::parseStringProperty(object, "type", true); |
|
|
|
|
ASSERT(type, "Gltf accessor '{}' missing required property 'type'", key); |
|
|
|
|
VERIFY(type, "Gltf accessor '{}' missing required property 'type'", key); |
|
|
|
|
|
|
|
|
|
auto max = Json::parseFloatArrayProperty(object, "max", false); |
|
|
|
|
ASSERT(!max || max.value().size() > 0, "Gltf accessor '{}' empty property 'max'", key); |
|
|
|
|
VERIFY(!max || max.value().size() > 0, "Gltf accessor '{}' empty property 'max'", key); |
|
|
|
|
|
|
|
|
|
auto min = Json::parseFloatArrayProperty(object, "min", false); |
|
|
|
|
ASSERT(!min || min.value().size() > 0, "Gltf accessor '{}' empty property 'min'", key); |
|
|
|
|
VERIFY(!min || min.value().size() > 0, "Gltf accessor '{}' empty property 'min'", key); |
|
|
|
|
|
|
|
|
|
auto name = Json::parseStringProperty(object, "name", false); |
|
|
|
|
|
|
|
|
@ -296,12 +296,12 @@ namespace Inferno {
|
|
|
|
|
void Gltf::parseBufferView(glTF::BufferView* bufferView, const std::string& key, const json& object) |
|
|
|
|
{ |
|
|
|
|
auto buffer = Json::parseUnsignedProperty(object, "buffer", false); |
|
|
|
|
ASSERT(buffer, "Gltf bufferView '{}' missing required property 'buffer'", key); |
|
|
|
|
VERIFY(buffer, "Gltf bufferView '{}' missing required property 'buffer'", key); |
|
|
|
|
|
|
|
|
|
auto byteOffset = Json::parseUnsignedProperty(object, "byteOffset", false); |
|
|
|
|
|
|
|
|
|
auto byteLength = Json::parseUnsignedProperty(object, "byteLength", true); |
|
|
|
|
ASSERT(byteLength, "Gltf bufferView '{}' missing required property 'byteLength'", key); |
|
|
|
|
VERIFY(byteLength, "Gltf bufferView '{}' missing required property 'byteLength'", key); |
|
|
|
|
|
|
|
|
|
auto byteStride = Json::parseUnsignedProperty(object, "byteStride", false); |
|
|
|
|
|
|
|
|
@ -323,12 +323,12 @@ namespace Inferno {
|
|
|
|
|
|
|
|
|
|
// Load external binary data
|
|
|
|
|
if (uri) { |
|
|
|
|
ASSERT(uri.value().find("data:", 0) == std::string::npos, "GltfFile embedded binary data is unsupported"); |
|
|
|
|
VERIFY(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); |
|
|
|
|
VERIFY(byteLength, "Gltf buffer '{}' missing required property 'byteLength'", key); |
|
|
|
|
|
|
|
|
|
auto name = Json::parseStringProperty(object, "name", false); |
|
|
|
|
|
|
|
|
|