@@ -48,6 +48,10 @@ struct Args {
4848 #[ arg( long, default_value = "4" ) ]
4949 speed_multiplier : u32 ,
5050
51+ /// Starting step/coordinate index in the runs (default: 0)
52+ #[ arg( long) ]
53+ start_step : Option < usize > ,
54+
5155 /// Maximum number of frames to render (for testing)
5256 #[ arg( long) ]
5357 max_frames : Option < usize > ,
@@ -99,6 +103,11 @@ async fn run() -> Result<()> {
99103 log:: info!( "Output: {:?}" , args. output) ;
100104 log:: info!( "Speed multiplier: {}x ({}ms between coords)" , args. speed_multiplier, args. interval_ms / args. speed_multiplier) ;
101105
106+ let start_step = args. start_step . unwrap_or ( 0 ) ;
107+ if start_step > 0 {
108+ log:: info!( "Starting from step/coord index: {}" , start_step) ;
109+ }
110+
102111 // Load coordinate mapper
103112 log:: info!( "Loading map data..." ) ;
104113 let coordinate_mapper = CoordinateMapper :: load ( & args. map_data ) ?;
@@ -116,19 +125,31 @@ async fn run() -> Result<()> {
116125 // Calculate max duration (with faster animation speed)
117126 let effective_interval_ms = ( args. interval_ms / args. speed_multiplier ) as f32 ;
118127 let max_coords = metadata. iter ( ) . map ( |m| m. coord_count ) . max ( ) . unwrap ( ) ;
119- let max_duration_ms = max_coords as f32 * effective_interval_ms;
120128
121- let mut total_frames = ( max_duration_ms / 1000.0 * args. fps as f32 ) . ceil ( ) as usize ;
129+ // Validate start_step
130+ if start_step >= max_coords {
131+ log:: error!( "start_step ({}) exceeds maximum coordinate count ({}) in runs" , start_step, max_coords) ;
132+ return Ok ( ( ) ) ;
133+ }
134+
135+ // Calculate time offset for start_step
136+ let start_time_offset_ms = start_step as f32 * effective_interval_ms;
137+
138+ // Calculate remaining duration from start_step to end
139+ let remaining_coords = max_coords - start_step;
140+ let remaining_duration_ms = remaining_coords as f32 * effective_interval_ms;
141+
142+ let mut total_frames = ( remaining_duration_ms / 1000.0 * args. fps as f32 ) . ceil ( ) as usize ;
122143
123144 if let Some ( max) = args. max_frames {
124145 if max < total_frames {
125146 total_frames = max;
126- log:: info!( "Limiting to {} frames (instead of full animation)" , max) ;
147+ log:: info!( "Limiting to {} frames (instead of full animation from start_step )" , max) ;
127148 }
128149 }
129150
130- log:: info!( "Animation: {:.2} seconds, {} frames @ {} fps" ,
131- total_frames as f32 / args. fps as f32 , total_frames, args. fps) ;
151+ log:: info!( "Animation: {:.2} seconds, {} frames @ {} fps (from step {} to end) " ,
152+ total_frames as f32 / args. fps as f32 , total_frames, args. fps, start_step ) ;
132153 log:: info!( "Total runs: {}" , metadata. len( ) ) ;
133154
134155 // Calculate chunk size (1/8 of max coords)
@@ -180,7 +201,8 @@ async fn run() -> Result<()> {
180201 let mut loaded_chunk_end = 0 ;
181202
182203 for frame_number in 0 ..total_frames {
183- let time_ms = frame_number as f32 * ( 1000.0 / args. fps as f32 ) ;
204+ // Add start_time_offset_ms to effectively start from start_step
205+ let time_ms = ( frame_number as f32 * ( 1000.0 / args. fps as f32 ) ) + start_time_offset_ms;
184206
185207 // Determine which coord indices are accessed in this frame (approximately)
186208 // Use median coord index to determine which chunk to load
0 commit comments