Loading...
Searching...
No Matches
GltfParser.hpp
1#pragma once
2#include <halp/file_port.hpp>
3
4#include <ossia/dataflow/geometry_port.hpp>
5
6#include <functional>
7#include <memory>
8#include <vector>
9
10namespace Threedim
11{
12
13// Internal glTF 2.0 parsing class — uses fastgltf + simdjson to parse
14// .gltf / .glb. Not a halp node itself; AssetLoader is the user-facing
15// entry point. AssetLoader calls the static `ins::gltf_t::process` to
16// obtain an apply-lambda, applies it against a throwaway GltfParser
17// instance, then copies out `m_raw_state`.
19{
20public:
21 struct ins
22 {
23 struct gltf_t : halp::file_port<"glTF file">
24 {
25 static std::function<void(GltfParser&)> process(file_type data);
26 } gltf;
27 } inputs;
28
29 void rebuild_scene();
30
31 // Rich scene staging. Same schema as FbxParser (kept in sync so a future
32 // shared helper can consume both).
33 struct ScenePart
34 {
35 std::shared_ptr<std::vector<float>> positions;
36 std::shared_ptr<std::vector<float>> normals;
37 std::shared_ptr<std::vector<float>> texcoords;
38 std::shared_ptr<std::vector<float>> texcoords1; // glTF TEXCOORD_1
39 std::shared_ptr<std::vector<float>> colors;
40 std::shared_ptr<std::vector<float>> tangents;
41 // Skinning attributes (present when the primitive references a skin).
42 // joints: uvec4 bone indices packed as uint32 x 4 per vertex.
43 // weights: vec4 bone weights per vertex.
44 std::shared_ptr<std::vector<uint32_t>> joints0;
45 std::shared_ptr<std::vector<float>> weights0;
46 std::shared_ptr<std::vector<uint32_t>> indices; // optional
47 uint32_t vertex_count{0};
48 uint32_t index_count{0};
49 int material_index{-1};
50 // Local-space AABB over the POSITION stream. Populated by
51 // extract_primitive from the glTF POSITION accessor's min/max when
52 // present (spec-required but optionally trusted); otherwise derived
53 // by walking positions. Empty aabb = "not yet computed"; downstream
54 // GPU culling treats empty as infinite (never cull).
55 ossia::aabb bounds{};
56 // KHR_materials_variants: per-variant material override index.
57 // Indexed by variant (parallel to scene_state::variant_names).
58 // -1 at a position = "no override for this variant, use default".
59 std::vector<int> variant_material_indices;
60 };
61
62 struct SceneNode
63 {
64 std::string name;
65 ossia::scene_transform local_transform;
66 int parent_index{-1};
67 std::vector<ScenePart> parts;
68 std::shared_ptr<ossia::light_component> light;
69 std::shared_ptr<ossia::camera_component> camera;
70 // glTF skin index. -1 = not skinned. When ≥ 0, the mesh_component
71 // emitted from this node's parts gets stamped with skin_index so
72 // ScenePreprocessor binds the matching skeleton's joint_matrices
73 // auxiliary buffer for the skinning vertex shader to read.
74 int32_t skin_index{-1};
75 // Stable node_id, derived from the glTF node index + 1. Used by
76 // AnimationPlayer to find the node via channel.target_node_id, and
77 // by skeleton_component::joint_node_ids to resolve each joint to
78 // its node's world transform.
79 std::uint64_t stable_id{0};
80 };
81
82 std::vector<SceneNode> m_scene_nodes;
83 std::vector<std::shared_ptr<ossia::material_component>> m_materials;
84 std::vector<std::shared_ptr<ossia::skeleton_component>> m_skeletons;
85 // KHR_materials_variants: names (UI-facing) declared at asset scope.
86 // Parallel to mesh_primitive::material_variants and
87 // scene_state::active_variant_index.
88 std::vector<std::string> m_variant_names;
89
90 // Rich scene state emitted by rebuild_scene — full hierarchy with
91 // materials, lights, cameras, skeletons. AssetLoader consumes this
92 // via the apply-lambda returned by ins::gltf_t::process.
93 std::shared_ptr<const ossia::scene_state> m_raw_state;
94};
95
96}
Definition GltfParser.hpp:19
Definition GltfParser.hpp:63
Definition GltfParser.hpp:34
Definition GltfParser.hpp:24
Definition GltfParser.hpp:22