Support KHR_lights_punctual in gltf parser
This commit is contained in:
parent
b52039d47c
commit
ef6ef081d8
2 changed files with 91 additions and 0 deletions
|
|
@ -8,6 +8,7 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
|
||||
namespace psemek::gfx
|
||||
{
|
||||
|
|
@ -18,6 +19,7 @@ namespace psemek::gfx
|
|||
{
|
||||
std::string name;
|
||||
std::optional<std::size_t> mesh;
|
||||
std::optional<std::size_t> light; // KHR_lights_punctual
|
||||
std::vector<std::size_t> children;
|
||||
|
||||
geom::vector<float, 3> translation;
|
||||
|
|
@ -75,6 +77,22 @@ namespace psemek::gfx
|
|||
std::string uri;
|
||||
};
|
||||
|
||||
// KHR_lights_punctual
|
||||
struct light
|
||||
{
|
||||
enum
|
||||
{
|
||||
directional,
|
||||
point,
|
||||
spot,
|
||||
} type;
|
||||
|
||||
gfx::color_3f color;
|
||||
float intensity;
|
||||
float range;
|
||||
geom::interval<float> cone_angle;
|
||||
};
|
||||
|
||||
std::vector<node> nodes;
|
||||
std::vector<mesh> meshes;
|
||||
std::vector<material> materials;
|
||||
|
|
@ -82,6 +100,7 @@ namespace psemek::gfx
|
|||
std::vector<accessor> accessors;
|
||||
std::vector<buffer_view> buffer_views;
|
||||
std::vector<buffer> buffers;
|
||||
std::vector<light> lights; // KHR_lights_punctual
|
||||
|
||||
std::unordered_map<std::string, std::size_t> node_index;
|
||||
std::unordered_map<std::string, std::size_t> material_index;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/istreamwrapper.h>
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
namespace psemek::gfx
|
||||
{
|
||||
|
||||
|
|
@ -56,6 +58,11 @@ namespace psemek::gfx
|
|||
throw std::runtime_error(util::to_string("Unknown accessor component type: ", type));
|
||||
}
|
||||
|
||||
static std::unordered_set<std::string> supported_extensions =
|
||||
{
|
||||
"KHR_lights_punctual",
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
gltf_asset parse_gltf(io::istream && stream)
|
||||
|
|
@ -70,6 +77,11 @@ namespace psemek::gfx
|
|||
|
||||
gltf_asset result;
|
||||
|
||||
if (document.HasMember("extensionsRequired"))
|
||||
for (auto const & extension : document["extensionsRequired"].GetArray())
|
||||
if (!supported_extensions.contains(extension.GetString()))
|
||||
throw std::runtime_error("glTF extension " + std::string(extension.GetString()) + " is not supported");
|
||||
|
||||
for (auto const & node : document["nodes"].GetArray())
|
||||
{
|
||||
auto & target = result.nodes.emplace_back();
|
||||
|
|
@ -106,6 +118,15 @@ namespace psemek::gfx
|
|||
for (auto const & child : node["children"].GetArray())
|
||||
target.children.push_back(child.GetUint64());
|
||||
}
|
||||
|
||||
if (node.HasMember("extensions"))
|
||||
for (auto const & extension : node["extensions"].GetObject())
|
||||
{
|
||||
if (extension.name == "KHR_lights_punctual")
|
||||
{
|
||||
target.light = extension.value["light"].GetUint64();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const & mesh : document["meshes"].GetArray())
|
||||
|
|
@ -199,6 +220,57 @@ namespace psemek::gfx
|
|||
target.uri = buffer["uri"].GetString();
|
||||
}
|
||||
|
||||
if (document.HasMember("extensions"))
|
||||
for (auto const & extension : document["extensions"].GetObject())
|
||||
{
|
||||
if (extension.name == "KHR_lights_punctual")
|
||||
{
|
||||
for (auto const & light : extension.value["lights"].GetArray())
|
||||
{
|
||||
auto & target = result.lights.emplace_back();
|
||||
target.color = {1.f, 1.f, 1.f};
|
||||
target.intensity = 1.f;
|
||||
target.range = std::numeric_limits<float>::infinity();
|
||||
target.cone_angle = {0.f, geom::pi / 4.f};
|
||||
|
||||
std::string type = light["type"].GetString();
|
||||
|
||||
if (type == "directional")
|
||||
target.type = gltf_asset::light::directional;
|
||||
else if (type == "point")
|
||||
target.type = gltf_asset::light::point;
|
||||
else if (type == "spot")
|
||||
target.type = gltf_asset::light::spot;
|
||||
else
|
||||
throw std::runtime_error("unknown light type: " + type);
|
||||
|
||||
if (light.HasMember("color"))
|
||||
{
|
||||
auto const & color = light["color"].GetArray();
|
||||
for (std::size_t i = 0; i < 3; ++i)
|
||||
target.color[i] = color[i].GetFloat();
|
||||
}
|
||||
|
||||
if (light.HasMember("intensity"))
|
||||
target.intensity = light["intensity"].GetFloat();
|
||||
|
||||
if (light.HasMember("range"))
|
||||
target.range = light["range"].GetFloat();
|
||||
|
||||
if (target.type == gltf_asset::light::spot)
|
||||
{
|
||||
auto const & spot = light["spot"].GetObject();
|
||||
|
||||
if (spot.HasMember("innerConeAngle"))
|
||||
target.cone_angle.min = spot["innerConeAngle"].GetFloat();
|
||||
|
||||
if (spot.HasMember("outerConeAngle"))
|
||||
target.cone_angle.max = spot["outerConeAngle"].GetFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < result.nodes.size(); ++i)
|
||||
result.node_index[result.nodes[i].name] = i;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue