Files
RustNotMC/crates/horizon-assets/examples/sprite_animation_fixture.rs
SashegDev 874b6f20c2 Клиент: начальный импорт кодовой базы
Основа — Horizon (MIT). История апстрима не переносится: этот репозиторий ведёт свою.
2026-10-29 22:04:28 +03:00

69 lines
2.6 KiB
Rust

use horizon_assets::animation::{AnimationMetadata, AnimationSample};
use serde_json::{Value, json};
use std::{
fs::File,
io::{BufRead, BufReader, BufWriter, Write},
};
fn probe(row: &Value) -> Result<Value, Box<dyn std::error::Error>> {
let m = AnimationMetadata::from_json(row["json"].as_str().unwrap())?;
let width = row["width"].as_i64().unwrap() as i32;
let height = row["height"].as_i64().unwrap() as i32;
let size = m.frame_size(width, height);
let frames = m.frames.as_ref().map(|frames| {
frames
.iter()
.map(|f| json!({"index":f.index,"time":f.time}))
.collect::<Vec<_>>()
});
let mut result = json!({"metadata":{"frames":frames,"width":m.width,"height":m.height,"frametime":m.frame_time,"interpolate":m.interpolate},"size":size});
if size[0] > width || size[1] > height || width % size[0] != 0 || height % size[1] != 0 {
return Ok(result);
}
result["animation"] = match m.clip(((width / size[0]) * (height / size[1])) as u32)? {
None => Value::Null,
Some(clip) => {
let samples: Vec<_> = (0..=row["ticks"].as_u64().unwrap())
.map(|tick| sample(clip.sample(tick)))
.collect();
let mut edges = Vec::new();
let mut start = 0u64;
for &(_, duration) in clip.sequence() {
let duration = i64::from(duration);
for sub in [0, 1, duration / 2, duration - 2, duration - 1] {
if sub >= 0 && sub < duration {
edges.push(sample(clip.sample(start + sub as u64 + 1)));
}
}
start += duration as u64;
}
json!({"sequence":clip.sequence(),"columns":width/size[0],"samples":samples,"edges":edges})
}
};
Ok(result)
}
fn sample(v: AnimationSample) -> Value {
json!([
v.sequence_index,
v.sub_frame,
v.frame,
v.next_frame,
v.dirty,
v.needs_draw,
v.interpolation_millis
])
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<_> = std::env::args().collect();
let input = BufReader::new(File::open(&args[1])?);
let mut output = BufWriter::new(File::create(&args[2])?);
for line in input.lines() {
let row: Value = serde_json::from_str(&line?)?;
let result = match probe(&row) {
Ok(value) => json!({"name":row["name"],"value":value}),
Err(_) => json!({"name":row["name"],"error":true}),
};
writeln!(output, "{result}")?;
}
Ok(())
}