use oxigaf_flame::sequence::FlameSequence;
use std::path::PathBuf;
fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
let args: Vec<String> = std::env::args().collect();
if args.len() < 3 {
eprintln!("Usage:");
eprintln!(" {} json <sequence.json>", args[0]);
eprintln!(" {} npz <sequence.npz>", args[0]);
eprintln!(" {} dir <directory> <pattern> <num_frames>", args[0]);
eprintln!();
eprintln!("Examples:");
eprintln!(" {} json my_sequence.json", args[0]);
eprintln!(" {} npz tracked_params.npz", args[0]);
eprintln!(" {} dir frames/ \"frame_{{:04}}.json\" 100", args[0]);
std::process::exit(1);
}
let format = &args[1];
let mut sequence = match format.as_str() {
"json" => {
let path = PathBuf::from(&args[2]);
println!("Loading sequence from JSON: {}", path.display());
FlameSequence::from_json(&path)?
}
"npz" => {
#[cfg(feature = "npz")]
{
let path = PathBuf::from(&args[2]);
println!("Loading sequence from NPZ: {}", path.display());
FlameSequence::from_npz(&path)?
}
#[cfg(not(feature = "npz"))]
{
eprintln!("Error: NPZ support not enabled. Rebuild with --features npz");
std::process::exit(1);
}
}
"dir" => {
if args.len() < 5 {
eprintln!("Error: Directory format requires 3 arguments");
eprintln!("Usage: {} dir <directory> <pattern> <num_frames>", args[0]);
std::process::exit(1);
}
let dir = PathBuf::from(&args[2]);
let pattern = &args[3];
let num_frames: usize = args[4]
.parse()
.map_err(|_| "Invalid num_frames: must be a positive integer")?;
println!("Loading sequence from directory: {}", dir.display());
println!(" Pattern: {}", pattern);
println!(" Frames: {}", num_frames);
FlameSequence::from_directory(&dir, pattern, num_frames, None)?
}
_ => {
eprintln!("Error: Unknown format '{}'", format);
eprintln!("Supported formats: json, npz, dir");
std::process::exit(1);
}
};
println!();
println!("Sequence loaded successfully!");
println!(" Total frames: {}", sequence.num_frames());
if let Some(fps) = sequence.fps() {
println!(" FPS: {}", fps);
println!(" Duration: {:.2}s", sequence.num_frames() as f32 / fps);
}
let first_frame = sequence.get_frame(0)?;
println!();
println!("Parameter dimensions:");
println!(" Shape: {} coefficients", first_frame.shape.len());
println!(
" Expression: {} coefficients",
first_frame.expression.len()
);
println!(" Pose: {} coefficients", first_frame.pose.len());
println!(
" Translation: [{:.3}, {:.3}, {:.3}]",
first_frame.translation[0], first_frame.translation[1], first_frame.translation[2]
);
println!();
println!("Frame access examples:");
if sequence.num_frames() > 1 {
let mid_idx = sequence.num_frames() / 2;
let mid_frame = sequence.get_frame(mid_idx)?;
println!(" Frame {} shape[0]: {:.6}", mid_idx, mid_frame.shape[0]);
}
if sequence.num_frames() > 2 {
let interp_frame = sequence.interpolate(1.5)?;
println!(
" Interpolated frame 1.5 shape[0]: {:.6}",
interp_frame.shape[0]
);
}
println!();
println!("First 5 frames:");
for (i, result) in sequence.iter().take(5).enumerate() {
let frame = result?;
println!(
" Frame {}: shape[0]={:.6}, expr[0]={:.6}",
i, frame.shape[0], frame.expression[0]
);
}
println!();
println!("Done!");
Ok(())
}