23 if (render.target_window) {
28 "mint: RenderConfig::target_window is required, there is no default window");
32 [[nodiscard]] std::shared_ptr<Nodes::GpuSync::MeshWriterNode> resolve_writer(
33 const std::optional<Kakshya::MeshData>& mesh,
35 const std::shared_ptr<Nodes::GpuSync::MeshWriterNode>& writer,
36 std::string_view context)
38 const unsigned int source_count =
static_cast<unsigned int>(mesh.has_value())
39 +
static_cast<unsigned int>(
static_cast<bool>(expression))
40 +
static_cast<unsigned int>(writer !=
nullptr);
42 if (source_count != 1) {
44 "mint: {} requires exactly one mesh, expression or writer source", context);
52 Kakshya::MeshData data = mesh ? *mesh : expression();
53 if (!data.is_valid()) {
55 "mint: {} produced invalid MeshData", context);
59 auto resolved = std::make_shared<Nodes::GpuSync::MeshWriterNode>(data.vertex_count());
60 resolved->set_mesh(data);
64 void add_extra_textures(
66 const std::vector<std::shared_ptr<Core::VKImage>>& textures,
70 if (textures[
index]) {
71 render.additional_textures.emplace_back(
72 "texture" + std::to_string(
index), textures[
index]);
77 void add_all_textures(
79 const std::vector<std::shared_ptr<Core::VKImage>>& textures)
81 if (!textures.empty() && textures.front()) {
82 render.additional_textures.emplace_back(
"diffuseTex", textures.front());
84 add_extra_textures(render, textures, 1);
87 void register_network_if_needed(
88 const std::shared_ptr<Nodes::Network::NodeNetwork>&
network)
96 template <
typename Buffer>
97 void bind_mesh_textures(
98 const std::shared_ptr<Buffer>&
buffer,
100 const std::vector<std::shared_ptr<Core::VKImage>>& textures)
102 if (!textures.empty() && textures.front()) {
103 const std::string binding = render.default_texture_binding.empty()
105 : render.default_texture_binding;
106 buffer->bind_diffuse_texture(textures.front(), binding);
107 render.default_texture_binding = binding;
109 add_extra_textures(render, textures, 1);
116 [[nodiscard]] std::shared_ptr<Buffers::MeshBuffer>
build(
119 if (!has_target(config.
render)) {
123 const unsigned int source_count =
static_cast<unsigned int>(config.
mesh.has_value())
124 +
static_cast<unsigned int>(
static_cast<bool>(config.
expression))
125 +
static_cast<unsigned int>(config.
writer !=
nullptr);
126 if (source_count != 1) {
128 "mint: Object requires exactly one mesh, expression or writer source");
132 auto writer = resolve_writer(
138 auto buffer = std::make_shared<Buffers::MeshBuffer>(writer);
143 buffer->setup_rendering(render);
147 [[nodiscard]] std::shared_ptr<Buffers::MeshNetworkBuffer>
build(
150 if (!has_target(config.
render)) {
156 : std::make_shared<Nodes::Network::MeshNetwork>();
157 const auto first_component_slot =
static_cast<uint32_t
>(
network->slot_count());
161 auto writer = resolve_writer(
162 component.mesh, component.expression, component.writer,
"Model component");
167 if (component.parent_component && component.parent_slot) {
169 "mint: Model component {} cannot name both a component and slot parent",
174 std::optional<uint32_t>
parent;
175 if (component.parent_component) {
176 if (*component.parent_component >=
index) {
178 "mint: Model component {} must name an earlier component as parent",
182 parent = first_component_slot + *component.parent_component;
183 }
else if (component.parent_slot) {
184 if (*component.parent_slot >= first_component_slot) {
186 "mint: Model component {} parent slot is not in the supplied network",
190 parent = component.parent_slot;
193 const uint32_t slot_index =
network->add_slot(
194 "component_" + std::to_string(
index), writer,
parent);
195 network->get_slot(slot_index).local_transform = component.local_transform;
198 if (
network->slot_count() == 0) {
200 "mint: Model requires at least one mesh component");
204 register_network_if_needed(
network);
205 auto buffer = std::make_shared<Buffers::MeshNetworkBuffer>(
210 buffer->setup_rendering(render);
214 [[nodiscard]] std::shared_ptr<Buffers::InstanceNetworkBuffer>
build(
217 if (!has_target(config.
render)) {
223 : std::make_shared<Nodes::Network::InstanceNetwork>();
226 auto writer = resolve_writer(
230 "Instances prototype");
236 const uint32_t slot_index =
network->add_slot(
237 "instance_" + std::to_string(
index), writer);
242 if (
network->slot_count() == 0) {
244 "mint: Instances requires an existing populated network or transforms");
248 register_network_if_needed(
network);
249 auto buffer = std::make_shared<Buffers::InstanceNetworkBuffer>(
252 add_all_textures(render, config.
textures);
254 buffer->setup_rendering(render);
258 [[nodiscard]] std::shared_ptr<Buffers::NetworkGeometryBuffer>
build(
261 if (!has_target(config.
render)) {
267 : std::make_shared<Nodes::Network::AssemblyNetwork>();
269 for (
const auto& source : config.
sources) {
273 if (
network->get_node_count() == 0) {
275 "mint: Assembly requires at least one geometry source");
279 register_network_if_needed(
network);
280 auto buffer = std::make_shared<Buffers::NetworkGeometryBuffer>(
network);
283 add_all_textures(render, config.
textures);
285 buffer->setup_rendering(render);
286 buffer->get_render_processor()->set_mill_spec(config.
mill);
290 [[nodiscard]] std::shared_ptr<Buffers::ComputeMeshBuffer>
build(
293 if (!has_target(config.
render)) {
297 const bool has_buffer = config.
buffer !=
nullptr;
298 const bool has_config = config.
config.has_value();
299 if (
static_cast<unsigned int>(has_buffer)
300 +
static_cast<unsigned int>(has_config)
303 "mint: Isosurface requires exactly one buffer or config");
309 : std::make_shared<Buffers::ComputeMeshBuffer>(*config.
config);
319 add_extra_textures(render, config.
textures, 1);
321 buffer->setup_rendering(render);
327 : m_impl(
std::make_unique<
Impl>())
337std::shared_ptr<Buffers::MeshBuffer>
Mint::build(
340 return m_impl->
build(config);
346 return m_impl->build(config);
352 return m_impl->build(config);
358 return m_impl->build(config);
364 return m_impl->build(config);
#define MF_ERROR(comp, ctx,...)
Core::GlobalNetworkConfig network
std::vector< uint32_t > parent
std::shared_ptr< NetworkGeometryBuffer > buffer
std::unique_ptr< Impl > m_impl
std::shared_ptr< Buffers::MeshBuffer > build(const StructureConfig::Object &config)
Turns a structural config into a registered and rendered object.
@ Init
Engine/subsystem initialization.
@ API
MayaFlux/API Wrapper and convenience functions.
@ VISUAL_RATE
Nodes that process at the visual frame rate.
std::shared_ptr< Nodes::NodeGraphManager > get_node_graph_manager()
Gets the node graph manager from the default engine.
void register_node_network(const std::shared_ptr< Nodes::Network::NodeNetwork > &network, const Nodes::ProcessingToken &token)
Registers a node network with the default engine's node graph manager.
void register_graphics_buffer(const std::shared_ptr< Buffers::VKBuffer > &buffer, Buffers::ProcessingToken token)
Registers a VKBuffer with the default engine's buffer manager.
Main namespace for the Maya Flux audio engine.
std::shared_ptr< Buffers::NetworkGeometryBuffer > build(const StructureConfig::Assembly &config) const
std::shared_ptr< Buffers::MeshNetworkBuffer > build(const StructureConfig::Model &config) const
std::shared_ptr< Buffers::MeshBuffer > build(const StructureConfig::Object &config) const
std::shared_ptr< Buffers::ComputeMeshBuffer > build(const StructureConfig::Isosurface &config) const
std::shared_ptr< Buffers::InstanceNetworkBuffer > build(const StructureConfig::Instances &config) const
Wiring sequences behind Mint.
bool triangulate
Reduce supplied spans to triangles before drawing them.
std::string default_texture_binding
Unified rendering configuration for graphics buffers.
std::shared_ptr< Nodes::Network::AssemblyNetwork > network
Existing assembly to complete, or null to construct one.
Portal::Graphics::MillSpec mill
Fixed milling policy shared by the rendered assembly.
std::vector< std::shared_ptr< Core::VKImage > > textures
Images available to the selected render pipeline.
RenderConfig render
Required render destination and pipeline overrides.
std::vector< Nodes::Network::AssemblyNetwork::Source > sources
Independent sources appended before registration.
Independent heterogeneous sources and their shared milling policy.
std::shared_ptr< Nodes::Network::InstanceNetwork > network
Existing network to complete, or null to construct one.
std::optional< Kakshya::MeshData > prototype_mesh
Fixed prototype source.
MeshExpression prototype_expression
Fixed prototype expression.
float over_allocate_factor
Fixed initial vertex-buffer capacity multiplier.
std::vector< glm::mat4 > transforms
Fixed initial world transform for each new instance.
std::shared_ptr< Nodes::GpuSync::MeshWriterNode > prototype_writer
Live prototype source.
RenderConfig render
Required render destination and pipeline overrides.
std::vector< std::shared_ptr< Core::VKImage > > textures
Images available to the selected render pipeline.
Prototype mesh and world transforms for one InstanceNetworkBuffer.
std::vector< std::shared_ptr< Core::VKImage > > textures
Images available to the selected render pipeline.
std::optional< Buffers::ComputeMeshBuffer::Config > config
Library-owned construction state when Mint creates the buffer.
RenderConfig render
Required render destination and pipeline overrides.
std::shared_ptr< Buffers::ComputeMeshBuffer > buffer
Existing isosurface buffer, exclusive with config.
Existing isosurface buffer or new buffer construction state.
float over_allocate_factor
Fixed initial vertex-buffer capacity multiplier.
std::shared_ptr< Nodes::Network::MeshNetwork > network
Existing network to complete, or null to construct one.
RenderConfig render
Required render destination and pipeline overrides.
std::vector< ModelComponent > components
Components appended before registration.
std::vector< std::shared_ptr< Core::VKImage > > textures
Images available to the selected render pipeline.
Mesh components and allocation policy for one MeshNetworkBuffer.
RenderConfig render
Required render destination and pipeline overrides.
MeshExpression expression
Fixed construction expression.
std::shared_ptr< Nodes::GpuSync::MeshWriterNode > writer
Live geometry source.
std::optional< Kakshya::MeshData > mesh
Fixed materialised source.
std::vector< std::shared_ptr< Core::VKImage > > textures
Images available to the selected render pipeline.
One independently rendered mesh-backed object.
std::function< Kakshya::MeshData()> MeshExpression
A one-shot typed mesh expression, normally invoking Kinesis.
Buffers::VKBuffer::RenderConfig RenderConfig
Render target and pipeline overrides.
API-side playground for a complete visible structure.