-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Labels
area:apiPublic API designPublic API designarea:writingFile/format writing/exportFile/format writing/exportcrate:ltk_animAnimation & skeleton crateAnimation & skeleton crateenhancementNew feature or requestNew feature or requestformat:anmAnimation formatAnimation formatgood first issueGood for newcomersGood for newcomers
Description
Summary
Add a builder API for creating Uncompressed animation assets from raw animation data. This is simpler than compressed animations since it does not require curve fitting.
Background
Currently, Uncompressed::new() exists but requires manually constructing palettes and frame indices:
pub fn new(
fps: f32,
vector_palette: Vec<Vec3>,
quat_palette: Vec<Quat>,
joint_frames: HashMap<u32, Vec<UncompressedFrame>>,
) -> SelfThis is low-level and requires users to:
- Build deduplicated vector/quaternion palettes manually
- Track palette indices for each frame
- Construct
UncompressedFrameentries with correct indices
Proposed API
A higher-level builder that handles palette construction automatically:
pub struct UncompressedBuilder {
fps: f32,
joints: Vec<u32>,
samples: HashMap<u32, Vec<JointTransform>>,
}
pub struct JointTransform {
pub rotation: Quat,
pub translation: Vec3,
pub scale: Vec3,
}
impl UncompressedBuilder {
/// Create a new builder with the given FPS
pub fn new(fps: f32) -> Self;
/// Add a joint to the animation
pub fn add_joint(&mut self, joint_hash: u32) -> &mut Self;
/// Add a frame for a joint (call once per frame, in order)
pub fn add_frame(
&mut self,
joint_hash: u32,
transform: JointTransform,
) -> &mut Self;
/// Add all frames for a joint at once
pub fn set_joint_frames(
&mut self,
joint_hash: u32,
frames: Vec<JointTransform>,
) -> &mut Self;
/// Build the animation
///
/// Automatically:
/// - Deduplicates vectors and quaternions into palettes
/// - Constructs frame index references
/// - Calculates duration from frame count
pub fn build(self) -> Result<Uncompressed, Error>;
}Example Usage
use ltk_anim::{UncompressedBuilder, JointTransform};
use glam::{Quat, Vec3};
let mut builder = UncompressedBuilder::new(30.0); // 30 FPS
// Add frames for each joint
for frame in 0..60 {
builder.add_frame(joint_hash, JointTransform {
rotation: Quat::from_rotation_y(frame as f32 * 0.1),
translation: Vec3::new(0.0, frame as f32 * 0.01, 0.0),
scale: Vec3::ONE,
});
}
let animation = builder.build()?;
animation.to_writer(&mut file)?;Implementation Notes
The build() method should:
- Collect all unique vectors (translations + scales) into a palette
- Collect all unique quaternions into a palette
- Use approximate equality for deduplication (configurable epsilon)
- Build
UncompressedFrameentries with palette indices - Validate all joints have the same frame count
Tasks
- Add
JointTransformstruct (or reuse existing transform type) - Implement
UncompressedBuilder - Add palette deduplication with configurable tolerance
- Add validation (frame count consistency, etc.)
- Add tests
- Add documentation with examples
Complexity
This is simpler than compressed animation writing since:
- No curve fitting required
- No special frame ordering
- No jump cache generation
- Just palette building and index tracking
Marked as good first issue for contributors familiar with Rust builders.
Metadata
Metadata
Assignees
Labels
area:apiPublic API designPublic API designarea:writingFile/format writing/exportFile/format writing/exportcrate:ltk_animAnimation & skeleton crateAnimation & skeleton crateenhancementNew feature or requestNew feature or requestformat:anmAnimation formatAnimation formatgood first issueGood for newcomersGood for newcomers
Type
Projects
Status
Todo