Loading...
Searching...
No Matches
AssetLoader.hpp
1#pragma once
2#include <Threedim/TinyObj.hpp>
3#include <Threedim/TransformHelper.hpp>
4#include <halp/controls.hpp>
5#include <halp/file_port.hpp>
6#include <halp/meta.hpp>
7
8#include <ossia/dataflow/geometry_port.hpp>
9
10#include <Gfx/Graph/GpuResourceRegistry.hpp>
11
12#include <score_plugin_threedim_export.h>
13
14#include <memory>
15#include <string_view>
16
17class QRhiResourceUpdateBatch;
18
19namespace score::gfx
20{
21class RenderList;
22struct Edge;
23}
24
25namespace Threedim
26{
27
28// External scene-file parser registry. An addon shipping a format-specific
29// parser registers itself here so AssetLoader can dispatch to it without a
30// link-time dependency from score-plugin-threedim.
31//
32// The callback takes the same halp::text_file_view the built-in glTF and FBX
33// parsers receive and returns a populated ossia::scene_state, or a null
34// shared_ptr on failure or unhandled input. AssetLoader wraps the state with the
35// Position / Rotation / Scale controls exactly as for the built-ins.
36//
37// Extensions match case-insensitively on the suffix after the final '.'. A
38// duplicate registration replaces the prior one. Calls are thread-safe.
39class SCORE_PLUGIN_THREEDIM_EXPORT AssetLoaderRegistry
40{
41public:
42 using ParseFn = std::shared_ptr<const ossia::scene_state> (*)(
43 const halp::text_file_view&);
44
45 // Register a parser for an extension (without the dot). Safe at
46 // static-init time — the underlying storage is a function-local
47 // Meyers singleton.
48 static void register_parser(std::string_view extension, ParseFn fn);
49
50 // Lookup by lowercased extension. Returns nullptr if no match.
51 static ParseFn lookup(std::string_view extension_lower) noexcept;
52};
53
54// Unified 3D asset loader. Accepts .fbx / .gltf / .glb / .obj / .ply / .stl /
55// .off natively, plus .usd / .usda / .usdc / .usdz when score-addon-academy is
56// loaded and has registered its UsdParser.
57//
58// Dispatch is by file extension:
59// .fbx ufbx (FbxParser's static parser)
60// .gltf / .glb fastgltf (GltfParser's static parser)
61// .obj tinyobjloader + sceneStateFromMeshes
62// .ply miniply + sceneStateFromMeshes
63// .stl / .off vcglib + sceneStateFromMeshes
64// .usd* OpenUSD (academy UsdParser, optional)
65// others AssetLoaderRegistry::lookup(ext)
66//
67// Position / Rotation / Scale controls wrap the loaded scene at a single root
68// TRS through TransformHelper::wrapSceneWithTransform.
69//
70// The geometry-only formats produce a scene with one scene_node per mesh part,
71// each holding a mesh_component over a single shared CPU buffer; FBX and glTF
72// retain their scene hierarchy of lights, cameras, materials, skeletons and
73// animations.
75{
76public:
77 halp_meta(name, "Asset Loader")
78 halp_meta(category, "Visuals/3D")
79 halp_meta(c_name, "asset_loader")
80 halp_meta(authors, "ossia team, ufbx / fastgltf / tinyobj / miniply / vcglib")
81 halp_meta(
82 manual_url,
83 "https://ossia.io/score-docs/processes/asset-loader.html")
84 halp_meta(uuid, "2f6a8c41-7d93-4e5b-b1c8-4e3f9a7d2c5b")
85
86 struct ins
87 {
88 struct asset_t : halp::file_port<"Asset file">
89 {
90 halp_meta(
91 extensions,
92 "3D assets (*.fbx *.gltf *.glb *.obj *.ply *.stl *.off "
93 "*.splat *.spz "
94 "*.usd *.usda *.usdc *.usdz)");
95 static std::function<void(AssetLoader&)> process(file_type data);
96 } asset;
97
98 PositionControl position;
99 RotationControl rotation;
100 ScaleControl scale;
101
102 // Stamps every primitive_cloud_component emitted by this asset
103 // with `format_id = value` when non-empty. Empty falls back to the
104 // parser's autodetection (PLY column sniffing, .splat / .spz
105 // hardcoded). Used to route unrecognised PLY columns or addon-
106 // produced files through a FlattenedSceneFilterNode in mode 12.
107 struct format_override_t : halp::lineedit<"Format override (auto if empty)", "">
108 {
109 void update(AssetLoader& n) { n.rebuild_format_state(); }
110 } format_override;
111 } inputs;
112
113 struct outs
114 {
115 struct
116 {
117 halp_meta(name, "Scene");
118 ossia::scene_spec scene;
119 uint8_t dirty{0};
120 } scene_out;
121 } outputs;
122
123 void operator()();
124
125 // Render-thread hooks. init() claims a RawTransform slot for the
126 // single root wrapping xform this node emits (TransformHelper's
127 // scene-wrapping transform). update() uploads the current TRS.
128 void init(score::gfx::RenderList& r, QRhiResourceUpdateBatch& res);
129 void update(
130 score::gfx::RenderList& r, QRhiResourceUpdateBatch& res,
132 void release(score::gfx::RenderList& r);
133
134 // Raw scene as parsed from the file — stable as long as the file
135 // doesn't change. The pipeline is:
136 // m_parsed_state (parser output, never mutated)
137 // ↓ applyFormatOverride(format_override.value)
138 // m_overridden_state (format_id rewrites applied, or = parsed)
139 // ↓ wrapSceneWithTransform(position/rotation/scale)
140 // m_wrapped_state (final, published downstream)
141 std::shared_ptr<const ossia::scene_state> m_parsed_state;
142 std::shared_ptr<const ossia::scene_state> m_overridden_state;
143 std::shared_ptr<const ossia::scene_state> m_wrapped_state;
144 std::string m_cached_format_override;
145 CachedTRS m_cached_xform;
146 int64_t m_version_counter{0};
147
148 // Re-runs applyFormatOverride from the parsed state. Triggered by the
149 // lineedit's update() callback when the user edits the override
150 // field; also called once after parsing.
151 void rebuild_format_state();
152
153 score::gfx::GpuResourceRegistry::Slot raw_transform_slot;
154 ossia::gpu_slot_ref m_xform_ref{};
155
156private:
157 void rebuild_wrapped_state();
158};
159
160}
Definition AssetLoader.hpp:75
Definition AssetLoader.hpp:40
List of nodes to be rendered to an output.
Definition RenderList.hpp:30
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11
Definition AssetLoader.hpp:89
Definition AssetLoader.hpp:108
Definition AssetLoader.hpp:87
Definition AssetLoader.hpp:114
Definition TransformHelper.hpp:26
Definition TinyObj.hpp:98
Definition TinyObj.hpp:103
Definition TinyObj.hpp:107
Connection between two score::gfx::Port.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:103
Definition GpuResourceRegistry.hpp:84