19 std::string stream_name,
20 std::shared_ptr<Buffers::NetworkGeometryBuffer>
buffer)
31 std::atomic<uint32_t> g_next_spatial_capture_id { 1 };
33 bool run_sources(SpatialCache& cache,
const std::vector<SpatialCaptureSource>& sources)
35 for (
const auto& source : sources) {
36 if (!source.capture_frame(cache, source.stream_name)) {
38 "SpatialCapture: source '{}' failed", source.stream_name);
47 std::shared_ptr<SpatialCache>
cache;
48 std::vector<SpatialCaptureSource>
sources;
50 std::atomic<uint32_t>
frame { 0 };
63 "SpatialCapture: failed at frame {}", state.
frame.load(std::memory_order_relaxed));
67 state.
frame.fetch_add(1, std::memory_order_relaxed);
73 std::shared_ptr<SpatialCache> cache,
74 std::vector<SpatialCaptureSource> sources)
75 : m_scheduler(scheduler)
76 , m_cache(
std::move(cache))
77 , m_sources(
std::move(sources))
88 return m_state &&
m_state->recording.load(std::memory_order_acquire);
93 return m_state ?
m_state->frame.load(std::memory_order_relaxed) : 0;
100 "SpatialCapture: cannot start, null cache");
106 "SpatialCapture: cannot start, no sources");
112 m_state = std::make_shared<CaptureState>();
115 m_state->max_frames = max_frames;
116 m_state->recording.store(
true, std::memory_order_release);
119 + std::to_string(g_next_spatial_capture_id.fetch_add(1, std::memory_order_relaxed));
122 std::shared_ptr<CaptureState> state,
125 while (!p.should_terminate
126 && !state->stop_requested.load(std::memory_order_acquire)
130 state->recording.store(
false, std::memory_order_release);
134 std::make_shared<Vruta::GraphicsRoutine>(
139 "SpatialCapture: recording {} stream(s) every {} frame(s), {}",
141 max_frames == 0 ? std::string(
"unbounded")
142 : std::format(
"{} frames", max_frames));
147 if (!
m_state || !
m_state->recording.load(std::memory_order_acquire)) {
151 m_state->stop_requested.store(
true, std::memory_order_release);
155 "SpatialCapture: stop requested after {} frames",
156 m_state->frame.load(std::memory_order_relaxed));
160 std::shared_ptr<Buffers::RelaxationGridBuffer> grid,
161 std::string stream_name,
164 : m_grid(
std::move(grid))
165 , m_stream_name(
std::move(stream_name))
166 , m_to_attributes(
std::move(to_attributes))
178 auto cache = std::make_shared<SpatialCache>();
179 if (!cache->open(filepath)) {
181 "RelaxationGridCapture: failed to open '{}': {}", filepath, cache->get_last_error());
187 "RelaxationGridCapture: recording '{}' to '{}'",
m_stream_name, filepath);
219 const std::string& path_pattern,
220 const std::vector<SpatialCaptureSource>& sources)
222 if (sources.empty()) {
224 "save_spatial_snapshot: no sources");
228 const auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
229 std::chrono::system_clock::now().time_since_epoch())
234 if (!cache.
open(path)) {
236 "save_spatial_snapshot: failed to open '{}': {}", path, cache.
get_last_error());
240 const bool ok = run_sources(cache, sources);
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
std::shared_ptr< NetworkGeometryBuffer > buffer
std::function< std::vector< SpatialAttribute >(std::span< const uint8_t >)> ToAttributes
std::shared_ptr< SpatialCache > m_cache
bool start(const std::string &filepath)
Open the archive.
void stop()
Close the archive.
std::vector< uint64_t > m_ids
std::vector< glm::vec3 > m_positions
ToAttributes m_to_attributes
RelaxationGridCapture(std::shared_ptr< Buffers::RelaxationGridBuffer > grid, std::string stream_name, float extent, ToAttributes to_attributes)
std::string m_stream_name
std::shared_ptr< Buffers::RelaxationGridBuffer > m_grid
bool write_snapshot(std::span< const uint8_t > bytes)
Write one snapshot as a sample, if currently capturing.
std::string get_last_error() const
bool open(const std::string &filepath)
Open an Alembic archive for writing, Ogawa backend.
void close()
Finalize and close the archive.
Alembic-backed writer for time-sampled spatial entity state: particle systems, point clouds,...
std::shared_ptr< SpatialCache > m_cache
std::vector< SpatialCaptureSource > m_sources
static bool run_one_frame(CaptureState &state)
One tick: write every source's stream.
void start(uint32_t max_frames=0, uint64_t frame_interval=1)
Spawn the capture routine, resetting the frame counter.
std::shared_ptr< CaptureState > m_state
uint32_t frames_written() const
Vruta::TaskScheduler & m_scheduler
void stop()
Request the capture routine stop.
SpatialCapture(Vruta::TaskScheduler &scheduler, std::shared_ptr< SpatialCache > cache, std::vector< SpatialCaptureSource > sources)
bool is_recording() const
A C++20 coroutine-based graphics processing task with frame-accurate timing.
void add_task(const std::shared_ptr< Routine > &routine, const std::string &name="", bool initialize=false)
Add a routine to the scheduler based on its processing token.
bool cancel_task(const std::shared_ptr< Routine > &routine)
Cancels and removes a task from the scheduler.
Token-based multimodal task scheduling system for unified coroutine processing.
bool relaxation_grid_positions(const std::shared_ptr< Buffers::RelaxationGridBuffer > &grid, float extent, std::vector< glm::vec3 > &positions, std::vector< uint64_t > &ids)
Generate the fixed grid positions and cell ids a RelaxationGridBuffer's cells occupy,...
bool save_spatial_snapshot(const std::string &path_pattern, const std::vector< SpatialCaptureSource > &sources)
Open a fresh SpatialCache, write every source once, then close it.
std::string resolve_sequence_path(std::string_view pattern, uint64_t frame)
Substitute a frame index into a numbered output pattern.
bool write_network_geometry_buffer_sample(SpatialCache &cache, const std::string &stream_name, const std::shared_ptr< Buffers::NetworkGeometryBuffer > &buffer)
Pack a NetworkGeometryBuffer's driving network into one or more SpatialCache streams,...
SpatialCaptureSource make_network_geometry_source(std::string stream_name, std::shared_ptr< Buffers::NetworkGeometryBuffer > buffer)
Build a SpatialCaptureSource that packs a NetworkGeometryBuffer's driving network through write_netwo...
@ FileIO
Filesystem I/O operations.
@ IO
Networking, file handling, streaming.
One named stream a SpatialCapture (or save_spatial_snapshot) writes into a SpatialCache each tick.
std::atomic< bool > stop_requested
std::shared_ptr< SpatialCache > cache
std::atomic< uint32_t > frame
std::atomic< bool > recording
std::vector< SpatialCaptureSource > sources
Portal::Graphics::PrimitiveTopology topology
One sample's worth of data for one named stream.
graphics-domain awaiter for frame-accurate timing delays
Templated awaitable for accessing a coroutine's promise object.