From 7ad2c92d31ac894b77d1fda9cee31c217e95e362 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Thu, 30 Mar 2023 10:48:54 +0300 Subject: [PATCH] Parse blender extras in glTF --- libs/gfx/include/psemek/gfx/gltf_parser.hpp | 9 ++++ libs/gfx/source/gltf_parser.cpp | 49 +++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/libs/gfx/include/psemek/gfx/gltf_parser.hpp b/libs/gfx/include/psemek/gfx/gltf_parser.hpp index 25145d0f..d086c262 100644 --- a/libs/gfx/include/psemek/gfx/gltf_parser.hpp +++ b/libs/gfx/include/psemek/gfx/gltf_parser.hpp @@ -18,6 +18,9 @@ namespace psemek::gfx struct gltf_asset { + using extra = std::variant, std::string>; + using extras_map = std::unordered_map; + struct node { std::string name; @@ -31,6 +34,8 @@ namespace psemek::gfx geom::quaternion rotation; geom::vector scale; geom::affine_transform transform; + + extras_map extras; }; struct mesh @@ -58,6 +63,8 @@ namespace psemek::gfx std::optional emission; std::optional emission_texture; std::optional material_texture; + + extras_map extras; }; struct texture @@ -146,6 +153,8 @@ namespace psemek::gfx float intensity; float range; geom::interval cone_angle; + + extras_map extras; }; std::vector nodes; diff --git a/libs/gfx/source/gltf_parser.cpp b/libs/gfx/source/gltf_parser.cpp index d725a9d0..5511aac9 100644 --- a/libs/gfx/source/gltf_parser.cpp +++ b/libs/gfx/source/gltf_parser.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -73,6 +74,48 @@ namespace psemek::gfx "KHR_materials_emissive_strength" }; + gltf_asset::extras_map parse_extras(rapidjson::GenericValue> const & value) + { + gltf_asset::extras_map result; + + if (value.HasMember("extras")) + { + for (auto const & extra : value["extras"].GetObject()) + { + std::string name = extra.name.GetString(); + gltf_asset::extra value; + + bool error = false; + + if (extra.value.IsNumber()) + value = extra.value.GetFloat(); + else if (extra.value.IsString()) + value = extra.value.GetString(); + else if (extra.value.IsArray()) + { + std::vector v; + for (auto const & val : extra.value.GetArray()) + { + if (!val.IsNumber()) + error = true; + else + v.push_back(val.GetFloat()); + } + value = std::move(v); + } + else + error = true; + + if (error) + log::warning() << "every 'extras' value must be either a number, an array of numbers, or a string (while parting glTF)"; + else + result[name] = std::move(value); + } + } + + return result; + } + } gltf_asset parse_gltf(io::istream && stream) @@ -144,6 +187,8 @@ namespace psemek::gfx target.light = extension.value["light"].GetUint64(); } } + + target.extras = parse_extras(node); } if (document.HasMember("meshes")) for (auto const & mesh : document["meshes"].GetArray()) @@ -224,6 +269,8 @@ namespace psemek::gfx *target.emission *= extensions["KHR_materials_emissive_strength"]["emissiveStrength"].GetFloat(); } } + + target.extras = parse_extras(material); } if (document.HasMember("images")) for (auto const & image : document["images"].GetArray()) @@ -367,6 +414,8 @@ namespace psemek::gfx if (spot.HasMember("outerConeAngle")) target.cone_angle.max = spot["outerConeAngle"].GetFloat(); } + + target.extras = parse_extras(light); } } }