MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
AssemblyOperator.hpp
Go to the documentation of this file.
1#pragma once
2
4
8
10
11/**
12 * @class AssemblyOperator
13 * @brief Holds an unordered set of independent geometry items, rendered as
14 * one milled draw.
15 *
16 * Not a specialized operator: unlike PathOperator/TopologyOperator/
17 * PhysicsOperator, it interpolates, connects, or simulates nothing between
18 * items. Items are stored in a plain std::vector<shared_ptr<GeometryWriterNode>>
19 * in insertion order, not behind a handle: the shared_ptr each add_geometry()
20 * overload returns is itself the caller's access token for later mutation or
21 * removal, the same idiom PathOperator::add_node() already uses for a single
22 * path. Removal is a pointer-identity scan; if that becomes a hot per-frame
23 * path for thousands of items, revisit the storage, not the access API.
24 *
25 * apply_one_to_one() is a documented no-op here (get_data_at() always
26 * returns nullptr): unrelated items added and removed independently have no
27 * positional correspondence for a ONE_TO_ONE per-index mapping to land on.
28 */
29class MAYAFLUX_API AssemblyOperator : public GraphicsOperator {
30public:
31 AssemblyOperator() = default;
32
33 /// @brief Add an item from plain positions (color/scalar/normal/uv default).
34 std::shared_ptr<GpuSync::GeometryLeafNode> add_geometry(
35 std::vector<glm::vec3> positions,
36 Portal::Graphics::PrimitiveTopology topology = Portal::Graphics::PrimitiveTopology::POINT_LIST);
37
38 /// @brief Add an item from fully specified vertices.
39 std::shared_ptr<GpuSync::GeometryLeafNode> add_geometry(
40 std::vector<Kakshya::Vertex> vertices,
41 Portal::Graphics::PrimitiveTopology topology = Portal::Graphics::PrimitiveTopology::POINT_LIST);
42
43 /// @brief Add an indexed triangle mesh. Topology is fixed TRIANGLE_LIST.
44 std::shared_ptr<GpuSync::MeshWriterNode> add_geometry(const Kakshya::MeshData& mesh);
45
46 /// @brief Add a caller-built node directly; its own topology is used as-is.
47 void add_geometry(std::shared_ptr<GpuSync::GeometryWriterNode> node);
48
49 /**
50 * @brief Remove an item by identity.
51 * @return true if the node was present and removed.
52 */
53 bool remove_geometry(const std::shared_ptr<GpuSync::GeometryWriterNode>& node);
54
55 [[nodiscard]] size_t item_count() const { return m_items.size(); }
56
57 void process(float dt) override;
58
59 [[nodiscard]] std::span<const uint8_t> get_vertex_data() const override;
60 [[nodiscard]] std::span<const uint8_t> get_vertex_data_for_collection(uint32_t idx) const override;
61
62 /**
63 * @brief The universal Kakshya::Vertex attribute layout, vertex_count 0
64 * when there are no items yet. Every item's record shares one
65 * 60-byte offset table regardless of topology (only the scalar
66 * field's name differs), so the shape is knowable -- and a
67 * render pipeline buildable -- before the first item ever
68 * arrives; only the count is data-dependent.
69 */
70 [[nodiscard]] Kakshya::VertexLayout get_vertex_layout() const override;
71 [[nodiscard]] size_t get_vertex_count() const override;
72 [[nodiscard]] bool is_vertex_data_dirty() const override;
73 void mark_vertex_data_clean() override;
74
75 /**
76 * @brief One DirtyVertexRange per item that needs a GPU update, in
77 * add_geometry() order, matching get_vertex_data().
78 */
79 [[nodiscard]] std::vector<DirtyVertexRange> dirty_vertex_ranges() const override;
80 [[nodiscard]] bool supports_incremental_upload() const override { return true; }
81
82 [[nodiscard]] size_t get_point_count() const override;
83
84 /**
85 * @brief One cluster id per item; coincides with get_vertex_count()
86 * since items carry no interpolation step of their own.
87 */
88 [[nodiscard]] std::vector<uint32_t> build_cluster_ids() const override;
89
90 /// @brief Forwards to the first item's own get_primitive_topology().
91 [[nodiscard]] std::optional<Portal::Graphics::PrimitiveTopology> declared_topology() const override;
92
93 /**
94 * @brief Coalesces adjacent items sharing a concatenable topology into
95 * one run; strip/fan items are always reported separately.
96 */
97 [[nodiscard]] std::vector<DrawRun> topology_runs() const override;
98
99 void set_parameter(std::string_view param, double value) override;
100 [[nodiscard]] std::optional<double> query_state(std::string_view query) const override;
101 [[nodiscard]] std::string_view get_type_name() const override { return "Assembly"; }
102 [[nodiscard]] const char* get_vertex_type_name() const override { return "Vertex"; }
103
104protected:
105 void* get_data_at(size_t global_index) override;
106
107private:
108 std::vector<std::shared_ptr<GpuSync::GeometryWriterNode>> m_items;
109 mutable std::vector<uint8_t> m_vertex_data_aggregate;
110};
111
112} // namespace MayaFlux::Nodes::Network
glm::vec3 value
std::vector< std::shared_ptr< GpuSync::GeometryWriterNode > > m_items
std::string_view get_type_name() const override
Type name for introspection.
bool supports_incremental_upload() const override
Whether every vertex mutation on this operator sets a group's dirty flag, so dirty_vertex_ranges() is...
const char * get_vertex_type_name() const override
Get human-readable vertex type name (for validation/debugging)
Holds an unordered set of independent geometry items, rendered as one milled draw.
Operator that produces GPU-renderable geometry.
PrimitiveTopology
Vertex assembly primitive topology.
Owning CPU-side representation of a loaded or generated mesh.
Definition MeshData.hpp:33
Complete description of vertex data layout in a buffer.