Loading...
Searching...
No Matches
FbxParser.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 FBX parsing class — drives ufbx + builds an ossia::scene_spec
14// out of an FBX file's bytes. Not a halp node in its own right (the
15// user-facing entry point is AssetLoader). AssetLoader calls the static
16// `ins::fbx_t::process` to obtain an apply-lambda, applies it against a
17// throwaway FbxParser instance, then copies out `m_raw_state`.
19{
20public:
21 struct ins
22 {
23 struct fbx_t : halp::file_port<"FBX file">
24 {
25 static std::function<void(FbxParser&)> process(file_type data);
26 } fbx;
27 } inputs;
28
29 void rebuild_scene();
30
31 // -- Rich scene staging (drives rebuild_scene) -----------------------------
32 // Built once per `process()` call. Lives on the execution thread; rebuilt
33 // into ossia::scene_spec by rebuild_scene().
34 struct ScenePart
35 {
36 // Per-attribute CPU buffers, one shared_ptr per stream. Each spans
37 // vertex_count elements of the matching format. Empty pointers indicate
38 // the attribute is absent on this part.
39 std::shared_ptr<std::vector<float>> positions; // 3 floats per vertex (always present)
40 std::shared_ptr<std::vector<float>> normals; // 3 floats per vertex
41 std::shared_ptr<std::vector<float>> texcoords; // 2 floats per vertex
42 std::shared_ptr<std::vector<float>> colors; // 4 floats per vertex (RGBA)
43 std::shared_ptr<std::vector<float>> tangents; // 4 floats per vertex
44
45 // Skinning: top-4 joints + weights per vertex. joints holds uint16 per
46 // component (4 per vertex); weights holds float (4 per vertex). Both
47 // are populated iff the mesh has a skin deformer.
48 std::shared_ptr<std::vector<uint16_t>> joints0;
49 std::shared_ptr<std::vector<float>> weights0;
50
51 uint32_t vertex_count{0};
52
53 // Index into FbxParser::m_materials. -1 = no material assigned.
54 int material_index{-1};
55
56 // Index into FbxParser::m_skeleton_joints_*, i.e. how many joints exist
57 // — stored on the ScenePart to propagate skin_index to mesh_component.
58 // 0 = no skin.
59 int skin_joint_count{0};
60
61 // Local-space AABB over `positions`. Computed once by extract_part
62 // (or whoever fills ScenePart) and carried into mesh_primitive by
63 // part_to_primitive. Empty aabb = "not yet computed"; downstream
64 // GPU culling treats empty as infinite.
65 ossia::aabb bounds{};
66 };
67
68 struct SceneNode
69 {
70 std::string name;
71 ossia::scene_transform local_transform; // node's local TRS
72 int parent_index{-1}; // index into m_scene_nodes (-1 = root)
73 std::vector<ScenePart> parts; // 0..N mesh parts (one per material)
74
75 // Optional attached components — populated during extraction when the
76 // ufbx_node carries them. `rebuild_scene` adds them as scene_payloads.
77 std::shared_ptr<ossia::light_component> light;
78 std::shared_ptr<ossia::camera_component> camera;
79 };
80
81 std::vector<SceneNode> m_scene_nodes;
82 std::vector<std::shared_ptr<ossia::material_component>> m_materials;
83
84 // One global skeleton built from all skin clusters encountered. Published
85 // to scene_state.skeletons[0]; mesh_component::skin_index is 0 for any
86 // mesh that uses skinning. Empty if the FBX has no skinning.
87 std::shared_ptr<ossia::skeleton_component> m_skeleton;
88
89 // Rich scene state emitted by rebuild_scene — full hierarchy with
90 // materials, lights, cameras, skeletons. AssetLoader consumes this
91 // via the apply-lambda returned by ins::fbx_t::process.
92 std::shared_ptr<const ossia::scene_state> m_raw_state;
93};
94
95}
Definition FbxParser.hpp:19
Definition FbxParser.hpp:69
Definition FbxParser.hpp:35
Definition FbxParser.hpp:24
Definition FbxParser.hpp:22